diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 0000000000..574fbb4b7b --- /dev/null +++ b/.coveragerc @@ -0,0 +1,17 @@ +[run] +branch=True +relative_files=True +source= + chia + tests +concurrency=multiprocessing +parallel=True + +[report] +precision = 1 +exclude_lines = + pragma: no cover + abc\.abstractmethod + typing\.overload + ^\s*\.\.\.\s*$ + if typing.TYPE_CHECKING: diff --git a/.github/workflows/benchmarks.yml b/.github/workflows/benchmarks.yml index bbcbf91456..90bea4ef84 100644 --- a/.github/workflows/benchmarks.yml +++ b/.github/workflows/benchmarks.yml @@ -28,7 +28,7 @@ jobs: steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -43,7 +43,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ${{ steps.pip-cache.outputs.dir }} key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }} diff --git a/.github/workflows/build-linux-arm64-installer.yml b/.github/workflows/build-linux-arm64-installer.yml index 5254306a4a..fad14fa525 100644 --- a/.github/workflows/build-linux-arm64-installer.yml +++ b/.github/workflows/build-linux-arm64-installer.yml @@ -31,7 +31,7 @@ jobs: - uses: Chia-Network/actions/clean-workspace@main - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 submodules: recursive @@ -62,13 +62,13 @@ jobs: SECRET: "${{ secrets.INSTALLER_UPLOAD_SECRET }}" # Get the most recent release from chia-plotter-madmax - - uses: actions/github-script@v4 + - uses: actions/github-script@v6 id: 'latest-madmax' with: github-token: ${{ secrets.GITHUB_TOKEN }} result-encoding: string script: | - const releases = await github.repos.listReleases({ + const releases = await github.rest.repos.listReleases({ owner: 'Chia-Network', repo: 'chia-plotter-madmax', }); @@ -83,13 +83,13 @@ jobs: chmod +x "$GITHUB_WORKSPACE/madmax/chia_plot_k34" # Get the most recent release from bladebit - - uses: actions/github-script@v4 + - uses: actions/github-script@v6 id: 'latest-bladebit' with: github-token: ${{ secrets.GITHUB_TOKEN }} result-encoding: string script: | - const releases = await github.repos.listReleases({ + const releases = await github.rest.repos.listReleases({ owner: 'Chia-Network', repo: 'bladebit', }); diff --git a/.github/workflows/build-linux-installer-deb.yml b/.github/workflows/build-linux-installer-deb.yml index 3cb64637a2..5734d6204f 100644 --- a/.github/workflows/build-linux-installer-deb.yml +++ b/.github/workflows/build-linux-installer-deb.yml @@ -30,7 +30,7 @@ jobs: steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 submodules: recursive @@ -49,7 +49,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Cache npm - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 env: cache-name: cache-node-modules with: @@ -67,7 +67,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: # Note that new runners may break this https://github.com/actions/cache/issues/292 path: ${{ steps.pip-cache.outputs.dir }} @@ -96,13 +96,13 @@ jobs: SECRET: "${{ secrets.INSTALLER_UPLOAD_SECRET }}" # Get the most recent release from chia-plotter-madmax - - uses: actions/github-script@v4 + - uses: actions/github-script@v6 id: 'latest-madmax' with: github-token: ${{ secrets.GITHUB_TOKEN }} result-encoding: string script: | - const releases = await github.repos.listReleases({ + const releases = await github.rest.repos.listReleases({ owner: 'Chia-Network', repo: 'chia-plotter-madmax', }); @@ -117,13 +117,13 @@ jobs: chmod +x "$GITHUB_WORKSPACE/madmax/chia_plot_k34" # Get the most recent release from bladebit - - uses: actions/github-script@v4 + - uses: actions/github-script@v6 id: 'latest-bladebit' with: github-token: ${{ secrets.GITHUB_TOKEN }} result-encoding: string script: | - const releases = await github.repos.listReleases({ + const releases = await github.rest.repos.listReleases({ owner: 'Chia-Network', repo: 'bladebit', }); @@ -144,7 +144,7 @@ jobs: sh install.sh - name: Setup Node 16.x - uses: actions/setup-node@v2.4.1 + uses: actions/setup-node@v3 with: node-version: '16.x' diff --git a/.github/workflows/build-linux-installer-rpm.yml b/.github/workflows/build-linux-installer-rpm.yml index e2fabeff28..5564b472e5 100644 --- a/.github/workflows/build-linux-installer-rpm.yml +++ b/.github/workflows/build-linux-installer-rpm.yml @@ -31,7 +31,7 @@ jobs: steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 submodules: recursive @@ -65,13 +65,13 @@ jobs: SECRET: "${{ secrets.INSTALLER_UPLOAD_SECRET }}" # Get the most recent release from chia-plotter-madmax - - uses: actions/github-script@v4 + - uses: actions/github-script@v6 id: 'latest-madmax' with: github-token: ${{ secrets.GITHUB_TOKEN }} result-encoding: string script: | - const releases = await github.repos.listReleases({ + const releases = await github.rest.repos.listReleases({ owner: 'Chia-Network', repo: 'chia-plotter-madmax', }); @@ -86,13 +86,13 @@ jobs: chmod +x "$GITHUB_WORKSPACE/madmax/chia_plot_k34" # Get the most recent release from bladebit - - uses: actions/github-script@v4 + - uses: actions/github-script@v6 id: 'latest-bladebit' with: github-token: ${{ secrets.GITHUB_TOKEN }} result-encoding: string script: | - const releases = await github.repos.listReleases({ + const releases = await github.rest.repos.listReleases({ owner: 'Chia-Network', repo: 'bladebit', }); diff --git a/.github/workflows/build-macos-installer.yml b/.github/workflows/build-macos-installer.yml index 56ab554812..f9d3fc3fae 100644 --- a/.github/workflows/build-macos-installer.yml +++ b/.github/workflows/build-macos-installer.yml @@ -29,7 +29,7 @@ jobs: steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 submodules: recursive @@ -70,7 +70,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Cache npm - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 env: cache-name: cache-node-modules with: @@ -88,7 +88,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: # Note that new runners may break this https://github.com/actions/cache/issues/292 path: ${{ steps.pip-cache.outputs.dir }} @@ -104,13 +104,13 @@ jobs: p12-password: ${{ secrets.APPLE_DEV_ID_APP_PASS }} # Get the most recent release from chia-plotter-madmax - - uses: actions/github-script@v4 + - uses: actions/github-script@v6 id: 'latest-madmax' with: github-token: ${{ secrets.GITHUB_TOKEN }} result-encoding: string script: | - const releases = await github.repos.listReleases({ + const releases = await github.rest.repos.listReleases({ owner: 'Chia-Network', repo: 'chia-plotter-madmax', }); @@ -132,7 +132,7 @@ jobs: sh install.sh - name: Setup Node 16.x - uses: actions/setup-node@v2.4.1 + uses: actions/setup-node@v3 with: node-version: '16.x' diff --git a/.github/workflows/build-macos-m1-installer.yml b/.github/workflows/build-macos-m1-installer.yml index 889e464e8e..7a178382e3 100644 --- a/.github/workflows/build-macos-m1-installer.yml +++ b/.github/workflows/build-macos-m1-installer.yml @@ -29,7 +29,7 @@ jobs: - uses: Chia-Network/actions/clean-workspace@main - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 submodules: recursive @@ -78,13 +78,13 @@ jobs: p12-password: ${{ secrets.APPLE_DEV_ID_APP_PASS }} # Get the most recent release from chia-plotter-madmax - - uses: actions/github-script@v4 + - uses: actions/github-script@v6 id: 'latest-madmax' with: github-token: ${{ secrets.GITHUB_TOKEN }} result-encoding: string script: | - const releases = await github.repos.listReleases({ + const releases = await github.rest.repos.listReleases({ owner: 'Chia-Network', repo: 'chia-plotter-madmax', }); diff --git a/.github/workflows/build-test-macos-blockchain.yml b/.github/workflows/build-test-macos-blockchain.yml index eb5c491156..6edf41d2d4 100644 --- a/.github/workflows/build-test-macos-blockchain.yml +++ b/.github/workflows/build-test-macos-blockchain.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.8, 3.9] os: [macOS-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_blockchain steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -54,7 +57,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: # Note that new runners may break this https://github.com/actions/cache/issues/292 path: ${{ steps.pip-cache.outputs.dir }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -89,7 +85,23 @@ jobs: - name: Test blockchain code with pytest run: | . ./activate - ./venv/bin/py.test tests/blockchain/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/blockchain/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" + + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme # diff --git a/.github/workflows/build-test-macos-clvm.yml b/.github/workflows/build-test-macos-clvm.yml index 4b50f98589..414ff342c7 100644 --- a/.github/workflows/build-test-macos-clvm.yml +++ b/.github/workflows/build-test-macos-clvm.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.8, 3.9] os: [macOS-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_clvm steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -54,7 +57,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: # Note that new runners may break this https://github.com/actions/cache/issues/292 path: ${{ steps.pip-cache.outputs.dir }} @@ -76,7 +79,23 @@ jobs: - name: Test clvm code with pytest run: | . ./activate - ./venv/bin/py.test tests/clvm/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/clvm/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" + + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme # diff --git a/.github/workflows/build-test-macos-core-cmds.yml b/.github/workflows/build-test-macos-core-cmds.yml index 1b39507bb3..6b5548a526 100644 --- a/.github/workflows/build-test-macos-core-cmds.yml +++ b/.github/workflows/build-test-macos-core-cmds.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.8, 3.9] os: [macOS-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_core-cmds steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -54,7 +57,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: # Note that new runners may break this https://github.com/actions/cache/issues/292 path: ${{ steps.pip-cache.outputs.dir }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -89,7 +85,23 @@ jobs: - name: Test core-cmds code with pytest run: | . ./activate - ./venv/bin/py.test tests/core/cmds/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/core/cmds/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" + + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme # diff --git a/.github/workflows/build-test-macos-core-consensus.yml b/.github/workflows/build-test-macos-core-consensus.yml index de123a845a..0a95110a98 100644 --- a/.github/workflows/build-test-macos-core-consensus.yml +++ b/.github/workflows/build-test-macos-core-consensus.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.8, 3.9] os: [macOS-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_core-consensus steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -54,7 +57,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: # Note that new runners may break this https://github.com/actions/cache/issues/292 path: ${{ steps.pip-cache.outputs.dir }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -89,7 +85,23 @@ jobs: - name: Test core-consensus code with pytest run: | . ./activate - ./venv/bin/py.test tests/core/consensus/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/core/consensus/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" + + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme # diff --git a/.github/workflows/build-test-macos-core-custom_types.yml b/.github/workflows/build-test-macos-core-custom_types.yml index da1af33f77..d08ed4e638 100644 --- a/.github/workflows/build-test-macos-core-custom_types.yml +++ b/.github/workflows/build-test-macos-core-custom_types.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.8, 3.9] os: [macOS-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_core-custom_types steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -54,7 +57,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: # Note that new runners may break this https://github.com/actions/cache/issues/292 path: ${{ steps.pip-cache.outputs.dir }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -89,7 +85,23 @@ jobs: - name: Test core-custom_types code with pytest run: | . ./activate - ./venv/bin/py.test tests/core/custom_types/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/core/custom_types/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" + + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme # diff --git a/.github/workflows/build-test-macos-core-daemon.yml b/.github/workflows/build-test-macos-core-daemon.yml index bb949be6bd..b7c94c8743 100644 --- a/.github/workflows/build-test-macos-core-daemon.yml +++ b/.github/workflows/build-test-macos-core-daemon.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.8, 3.9] os: [macOS-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_core-daemon steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -54,7 +57,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: # Note that new runners may break this https://github.com/actions/cache/issues/292 path: ${{ steps.pip-cache.outputs.dir }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -101,7 +97,23 @@ jobs: - name: Test core-daemon code with pytest run: | . ./activate - ./venv/bin/py.test tests/core/daemon/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/core/daemon/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" + + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme # diff --git a/.github/workflows/build-test-macos-core-full_node-full_sync.yml b/.github/workflows/build-test-macos-core-full_node-full_sync.yml index 070827af08..f0ae27d1d6 100644 --- a/.github/workflows/build-test-macos-core-full_node-full_sync.yml +++ b/.github/workflows/build-test-macos-core-full_node-full_sync.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.8, 3.9] os: [macOS-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_core-full_node-full_sync steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -54,7 +57,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: # Note that new runners may break this https://github.com/actions/cache/issues/292 path: ${{ steps.pip-cache.outputs.dir }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -89,7 +85,23 @@ jobs: - name: Test core-full_node-full_sync code with pytest run: | . ./activate - ./venv/bin/py.test tests/core/full_node/full_sync/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/core/full_node/full_sync/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" + + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme # diff --git a/.github/workflows/build-test-macos-core-full_node-stores.yml b/.github/workflows/build-test-macos-core-full_node-stores.yml index ae890bc0f9..c971b17215 100644 --- a/.github/workflows/build-test-macos-core-full_node-stores.yml +++ b/.github/workflows/build-test-macos-core-full_node-stores.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.8, 3.9] os: [macOS-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_core-full_node-stores steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -54,7 +57,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: # Note that new runners may break this https://github.com/actions/cache/issues/292 path: ${{ steps.pip-cache.outputs.dir }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -89,7 +85,23 @@ jobs: - name: Test core-full_node-stores code with pytest run: | . ./activate - ./venv/bin/py.test tests/core/full_node/stores/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/core/full_node/stores/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" + + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme # diff --git a/.github/workflows/build-test-macos-core-full_node.yml b/.github/workflows/build-test-macos-core-full_node.yml index 417aec6810..4c13a79b5d 100644 --- a/.github/workflows/build-test-macos-core-full_node.yml +++ b/.github/workflows/build-test-macos-core-full_node.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.8, 3.9] os: [macOS-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_core-full_node steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -54,7 +57,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: # Note that new runners may break this https://github.com/actions/cache/issues/292 path: ${{ steps.pip-cache.outputs.dir }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -89,7 +85,23 @@ jobs: - name: Test core-full_node code with pytest run: | . ./activate - ./venv/bin/py.test tests/core/full_node/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/core/full_node/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" + + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme # diff --git a/.github/workflows/build-test-macos-core-server.yml b/.github/workflows/build-test-macos-core-server.yml index 5b214cac40..e4bceaf93d 100644 --- a/.github/workflows/build-test-macos-core-server.yml +++ b/.github/workflows/build-test-macos-core-server.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.8, 3.9] os: [macOS-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_core-server steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -54,7 +57,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: # Note that new runners may break this https://github.com/actions/cache/issues/292 path: ${{ steps.pip-cache.outputs.dir }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -89,7 +85,23 @@ jobs: - name: Test core-server code with pytest run: | . ./activate - ./venv/bin/py.test tests/core/server/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/core/server/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" + + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme # diff --git a/.github/workflows/build-test-macos-core-ssl.yml b/.github/workflows/build-test-macos-core-ssl.yml index 5ff17da64f..6b4b174832 100644 --- a/.github/workflows/build-test-macos-core-ssl.yml +++ b/.github/workflows/build-test-macos-core-ssl.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.8, 3.9] os: [macOS-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_core-ssl steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -54,7 +57,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: # Note that new runners may break this https://github.com/actions/cache/issues/292 path: ${{ steps.pip-cache.outputs.dir }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -89,7 +85,23 @@ jobs: - name: Test core-ssl code with pytest run: | . ./activate - ./venv/bin/py.test tests/core/ssl/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/core/ssl/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" + + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme # diff --git a/.github/workflows/build-test-macos-core-util.yml b/.github/workflows/build-test-macos-core-util.yml index 7775a0d121..2a01174dcd 100644 --- a/.github/workflows/build-test-macos-core-util.yml +++ b/.github/workflows/build-test-macos-core-util.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.8, 3.9] os: [macOS-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_core-util steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -54,7 +57,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: # Note that new runners may break this https://github.com/actions/cache/issues/292 path: ${{ steps.pip-cache.outputs.dir }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -89,7 +85,23 @@ jobs: - name: Test core-util code with pytest run: | . ./activate - ./venv/bin/py.test tests/core/util/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/core/util/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" + + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme # diff --git a/.github/workflows/build-test-macos-core.yml b/.github/workflows/build-test-macos-core.yml index 3b6535909f..db9288eda4 100644 --- a/.github/workflows/build-test-macos-core.yml +++ b/.github/workflows/build-test-macos-core.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.8, 3.9] os: [macOS-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_core steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -54,7 +57,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: # Note that new runners may break this https://github.com/actions/cache/issues/292 path: ${{ steps.pip-cache.outputs.dir }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -89,7 +85,23 @@ jobs: - name: Test core code with pytest run: | . ./activate - ./venv/bin/py.test tests/core/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/core/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" + + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme # diff --git a/.github/workflows/build-test-macos-farmer_harvester.yml b/.github/workflows/build-test-macos-farmer_harvester.yml index 883e33ef29..d22814b660 100644 --- a/.github/workflows/build-test-macos-farmer_harvester.yml +++ b/.github/workflows/build-test-macos-farmer_harvester.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.8, 3.9] os: [macOS-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_farmer_harvester steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -54,7 +57,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: # Note that new runners may break this https://github.com/actions/cache/issues/292 path: ${{ steps.pip-cache.outputs.dir }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -89,7 +85,23 @@ jobs: - name: Test farmer_harvester code with pytest run: | . ./activate - ./venv/bin/py.test tests/farmer_harvester/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/farmer_harvester/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" + + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme # diff --git a/.github/workflows/build-test-macos-generator.yml b/.github/workflows/build-test-macos-generator.yml index 2b4edb974f..339d88dcaa 100644 --- a/.github/workflows/build-test-macos-generator.yml +++ b/.github/workflows/build-test-macos-generator.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.8, 3.9] os: [macOS-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_generator steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -54,7 +57,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: # Note that new runners may break this https://github.com/actions/cache/issues/292 path: ${{ steps.pip-cache.outputs.dir }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -89,7 +85,23 @@ jobs: - name: Test generator code with pytest run: | . ./activate - ./venv/bin/py.test tests/generator/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/generator/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" + + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme # diff --git a/.github/workflows/build-test-macos-plotting.yml b/.github/workflows/build-test-macos-plotting.yml index ec5b9cf895..0d614d0428 100644 --- a/.github/workflows/build-test-macos-plotting.yml +++ b/.github/workflows/build-test-macos-plotting.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.8, 3.9] os: [macOS-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_plotting steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -54,7 +57,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: # Note that new runners may break this https://github.com/actions/cache/issues/292 path: ${{ steps.pip-cache.outputs.dir }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -89,7 +85,23 @@ jobs: - name: Test plotting code with pytest run: | . ./activate - ./venv/bin/py.test tests/plotting/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/plotting/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" + + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme # diff --git a/.github/workflows/build-test-macos-pools.yml b/.github/workflows/build-test-macos-pools.yml index 4f7901bebe..80ff69a5db 100644 --- a/.github/workflows/build-test-macos-pools.yml +++ b/.github/workflows/build-test-macos-pools.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.8, 3.9] os: [macOS-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_pools steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -54,7 +57,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: # Note that new runners may break this https://github.com/actions/cache/issues/292 path: ${{ steps.pip-cache.outputs.dir }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -89,7 +85,23 @@ jobs: - name: Test pools code with pytest run: | . ./activate - ./venv/bin/py.test tests/pools/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/pools/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" + + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme # diff --git a/.github/workflows/build-test-macos-simulation.yml b/.github/workflows/build-test-macos-simulation.yml index e5c74f5613..3859585c05 100644 --- a/.github/workflows/build-test-macos-simulation.yml +++ b/.github/workflows/build-test-macos-simulation.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.8, 3.9] os: [macOS-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_simulation steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -54,7 +57,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: # Note that new runners may break this https://github.com/actions/cache/issues/292 path: ${{ steps.pip-cache.outputs.dir }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -101,7 +97,23 @@ jobs: - name: Test simulation code with pytest run: | . ./activate - ./venv/bin/py.test tests/simulation/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/simulation/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" + + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme # diff --git a/.github/workflows/build-test-macos-tools.yml b/.github/workflows/build-test-macos-tools.yml index aa43cf015d..3e4e981a37 100644 --- a/.github/workflows/build-test-macos-tools.yml +++ b/.github/workflows/build-test-macos-tools.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.8, 3.9] os: [macOS-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_tools steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -54,7 +57,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: # Note that new runners may break this https://github.com/actions/cache/issues/292 path: ${{ steps.pip-cache.outputs.dir }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -89,7 +85,23 @@ jobs: - name: Test tools code with pytest run: | . ./activate - ./venv/bin/py.test tests/tools/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/tools/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" + + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme # diff --git a/.github/workflows/build-test-macos-util.yml b/.github/workflows/build-test-macos-util.yml index 3e5b5c191d..3fa4a0c2ee 100644 --- a/.github/workflows/build-test-macos-util.yml +++ b/.github/workflows/build-test-macos-util.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.8, 3.9] os: [macOS-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_util steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -54,7 +57,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: # Note that new runners may break this https://github.com/actions/cache/issues/292 path: ${{ steps.pip-cache.outputs.dir }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -89,7 +85,23 @@ jobs: - name: Test util code with pytest run: | . ./activate - ./venv/bin/py.test tests/util/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/util/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" + + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme # diff --git a/.github/workflows/build-test-macos-wallet-cat_wallet.yml b/.github/workflows/build-test-macos-wallet-cat_wallet.yml index bdbe48290f..16be450bd0 100644 --- a/.github/workflows/build-test-macos-wallet-cat_wallet.yml +++ b/.github/workflows/build-test-macos-wallet-cat_wallet.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.8, 3.9] os: [macOS-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_wallet-cat_wallet steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -54,7 +57,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: # Note that new runners may break this https://github.com/actions/cache/issues/292 path: ${{ steps.pip-cache.outputs.dir }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -89,7 +85,23 @@ jobs: - name: Test wallet-cat_wallet code with pytest run: | . ./activate - ./venv/bin/py.test tests/wallet/cat_wallet/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/wallet/cat_wallet/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" + + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme # diff --git a/.github/workflows/build-test-macos-wallet-did_wallet.yml b/.github/workflows/build-test-macos-wallet-did_wallet.yml index 1bea77b1f4..29efd583d7 100644 --- a/.github/workflows/build-test-macos-wallet-did_wallet.yml +++ b/.github/workflows/build-test-macos-wallet-did_wallet.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.8, 3.9] os: [macOS-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_wallet-did_wallet steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -54,7 +57,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: # Note that new runners may break this https://github.com/actions/cache/issues/292 path: ${{ steps.pip-cache.outputs.dir }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -89,7 +85,23 @@ jobs: - name: Test wallet-did_wallet code with pytest run: | . ./activate - ./venv/bin/py.test tests/wallet/did_wallet/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/wallet/did_wallet/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" + + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme # diff --git a/.github/workflows/build-test-macos-wallet-rl_wallet.yml b/.github/workflows/build-test-macos-wallet-rl_wallet.yml index 2ebbe237c4..af3cb0d9d1 100644 --- a/.github/workflows/build-test-macos-wallet-rl_wallet.yml +++ b/.github/workflows/build-test-macos-wallet-rl_wallet.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.8, 3.9] os: [macOS-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_wallet-rl_wallet steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -54,7 +57,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: # Note that new runners may break this https://github.com/actions/cache/issues/292 path: ${{ steps.pip-cache.outputs.dir }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -89,7 +85,23 @@ jobs: - name: Test wallet-rl_wallet code with pytest run: | . ./activate - ./venv/bin/py.test tests/wallet/rl_wallet/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/wallet/rl_wallet/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" + + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme # diff --git a/.github/workflows/build-test-macos-wallet-rpc.yml b/.github/workflows/build-test-macos-wallet-rpc.yml index b7be9d3274..9629b8d628 100644 --- a/.github/workflows/build-test-macos-wallet-rpc.yml +++ b/.github/workflows/build-test-macos-wallet-rpc.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.8, 3.9] os: [macOS-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_wallet-rpc steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -54,7 +57,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: # Note that new runners may break this https://github.com/actions/cache/issues/292 path: ${{ steps.pip-cache.outputs.dir }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -89,7 +85,23 @@ jobs: - name: Test wallet-rpc code with pytest run: | . ./activate - ./venv/bin/py.test tests/wallet/rpc/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/wallet/rpc/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" + + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme # diff --git a/.github/workflows/build-test-macos-wallet-simple_sync.yml b/.github/workflows/build-test-macos-wallet-simple_sync.yml index c943ac4c67..7c6ae1eee6 100644 --- a/.github/workflows/build-test-macos-wallet-simple_sync.yml +++ b/.github/workflows/build-test-macos-wallet-simple_sync.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.8, 3.9] os: [macOS-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_wallet-simple_sync steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -54,7 +57,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: # Note that new runners may break this https://github.com/actions/cache/issues/292 path: ${{ steps.pip-cache.outputs.dir }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -89,7 +85,23 @@ jobs: - name: Test wallet-simple_sync code with pytest run: | . ./activate - ./venv/bin/py.test tests/wallet/simple_sync/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/wallet/simple_sync/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" + + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme # diff --git a/.github/workflows/build-test-macos-wallet-sync.yml b/.github/workflows/build-test-macos-wallet-sync.yml index ac0c0ce180..ad293617eb 100644 --- a/.github/workflows/build-test-macos-wallet-sync.yml +++ b/.github/workflows/build-test-macos-wallet-sync.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.8, 3.9] os: [macOS-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_wallet-sync steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -54,7 +57,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: # Note that new runners may break this https://github.com/actions/cache/issues/292 path: ${{ steps.pip-cache.outputs.dir }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -89,7 +85,23 @@ jobs: - name: Test wallet-sync code with pytest run: | . ./activate - ./venv/bin/py.test tests/wallet/sync/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/wallet/sync/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" + + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme # diff --git a/.github/workflows/build-test-macos-wallet.yml b/.github/workflows/build-test-macos-wallet.yml index 9f5f2376a2..8073f21328 100644 --- a/.github/workflows/build-test-macos-wallet.yml +++ b/.github/workflows/build-test-macos-wallet.yml @@ -22,17 +22,20 @@ jobs: build: name: MacOS wallet Tests runs-on: ${{ matrix.os }} - timeout-minutes: 30 + timeout-minutes: 40 strategy: fail-fast: false max-parallel: 4 matrix: python-version: [3.8, 3.9] os: [macOS-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_wallet steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -54,7 +57,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: # Note that new runners may break this https://github.com/actions/cache/issues/292 path: ${{ steps.pip-cache.outputs.dir }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -89,7 +85,23 @@ jobs: - name: Test wallet code with pytest run: | . ./activate - ./venv/bin/py.test tests/wallet/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/wallet/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" + + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme # diff --git a/.github/workflows/build-test-macos-weight_proof.yml b/.github/workflows/build-test-macos-weight_proof.yml index a20984374c..2c45969587 100644 --- a/.github/workflows/build-test-macos-weight_proof.yml +++ b/.github/workflows/build-test-macos-weight_proof.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.8, 3.9] os: [macOS-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_weight_proof steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -54,7 +57,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: # Note that new runners may break this https://github.com/actions/cache/issues/292 path: ${{ steps.pip-cache.outputs.dir }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -89,7 +85,23 @@ jobs: - name: Test weight_proof code with pytest run: | . ./activate - ./venv/bin/py.test tests/weight_proof/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/weight_proof/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" + + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme # diff --git a/.github/workflows/build-test-ubuntu-blockchain.yml b/.github/workflows/build-test-ubuntu-blockchain.yml index e022781bdc..94109d800d 100644 --- a/.github/workflows/build-test-ubuntu-blockchain.yml +++ b/.github/workflows/build-test-ubuntu-blockchain.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.7, 3.8, 3.9] os: [ubuntu-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_blockchain steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -42,7 +45,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Cache npm - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} @@ -55,7 +58,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ${{ steps.pip-cache.outputs.dir }} key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -88,8 +84,25 @@ jobs: - name: Test blockchain code with pytest run: | . ./activate - ./venv/bin/py.test tests/blockchain/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/blockchain/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" -p no:monitor + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error + +# Omitted resource usage check # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme diff --git a/.github/workflows/build-test-ubuntu-clvm.yml b/.github/workflows/build-test-ubuntu-clvm.yml index 3502240563..de7660a488 100644 --- a/.github/workflows/build-test-ubuntu-clvm.yml +++ b/.github/workflows/build-test-ubuntu-clvm.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.7, 3.8, 3.9] os: [ubuntu-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_clvm steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -42,7 +45,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Cache npm - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} @@ -55,7 +58,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ${{ steps.pip-cache.outputs.dir }} key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }} @@ -75,8 +78,25 @@ jobs: - name: Test clvm code with pytest run: | . ./activate - ./venv/bin/py.test tests/clvm/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/clvm/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" -p no:monitor + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error + +# Omitted resource usage check # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme diff --git a/.github/workflows/build-test-ubuntu-core-cmds.yml b/.github/workflows/build-test-ubuntu-core-cmds.yml index a8a76f9250..7939d45b1f 100644 --- a/.github/workflows/build-test-ubuntu-core-cmds.yml +++ b/.github/workflows/build-test-ubuntu-core-cmds.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.7, 3.8, 3.9] os: [ubuntu-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_core-cmds steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -42,7 +45,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Cache npm - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} @@ -55,7 +58,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ${{ steps.pip-cache.outputs.dir }} key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -88,8 +84,25 @@ jobs: - name: Test core-cmds code with pytest run: | . ./activate - ./venv/bin/py.test tests/core/cmds/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/core/cmds/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" -p no:monitor + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error + +# Omitted resource usage check # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme diff --git a/.github/workflows/build-test-ubuntu-core-consensus.yml b/.github/workflows/build-test-ubuntu-core-consensus.yml index c5d4c99816..8083c05ad5 100644 --- a/.github/workflows/build-test-ubuntu-core-consensus.yml +++ b/.github/workflows/build-test-ubuntu-core-consensus.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.7, 3.8, 3.9] os: [ubuntu-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_core-consensus steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -42,7 +45,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Cache npm - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} @@ -55,7 +58,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ${{ steps.pip-cache.outputs.dir }} key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -88,8 +84,25 @@ jobs: - name: Test core-consensus code with pytest run: | . ./activate - ./venv/bin/py.test tests/core/consensus/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/core/consensus/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" -p no:monitor + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error + +# Omitted resource usage check # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme diff --git a/.github/workflows/build-test-ubuntu-core-custom_types.yml b/.github/workflows/build-test-ubuntu-core-custom_types.yml index 1dbb92a55a..4684f2c25d 100644 --- a/.github/workflows/build-test-ubuntu-core-custom_types.yml +++ b/.github/workflows/build-test-ubuntu-core-custom_types.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.7, 3.8, 3.9] os: [ubuntu-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_core-custom_types steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -42,7 +45,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Cache npm - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} @@ -55,7 +58,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ${{ steps.pip-cache.outputs.dir }} key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -88,8 +84,25 @@ jobs: - name: Test core-custom_types code with pytest run: | . ./activate - ./venv/bin/py.test tests/core/custom_types/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/core/custom_types/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" -p no:monitor + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error + +# Omitted resource usage check # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme diff --git a/.github/workflows/build-test-ubuntu-core-daemon.yml b/.github/workflows/build-test-ubuntu-core-daemon.yml index 7dfbf69c77..524ab9ad30 100644 --- a/.github/workflows/build-test-ubuntu-core-daemon.yml +++ b/.github/workflows/build-test-ubuntu-core-daemon.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.7, 3.8, 3.9] os: [ubuntu-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_core-daemon steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -42,7 +45,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Cache npm - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} @@ -55,7 +58,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ${{ steps.pip-cache.outputs.dir }} key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -100,8 +96,25 @@ jobs: - name: Test core-daemon code with pytest run: | . ./activate - ./venv/bin/py.test tests/core/daemon/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/core/daemon/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" -p no:monitor + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error + +# Omitted resource usage check # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme diff --git a/.github/workflows/build-test-ubuntu-core-full_node-full_sync.yml b/.github/workflows/build-test-ubuntu-core-full_node-full_sync.yml index 29d3520904..40f05d1bfb 100644 --- a/.github/workflows/build-test-ubuntu-core-full_node-full_sync.yml +++ b/.github/workflows/build-test-ubuntu-core-full_node-full_sync.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.7, 3.8, 3.9] os: [ubuntu-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_core-full_node-full_sync steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -42,7 +45,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Cache npm - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} @@ -55,7 +58,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ${{ steps.pip-cache.outputs.dir }} key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -88,8 +84,25 @@ jobs: - name: Test core-full_node-full_sync code with pytest run: | . ./activate - ./venv/bin/py.test tests/core/full_node/full_sync/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/core/full_node/full_sync/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" -p no:monitor + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error + +# Omitted resource usage check # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme diff --git a/.github/workflows/build-test-ubuntu-core-full_node-stores.yml b/.github/workflows/build-test-ubuntu-core-full_node-stores.yml index ee7872baa1..d28a1294e9 100644 --- a/.github/workflows/build-test-ubuntu-core-full_node-stores.yml +++ b/.github/workflows/build-test-ubuntu-core-full_node-stores.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.7, 3.8, 3.9] os: [ubuntu-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_core-full_node-stores steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -42,7 +45,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Cache npm - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} @@ -55,7 +58,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ${{ steps.pip-cache.outputs.dir }} key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -88,8 +84,23 @@ jobs: - name: Test core-full_node-stores code with pytest run: | . ./activate - ./venv/bin/py.test tests/core/full_node/stores/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/core/full_node/stores/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error - name: Check resource usage run: | diff --git a/.github/workflows/build-test-ubuntu-core-full_node.yml b/.github/workflows/build-test-ubuntu-core-full_node.yml index 145edd820a..d19fb71f32 100644 --- a/.github/workflows/build-test-ubuntu-core-full_node.yml +++ b/.github/workflows/build-test-ubuntu-core-full_node.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.7, 3.8, 3.9] os: [ubuntu-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_core-full_node steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -42,7 +45,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Cache npm - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} @@ -55,7 +58,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ${{ steps.pip-cache.outputs.dir }} key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -88,8 +84,23 @@ jobs: - name: Test core-full_node code with pytest run: | . ./activate - ./venv/bin/py.test tests/core/full_node/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/core/full_node/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error - name: Check resource usage run: | diff --git a/.github/workflows/build-test-ubuntu-core-server.yml b/.github/workflows/build-test-ubuntu-core-server.yml index bb8d60e75a..6a24118aa7 100644 --- a/.github/workflows/build-test-ubuntu-core-server.yml +++ b/.github/workflows/build-test-ubuntu-core-server.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.7, 3.8, 3.9] os: [ubuntu-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_core-server steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -42,7 +45,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Cache npm - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} @@ -55,7 +58,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ${{ steps.pip-cache.outputs.dir }} key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -88,8 +84,25 @@ jobs: - name: Test core-server code with pytest run: | . ./activate - ./venv/bin/py.test tests/core/server/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/core/server/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" -p no:monitor + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error + +# Omitted resource usage check # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme diff --git a/.github/workflows/build-test-ubuntu-core-ssl.yml b/.github/workflows/build-test-ubuntu-core-ssl.yml index a4000b081d..e5074ab76b 100644 --- a/.github/workflows/build-test-ubuntu-core-ssl.yml +++ b/.github/workflows/build-test-ubuntu-core-ssl.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.7, 3.8, 3.9] os: [ubuntu-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_core-ssl steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -42,7 +45,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Cache npm - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} @@ -55,7 +58,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ${{ steps.pip-cache.outputs.dir }} key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -88,8 +84,25 @@ jobs: - name: Test core-ssl code with pytest run: | . ./activate - ./venv/bin/py.test tests/core/ssl/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/core/ssl/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" -p no:monitor + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error + +# Omitted resource usage check # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme diff --git a/.github/workflows/build-test-ubuntu-core-util.yml b/.github/workflows/build-test-ubuntu-core-util.yml index 076ee0943d..0b23005959 100644 --- a/.github/workflows/build-test-ubuntu-core-util.yml +++ b/.github/workflows/build-test-ubuntu-core-util.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.7, 3.8, 3.9] os: [ubuntu-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_core-util steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -42,7 +45,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Cache npm - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} @@ -55,7 +58,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ${{ steps.pip-cache.outputs.dir }} key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -88,8 +84,25 @@ jobs: - name: Test core-util code with pytest run: | . ./activate - ./venv/bin/py.test tests/core/util/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/core/util/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" -p no:monitor + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error + +# Omitted resource usage check # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme diff --git a/.github/workflows/build-test-ubuntu-core.yml b/.github/workflows/build-test-ubuntu-core.yml index 428f755292..eb06af8df6 100644 --- a/.github/workflows/build-test-ubuntu-core.yml +++ b/.github/workflows/build-test-ubuntu-core.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.7, 3.8, 3.9] os: [ubuntu-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_core steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -42,7 +45,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Cache npm - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} @@ -55,7 +58,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ${{ steps.pip-cache.outputs.dir }} key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -88,8 +84,25 @@ jobs: - name: Test core code with pytest run: | . ./activate - ./venv/bin/py.test tests/core/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/core/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" -p no:monitor + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error + +# Omitted resource usage check # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme diff --git a/.github/workflows/build-test-ubuntu-farmer_harvester.yml b/.github/workflows/build-test-ubuntu-farmer_harvester.yml index 882efb7cd4..37eaa651f7 100644 --- a/.github/workflows/build-test-ubuntu-farmer_harvester.yml +++ b/.github/workflows/build-test-ubuntu-farmer_harvester.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.7, 3.8, 3.9] os: [ubuntu-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_farmer_harvester steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -42,7 +45,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Cache npm - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} @@ -55,7 +58,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ${{ steps.pip-cache.outputs.dir }} key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -88,8 +84,25 @@ jobs: - name: Test farmer_harvester code with pytest run: | . ./activate - ./venv/bin/py.test tests/farmer_harvester/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/farmer_harvester/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" -p no:monitor + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error + +# Omitted resource usage check # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme diff --git a/.github/workflows/build-test-ubuntu-generator.yml b/.github/workflows/build-test-ubuntu-generator.yml index 1195dbd98d..707deb5adb 100644 --- a/.github/workflows/build-test-ubuntu-generator.yml +++ b/.github/workflows/build-test-ubuntu-generator.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.7, 3.8, 3.9] os: [ubuntu-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_generator steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -42,7 +45,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Cache npm - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} @@ -55,7 +58,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ${{ steps.pip-cache.outputs.dir }} key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -88,8 +84,25 @@ jobs: - name: Test generator code with pytest run: | . ./activate - ./venv/bin/py.test tests/generator/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/generator/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" -p no:monitor + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error + +# Omitted resource usage check # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme diff --git a/.github/workflows/build-test-ubuntu-plotting.yml b/.github/workflows/build-test-ubuntu-plotting.yml index db621908e8..9561180be1 100644 --- a/.github/workflows/build-test-ubuntu-plotting.yml +++ b/.github/workflows/build-test-ubuntu-plotting.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.7, 3.8, 3.9] os: [ubuntu-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_plotting steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -42,7 +45,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Cache npm - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} @@ -55,7 +58,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ${{ steps.pip-cache.outputs.dir }} key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -88,8 +84,25 @@ jobs: - name: Test plotting code with pytest run: | . ./activate - ./venv/bin/py.test tests/plotting/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/plotting/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" -p no:monitor + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error + +# Omitted resource usage check # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme diff --git a/.github/workflows/build-test-ubuntu-pools.yml b/.github/workflows/build-test-ubuntu-pools.yml index dec387db50..d083a12d7c 100644 --- a/.github/workflows/build-test-ubuntu-pools.yml +++ b/.github/workflows/build-test-ubuntu-pools.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.7, 3.8, 3.9] os: [ubuntu-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_pools steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -42,7 +45,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Cache npm - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} @@ -55,7 +58,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ${{ steps.pip-cache.outputs.dir }} key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -88,8 +84,25 @@ jobs: - name: Test pools code with pytest run: | . ./activate - ./venv/bin/py.test tests/pools/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/pools/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" -p no:monitor + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error + +# Omitted resource usage check # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme diff --git a/.github/workflows/build-test-ubuntu-simulation.yml b/.github/workflows/build-test-ubuntu-simulation.yml index 645a121e08..385fce0ed9 100644 --- a/.github/workflows/build-test-ubuntu-simulation.yml +++ b/.github/workflows/build-test-ubuntu-simulation.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.7, 3.8, 3.9] os: [ubuntu-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_simulation steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -42,7 +45,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Cache npm - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} @@ -55,7 +58,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ${{ steps.pip-cache.outputs.dir }} key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -100,8 +96,25 @@ jobs: - name: Test simulation code with pytest run: | . ./activate - ./venv/bin/py.test tests/simulation/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/simulation/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" -p no:monitor + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error + +# Omitted resource usage check # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme diff --git a/.github/workflows/build-test-ubuntu-tools.yml b/.github/workflows/build-test-ubuntu-tools.yml index 94b566cfe9..4a738a726e 100644 --- a/.github/workflows/build-test-ubuntu-tools.yml +++ b/.github/workflows/build-test-ubuntu-tools.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.7, 3.8, 3.9] os: [ubuntu-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_tools steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -42,7 +45,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Cache npm - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} @@ -55,7 +58,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ${{ steps.pip-cache.outputs.dir }} key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -88,8 +84,25 @@ jobs: - name: Test tools code with pytest run: | . ./activate - ./venv/bin/py.test tests/tools/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/tools/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" -p no:monitor + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error + +# Omitted resource usage check # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme diff --git a/.github/workflows/build-test-ubuntu-util.yml b/.github/workflows/build-test-ubuntu-util.yml index b25e6145ab..9637c59bc4 100644 --- a/.github/workflows/build-test-ubuntu-util.yml +++ b/.github/workflows/build-test-ubuntu-util.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.7, 3.8, 3.9] os: [ubuntu-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_util steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -42,7 +45,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Cache npm - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} @@ -55,7 +58,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ${{ steps.pip-cache.outputs.dir }} key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -88,8 +84,25 @@ jobs: - name: Test util code with pytest run: | . ./activate - ./venv/bin/py.test tests/util/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/util/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" -p no:monitor + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error + +# Omitted resource usage check # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme diff --git a/.github/workflows/build-test-ubuntu-wallet-cat_wallet.yml b/.github/workflows/build-test-ubuntu-wallet-cat_wallet.yml index ae92a9c7ee..b83b9aa953 100644 --- a/.github/workflows/build-test-ubuntu-wallet-cat_wallet.yml +++ b/.github/workflows/build-test-ubuntu-wallet-cat_wallet.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.7, 3.8, 3.9] os: [ubuntu-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_wallet-cat_wallet steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -42,7 +45,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Cache npm - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} @@ -55,7 +58,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ${{ steps.pip-cache.outputs.dir }} key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -88,8 +84,25 @@ jobs: - name: Test wallet-cat_wallet code with pytest run: | . ./activate - ./venv/bin/py.test tests/wallet/cat_wallet/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/wallet/cat_wallet/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" -p no:monitor + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error + +# Omitted resource usage check # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme diff --git a/.github/workflows/build-test-ubuntu-wallet-did_wallet.yml b/.github/workflows/build-test-ubuntu-wallet-did_wallet.yml index 8a30c642df..084dca1d9d 100644 --- a/.github/workflows/build-test-ubuntu-wallet-did_wallet.yml +++ b/.github/workflows/build-test-ubuntu-wallet-did_wallet.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.7, 3.8, 3.9] os: [ubuntu-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_wallet-did_wallet steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -42,7 +45,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Cache npm - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} @@ -55,7 +58,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ${{ steps.pip-cache.outputs.dir }} key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -88,8 +84,25 @@ jobs: - name: Test wallet-did_wallet code with pytest run: | . ./activate - ./venv/bin/py.test tests/wallet/did_wallet/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/wallet/did_wallet/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" -p no:monitor + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error + +# Omitted resource usage check # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme diff --git a/.github/workflows/build-test-ubuntu-wallet-rl_wallet.yml b/.github/workflows/build-test-ubuntu-wallet-rl_wallet.yml index 1354f84ed3..75200f1423 100644 --- a/.github/workflows/build-test-ubuntu-wallet-rl_wallet.yml +++ b/.github/workflows/build-test-ubuntu-wallet-rl_wallet.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.7, 3.8, 3.9] os: [ubuntu-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_wallet-rl_wallet steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -42,7 +45,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Cache npm - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} @@ -55,7 +58,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ${{ steps.pip-cache.outputs.dir }} key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -88,8 +84,25 @@ jobs: - name: Test wallet-rl_wallet code with pytest run: | . ./activate - ./venv/bin/py.test tests/wallet/rl_wallet/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/wallet/rl_wallet/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" -p no:monitor + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error + +# Omitted resource usage check # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme diff --git a/.github/workflows/build-test-ubuntu-wallet-rpc.yml b/.github/workflows/build-test-ubuntu-wallet-rpc.yml index 1aeb970a4e..6f9a5e2277 100644 --- a/.github/workflows/build-test-ubuntu-wallet-rpc.yml +++ b/.github/workflows/build-test-ubuntu-wallet-rpc.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.7, 3.8, 3.9] os: [ubuntu-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_wallet-rpc steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -42,7 +45,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Cache npm - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} @@ -55,7 +58,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ${{ steps.pip-cache.outputs.dir }} key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -88,8 +84,25 @@ jobs: - name: Test wallet-rpc code with pytest run: | . ./activate - ./venv/bin/py.test tests/wallet/rpc/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/wallet/rpc/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" -p no:monitor + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error + +# Omitted resource usage check # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme diff --git a/.github/workflows/build-test-ubuntu-wallet-simple_sync.yml b/.github/workflows/build-test-ubuntu-wallet-simple_sync.yml index 29ac1de6a4..85fd306fc8 100644 --- a/.github/workflows/build-test-ubuntu-wallet-simple_sync.yml +++ b/.github/workflows/build-test-ubuntu-wallet-simple_sync.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.7, 3.8, 3.9] os: [ubuntu-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_wallet-simple_sync steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -42,7 +45,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Cache npm - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} @@ -55,7 +58,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ${{ steps.pip-cache.outputs.dir }} key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -88,8 +84,25 @@ jobs: - name: Test wallet-simple_sync code with pytest run: | . ./activate - ./venv/bin/py.test tests/wallet/simple_sync/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/wallet/simple_sync/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" -p no:monitor + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error + +# Omitted resource usage check # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme diff --git a/.github/workflows/build-test-ubuntu-wallet-sync.yml b/.github/workflows/build-test-ubuntu-wallet-sync.yml index 06b8337b00..924485cb7e 100644 --- a/.github/workflows/build-test-ubuntu-wallet-sync.yml +++ b/.github/workflows/build-test-ubuntu-wallet-sync.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.7, 3.8, 3.9] os: [ubuntu-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_wallet-sync steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -42,7 +45,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Cache npm - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} @@ -55,7 +58,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ${{ steps.pip-cache.outputs.dir }} key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -88,8 +84,25 @@ jobs: - name: Test wallet-sync code with pytest run: | . ./activate - ./venv/bin/py.test tests/wallet/sync/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/wallet/sync/test_*.py -s -v --durations 0 -n 0 -m "not benchmark" -p no:monitor + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error + +# Omitted resource usage check # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme diff --git a/.github/workflows/build-test-ubuntu-wallet.yml b/.github/workflows/build-test-ubuntu-wallet.yml index 1c0b5073a1..88c1c1bfa5 100644 --- a/.github/workflows/build-test-ubuntu-wallet.yml +++ b/.github/workflows/build-test-ubuntu-wallet.yml @@ -22,17 +22,20 @@ jobs: build: name: Ubuntu wallet Test runs-on: ${{ matrix.os }} - timeout-minutes: 30 + timeout-minutes: 40 strategy: fail-fast: false max-parallel: 4 matrix: python-version: [3.7, 3.8, 3.9] os: [ubuntu-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_wallet steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -42,7 +45,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Cache npm - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} @@ -55,7 +58,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ${{ steps.pip-cache.outputs.dir }} key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -88,8 +84,25 @@ jobs: - name: Test wallet code with pytest run: | . ./activate - ./venv/bin/py.test tests/wallet/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/wallet/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" -p no:monitor + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error + +# Omitted resource usage check # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme diff --git a/.github/workflows/build-test-ubuntu-weight_proof.yml b/.github/workflows/build-test-ubuntu-weight_proof.yml index ad4469649e..3a43ec6b3c 100644 --- a/.github/workflows/build-test-ubuntu-weight_proof.yml +++ b/.github/workflows/build-test-ubuntu-weight_proof.yml @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.7, 3.8, 3.9] os: [ubuntu-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_weight_proof steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -42,7 +45,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Cache npm - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} @@ -55,7 +58,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ${{ steps.pip-cache.outputs.dir }} key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }} @@ -63,20 +66,13 @@ jobs: ${{ runner.os }}-pip- - name: Checkout test blocks and plots - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: repository: 'Chia-Network/test-cache' path: '.chia' ref: '0.28.0' fetch-depth: 1 - - name: Link home directory - run: | - cd $HOME - ln -s $GITHUB_WORKSPACE/.chia - echo "$HOME/.chia" - ls -al $HOME/.chia - - name: Run install script env: INSTALL_PYTHON_VERSION: ${{ matrix.python-version }} @@ -88,8 +84,25 @@ jobs: - name: Test weight_proof code with pytest run: | . ./activate - ./venv/bin/py.test tests/weight_proof/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test tests/weight_proof/test_*.py -s -v --durations 0 -n 4 -m "not benchmark" -p no:monitor + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error + +# Omitted resource usage check # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme diff --git a/.github/workflows/build-windows-installer.yml b/.github/workflows/build-windows-installer.yml index 65bb4eeeb2..7f7c6bd8cb 100644 --- a/.github/workflows/build-windows-installer.yml +++ b/.github/workflows/build-windows-installer.yml @@ -23,7 +23,7 @@ jobs: steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 submodules: recursive @@ -38,7 +38,7 @@ jobs: echo "::set-output name=dir::$(npm config get cache)" - name: Cache npm - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ${{ steps.npm-cache.outputs.dir }} key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} @@ -51,7 +51,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ${{ steps.pip-cache.outputs.dir }} key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }} @@ -65,7 +65,7 @@ jobs: python-version: "3.9" - name: Setup Node 16.x - uses: actions/setup-node@v2.4.1 + uses: actions/setup-node@v3 with: node-version: '16.x' @@ -105,13 +105,13 @@ jobs: deactivate # Get the most recent release from chia-plotter-madmax - - uses: actions/github-script@v4 + - uses: actions/github-script@v6 id: 'latest-madmax' with: github-token: ${{ secrets.GITHUB_TOKEN }} result-encoding: string script: | - const releases = await github.repos.listReleases({ + const releases = await github.rest.repos.listReleases({ owner: 'Chia-Network', repo: 'chia-plotter-madmax', }); @@ -124,13 +124,13 @@ jobs: Invoke-WebRequest https://github.com/Chia-Network/chia-plotter-madmax/releases/download/${{ steps.latest-madmax.outputs.result }}/chia_plot_k34-${{ steps.latest-madmax.outputs.result }}.exe -OutFile "$env:GITHUB_WORKSPACE\madmax\chia_plot_k34.exe" # Get the most recent release from bladebit - - uses: actions/github-script@v4 + - uses: actions/github-script@v6 id: 'latest-bladebit' with: github-token: ${{ secrets.GITHUB_TOKEN }} result-encoding: string script: | - const releases = await github.repos.listReleases({ + const releases = await github.rest.repos.listReleases({ owner: 'Chia-Network', repo: 'bladebit', }); diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 9e77092852..78c4b61a21 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -40,7 +40,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/mozilla-ca-cert.yml b/.github/workflows/mozilla-ca-cert.yml index 4bcd7333e1..73edbaa78a 100644 --- a/.github/workflows/mozilla-ca-cert.yml +++ b/.github/workflows/mozilla-ca-cert.yml @@ -8,7 +8,7 @@ jobs: update_ca_module: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 0 ref: "${{ github.event.inputs.chia_ref }}" diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index dfebc9cda1..7ccc0f79b5 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -14,6 +14,6 @@ jobs: pre-commit: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: actions/setup-python@v2 - uses: pre-commit/action@v2.0.3 diff --git a/.github/workflows/super-linter.yml b/.github/workflows/super-linter.yml index 255ae54c0f..8059e90352 100644 --- a/.github/workflows/super-linter.yml +++ b/.github/workflows/super-linter.yml @@ -49,13 +49,13 @@ jobs: # Checkout the code base # ########################## - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 ################################ # Run Linter against code base # ################################ - name: Lint Code Base - uses: github/super-linter@v4.8.1 + uses: github/super-linter@v4.9.1 # uses: docker://github/super-linter:v3.10.2 env: VALIDATE_ALL_CODEBASE: true diff --git a/.github/workflows/test-install-scripts.yml b/.github/workflows/test-install-scripts.yml index e8e27dd615..90917ac0f4 100644 --- a/.github/workflows/test-install-scripts.yml +++ b/.github/workflows/test-install-scripts.yml @@ -28,7 +28,7 @@ jobs: steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -181,7 +181,7 @@ jobs: # after installing git so we use that copy - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 diff --git a/.github/workflows/upload-pypi-source.yml b/.github/workflows/upload-pypi-source.yml index c02d72f92c..9114d34986 100644 --- a/.github/workflows/upload-pypi-source.yml +++ b/.github/workflows/upload-pypi-source.yml @@ -23,7 +23,7 @@ jobs: steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 submodules: recursive diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 86e5236837..eb6206b15f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -6,6 +6,11 @@ repos: entry: ./tests/build-workflows.py --fail-on-update language: python pass_filenames: false + - id: check-sql + name: Validate SQL statements + entry: ./tests/check_sql_statements.py + language: python + pass_filenames: false - repo: local hooks: - id: init_py_files @@ -49,12 +54,13 @@ repos: rev: 21.12b0 hooks: - id: black + additional_dependencies: ['click<8.1'] - repo: https://gitlab.com/pycqa/flake8 rev: 3.9.2 hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy - rev: v0.941 + rev: v0.942 hooks: - id: mypy additional_dependencies: [filelock, pytest, pytest-asyncio, types-aiofiles, types-click, types-setuptools, types-PyYAML] diff --git a/benchmarks/block_ref.py b/benchmarks/block_ref.py index cc5833400c..31571484a9 100644 --- a/benchmarks/block_ref.py +++ b/benchmarks/block_ref.py @@ -17,7 +17,7 @@ from chia.full_node.hint_store import HintStore from chia.types.blockchain_format.program import SerializedProgram from chia.types.blockchain_format.sized_bytes import bytes32 from chia.util.db_version import lookup_db_version -from chia.util.db_wrapper import DBWrapper +from chia.util.db_wrapper import DBWrapper2 from chia.util.ints import uint32 # the first transaction block. Each byte in transaction_height_delta is the @@ -57,7 +57,9 @@ async def main(db_path: Path): await connection.execute("pragma query_only=ON") db_version: int = await lookup_db_version(connection) - db_wrapper = DBWrapper(connection, db_version=db_version) + db_wrapper = DBWrapper2(connection, db_version=db_version) + await db_wrapper.add_connection(await aiosqlite.connect(db_path)) + block_store = await BlockStore.create(db_wrapper) hint_store = await HintStore.create(db_wrapper) coin_store = await CoinStore.create(db_wrapper) diff --git a/benchmarks/block_store.py b/benchmarks/block_store.py index 4169bf50ab..de41f5bec1 100644 --- a/benchmarks/block_store.py +++ b/benchmarks/block_store.py @@ -7,7 +7,7 @@ import os import sys from benchmarks.utils import clvm_generator -from chia.util.db_wrapper import DBWrapper +from chia.util.db_wrapper import DBWrapper2 from chia.util.ints import uint128, uint64, uint32, uint8 from utils import ( rewards, @@ -40,7 +40,7 @@ random.seed(123456789) async def run_add_block_benchmark(version: int): verbose: bool = "--verbose" in sys.argv - db_wrapper: DBWrapper = await setup_db("block-store-benchmark.db", version) + db_wrapper: DBWrapper2 = await setup_db("block-store-benchmark.db", version) # keep track of benchmark total time all_test_time = 0.0 @@ -218,7 +218,6 @@ async def run_add_block_benchmark(version: int): await block_store.set_in_chain([(header_hash,)]) header_hashes.append(header_hash) await block_store.set_peak(header_hash) - await db_wrapper.db.commit() stop = monotonic() total_time += stop - start @@ -288,10 +287,10 @@ async def run_add_block_benchmark(version: int): print("profiling get_full_blocks_at") start = monotonic() - for h in range(1, block_height): - blocks = await block_store.get_full_blocks_at([h]) + for hi in range(1, block_height): + blocks = await block_store.get_full_blocks_at([hi]) assert len(blocks) == 1 - assert blocks[0].height == h + assert blocks[0].height == hi stop = monotonic() total_time += stop - start @@ -352,8 +351,8 @@ async def run_add_block_benchmark(version: int): start = monotonic() for i in range(100): - h = random.randint(1, block_height - 100) - blocks = await block_store.get_block_records_in_range(h, h + 99) + hi = random.randint(1, block_height - 100) + blocks = await block_store.get_block_records_in_range(hi, hi + 99) assert len(blocks) == 100 stop = monotonic() @@ -411,7 +410,7 @@ async def run_add_block_benchmark(version: int): print(f"database size: {db_size/1000000:.3f} MB") finally: - await db_wrapper.db.close() + await db_wrapper.close() if __name__ == "__main__": diff --git a/benchmarks/coin_store.py b/benchmarks/coin_store.py index 068f704b85..08f31c09f1 100644 --- a/benchmarks/coin_store.py +++ b/benchmarks/coin_store.py @@ -7,7 +7,7 @@ from typing import List, Tuple import os import sys -from chia.util.db_wrapper import DBWrapper +from chia.util.db_wrapper import DBWrapper2 from chia.types.blockchain_format.sized_bytes import bytes32 from chia.types.blockchain_format.coin import Coin from chia.util.ints import uint64, uint32 @@ -37,7 +37,7 @@ def make_coins(num: int) -> Tuple[List[Coin], List[bytes32]]: async def run_new_block_benchmark(version: int): verbose: bool = "--verbose" in sys.argv - db_wrapper: DBWrapper = await setup_db("coin-store-benchmark.db", version) + db_wrapper: DBWrapper2 = await setup_db("coin-store-benchmark.db", version) # keep track of benchmark total time all_test_time = 0.0 @@ -75,7 +75,6 @@ async def run_new_block_benchmark(version: int): additions, removals, ) - await db_wrapper.db.commit() # 19 seconds per block timestamp += 19 @@ -117,7 +116,6 @@ async def run_new_block_benchmark(version: int): additions, removals, ) - await db_wrapper.db.commit() stop = monotonic() # 19 seconds per block @@ -168,7 +166,6 @@ async def run_new_block_benchmark(version: int): additions, removals, ) - await db_wrapper.db.commit() stop = monotonic() @@ -218,7 +215,6 @@ async def run_new_block_benchmark(version: int): additions, removals, ) - await db_wrapper.db.commit() stop = monotonic() # 19 seconds per block @@ -305,7 +301,7 @@ async def run_new_block_benchmark(version: int): print(f"all tests completed in {all_test_time:0.4f}s") finally: - await db_wrapper.db.close() + await db_wrapper.close() db_size = os.path.getsize(Path("coin-store-benchmark.db")) print(f"database size: {db_size/1000000:.3f} MB") diff --git a/benchmarks/utils.py b/benchmarks/utils.py index bda6216385..3646db14f3 100644 --- a/benchmarks/utils.py +++ b/benchmarks/utils.py @@ -12,7 +12,7 @@ from chia.types.blockchain_format.proof_of_space import ProofOfSpace from chia.types.blockchain_format.reward_chain_block import RewardChainBlock from chia.types.full_block import FullBlock from chia.util.ints import uint128 -from chia.util.db_wrapper import DBWrapper +from chia.util.db_wrapper import DBWrapper2 from typing import Tuple from pathlib import Path from datetime import datetime @@ -176,7 +176,7 @@ def rand_full_block() -> FullBlock: return full_block -async def setup_db(name: str, db_version: int) -> DBWrapper: +async def setup_db(name: str, db_version: int) -> DBWrapper2: db_filename = Path(name) try: os.unlink(db_filename) @@ -197,7 +197,9 @@ async def setup_db(name: str, db_version: int) -> DBWrapper: await connection.execute("pragma journal_mode=wal") await connection.execute("pragma synchronous=full") - return DBWrapper(connection, db_version) + ret = DBWrapper2(connection, db_version) + await ret.add_connection(await aiosqlite.connect(db_filename)) + return ret def get_commit_hash() -> str: diff --git a/build_scripts/npm_macos_m1/package-lock.json b/build_scripts/npm_macos_m1/package-lock.json index acfd2b6d24..66df6b7672 100644 --- a/build_scripts/npm_macos_m1/package-lock.json +++ b/build_scripts/npm_macos_m1/package-lock.json @@ -9,6 +9,7 @@ "version": "1.0.0", "license": "ISC", "dependencies": { + "appdmg": "^0.6.4", "electron-installer-dmg": "^3.0.0", "electron-osx-sign": "^0.5.0", "electron-packager": "^15.4.0", @@ -2429,10 +2430,9 @@ } }, "node_modules/appdmg": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/appdmg/-/appdmg-0.6.2.tgz", - "integrity": "sha512-mbJyAxn2/JmDpckNpXDU4AQ/XF7fltOyrLcETZxGfYwESt0NdCjQB8L2vIxxAyZKT0R/c0aSzb9yE+P2yDh9TQ==", - "optional": true, + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/appdmg/-/appdmg-0.6.4.tgz", + "integrity": "sha512-YTilgNF0DF2DSRzGzzGDxaTMLXlhe3b3HB8RAaoJJ/VJXZbOlzIAcZ7gdPniHUVUuHjGwnS7fUMd4FvO2Rp94A==", "os": [ "darwin" ], @@ -2570,8 +2570,7 @@ "node_modules/async": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "optional": true + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" }, "node_modules/asynckit": { "version": "0.4.0", @@ -2616,7 +2615,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/base32-encode/-/base32-encode-1.2.0.tgz", "integrity": "sha512-cHFU8XeRyx0GgmoWi5qHMCVRiqU6J3MHWxVgun7jggCBUpVzm1Ir7M9dYr2whjSNc3tFeXfQ/oZjQu/4u55h9A==", - "optional": true, "dependencies": { "to-data-view": "^1.1.0" } @@ -2668,7 +2666,6 @@ "version": "0.0.8", "resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.0.8.tgz", "integrity": "sha512-Za9JKzD6fjLC16oX2wsXfc+qBEhJBJB1YPInoAQpMLhDuj5aVOv1baGeIQSq1Fr3OCqzvsoQcSBSwGId/Ja2PA==", - "optional": true, "dependencies": { "stream-buffers": "~2.2.0" } @@ -3597,7 +3594,6 @@ "version": "0.1.6", "resolved": "https://registry.npmjs.org/ds-store/-/ds-store-0.1.6.tgz", "integrity": "sha1-0QJO90btDBPw9/7IXH6FjoxLfKc=", - "optional": true, "dependencies": { "bplist-creator": "~0.0.3", "macos-alias": "~0.2.5", @@ -3795,8 +3791,7 @@ "node_modules/encode-utf8": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/encode-utf8/-/encode-utf8-1.0.3.tgz", - "integrity": "sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==", - "optional": true + "integrity": "sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==" }, "node_modules/encodeurl": { "version": "1.0.2", @@ -3948,7 +3943,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "optional": true, "dependencies": { "cross-spawn": "^6.0.0", "get-stream": "^4.0.0", @@ -3966,7 +3960,6 @@ "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "optional": true, "dependencies": { "nice-try": "^1.0.4", "path-key": "^2.0.1", @@ -3982,7 +3975,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "optional": true, "engines": { "node": ">=4" } @@ -3991,7 +3983,6 @@ "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "optional": true, "bin": { "semver": "bin/semver" } @@ -4000,7 +3991,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "optional": true, "dependencies": { "shebang-regex": "^1.0.0" }, @@ -4012,7 +4002,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "optional": true, "engines": { "node": ">=0.10.0" } @@ -4021,7 +4010,6 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "optional": true, "dependencies": { "isexe": "^2.0.0" }, @@ -4227,7 +4215,6 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/fmix/-/fmix-0.1.0.tgz", "integrity": "sha1-x7vxJN7ELJ0ZHPuUfQqXeN2YbAw=", - "optional": true, "dependencies": { "imul": "^1.0.0" } @@ -4281,7 +4268,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/fs-temp/-/fs-temp-1.2.1.tgz", "integrity": "sha512-okTwLB7/Qsq82G6iN5zZJFsOfZtx2/pqrA7Hk/9fvy+c+eJS9CvgGXT2uNxwnI14BDY9L/jQPkaBgSvlKfSW9w==", - "optional": true, "dependencies": { "random-path": "^0.1.0" } @@ -4291,7 +4277,6 @@ "resolved": "https://registry.npmjs.org/fs-xattr/-/fs-xattr-0.3.1.tgz", "integrity": "sha512-UVqkrEW0GfDabw4C3HOrFlxKfx0eeigfRne69FxSBdHIP8Qt5Sq6Pu3RM9KmMlkygtC4pPKkj5CiPO5USnj2GA==", "hasInstallScript": true, - "optional": true, "os": [ "!win32" ], @@ -4385,7 +4370,6 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", - "optional": true, "dependencies": { "is-property": "^1.0.2" } @@ -4394,7 +4378,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", - "optional": true, "dependencies": { "is-property": "^1.0.0" } @@ -4961,7 +4944,6 @@ "version": "0.7.5", "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.7.5.tgz", "integrity": "sha512-Hiyv+mXHfFEP7LzUL/llg9RwFxxY+o9N3JVLIeG5E7iFIFAalxvRU9UZthBdYDEVnzHMgjnKJPPpay5BWf1g9g==", - "optional": true, "bin": { "image-size": "bin/image-size.js" }, @@ -5014,7 +4996,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/imul/-/imul-1.0.1.tgz", "integrity": "sha1-nVhnFh6LPelsLDjV3HyxAvNeKsk=", - "optional": true, "engines": { "node": ">=0.10.0" } @@ -5277,14 +5258,12 @@ "node_modules/is-my-ip-valid": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz", - "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==", - "optional": true + "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==" }, "node_modules/is-my-json-valid": { "version": "2.20.6", "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.20.6.tgz", "integrity": "sha512-1JQwulVNjx8UqkPE/bqDaxtH4PXCe/2VRh/y3p99heOV87HG4Id5/VfDswd+YiAfHcRTfDlWgISycnHuhZq1aw==", - "optional": true, "dependencies": { "generate-function": "^2.0.0", "generate-object-property": "^1.1.0", @@ -5353,8 +5332,7 @@ "node_modules/is-property": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", - "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", - "optional": true + "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=" }, "node_modules/is-regex": { "version": "1.1.4", @@ -5391,7 +5369,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "optional": true, "engines": { "node": ">=0.10.0" } @@ -5556,7 +5533,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.0.tgz", "integrity": "sha512-PNYZIdMjVIvVgDSYKTT63Y+KZ6IZvGRNNWcxwD+GNnUz1MKPfv30J8ueCjdwcN0nDx2SlshgyB7Oy0epAzVRRg==", - "optional": true, "engines": { "node": ">=0.10.0" } @@ -5883,7 +5859,6 @@ "resolved": "https://registry.npmjs.org/macos-alias/-/macos-alias-0.2.11.tgz", "integrity": "sha1-/u6mwTuhGYFKQ/xDxHCzHlnvcYo=", "hasInstallScript": true, - "optional": true, "os": [ "darwin" ], @@ -6334,7 +6309,6 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/murmur-32/-/murmur-32-0.2.0.tgz", "integrity": "sha512-ZkcWZudylwF+ir3Ld1n7gL6bI2mQAzXvSobPwVtu8aYi2sbXeipeSkdcanRLzIofLcM5F53lGaKm2dk7orBi7Q==", - "optional": true, "dependencies": { "encode-utf8": "^1.0.3", "fmix": "^0.1.0", @@ -6349,8 +6323,7 @@ "node_modules/nan": { "version": "2.15.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", - "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==", - "optional": true + "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==" }, "node_modules/negotiator": { "version": "0.6.2", @@ -6368,8 +6341,7 @@ "node_modules/nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "optional": true + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" }, "node_modules/node-fetch": { "version": "2.6.6", @@ -6778,7 +6750,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "optional": true, "dependencies": { "path-key": "^2.0.0" }, @@ -6790,7 +6761,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "optional": true, "engines": { "node": ">=4" } @@ -7169,7 +7139,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/parse-color/-/parse-color-1.0.0.tgz", "integrity": "sha1-e3SLlag/A/FqlPU15S1/PZRlhhk=", - "optional": true, "dependencies": { "color-convert": "~0.5.0" } @@ -7177,8 +7146,7 @@ "node_modules/parse-color/node_modules/color-convert": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-0.5.3.tgz", - "integrity": "sha1-vbbGnOZg+t/+CwAHzER+G59ygr0=", - "optional": true + "integrity": "sha1-vbbGnOZg+t/+CwAHzER+G59ygr0=" }, "node_modules/parse-json": { "version": "5.2.0", @@ -7471,7 +7439,6 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/random-path/-/random-path-0.1.2.tgz", "integrity": "sha512-4jY0yoEaQ5v9StCl5kZbNIQlg1QheIDBrdkDn53EynpPb9FgO6//p3X/tgMnrC45XN6QZCzU1Xz/+pSSsJBpRw==", - "optional": true, "dependencies": { "base32-encode": "^0.1.0 || ^1.0.0", "murmur-32": "^0.1.0 || ^0.2.0" @@ -7867,7 +7834,6 @@ "version": "1.6.1", "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "optional": true, "engines": { "node": ">=0.10" } @@ -8373,7 +8339,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz", "integrity": "sha1-kdX1Ew0c75bc+n9yaUUYh0HQnuQ=", - "optional": true, "engines": { "node": ">= 0.10.0" } @@ -8473,7 +8438,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "optional": true, "engines": { "node": ">=0.10.0" } @@ -8643,7 +8607,6 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/tn1150/-/tn1150-0.1.0.tgz", "integrity": "sha1-ZzUD0k1WuH3ouMd/7j/AhT1ZoY0=", - "optional": true, "dependencies": { "unorm": "^1.4.1" }, @@ -8654,8 +8617,7 @@ "node_modules/to-data-view": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/to-data-view/-/to-data-view-1.1.0.tgz", - "integrity": "sha512-1eAdufMg6mwgmlojAx3QeMnzB/BTVp7Tbndi3U7ftcT2zCZadjxkkmLmd97zmaxWi+sgGcgWrokmpEoy0Dn0vQ==", - "optional": true + "integrity": "sha512-1eAdufMg6mwgmlojAx3QeMnzB/BTVp7Tbndi3U7ftcT2zCZadjxkkmLmd97zmaxWi+sgGcgWrokmpEoy0Dn0vQ==" }, "node_modules/to-readable-stream": { "version": "1.0.0", @@ -8844,7 +8806,6 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/unorm/-/unorm-1.6.0.tgz", "integrity": "sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA==", - "optional": true, "engines": { "node": ">= 0.4.0" } @@ -11175,10 +11136,9 @@ } }, "appdmg": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/appdmg/-/appdmg-0.6.2.tgz", - "integrity": "sha512-mbJyAxn2/JmDpckNpXDU4AQ/XF7fltOyrLcETZxGfYwESt0NdCjQB8L2vIxxAyZKT0R/c0aSzb9yE+P2yDh9TQ==", - "optional": true, + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/appdmg/-/appdmg-0.6.4.tgz", + "integrity": "sha512-YTilgNF0DF2DSRzGzzGDxaTMLXlhe3b3HB8RAaoJJ/VJXZbOlzIAcZ7gdPniHUVUuHjGwnS7fUMd4FvO2Rp94A==", "requires": { "async": "^1.4.2", "ds-store": "^0.1.5", @@ -11289,8 +11249,7 @@ "async": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "optional": true + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" }, "asynckit": { "version": "0.4.0", @@ -11326,7 +11285,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/base32-encode/-/base32-encode-1.2.0.tgz", "integrity": "sha512-cHFU8XeRyx0GgmoWi5qHMCVRiqU6J3MHWxVgun7jggCBUpVzm1Ir7M9dYr2whjSNc3tFeXfQ/oZjQu/4u55h9A==", - "optional": true, "requires": { "to-data-view": "^1.1.0" } @@ -11364,7 +11322,6 @@ "version": "0.0.8", "resolved": "https://registry.npmjs.org/bplist-creator/-/bplist-creator-0.0.8.tgz", "integrity": "sha512-Za9JKzD6fjLC16oX2wsXfc+qBEhJBJB1YPInoAQpMLhDuj5aVOv1baGeIQSq1Fr3OCqzvsoQcSBSwGId/Ja2PA==", - "optional": true, "requires": { "stream-buffers": "~2.2.0" } @@ -12072,7 +12029,6 @@ "version": "0.1.6", "resolved": "https://registry.npmjs.org/ds-store/-/ds-store-0.1.6.tgz", "integrity": "sha1-0QJO90btDBPw9/7IXH6FjoxLfKc=", - "optional": true, "requires": { "bplist-creator": "~0.0.3", "macos-alias": "~0.2.5", @@ -12233,8 +12189,7 @@ "encode-utf8": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/encode-utf8/-/encode-utf8-1.0.3.tgz", - "integrity": "sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==", - "optional": true + "integrity": "sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==" }, "encodeurl": { "version": "1.0.2", @@ -12355,7 +12310,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "optional": true, "requires": { "cross-spawn": "^6.0.0", "get-stream": "^4.0.0", @@ -12370,7 +12324,6 @@ "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "optional": true, "requires": { "nice-try": "^1.0.4", "path-key": "^2.0.1", @@ -12382,20 +12335,17 @@ "path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "optional": true + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "optional": true + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" }, "shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "optional": true, "requires": { "shebang-regex": "^1.0.0" } @@ -12403,14 +12353,12 @@ "shebang-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "optional": true + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "optional": true, "requires": { "isexe": "^2.0.0" } @@ -12566,7 +12514,6 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/fmix/-/fmix-0.1.0.tgz", "integrity": "sha1-x7vxJN7ELJ0ZHPuUfQqXeN2YbAw=", - "optional": true, "requires": { "imul": "^1.0.0" } @@ -12608,7 +12555,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/fs-temp/-/fs-temp-1.2.1.tgz", "integrity": "sha512-okTwLB7/Qsq82G6iN5zZJFsOfZtx2/pqrA7Hk/9fvy+c+eJS9CvgGXT2uNxwnI14BDY9L/jQPkaBgSvlKfSW9w==", - "optional": true, "requires": { "random-path": "^0.1.0" } @@ -12616,8 +12562,7 @@ "fs-xattr": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/fs-xattr/-/fs-xattr-0.3.1.tgz", - "integrity": "sha512-UVqkrEW0GfDabw4C3HOrFlxKfx0eeigfRne69FxSBdHIP8Qt5Sq6Pu3RM9KmMlkygtC4pPKkj5CiPO5USnj2GA==", - "optional": true + "integrity": "sha512-UVqkrEW0GfDabw4C3HOrFlxKfx0eeigfRne69FxSBdHIP8Qt5Sq6Pu3RM9KmMlkygtC4pPKkj5CiPO5USnj2GA==" }, "fs.realpath": { "version": "1.0.0", @@ -12703,7 +12648,6 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", - "optional": true, "requires": { "is-property": "^1.0.2" } @@ -12712,7 +12656,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", - "optional": true, "requires": { "is-property": "^1.0.0" } @@ -13144,8 +13087,7 @@ "image-size": { "version": "0.7.5", "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.7.5.tgz", - "integrity": "sha512-Hiyv+mXHfFEP7LzUL/llg9RwFxxY+o9N3JVLIeG5E7iFIFAalxvRU9UZthBdYDEVnzHMgjnKJPPpay5BWf1g9g==", - "optional": true + "integrity": "sha512-Hiyv+mXHfFEP7LzUL/llg9RwFxxY+o9N3JVLIeG5E7iFIFAalxvRU9UZthBdYDEVnzHMgjnKJPPpay5BWf1g9g==" }, "import-fresh": { "version": "3.3.0", @@ -13175,8 +13117,7 @@ "imul": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/imul/-/imul-1.0.1.tgz", - "integrity": "sha1-nVhnFh6LPelsLDjV3HyxAvNeKsk=", - "optional": true + "integrity": "sha1-nVhnFh6LPelsLDjV3HyxAvNeKsk=" }, "imurmurhash": { "version": "0.1.4", @@ -13371,14 +13312,12 @@ "is-my-ip-valid": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz", - "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==", - "optional": true + "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==" }, "is-my-json-valid": { "version": "2.20.6", "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.20.6.tgz", "integrity": "sha512-1JQwulVNjx8UqkPE/bqDaxtH4PXCe/2VRh/y3p99heOV87HG4Id5/VfDswd+YiAfHcRTfDlWgISycnHuhZq1aw==", - "optional": true, "requires": { "generate-function": "^2.0.0", "generate-object-property": "^1.1.0", @@ -13423,8 +13362,7 @@ "is-property": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", - "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", - "optional": true + "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=" }, "is-regex": { "version": "1.1.4", @@ -13451,8 +13389,7 @@ "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "optional": true + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" }, "is-string": { "version": "1.0.7", @@ -13583,8 +13520,7 @@ "jsonpointer": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.0.tgz", - "integrity": "sha512-PNYZIdMjVIvVgDSYKTT63Y+KZ6IZvGRNNWcxwD+GNnUz1MKPfv30J8ueCjdwcN0nDx2SlshgyB7Oy0epAzVRRg==", - "optional": true + "integrity": "sha512-PNYZIdMjVIvVgDSYKTT63Y+KZ6IZvGRNNWcxwD+GNnUz1MKPfv30J8ueCjdwcN0nDx2SlshgyB7Oy0epAzVRRg==" }, "JSONStream": { "version": "1.3.5", @@ -13853,7 +13789,6 @@ "version": "0.2.11", "resolved": "https://registry.npmjs.org/macos-alias/-/macos-alias-0.2.11.tgz", "integrity": "sha1-/u6mwTuhGYFKQ/xDxHCzHlnvcYo=", - "optional": true, "requires": { "nan": "^2.4.0" } @@ -14185,7 +14120,6 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/murmur-32/-/murmur-32-0.2.0.tgz", "integrity": "sha512-ZkcWZudylwF+ir3Ld1n7gL6bI2mQAzXvSobPwVtu8aYi2sbXeipeSkdcanRLzIofLcM5F53lGaKm2dk7orBi7Q==", - "optional": true, "requires": { "encode-utf8": "^1.0.3", "fmix": "^0.1.0", @@ -14200,8 +14134,7 @@ "nan": { "version": "2.15.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", - "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==", - "optional": true + "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==" }, "negotiator": { "version": "0.6.2", @@ -14216,8 +14149,7 @@ "nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "optional": true + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" }, "node-fetch": { "version": "2.6.6", @@ -14546,7 +14478,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "optional": true, "requires": { "path-key": "^2.0.0" }, @@ -14554,8 +14485,7 @@ "path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "optional": true + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" } } }, @@ -14824,7 +14754,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/parse-color/-/parse-color-1.0.0.tgz", "integrity": "sha1-e3SLlag/A/FqlPU15S1/PZRlhhk=", - "optional": true, "requires": { "color-convert": "~0.5.0" }, @@ -14832,8 +14761,7 @@ "color-convert": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-0.5.3.tgz", - "integrity": "sha1-vbbGnOZg+t/+CwAHzER+G59ygr0=", - "optional": true + "integrity": "sha1-vbbGnOZg+t/+CwAHzER+G59ygr0=" } } }, @@ -15043,7 +14971,6 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/random-path/-/random-path-0.1.2.tgz", "integrity": "sha512-4jY0yoEaQ5v9StCl5kZbNIQlg1QheIDBrdkDn53EynpPb9FgO6//p3X/tgMnrC45XN6QZCzU1Xz/+pSSsJBpRw==", - "optional": true, "requires": { "base32-encode": "^0.1.0 || ^1.0.0", "murmur-32": "^0.1.0 || ^0.2.0" @@ -15360,8 +15287,7 @@ "repeat-string": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "optional": true + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=" }, "request": { "version": "2.88.2", @@ -15720,8 +15646,7 @@ "stream-buffers": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/stream-buffers/-/stream-buffers-2.2.0.tgz", - "integrity": "sha1-kdX1Ew0c75bc+n9yaUUYh0HQnuQ=", - "optional": true + "integrity": "sha1-kdX1Ew0c75bc+n9yaUUYh0HQnuQ=" }, "strict-uri-encode": { "version": "2.0.0", @@ -15795,8 +15720,7 @@ "strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "optional": true + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" }, "strip-final-newline": { "version": "2.0.0", @@ -15917,7 +15841,6 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/tn1150/-/tn1150-0.1.0.tgz", "integrity": "sha1-ZzUD0k1WuH3ouMd/7j/AhT1ZoY0=", - "optional": true, "requires": { "unorm": "^1.4.1" } @@ -15925,8 +15848,7 @@ "to-data-view": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/to-data-view/-/to-data-view-1.1.0.tgz", - "integrity": "sha512-1eAdufMg6mwgmlojAx3QeMnzB/BTVp7Tbndi3U7ftcT2zCZadjxkkmLmd97zmaxWi+sgGcgWrokmpEoy0Dn0vQ==", - "optional": true + "integrity": "sha512-1eAdufMg6mwgmlojAx3QeMnzB/BTVp7Tbndi3U7ftcT2zCZadjxkkmLmd97zmaxWi+sgGcgWrokmpEoy0Dn0vQ==" }, "to-readable-stream": { "version": "1.0.0", @@ -16069,8 +15991,7 @@ "unorm": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/unorm/-/unorm-1.6.0.tgz", - "integrity": "sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA==", - "optional": true + "integrity": "sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA==" }, "upath": { "version": "2.0.1", diff --git a/build_scripts/npm_macos_m1/package.json b/build_scripts/npm_macos_m1/package.json index 9c814aebbd..7535aa2244 100644 --- a/build_scripts/npm_macos_m1/package.json +++ b/build_scripts/npm_macos_m1/package.json @@ -10,6 +10,7 @@ "author": "", "license": "ISC", "dependencies": { + "appdmg": "^0.6.4", "electron-installer-dmg": "^3.0.0", "electron-osx-sign": "^0.5.0", "electron-packager": "^15.4.0", diff --git a/chia-blockchain-gui b/chia-blockchain-gui index 80e8bcb83c..054d7b342e 160000 --- a/chia-blockchain-gui +++ b/chia-blockchain-gui @@ -1 +1 @@ -Subproject commit 80e8bcb83c8dac3c2e37e40a7f701ad9842bb120 +Subproject commit 054d7b342e7c8284c9b58a775f87d393a1008bfe diff --git a/chia/clvm/spend_sim.py b/chia/clvm/spend_sim.py index 5c22f365b0..b448966e4a 100644 --- a/chia/clvm/spend_sim.py +++ b/chia/clvm/spend_sim.py @@ -1,4 +1,5 @@ import aiosqlite +import random from dataclasses import dataclass from typing import Optional, List, Dict, Tuple, Any @@ -9,7 +10,7 @@ from chia.types.blockchain_format.program import Program, SerializedProgram from chia.util.ints import uint64, uint32 from chia.util.hash import std_hash from chia.util.errors import Err, ValidationError -from chia.util.db_wrapper import DBWrapper +from chia.util.db_wrapper import DBWrapper2 from chia.util.streamable import Streamable, streamable from chia.types.coin_record import CoinRecord from chia.types.spend_bundle import SpendBundle @@ -79,7 +80,7 @@ class SimStore(Streamable): class SpendSim: - connection: aiosqlite.Connection + db_wrapper: DBWrapper2 mempool_manager: MempoolManager block_records: List[SimBlockRecord] blocks: List[SimFullBlock] @@ -90,39 +91,43 @@ class SpendSim: @classmethod async def create(cls, db_path=":memory:", defaults=DEFAULT_CONSTANTS): self = cls() - self.connection = DBWrapper(await aiosqlite.connect(db_path)) - coin_store = await CoinStore.create(self.connection) + uri = f"file:db_{random.randint(0, 99999999)}?mode=memory&cache=shared" + connection = await aiosqlite.connect(uri, uri=True) + self.db_wrapper = DBWrapper2(connection) + await self.db_wrapper.add_connection(await aiosqlite.connect(uri, uri=True)) + coin_store = await CoinStore.create(self.db_wrapper) self.mempool_manager = MempoolManager(coin_store, defaults) self.defaults = defaults # Load the next data if there is any - await self.connection.db.execute("CREATE TABLE IF NOT EXISTS block_data(data blob PRIMARY_KEY)") - cursor = await self.connection.db.execute("SELECT * from block_data") - row = await cursor.fetchone() - await cursor.close() - if row is not None: - store_data = SimStore.from_bytes(row[0]) - self.timestamp = store_data.timestamp - self.block_height = store_data.block_height - self.block_records = store_data.block_records - self.blocks = store_data.blocks - else: - self.timestamp = 1 - self.block_height = 0 - self.block_records = [] - self.blocks = [] - return self + async with self.db_wrapper.write_db() as conn: + await conn.execute("CREATE TABLE IF NOT EXISTS block_data(data blob PRIMARY_KEY)") + cursor = await conn.execute("SELECT * from block_data") + row = await cursor.fetchone() + await cursor.close() + if row is not None: + store_data = SimStore.from_bytes(row[0]) + self.timestamp = store_data.timestamp + self.block_height = store_data.block_height + self.block_records = store_data.block_records + self.blocks = store_data.blocks + else: + self.timestamp = 1 + self.block_height = 0 + self.block_records = [] + self.blocks = [] + return self async def close(self): - c = await self.connection.db.execute("DELETE FROM block_data") - await c.close() - c = await self.connection.db.execute( - "INSERT INTO block_data VALUES(?)", - (bytes(SimStore(self.timestamp, self.block_height, self.block_records, self.blocks)),), - ) - await c.close() - await self.connection.db.commit() - await self.connection.db.close() + async with self.db_wrapper.write_db() as conn: + c = await conn.execute("DELETE FROM block_data") + await c.close() + c = await conn.execute( + "INSERT INTO block_data VALUES(?)", + (bytes(SimStore(self.timestamp, self.block_height, self.block_records, self.blocks)),), + ) + await c.close() + await self.db_wrapper.close() async def new_peak(self): await self.mempool_manager.new_peak(self.block_records[-1], []) @@ -138,12 +143,13 @@ class SpendSim: async def all_non_reward_coins(self) -> List[Coin]: coins = set() - cursor = await self.mempool_manager.coin_store.coin_record_db.execute( - "SELECT * from coin_record WHERE coinbase=0 AND spent=0 ", - ) - rows = await cursor.fetchall() + async with self.mempool_manager.coin_store.db_wrapper.read_db() as conn: + cursor = await conn.execute( + "SELECT * from coin_record WHERE coinbase=0 AND spent=0 ", + ) + rows = await cursor.fetchall() - await cursor.close() + await cursor.close() for row in rows: coin = Coin(bytes32(bytes.fromhex(row[6])), bytes32(bytes.fromhex(row[5])), uint64.from_bytes(row[7])) coins.add(coin) diff --git a/chia/cmds/chia.py b/chia/cmds/chia.py index 1a02749ef8..00fe6e6fb1 100644 --- a/chia/cmds/chia.py +++ b/chia/cmds/chia.py @@ -123,7 +123,7 @@ def run_daemon_cmd(ctx: click.Context, wait_for_unlock: bool) -> None: wait_for_unlock = wait_for_unlock and Keychain.is_keyring_locked() - asyncio.get_event_loop().run_until_complete(async_run_daemon(ctx.obj["root_path"], wait_for_unlock=wait_for_unlock)) + asyncio.run(async_run_daemon(ctx.obj["root_path"], wait_for_unlock=wait_for_unlock)) cli.add_command(keys_cmd) diff --git a/chia/cmds/configure.py b/chia/cmds/configure.py index 0123fb4396..3b3e336f6b 100644 --- a/chia/cmds/configure.py +++ b/chia/cmds/configure.py @@ -1,9 +1,9 @@ from pathlib import Path -from typing import Dict, Optional +from typing import Optional import click -from chia.util.config import get_config_lock, load_config, save_config, str2bool +from chia.util.config import lock_and_load_config, save_config, str2bool def configure( @@ -23,8 +23,7 @@ def configure( seeder_domain_name: str, seeder_nameserver: str, ): - with get_config_lock(root_path, "config.yaml"): - config: Dict = load_config(root_path, "config.yaml", acquire_lock=False) + with lock_and_load_config(root_path, "config.yaml") as config: change_made = False if set_node_introducer: try: diff --git a/chia/cmds/db_upgrade_func.py b/chia/cmds/db_upgrade_func.py index e4e6442c1d..e12ca79f34 100644 --- a/chia/cmds/db_upgrade_func.py +++ b/chia/cmds/db_upgrade_func.py @@ -7,7 +7,7 @@ from time import time import textwrap import os -from chia.util.config import load_config, save_config, get_config_lock +from chia.util.config import load_config, lock_and_load_config, save_config from chia.util.path import mkdir, path_from_root from chia.util.ints import uint32 from chia.types.blockchain_format.sized_bytes import bytes32 @@ -70,8 +70,7 @@ def db_upgrade_func( if update_config: print("updating config.yaml") - with get_config_lock(root_path, "config.yaml"): - config = load_config(root_path, "config.yaml", acquire_lock=False) + with lock_and_load_config(root_path, "config.yaml") as config: new_db_path = db_pattern.replace("_v1_", "_v2_") config["full_node"]["database_path"] = new_db_path print(f"database_path: {new_db_path}") diff --git a/chia/cmds/init_funcs.py b/chia/cmds/init_funcs.py index 4182c5be3a..1bf2dea4f2 100644 --- a/chia/cmds/init_funcs.py +++ b/chia/cmds/init_funcs.py @@ -20,9 +20,9 @@ from chia.util.config import ( create_default_chia_config, initial_config_file, load_config, + lock_and_load_config, save_config, unflatten_properties, - get_config_lock, ) from chia.util.db_version import set_db_version from chia.util.keychain import Keychain @@ -44,8 +44,8 @@ from chia.wallet.derive_keys import ( ) from chia.cmds.configure import configure -private_node_names = {"full_node", "wallet", "farmer", "harvester", "timelord", "crawler", "daemon"} -public_node_names = {"full_node", "wallet", "farmer", "introducer", "timelord"} +private_node_names: List[str] = ["full_node", "wallet", "farmer", "harvester", "timelord", "crawler", "daemon"] +public_node_names: List[str] = ["full_node", "wallet", "farmer", "introducer", "timelord"] def dict_add_new_default(updated: Dict, default: Dict, do_not_migrate_keys: Dict[str, Any]): @@ -77,8 +77,7 @@ def check_keys(new_root: Path, keychain: Optional[Keychain] = None) -> None: print("No keys are present in the keychain. Generate them with 'chia keys generate'") return None - with get_config_lock(new_root, "config.yaml"): - config: Dict = load_config(new_root, "config.yaml", acquire_lock=False) + with lock_and_load_config(new_root, "config.yaml") as config: pool_child_pubkeys = [master_sk_to_pool_sk(sk).get_g1() for sk, _ in all_sks] all_targets = [] stop_searching_for_farmer = "xch_target_address" not in config["farmer"] @@ -199,8 +198,7 @@ def migrate_from( # update config yaml with new keys - with get_config_lock(new_root, "config.yaml"): - config: Dict = load_config(new_root, "config.yaml", acquire_lock=False) + with lock_and_load_config(new_root, "config.yaml") as config: config_str: str = initial_config_file("config.yaml") default_config: Dict = yaml.safe_load(config_str) flattened_keys = unflatten_properties({k: "" for k in do_not_migrate_settings}) @@ -213,7 +211,12 @@ def migrate_from( return 1 -def create_all_ssl(root_path: Path): +def create_all_ssl( + root_path: Path, + *, + private_ca_crt_and_key: Optional[Tuple[bytes, bytes]] = None, + node_certs_and_keys: Optional[Dict[str, Dict]] = None, +): # remove old key and crt config_dir = root_path / "config" old_key_path = config_dir / "trusted.key" @@ -236,6 +239,11 @@ def create_all_ssl(root_path: Path): chia_ca_key_path = ca_dir / "chia_ca.key" write_ssl_cert_and_key(chia_ca_crt_path, chia_ca_crt, chia_ca_key_path, chia_ca_key) + # If Private CA crt/key are passed-in, write them out + if private_ca_crt_and_key is not None: + private_ca_crt, private_ca_key = private_ca_crt_and_key + write_ssl_cert_and_key(private_ca_crt_path, private_ca_crt, private_ca_key_path, private_ca_key) + if not private_ca_key_path.exists() or not private_ca_crt_path.exists(): # Create private CA print(f"Can't find private CA, creating a new one in {root_path} to generate TLS certificates") @@ -243,33 +251,53 @@ def create_all_ssl(root_path: Path): # Create private certs for each node ca_key = private_ca_key_path.read_bytes() ca_crt = private_ca_crt_path.read_bytes() - generate_ssl_for_nodes(ssl_dir, ca_crt, ca_key, True) + generate_ssl_for_nodes( + ssl_dir, ca_crt, ca_key, prefix="private", nodes=private_node_names, node_certs_and_keys=node_certs_and_keys + ) else: # This is entered when user copied over private CA print(f"Found private CA in {root_path}, using it to generate TLS certificates") ca_key = private_ca_key_path.read_bytes() ca_crt = private_ca_crt_path.read_bytes() - generate_ssl_for_nodes(ssl_dir, ca_crt, ca_key, True) + generate_ssl_for_nodes( + ssl_dir, ca_crt, ca_key, prefix="private", nodes=private_node_names, node_certs_and_keys=node_certs_and_keys + ) chia_ca_crt, chia_ca_key = get_chia_ca_crt_key() - generate_ssl_for_nodes(ssl_dir, chia_ca_crt, chia_ca_key, False, overwrite=False) + generate_ssl_for_nodes( + ssl_dir, + chia_ca_crt, + chia_ca_key, + prefix="public", + nodes=public_node_names, + overwrite=False, + node_certs_and_keys=node_certs_and_keys, + ) -def generate_ssl_for_nodes(ssl_dir: Path, ca_crt: bytes, ca_key: bytes, private: bool, overwrite=True): - if private: - names = private_node_names - else: - names = public_node_names - - for node_name in names: +def generate_ssl_for_nodes( + ssl_dir: Path, + ca_crt: bytes, + ca_key: bytes, + *, + prefix: str, + nodes: List[str], + overwrite: bool = True, + node_certs_and_keys: Optional[Dict[str, Dict]] = None, +): + for node_name in nodes: node_dir = ssl_dir / node_name ensure_ssl_dirs([node_dir]) - if private: - prefix = "private" - else: - prefix = "public" key_path = node_dir / f"{prefix}_{node_name}.key" crt_path = node_dir / f"{prefix}_{node_name}.crt" + if node_certs_and_keys is not None: + certs_and_keys = node_certs_and_keys.get(node_name, {}).get(prefix, {}) + crt = certs_and_keys.get("crt", None) + key = certs_and_keys.get("key", None) + if crt is not None and key is not None: + write_ssl_cert_and_key(crt_path, crt, key_path, key) + continue + if key_path.exists() and crt_path.exists() and overwrite is False: continue generate_ca_signed_cert(ca_crt, ca_key, crt_path, key_path) @@ -465,10 +493,9 @@ def chia_init( config: Dict - with get_config_lock(root_path, "config.yaml"): - db_path_replaced: str - if v1_db: - config = load_config(root_path, "config.yaml", acquire_lock=False) + db_path_replaced: str + if v1_db: + with lock_and_load_config(root_path, "config.yaml") as config: db_pattern = config["full_node"]["database_path"] new_db_path = db_pattern.replace("_v2_", "_v1_") config["full_node"]["database_path"] = new_db_path @@ -480,14 +507,14 @@ def chia_init( save_config(root_path, "config.yaml", config) - else: - config = load_config(root_path, "config.yaml", acquire_lock=False)["full_node"] - db_path_replaced = config["database_path"].replace("CHALLENGE", config["selected_network"]) - db_path = path_from_root(root_path, db_path_replaced) - mkdir(db_path.parent) + else: + config = load_config(root_path, "config.yaml")["full_node"] + db_path_replaced = config["database_path"].replace("CHALLENGE", config["selected_network"]) + db_path = path_from_root(root_path, db_path_replaced) + mkdir(db_path.parent) - with sqlite3.connect(db_path) as connection: - set_db_version(connection, 2) + with sqlite3.connect(db_path) as connection: + set_db_version(connection, 2) print("") print("To see your keys, run 'chia keys show --show-mnemonic-seed'") diff --git a/chia/cmds/passphrase.py b/chia/cmds/passphrase.py index 7e55d17ed0..dff0fbeb29 100644 --- a/chia/cmds/passphrase.py +++ b/chia/cmds/passphrase.py @@ -65,11 +65,7 @@ def set_cmd( if success: # Attempt to update the daemon's passphrase cache - sys.exit( - asyncio.get_event_loop().run_until_complete( - async_update_daemon_passphrase_cache_if_running(ctx.obj["root_path"]) - ) - ) + sys.exit(asyncio.run(async_update_daemon_passphrase_cache_if_running(ctx.obj["root_path"]))) @passphrase_cmd.command( @@ -95,11 +91,7 @@ def remove_cmd(ctx: click.Context, current_passphrase_file: Optional[TextIOWrapp if remove_passphrase(current_passphrase): # Attempt to update the daemon's passphrase cache - sys.exit( - asyncio.get_event_loop().run_until_complete( - async_update_daemon_passphrase_cache_if_running(ctx.obj["root_path"]) - ) - ) + sys.exit(asyncio.run(async_update_daemon_passphrase_cache_if_running(ctx.obj["root_path"]))) @passphrase_cmd.group("hint", short_help="Manage the optional keyring passphrase hint") diff --git a/chia/cmds/plots.py b/chia/cmds/plots.py index 6259cb8bf5..247f603edc 100644 --- a/chia/cmds/plots.py +++ b/chia/cmds/plots.py @@ -138,7 +138,7 @@ def create_cmd( print("Error: The minimum k size allowed from the cli is k=25.") sys.exit(1) - plot_keys = asyncio.get_event_loop().run_until_complete( + plot_keys = asyncio.run( resolve_plot_keys( farmer_public_key, alt_fingerprint, @@ -150,7 +150,7 @@ def create_cmd( ) ) - asyncio.get_event_loop().run_until_complete(create_plots(Params(), plot_keys, ctx.obj["root_path"])) + asyncio.run(create_plots(Params(), plot_keys, ctx.obj["root_path"])) @plots_cmd.command("check", short_help="Checks plots") diff --git a/chia/cmds/start.py b/chia/cmds/start.py index 624b430078..0dd5acebe9 100644 --- a/chia/cmds/start.py +++ b/chia/cmds/start.py @@ -11,4 +11,4 @@ def start_cmd(ctx: click.Context, restart: bool, group: str) -> None: import asyncio from .start_funcs import async_start - asyncio.get_event_loop().run_until_complete(async_start(ctx.obj["root_path"], group, restart)) + asyncio.run(async_start(ctx.obj["root_path"], group, restart)) diff --git a/chia/cmds/stop.py b/chia/cmds/stop.py index cfe91411b3..832a199bb7 100644 --- a/chia/cmds/stop.py +++ b/chia/cmds/stop.py @@ -43,4 +43,4 @@ async def async_stop(root_path: Path, group: str, stop_daemon: bool) -> int: def stop_cmd(ctx: click.Context, daemon: bool, group: str) -> None: import asyncio - sys.exit(asyncio.get_event_loop().run_until_complete(async_stop(ctx.obj["root_path"], group, daemon))) + sys.exit(asyncio.run(async_stop(ctx.obj["root_path"], group, daemon))) diff --git a/chia/cmds/wallet.py b/chia/cmds/wallet.py index 2d0f85b7ef..b2e9395405 100644 --- a/chia/cmds/wallet.py +++ b/chia/cmds/wallet.py @@ -167,8 +167,18 @@ def show_cmd(wallet_rpc_port: Optional[int], fingerprint: int, wallet_type: Opti ) @click.option("-i", "--id", help="Id of the wallet to use", type=int, default=1, show_default=True, required=True) @click.option("-f", "--fingerprint", help="Set the fingerprint to specify which wallet to use", type=int) -def get_address_cmd(wallet_rpc_port: Optional[int], id, fingerprint: int) -> None: - extra_params = {"id": id} +@click.option( + "-n/-l", + "--new-address/--latest-address", + help=( + "Create a new wallet receive address, or show the most recently created wallet receive address" + " [default: show most recent address]" + ), + is_flag=True, + default=False, +) +def get_address_cmd(wallet_rpc_port: Optional[int], id, fingerprint: int, new_address: bool) -> None: + extra_params = {"id": id, "new_address": new_address} import asyncio from .wallet_funcs import execute_with_wallet, get_address diff --git a/chia/cmds/wallet_funcs.py b/chia/cmds/wallet_funcs.py index 2b957ccd90..7a8b42baab 100644 --- a/chia/cmds/wallet_funcs.py +++ b/chia/cmds/wallet_funcs.py @@ -216,7 +216,8 @@ async def send(args: dict, wallet_client: WalletRpcClient, fingerprint: int) -> async def get_address(args: dict, wallet_client: WalletRpcClient, fingerprint: int) -> None: wallet_id = args["id"] - res = await wallet_client.get_next_address(wallet_id, False) + new_address: bool = args.get("new_address", False) + res = await wallet_client.get_next_address(wallet_id, new_address) print(res) @@ -482,17 +483,28 @@ async def print_balances(args: dict, wallet_client: WalletRpcClient, fingerprint else: print(f"Balances, fingerprint: {fingerprint}") for summary in summaries_response: + indent: str = " " + # asset_id currently contains both the asset ID and TAIL program bytes concatenated together. + # A future RPC update may split them apart, but for now we'll show the first 32 bytes (64 chars) + asset_id = summary["data"][:64] wallet_id = summary["id"] balances = await wallet_client.get_wallet_balance(wallet_id) typ = WalletType(int(summary["type"])) address_prefix, scale = wallet_coin_unit(typ, address_prefix) - print(f"Wallet ID {wallet_id} type {typ.name} {summary['name']}") - print(f" -Total Balance: {print_balance(balances['confirmed_wallet_balance'], scale, address_prefix)}") - print( - f" -Pending Total Balance: " - f"{print_balance(balances['unconfirmed_wallet_balance'], scale, address_prefix)}" + total_balance: str = print_balance(balances["confirmed_wallet_balance"], scale, address_prefix) + unconfirmed_wallet_balance: str = print_balance( + balances["unconfirmed_wallet_balance"], scale, address_prefix ) - print(f" -Spendable: {print_balance(balances['spendable_balance'], scale, address_prefix)}") + spendable_balance: str = print_balance(balances["spendable_balance"], scale, address_prefix) + print() + print(f"{summary['name']}:") + print(f"{indent}{'-Total Balance:'.ljust(23)} {total_balance}") + print(f"{indent}{'-Pending Total Balance:'.ljust(23)} " f"{unconfirmed_wallet_balance}") + print(f"{indent}{'-Spendable:'.ljust(23)} {spendable_balance}") + print(f"{indent}{'-Type:'.ljust(23)} {typ.name}") + if len(asset_id) > 0: + print(f"{indent}{'-Asset ID:'.ljust(23)} {asset_id}") + print(f"{indent}{'-Wallet ID:'.ljust(23)} {wallet_id}") print(" ") trusted_peers: Dict = config["wallet"].get("trusted_peers", {}) @@ -512,9 +524,24 @@ async def get_wallet(wallet_client: WalletRpcClient, fingerprint: int = None) -> if fingerprint is not None: log_in_response = await wallet_client.log_in(fingerprint) else: + logged_in_fingerprint: Optional[int] = await wallet_client.get_logged_in_fingerprint() + spacing: str = " " if logged_in_fingerprint is not None else "" + current_sync_status: str = "" + if logged_in_fingerprint is not None: + if await wallet_client.get_synced(): + current_sync_status = "Synced" + elif await wallet_client.get_sync_status(): + current_sync_status = "Syncing" + else: + current_sync_status = "Not Synced" print("Choose wallet key:") for i, fp in enumerate(fingerprints): - print(f"{i+1}) {fp}") + row: str = f"{i+1}) " + row += "* " if fp == logged_in_fingerprint else spacing + row += f"{fp}" + if fp == logged_in_fingerprint and len(current_sync_status) > 0: + row += f" ({current_sync_status})" + print(row) val = None while val is None: val = input("Enter a number to pick or q to quit: ") diff --git a/chia/consensus/block_body_validation.py b/chia/consensus/block_body_validation.py index 0ed75c90b1..5ce7cad6f5 100644 --- a/chia/consensus/block_body_validation.py +++ b/chia/consensus/block_body_validation.py @@ -1,6 +1,6 @@ import collections import logging -from typing import Callable, Dict, List, Optional, Set, Tuple, Union +from typing import Awaitable, Callable, Dict, List, Optional, Set, Tuple, Union from chiabip158 import PyBIP158 from clvm.casts import int_from_bytes @@ -16,6 +16,7 @@ from chia.consensus.find_fork_point import find_fork_point_in_chain from chia.full_node.block_store import BlockStore from chia.full_node.coin_store import CoinStore from chia.full_node.mempool_check_conditions import get_name_puzzle_conditions, mempool_check_conditions_dict +from chia.types.block_protocol import BlockInfo from chia.types.blockchain_format.coin import Coin from chia.types.blockchain_format.sized_bytes import bytes32 from chia.types.coin_record import CoinRecord @@ -45,7 +46,7 @@ async def validate_block_body( height: uint32, npc_result: Optional[NPCResult], fork_point_with_peak: Optional[uint32], - get_block_generator: Callable, + get_block_generator: Callable[[BlockInfo], Awaitable[Optional[BlockGenerator]]], *, validate_signature=True, ) -> Tuple[Optional[Err], Optional[NPCResult]]: @@ -345,7 +346,7 @@ async def validate_block_body( ) if curr.height == 0: break - curr = reorg_blocks[curr.height - 1] + curr = reorg_blocks[uint32(curr.height - 1)] assert curr is not None removal_coin_records: Dict[bytes32, CoinRecord] = {} diff --git a/chia/consensus/blockchain.py b/chia/consensus/blockchain.py index 06e440c921..fbbf4cc02d 100644 --- a/chia/consensus/blockchain.py +++ b/chia/consensus/blockchain.py @@ -3,6 +3,7 @@ import dataclasses import logging import multiprocessing import traceback +from concurrent.futures import Executor from concurrent.futures.process import ProcessPoolExecutor from enum import Enum from multiprocessing.context import BaseContext @@ -47,6 +48,7 @@ from chia.types.unfinished_header_block import UnfinishedHeaderBlock from chia.types.weight_proof import SubEpochChallengeSegment from chia.util.errors import ConsensusError, Err from chia.util.generator_tools import get_block_header, tx_removals_and_additions +from chia.util.inline_executor import InlineExecutor from chia.util.ints import uint16, uint32, uint64, uint128 from chia.util.setproctitle import getproctitle, setproctitle from chia.util.streamable import recurse_jsonify @@ -86,7 +88,7 @@ class Blockchain(BlockchainInterface): # Store block_store: BlockStore # Used to verify blocks in parallel - pool: ProcessPoolExecutor + pool: Executor # Set holding seen compact proofs, in order to avoid duplicates. _seen_compact_proofs: Set[Tuple[VDFInfo, uint32]] @@ -107,6 +109,8 @@ class Blockchain(BlockchainInterface): blockchain_dir: Path, reserved_cores: int, multiprocessing_context: Optional[BaseContext] = None, + *, + single_threaded: bool = False, ): """ Initializes a blockchain with the BlockRecords from disk, assuming they have all been @@ -116,17 +120,20 @@ class Blockchain(BlockchainInterface): self = Blockchain() self.lock = asyncio.Lock() # External lock handled by full node self.compact_proof_lock = asyncio.Lock() - cpu_count = multiprocessing.cpu_count() - if cpu_count > 61: - cpu_count = 61 # Windows Server 2016 has an issue https://bugs.python.org/issue26903 - num_workers = max(cpu_count - reserved_cores, 1) - self.pool = ProcessPoolExecutor( - max_workers=num_workers, - mp_context=multiprocessing_context, - initializer=setproctitle, - initargs=(f"{getproctitle()}_worker",), - ) - log.info(f"Started {num_workers} processes for block validation") + if single_threaded: + self.pool = InlineExecutor() + else: + cpu_count = multiprocessing.cpu_count() + if cpu_count > 61: + cpu_count = 61 # Windows Server 2016 has an issue https://bugs.python.org/issue26903 + num_workers = max(cpu_count - reserved_cores, 1) + self.pool = ProcessPoolExecutor( + max_workers=num_workers, + mp_context=multiprocessing_context, + initializer=setproctitle, + initargs=(f"{getproctitle()}_worker",), + ) + log.info(f"Started {num_workers} processes for block validation") self.constants = consensus_constants self.coin_store = coin_store @@ -257,16 +264,14 @@ class Blockchain(BlockchainInterface): None, ) # Always add the block to the database - async with self.block_store.db_wrapper.lock: + async with self.block_store.db_wrapper.write_db(): try: header_hash: bytes32 = block.header_hash # Perform the DB operations to update the state, and rollback if something goes wrong - await self.block_store.db_wrapper.begin_transaction() await self.block_store.add_full_block(header_hash, block, block_record) fork_height, peak_height, records, (coin_record_change, hint_changes) = await self._reconsider_peak( block_record, genesis, fork_point_with_peak, npc_result ) - await self.block_store.db_wrapper.commit_transaction() # Then update the memory cache. It is important that this task is not cancelled and does not throw self.add_block_record(block_record) @@ -281,7 +286,6 @@ class Blockchain(BlockchainInterface): await self.__height_map.maybe_flush() except BaseException as e: self.block_store.rollback_cache_block(header_hash) - await self.block_store.db_wrapper.rollback_transaction() log.error( f"Error while adding block {block.header_hash} height {block.height}," f" rolling back: {traceback.format_exc()} {e}" @@ -359,121 +363,122 @@ class Blockchain(BlockchainInterface): return None, None, [], ([], {}) assert peak is not None - if block_record.weight > peak.weight: - # Find the fork. if the block is just being appended, it will return the peak - # If no blocks in common, returns -1, and reverts all blocks - if block_record.prev_hash == peak.header_hash: - fork_height: int = peak.height - elif fork_point_with_peak is not None: - fork_height = fork_point_with_peak + if block_record.weight <= peak.weight: + # This is not a heavier block than the heaviest we have seen, so we don't change the coin set + return None, None, [], ([], {}) + + # Find the fork. if the block is just being appended, it will return the peak + # If no blocks in common, returns -1, and reverts all blocks + if block_record.prev_hash == peak.header_hash: + fork_height: int = peak.height + elif fork_point_with_peak is not None: + fork_height = fork_point_with_peak + else: + fork_height = find_fork_point_in_chain(self, block_record, peak) + + if block_record.prev_hash != peak.header_hash: + roll_changes: List[CoinRecord] = await self.coin_store.rollback_to_block(fork_height) + for coin_record in roll_changes: + latest_coin_state[coin_record.name] = coin_record + + # Rollback sub_epoch_summaries + self.__height_map.rollback(fork_height) + await self.block_store.rollback(fork_height) + + # Collect all blocks from fork point to new peak + blocks_to_add: List[Tuple[FullBlock, BlockRecord]] = [] + curr = block_record.header_hash + + while fork_height < 0 or curr != self.height_to_hash(uint32(fork_height)): + fetched_full_block: Optional[FullBlock] = await self.block_store.get_full_block(curr) + fetched_block_record: Optional[BlockRecord] = await self.block_store.get_block_record(curr) + assert fetched_full_block is not None + assert fetched_block_record is not None + blocks_to_add.append((fetched_full_block, fetched_block_record)) + if fetched_full_block.height == 0: + # Doing a full reorg, starting at height 0 + break + curr = fetched_block_record.prev_hash + + records_to_add = [] + for fetched_full_block, fetched_block_record in reversed(blocks_to_add): + records_to_add.append(fetched_block_record) + if not fetched_full_block.is_transaction_block(): + continue + + if fetched_block_record.header_hash == block_record.header_hash: + tx_removals, tx_additions, npc_res = await self.get_tx_removals_and_additions( + fetched_full_block, npc_result + ) else: - fork_height = find_fork_point_in_chain(self, block_record, peak) + tx_removals, tx_additions, npc_res = await self.get_tx_removals_and_additions(fetched_full_block, None) - if block_record.prev_hash != peak.header_hash: - roll_changes: List[CoinRecord] = await self.coin_store.rollback_to_block(fork_height) - for coin_record in roll_changes: - latest_coin_state[coin_record.name] = coin_record - - # Rollback sub_epoch_summaries - self.__height_map.rollback(fork_height) - await self.block_store.rollback(fork_height) - - # Collect all blocks from fork point to new peak - blocks_to_add: List[Tuple[FullBlock, BlockRecord]] = [] - curr = block_record.header_hash - - while fork_height < 0 or curr != self.height_to_hash(uint32(fork_height)): - fetched_full_block: Optional[FullBlock] = await self.block_store.get_full_block(curr) - fetched_block_record: Optional[BlockRecord] = await self.block_store.get_block_record(curr) - assert fetched_full_block is not None - assert fetched_block_record is not None - blocks_to_add.append((fetched_full_block, fetched_block_record)) - if fetched_full_block.height == 0: - # Doing a full reorg, starting at height 0 - break - curr = fetched_block_record.prev_hash - - records_to_add = [] - for fetched_full_block, fetched_block_record in reversed(blocks_to_add): - records_to_add.append(fetched_block_record) - if fetched_full_block.is_transaction_block(): - if fetched_block_record.header_hash == block_record.header_hash: - tx_removals, tx_additions, npc_res = await self.get_tx_removals_and_additions( - fetched_full_block, npc_result - ) - else: - tx_removals, tx_additions, npc_res = await self.get_tx_removals_and_additions( - fetched_full_block, None - ) - - assert fetched_full_block.foliage_transaction_block is not None - added_rec = await self.coin_store.new_block( - fetched_full_block.height, - fetched_full_block.foliage_transaction_block.timestamp, - fetched_full_block.get_included_reward_coins(), - tx_additions, - tx_removals, - ) - removed_rec: List[Optional[CoinRecord]] = [ - await self.coin_store.get_coin_record(name) for name in tx_removals - ] - - # Set additions first, then removals in order to handle ephemeral coin state - # Add in height order is also required - record: Optional[CoinRecord] - for record in added_rec: - assert record - latest_coin_state[record.name] = record - for record in removed_rec: - assert record - latest_coin_state[record.name] = record - - if npc_res is not None: - hint_list: List[Tuple[bytes32, bytes]] = self.get_hint_list(npc_res) - await self.hint_store.add_hints(hint_list) - # There can be multiple coins for the same hint - for coin_id, hint in hint_list: - key = hint - if key not in hint_coin_state: - hint_coin_state[key] = {} - hint_coin_state[key][coin_id] = latest_coin_state[coin_id] - - await self.block_store.set_in_chain([(br.header_hash,) for br in records_to_add]) - - # Changes the peak to be the new peak - await self.block_store.set_peak(block_record.header_hash) - return ( - uint32(max(fork_height, 0)), - block_record.height, - records_to_add, - (list(latest_coin_state.values()), hint_coin_state), + assert fetched_full_block.foliage_transaction_block is not None + added_rec = await self.coin_store.new_block( + fetched_full_block.height, + fetched_full_block.foliage_transaction_block.timestamp, + fetched_full_block.get_included_reward_coins(), + tx_additions, + tx_removals, ) + removed_rec: List[Optional[CoinRecord]] = [ + await self.coin_store.get_coin_record(name) for name in tx_removals + ] - # This is not a heavier block than the heaviest we have seen, so we don't change the coin set - return None, None, [], ([], {}) + # Set additions first, then removals in order to handle ephemeral coin state + # Add in height order is also required + record: Optional[CoinRecord] + for record in added_rec: + assert record + latest_coin_state[record.name] = record + for record in removed_rec: + assert record + latest_coin_state[record.name] = record + + if npc_res is not None: + hint_list: List[Tuple[bytes32, bytes]] = self.get_hint_list(npc_res) + await self.hint_store.add_hints(hint_list) + # There can be multiple coins for the same hint + for coin_id, hint in hint_list: + key = hint + if key not in hint_coin_state: + hint_coin_state[key] = {} + hint_coin_state[key][coin_id] = latest_coin_state[coin_id] + + await self.block_store.set_in_chain([(br.header_hash,) for br in records_to_add]) + + # Changes the peak to be the new peak + await self.block_store.set_peak(block_record.header_hash) + return ( + uint32(max(fork_height, 0)), + block_record.height, + records_to_add, + (list(latest_coin_state.values()), hint_coin_state), + ) async def get_tx_removals_and_additions( self, block: FullBlock, npc_result: Optional[NPCResult] = None ) -> Tuple[List[bytes32], List[Coin], Optional[NPCResult]]: - if block.is_transaction_block(): - if block.transactions_generator is not None: - if npc_result is None: - block_generator: Optional[BlockGenerator] = await self.get_block_generator(block) - assert block_generator is not None - npc_result = get_name_puzzle_conditions( - block_generator, - self.constants.MAX_BLOCK_COST_CLVM, - cost_per_byte=self.constants.COST_PER_BYTE, - mempool_mode=False, - height=block.height, - ) - tx_removals, tx_additions = tx_removals_and_additions(npc_result.npc_list) - return tx_removals, tx_additions, npc_result - else: - return [], [], None - else: + + if not block.is_transaction_block(): return [], [], None + if block.transactions_generator is None: + return [], [], None + + if npc_result is None: + block_generator: Optional[BlockGenerator] = await self.get_block_generator(block) + assert block_generator is not None + npc_result = get_name_puzzle_conditions( + block_generator, + self.constants.MAX_BLOCK_COST_CLVM, + cost_per_byte=self.constants.COST_PER_BYTE, + mempool_mode=False, + height=block.height, + ) + tx_removals, tx_additions = tx_removals_and_additions(npc_result.npc_list) + return tx_removals, tx_additions, npc_result + def get_next_difficulty(self, header_hash: bytes32, new_slot: bool) -> uint64: assert self.contains_block(header_hash) curr = self.block_record(header_hash) diff --git a/chia/consensus/multiprocess_validation.py b/chia/consensus/multiprocess_validation.py index ba19fd1e4c..9fe5485829 100644 --- a/chia/consensus/multiprocess_validation.py +++ b/chia/consensus/multiprocess_validation.py @@ -1,9 +1,9 @@ import asyncio import logging import traceback -from concurrent.futures.process import ProcessPoolExecutor +from concurrent.futures import Executor from dataclasses import dataclass -from typing import Callable, Dict, List, Optional, Sequence, Tuple, Union +from typing import Awaitable, Callable, Dict, List, Optional, Sequence, Tuple from blspy import AugSchemeMPL, G1Element @@ -17,6 +17,7 @@ from chia.consensus.full_block_to_block_record import block_to_block_record from chia.consensus.get_block_challenge import get_block_challenge from chia.consensus.pot_iterations import calculate_iterations_quality, is_overflow_block from chia.full_node.mempool_check_conditions import get_name_puzzle_conditions +from chia.types.block_protocol import BlockInfo from chia.types.blockchain_format.coin import Coin from chia.types.blockchain_format.sized_bytes import bytes32 from chia.types.blockchain_format.sub_epoch_summary import SubEpochSummary @@ -169,11 +170,11 @@ async def pre_validate_blocks_multiprocessing( constants: ConsensusConstants, constants_json: Dict, block_records: BlockchainInterface, - blocks: Sequence[Union[FullBlock, HeaderBlock]], - pool: ProcessPoolExecutor, + blocks: Sequence[FullBlock], + pool: Executor, check_filter: bool, npc_results: Dict[uint32, NPCResult], - get_block_generator: Optional[Callable], + get_block_generator: Callable[[BlockInfo, Optional[Dict[bytes32, FullBlock]]], Awaitable[Optional[BlockGenerator]]], batch_size: int, wp_summaries: Optional[List[SubEpochSummary]] = None, *, @@ -288,7 +289,7 @@ async def pre_validate_blocks_multiprocessing( prev_b = block_rec diff_ssis.append((difficulty, sub_slot_iters)) - block_dict: Dict[bytes32, Union[FullBlock, HeaderBlock]] = {} + block_dict: Dict[bytes32, FullBlock] = {} for i, block in enumerate(blocks): block_dict[block.header_hash] = block if not block_record_was_present[i]: @@ -314,8 +315,8 @@ async def pre_validate_blocks_multiprocessing( # We ONLY add blocks which are in the past, based on header hashes (which are validated later) to the # prev blocks dict. This is important since these blocks are assumed to be valid and are used as previous # generator references - prev_blocks_dict: Dict[uint32, Union[FullBlock, HeaderBlock]] = {} - curr_b: Union[FullBlock, HeaderBlock] = block + prev_blocks_dict: Dict[bytes32, FullBlock] = {} + curr_b: FullBlock = block while curr_b.prev_header_hash in block_dict: curr_b = block_dict[curr_b.prev_header_hash] diff --git a/chia/daemon/server.py b/chia/daemon/server.py index e9cda8fdff..c1216c3f12 100644 --- a/chia/daemon/server.py +++ b/chia/daemon/server.py @@ -1015,7 +1015,8 @@ class WebSocketServer: if parallel is True or can_start_serial_plotting: log.info(f"Plotting will start in {config['delay']} seconds") - loop = asyncio.get_event_loop() + # TODO: loop gets passed down a lot, review for potential removal + loop = asyncio.get_running_loop() loop.create_task(self._start_plotting(id, loop, queue)) else: log.info("Plotting will start automatically when previous plotting finish") @@ -1058,7 +1059,8 @@ class WebSocketServer: self.plots_queue.remove(config) if run_next: - loop = asyncio.get_event_loop() + # TODO: review to see if we can remove this + loop = asyncio.get_running_loop() self._run_next_serial_plotting(loop, queue) return {"success": True} @@ -1156,9 +1158,7 @@ class WebSocketServer: await asyncio.wait(jobs) self.services.clear() - # TODO: fix this hack - asyncio.get_event_loop().call_later(5, lambda *args: sys.exit(0)) - log.info("chia daemon exiting in 5 seconds") + log.info("chia daemon exiting") response = {"success": True} return response @@ -1488,7 +1488,7 @@ async def async_run_daemon(root_path: Path, wait_for_unlock: bool = False) -> in def run_daemon(root_path: Path, wait_for_unlock: bool = False) -> int: - result = asyncio.get_event_loop().run_until_complete(async_run_daemon(root_path, wait_for_unlock)) + result = asyncio.run(async_run_daemon(root_path, wait_for_unlock)) return result diff --git a/chia/farmer/farmer.py b/chia/farmer/farmer.py index 8eede4e6e6..3bb68a6fa5 100644 --- a/chia/farmer/farmer.py +++ b/chia/farmer/farmer.py @@ -40,7 +40,7 @@ from chia.types.blockchain_format.proof_of_space import ProofOfSpace from chia.types.blockchain_format.sized_bytes import bytes32 from chia.util.bech32m import decode_puzzle_hash from chia.util.byte_types import hexstr_to_bytes -from chia.util.config import load_config, save_config, config_path_for_filename, get_config_lock +from chia.util.config import load_config, lock_and_load_config, save_config, config_path_for_filename from chia.util.hash import std_hash from chia.util.ints import uint8, uint16, uint32, uint64 from chia.util.keychain import Keychain @@ -581,8 +581,7 @@ class Farmer: } def set_reward_targets(self, farmer_target_encoded: Optional[str], pool_target_encoded: Optional[str]): - with get_config_lock(self._root_path, "config.yaml"): - config = load_config(self._root_path, "config.yaml", acquire_lock=False) + with lock_and_load_config(self._root_path, "config.yaml") as config: if farmer_target_encoded is not None: self.farmer_target_encoded = farmer_target_encoded self.farmer_target = decode_puzzle_hash(farmer_target_encoded) @@ -596,8 +595,7 @@ class Farmer: async def set_payout_instructions(self, launcher_id: bytes32, payout_instructions: str): for p2_singleton_puzzle_hash, pool_state_dict in self.pool_state.items(): if launcher_id == pool_state_dict["pool_config"].launcher_id: - with get_config_lock(self._root_path, "config.yaml"): - config = load_config(self._root_path, "config.yaml", acquire_lock=False) + with lock_and_load_config(self._root_path, "config.yaml") as config: new_list = [] pool_list = config["pool"].get("pool_list", []) if pool_list is not None: diff --git a/chia/full_node/block_height_map.py b/chia/full_node/block_height_map.py index 216e4d4a32..98a4d2826d 100644 --- a/chia/full_node/block_height_map.py +++ b/chia/full_node/block_height_map.py @@ -8,7 +8,7 @@ import aiofiles from dataclasses import dataclass from chia.util.streamable import Streamable, streamable from chia.util.files import write_file_async -from chia.util.db_wrapper import DBWrapper +from chia.util.db_wrapper import DBWrapper2 log = logging.getLogger(__name__) @@ -20,7 +20,7 @@ class SesCache(Streamable): class BlockHeightMap: - db: DBWrapper + db: DBWrapper2 # the below dictionaries are loaded from the database, from the peak # and back in time on startup. @@ -47,7 +47,7 @@ class BlockHeightMap: __ses_filename: Path @classmethod - async def create(cls, blockchain_dir: Path, db: DBWrapper) -> "BlockHeightMap": + async def create(cls, blockchain_dir: Path, db: DBWrapper2) -> "BlockHeightMap": self = BlockHeightMap() self.db = db @@ -57,26 +57,27 @@ class BlockHeightMap: self.__height_to_hash_filename = blockchain_dir / "height-to-hash" self.__ses_filename = blockchain_dir / "sub-epoch-summaries" - if db.db_version == 2: - async with self.db.db.execute("SELECT hash FROM current_peak WHERE key = 0") as cursor: - peak_row = await cursor.fetchone() - if peak_row is None: - return self + async with self.db.read_db() as conn: + if db.db_version == 2: + async with conn.execute("SELECT hash FROM current_peak WHERE key = 0") as cursor: + peak_row = await cursor.fetchone() + if peak_row is None: + return self - async with db.db.execute( - "SELECT header_hash,prev_hash,height,sub_epoch_summary FROM full_blocks WHERE header_hash=?", - (peak_row[0],), - ) as cursor: - row = await cursor.fetchone() - if row is None: - return self - else: - async with await db.db.execute( - "SELECT header_hash,prev_hash,height,sub_epoch_summary from block_records WHERE is_peak=1" - ) as cursor: - row = await cursor.fetchone() - if row is None: - return self + async with conn.execute( + "SELECT header_hash,prev_hash,height,sub_epoch_summary FROM full_blocks WHERE header_hash=?", + (peak_row[0],), + ) as cursor: + row = await cursor.fetchone() + if row is None: + return self + else: + async with await conn.execute( + "SELECT header_hash,prev_hash,height,sub_epoch_summary from block_records WHERE is_peak=1" + ) as cursor: + row = await cursor.fetchone() + if row is None: + return self try: async with aiofiles.open(self.__height_to_hash_filename, "rb") as f: @@ -169,17 +170,18 @@ class BlockHeightMap: "INDEXED BY height WHERE height>=? AND height (height, prev-hash, sub-epoch-summary) - ordered: Dict[bytes32, Tuple[uint32, bytes32, Optional[bytes]]] = {} + # maps block-hash -> (height, prev-hash, sub-epoch-summary) + ordered: Dict[bytes32, Tuple[uint32, bytes32, Optional[bytes]]] = {} - if self.db.db_version == 2: - for r in await cursor.fetchall(): - ordered[r[0]] = (r[2], r[1], r[3]) - else: - for r in await cursor.fetchall(): - ordered[bytes32.fromhex(r[0])] = (r[2], bytes32.fromhex(r[1]), r[3]) + if self.db.db_version == 2: + for r in await cursor.fetchall(): + ordered[r[0]] = (r[2], r[1], r[3]) + else: + for r in await cursor.fetchall(): + ordered[bytes32.fromhex(r[0])] = (r[2], bytes32.fromhex(r[1]), r[3]) while height > window_end: entry = ordered[prev_hash] diff --git a/chia/full_node/block_store.py b/chia/full_node/block_store.py index 418e0b5760..3da53d27ad 100644 --- a/chia/full_node/block_store.py +++ b/chia/full_node/block_store.py @@ -1,7 +1,6 @@ import logging from typing import Dict, List, Optional, Tuple, Any -import aiosqlite import zstd from chia.consensus.block_record import BlockRecord @@ -10,7 +9,7 @@ from chia.types.full_block import FullBlock from chia.types.blockchain_format.program import SerializedProgram from chia.types.weight_proof import SubEpochChallengeSegment, SubEpochSegments from chia.util.errors import Err -from chia.util.db_wrapper import DBWrapper +from chia.util.db_wrapper import DBWrapper2 from chia.util.ints import uint32 from chia.util.lru_cache import LRUCache from chia.util.full_block_utils import generator_from_block @@ -19,94 +18,92 @@ log = logging.getLogger(__name__) class BlockStore: - db: aiosqlite.Connection block_cache: LRUCache - db_wrapper: DBWrapper + db_wrapper: DBWrapper2 ses_challenge_cache: LRUCache @classmethod - async def create(cls, db_wrapper: DBWrapper): + async def create(cls, db_wrapper: DBWrapper2): self = cls() - # All full blocks which have been added to the blockchain. Header_hash -> block self.db_wrapper = db_wrapper - self.db = db_wrapper.db - if self.db_wrapper.db_version == 2: + async with self.db_wrapper.write_db() as conn: - # TODO: most data in block is duplicated in block_record. The only - # reason for this is that our parsing of a FullBlock is so slow, - # it's faster to store duplicate data to parse less when we just - # need the BlockRecord. Once we fix the parsing (and data structure) - # of FullBlock, this can use less space - await self.db.execute( - "CREATE TABLE IF NOT EXISTS full_blocks(" - "header_hash blob PRIMARY KEY," - "prev_hash blob," - "height bigint," - "sub_epoch_summary blob," - "is_fully_compactified tinyint," - "in_main_chain tinyint," - "block blob," - "block_record blob)" - ) + if self.db_wrapper.db_version == 2: - # This is a single-row table containing the hash of the current - # peak. The "key" field is there to make update statements simple - await self.db.execute("CREATE TABLE IF NOT EXISTS current_peak(key int PRIMARY KEY, hash blob)") + # TODO: most data in block is duplicated in block_record. The only + # reason for this is that our parsing of a FullBlock is so slow, + # it's faster to store duplicate data to parse less when we just + # need the BlockRecord. Once we fix the parsing (and data structure) + # of FullBlock, this can use less space + await conn.execute( + "CREATE TABLE IF NOT EXISTS full_blocks(" + "header_hash blob PRIMARY KEY," + "prev_hash blob," + "height bigint," + "sub_epoch_summary blob," + "is_fully_compactified tinyint," + "in_main_chain tinyint," + "block blob," + "block_record blob)" + ) - # If any of these indices are altered, they should also be altered - # in the chia/cmds/db_upgrade.py file - await self.db.execute("CREATE INDEX IF NOT EXISTS height on full_blocks(height)") + # This is a single-row table containing the hash of the current + # peak. The "key" field is there to make update statements simple + await conn.execute("CREATE TABLE IF NOT EXISTS current_peak(key int PRIMARY KEY, hash blob)") - # Sub epoch segments for weight proofs - await self.db.execute( - "CREATE TABLE IF NOT EXISTS sub_epoch_segments_v3(" - "ses_block_hash blob PRIMARY KEY," - "challenge_segments blob)" - ) + # If any of these indices are altered, they should also be altered + # in the chia/cmds/db_upgrade.py file + await conn.execute("CREATE INDEX IF NOT EXISTS height on full_blocks(height)") - # If any of these indices are altered, they should also be altered - # in the chia/cmds/db_upgrade.py file - await self.db.execute( - "CREATE INDEX IF NOT EXISTS is_fully_compactified ON" - " full_blocks(is_fully_compactified, in_main_chain) WHERE in_main_chain=1" - ) - await self.db.execute( - "CREATE INDEX IF NOT EXISTS main_chain ON full_blocks(height, in_main_chain) WHERE in_main_chain=1" - ) + # Sub epoch segments for weight proofs + await conn.execute( + "CREATE TABLE IF NOT EXISTS sub_epoch_segments_v3(" + "ses_block_hash blob PRIMARY KEY," + "challenge_segments blob)" + ) - else: + # If any of these indices are altered, they should also be altered + # in the chia/cmds/db_upgrade.py file + await conn.execute( + "CREATE INDEX IF NOT EXISTS is_fully_compactified ON" + " full_blocks(is_fully_compactified, in_main_chain) WHERE in_main_chain=1" + ) + await conn.execute( + "CREATE INDEX IF NOT EXISTS main_chain ON full_blocks(height, in_main_chain) WHERE in_main_chain=1" + ) - await self.db.execute( - "CREATE TABLE IF NOT EXISTS full_blocks(header_hash text PRIMARY KEY, height bigint," - " is_block tinyint, is_fully_compactified tinyint, block blob)" - ) + else: - # Block records - await self.db.execute( - "CREATE TABLE IF NOT EXISTS block_records(header_hash " - "text PRIMARY KEY, prev_hash text, height bigint," - "block blob, sub_epoch_summary blob, is_peak tinyint, is_block tinyint)" - ) + await conn.execute( + "CREATE TABLE IF NOT EXISTS full_blocks(header_hash text PRIMARY KEY, height bigint," + " is_block tinyint, is_fully_compactified tinyint, block blob)" + ) - # Sub epoch segments for weight proofs - await self.db.execute( - "CREATE TABLE IF NOT EXISTS sub_epoch_segments_v3(ses_block_hash text PRIMARY KEY," - "challenge_segments blob)" - ) + # Block records + await conn.execute( + "CREATE TABLE IF NOT EXISTS block_records(header_hash " + "text PRIMARY KEY, prev_hash text, height bigint," + "block blob, sub_epoch_summary blob, is_peak tinyint, is_block tinyint)" + ) - # Height index so we can look up in order of height for sync purposes - await self.db.execute("CREATE INDEX IF NOT EXISTS full_block_height on full_blocks(height)") - await self.db.execute( - "CREATE INDEX IF NOT EXISTS is_fully_compactified on full_blocks(is_fully_compactified)" - ) + # Sub epoch segments for weight proofs + await conn.execute( + "CREATE TABLE IF NOT EXISTS sub_epoch_segments_v3(ses_block_hash text PRIMARY KEY," + "challenge_segments blob)" + ) - await self.db.execute("CREATE INDEX IF NOT EXISTS height on block_records(height)") + # Height index so we can look up in order of height for sync purposes + await conn.execute("CREATE INDEX IF NOT EXISTS full_block_height on full_blocks(height)") + await conn.execute( + "CREATE INDEX IF NOT EXISTS is_fully_compactified on full_blocks(is_fully_compactified)" + ) - await self.db.execute("CREATE INDEX IF NOT EXISTS peak on block_records(is_peak)") + await conn.execute("CREATE INDEX IF NOT EXISTS height on block_records(height)") + + await conn.execute("CREATE INDEX IF NOT EXISTS peak on block_records(is_peak)") - await self.db.commit() self.block_cache = LRUCache(1000) self.ses_challenge_cache = LRUCache(50) return self @@ -134,15 +131,17 @@ class BlockStore: async def rollback(self, height: int) -> None: if self.db_wrapper.db_version == 2: - await self.db.execute( - "UPDATE OR FAIL full_blocks SET in_main_chain=0 WHERE height>? AND in_main_chain=1", (height,) - ) + async with self.db_wrapper.write_db() as conn: + await conn.execute( + "UPDATE OR FAIL full_blocks SET in_main_chain=0 WHERE height>? AND in_main_chain=1", (height,) + ) async def set_in_chain(self, header_hashes: List[Tuple[bytes32]]) -> None: if self.db_wrapper.db_version == 2: - await self.db.executemany( - "UPDATE OR FAIL full_blocks SET in_main_chain=1 WHERE header_hash=?", header_hashes - ) + async with self.db_wrapper.write_db() as conn: + await conn.executemany( + "UPDATE OR FAIL full_blocks SET in_main_chain=1 WHERE header_hash=?", header_hashes + ) async def replace_proof(self, header_hash: bytes32, block: FullBlock) -> None: @@ -156,14 +155,15 @@ class BlockStore: self.block_cache.put(header_hash, block) - await self.db.execute( - "UPDATE full_blocks SET block=?,is_fully_compactified=? WHERE header_hash=?", - ( - block_bytes, - int(block.is_fully_compactified()), - self.maybe_to_hex(header_hash), - ), - ) + async with self.db_wrapper.write_db() as conn: + await conn.execute( + "UPDATE full_blocks SET block=?,is_fully_compactified=? WHERE header_hash=?", + ( + block_bytes, + int(block.is_fully_compactified()), + self.maybe_to_hex(header_hash), + ), + ) async def add_full_block(self, header_hash: bytes32, block: FullBlock, block_record: BlockRecord) -> None: self.block_cache.put(header_hash, block) @@ -176,56 +176,57 @@ class BlockStore: else bytes(block_record.sub_epoch_summary_included) ) - await self.db.execute( - "INSERT OR IGNORE INTO full_blocks VALUES(?, ?, ?, ?, ?, ?, ?, ?)", - ( - header_hash, - block.prev_header_hash, - block.height, - ses, - int(block.is_fully_compactified()), - False, # in_main_chain - self.compress(block), - bytes(block_record), - ), - ) + async with self.db_wrapper.write_db() as conn: + await conn.execute( + "INSERT OR IGNORE INTO full_blocks VALUES(?, ?, ?, ?, ?, ?, ?, ?)", + ( + header_hash, + block.prev_header_hash, + block.height, + ses, + int(block.is_fully_compactified()), + False, # in_main_chain + self.compress(block), + bytes(block_record), + ), + ) else: - await self.db.execute( - "INSERT OR IGNORE INTO full_blocks VALUES(?, ?, ?, ?, ?)", - ( - header_hash.hex(), - block.height, - int(block.is_transaction_block()), - int(block.is_fully_compactified()), - bytes(block), - ), - ) + async with self.db_wrapper.write_db() as conn: + await conn.execute( + "INSERT OR IGNORE INTO full_blocks VALUES(?, ?, ?, ?, ?)", + ( + header_hash.hex(), + block.height, + int(block.is_transaction_block()), + int(block.is_fully_compactified()), + bytes(block), + ), + ) - await self.db.execute( - "INSERT OR IGNORE INTO block_records VALUES(?, ?, ?, ?,?, ?, ?)", - ( - header_hash.hex(), - block.prev_header_hash.hex(), - block.height, - bytes(block_record), - None - if block_record.sub_epoch_summary_included is None - else bytes(block_record.sub_epoch_summary_included), - False, - block.is_transaction_block(), - ), - ) + await conn.execute( + "INSERT OR IGNORE INTO block_records VALUES(?, ?, ?, ?,?, ?, ?)", + ( + header_hash.hex(), + block.prev_header_hash.hex(), + block.height, + bytes(block_record), + None + if block_record.sub_epoch_summary_included is None + else bytes(block_record.sub_epoch_summary_included), + False, + block.is_transaction_block(), + ), + ) async def persist_sub_epoch_challenge_segments( self, ses_block_hash: bytes32, segments: List[SubEpochChallengeSegment] ) -> None: - async with self.db_wrapper.lock: - await self.db.execute( + async with self.db_wrapper.write_db() as conn: + await conn.execute( "INSERT OR REPLACE INTO sub_epoch_segments_v3 VALUES(?, ?)", (self.maybe_to_hex(ses_block_hash), bytes(SubEpochSegments(segments))), ) - await self.db.commit() async def get_sub_epoch_challenge_segments( self, @@ -235,11 +236,12 @@ class BlockStore: if cached is not None: return cached - async with self.db.execute( - "SELECT challenge_segments from sub_epoch_segments_v3 WHERE ses_block_hash=?", - (self.maybe_to_hex(ses_block_hash),), - ) as cursor: - row = await cursor.fetchone() + async with self.db_wrapper.read_db() as conn: + async with conn.execute( + "SELECT challenge_segments from sub_epoch_segments_v3 WHERE ses_block_hash=?", + (self.maybe_to_hex(ses_block_hash),), + ) as cursor: + row = await cursor.fetchone() if row is not None: challenge_segments = SubEpochSegments.from_bytes(row[0]).challenge_segments @@ -261,10 +263,11 @@ class BlockStore: log.debug(f"cache hit for block {header_hash.hex()}") return cached log.debug(f"cache miss for block {header_hash.hex()}") - async with self.db.execute( - "SELECT block from full_blocks WHERE header_hash=?", (self.maybe_to_hex(header_hash),) - ) as cursor: - row = await cursor.fetchone() + async with self.db_wrapper.read_db() as conn: + async with conn.execute( + "SELECT block from full_blocks WHERE header_hash=?", (self.maybe_to_hex(header_hash),) + ) as cursor: + row = await cursor.fetchone() if row is not None: block = self.maybe_decompress(row[0]) self.block_cache.put(header_hash, block) @@ -277,10 +280,11 @@ class BlockStore: log.debug(f"cache hit for block {header_hash.hex()}") return bytes(cached) log.debug(f"cache miss for block {header_hash.hex()}") - async with self.db.execute( - "SELECT block from full_blocks WHERE header_hash=?", (self.maybe_to_hex(header_hash),) - ) as cursor: - row = await cursor.fetchone() + async with self.db_wrapper.read_db() as conn: + async with conn.execute( + "SELECT block from full_blocks WHERE header_hash=?", (self.maybe_to_hex(header_hash),) + ) as cursor: + row = await cursor.fetchone() if row is not None: if self.db_wrapper.db_version == 2: return zstd.decompress(row[0]) @@ -295,11 +299,12 @@ class BlockStore: heights_db = tuple(heights) formatted_str = f'SELECT block from full_blocks WHERE height in ({"?," * (len(heights_db) - 1)}?)' - async with self.db.execute(formatted_str, heights_db) as cursor: - ret: List[FullBlock] = [] - for row in await cursor.fetchall(): - ret.append(self.maybe_decompress(row[0])) - return ret + async with self.db_wrapper.read_db() as conn: + async with conn.execute(formatted_str, heights_db) as cursor: + ret: List[FullBlock] = [] + for row in await cursor.fetchall(): + ret.append(self.maybe_decompress(row[0])) + return ret async def get_generator(self, header_hash: bytes32) -> Optional[SerializedProgram]: @@ -309,24 +314,25 @@ class BlockStore: return cached.transactions_generator formatted_str = "SELECT block, height from full_blocks WHERE header_hash=?" - async with self.db.execute(formatted_str, (self.maybe_to_hex(header_hash),)) as cursor: - row = await cursor.fetchone() - if row is None: - return None - if self.db_wrapper.db_version == 2: - block_bytes = zstd.decompress(row[0]) - else: - block_bytes = row[0] + async with self.db_wrapper.read_db() as conn: + async with conn.execute(formatted_str, (self.maybe_to_hex(header_hash),)) as cursor: + row = await cursor.fetchone() + if row is None: + return None + if self.db_wrapper.db_version == 2: + block_bytes = zstd.decompress(row[0]) + else: + block_bytes = row[0] - try: - return generator_from_block(block_bytes) - except Exception as e: - log.error(f"cheap parser failed for block at height {row[1]}: {e}") - # this is defensive, on the off-chance that - # generator_from_block() fails, fall back to the reliable - # definition of parsing a block - b = FullBlock.from_bytes(block_bytes) - return b.transactions_generator + try: + return generator_from_block(block_bytes) + except Exception as e: + log.error(f"cheap parser failed for block at height {row[1]}: {e}") + # this is defensive, on the off-chance that + # generator_from_block() fails, fall back to the reliable + # definition of parsing a block + b = FullBlock.from_bytes(block_bytes) + return b.transactions_generator async def get_generators_at(self, heights: List[uint32]) -> List[SerializedProgram]: assert self.db_wrapper.db_version == 2 @@ -340,22 +346,23 @@ class BlockStore: f"SELECT block, height from full_blocks " f'WHERE in_main_chain=1 AND height in ({"?," * (len(heights_db) - 1)}?)' ) - async with self.db.execute(formatted_str, heights_db) as cursor: - async for row in cursor: - block_bytes = zstd.decompress(row[0]) + async with self.db_wrapper.read_db() as conn: + async with conn.execute(formatted_str, heights_db) as cursor: + async for row in cursor: + block_bytes = zstd.decompress(row[0]) - try: - gen = generator_from_block(block_bytes) - except Exception as e: - log.error(f"cheap parser failed for block at height {row[1]}: {e}") - # this is defensive, on the off-chance that - # generator_from_block() fails, fall back to the reliable - # definition of parsing a block - b = FullBlock.from_bytes(block_bytes) - gen = b.transactions_generator - if gen is None: - raise ValueError(Err.GENERATOR_REF_HAS_NO_GENERATOR) - generators[uint32(row[1])] = gen + try: + gen = generator_from_block(block_bytes) + except Exception as e: + log.error(f"cheap parser failed for block at height {row[1]}: {e}") + # this is defensive, on the off-chance that + # generator_from_block() fails, fall back to the reliable + # definition of parsing a block + b = FullBlock.from_bytes(block_bytes) + gen = b.transactions_generator + if gen is None: + raise ValueError(Err.GENERATOR_REF_HAS_NO_GENERATOR) + generators[uint32(row[1])] = gen return [generators[h] for h in heights] @@ -369,20 +376,22 @@ class BlockStore: all_blocks: Dict[bytes32, BlockRecord] = {} if self.db_wrapper.db_version == 2: - async with self.db.execute( - "SELECT header_hash,block_record FROM full_blocks " - f'WHERE header_hash in ({"?," * (len(header_hashes) - 1)}?)', - tuple(header_hashes), - ) as cursor: - for row in await cursor.fetchall(): - header_hash = bytes32(row[0]) - all_blocks[header_hash] = BlockRecord.from_bytes(row[1]) + async with self.db_wrapper.read_db() as conn: + async with conn.execute( + "SELECT header_hash,block_record FROM full_blocks " + f'WHERE header_hash in ({"?," * (len(header_hashes) - 1)}?)', + tuple(header_hashes), + ) as cursor: + for row in await cursor.fetchall(): + header_hash = bytes32(row[0]) + all_blocks[header_hash] = BlockRecord.from_bytes(row[1]) else: formatted_str = f'SELECT block from block_records WHERE header_hash in ({"?," * (len(header_hashes) - 1)}?)' - async with self.db.execute(formatted_str, tuple([hh.hex() for hh in header_hashes])) as cursor: - for row in await cursor.fetchall(): - block_rec: BlockRecord = BlockRecord.from_bytes(row[0]) - all_blocks[block_rec.header_hash] = block_rec + async with self.db_wrapper.read_db() as conn: + async with conn.execute(formatted_str, tuple([hh.hex() for hh in header_hashes])) as cursor: + for row in await cursor.fetchall(): + block_rec: BlockRecord = BlockRecord.from_bytes(row[0]) + all_blocks[block_rec.header_hash] = block_rec ret: List[BlockRecord] = [] for hh in header_hashes: @@ -409,15 +418,16 @@ class BlockStore: f'SELECT header_hash, block from full_blocks WHERE header_hash in ({"?," * (len(header_hashes_db) - 1)}?)' ) all_blocks: Dict[bytes32, FullBlock] = {} - async with self.db.execute(formatted_str, header_hashes_db) as cursor: - for row in await cursor.fetchall(): - header_hash = self.maybe_from_hex(row[0]) - full_block: FullBlock = self.maybe_decompress(row[1]) - # TODO: address hint error and remove ignore - # error: Invalid index type "bytes" for "Dict[bytes32, FullBlock]"; - # expected type "bytes32" [index] - all_blocks[header_hash] = full_block # type: ignore[index] - self.block_cache.put(header_hash, full_block) + async with self.db_wrapper.read_db() as conn: + async with conn.execute(formatted_str, header_hashes_db) as cursor: + for row in await cursor.fetchall(): + header_hash = self.maybe_from_hex(row[0]) + full_block: FullBlock = self.maybe_decompress(row[1]) + # TODO: address hint error and remove ignore + # error: Invalid index type "bytes" for "Dict[bytes32, FullBlock]"; + # expected type "bytes32" [index] + all_blocks[header_hash] = full_block # type: ignore[index] + self.block_cache.put(header_hash, full_block) ret: List[FullBlock] = [] for hh in header_hashes: if hh not in all_blocks: @@ -429,20 +439,22 @@ class BlockStore: if self.db_wrapper.db_version == 2: - async with self.db.execute( - "SELECT block_record FROM full_blocks WHERE header_hash=?", - (header_hash,), - ) as cursor: - row = await cursor.fetchone() + async with self.db_wrapper.read_db() as conn: + async with conn.execute( + "SELECT block_record FROM full_blocks WHERE header_hash=?", + (header_hash,), + ) as cursor: + row = await cursor.fetchone() if row is not None: return BlockRecord.from_bytes(row[0]) else: - async with self.db.execute( - "SELECT block from block_records WHERE header_hash=?", - (header_hash.hex(),), - ) as cursor: - row = await cursor.fetchone() + async with self.db_wrapper.read_db() as conn: + async with conn.execute( + "SELECT block from block_records WHERE header_hash=?", + (header_hash.hex(),), + ) as cursor: + row = await cursor.fetchone() if row is not None: return BlockRecord.from_bytes(row[0]) return None @@ -460,40 +472,45 @@ class BlockStore: ret: Dict[bytes32, BlockRecord] = {} if self.db_wrapper.db_version == 2: - async with self.db.execute( - "SELECT header_hash, block_record FROM full_blocks WHERE height >= ? AND height <= ?", - (start, stop), - ) as cursor: - for row in await cursor.fetchall(): - header_hash = bytes32(row[0]) - ret[header_hash] = BlockRecord.from_bytes(row[1]) + async with self.db_wrapper.read_db() as conn: + async with conn.execute( + "SELECT header_hash, block_record FROM full_blocks WHERE height >= ? AND height <= ?", + (start, stop), + ) as cursor: + for row in await cursor.fetchall(): + header_hash = bytes32(row[0]) + ret[header_hash] = BlockRecord.from_bytes(row[1]) else: formatted_str = f"SELECT header_hash, block from block_records WHERE height >= {start} and height <= {stop}" - async with await self.db.execute(formatted_str) as cursor: - for row in await cursor.fetchall(): - header_hash = bytes32(self.maybe_from_hex(row[0])) - ret[header_hash] = BlockRecord.from_bytes(row[1]) + async with self.db_wrapper.read_db() as conn: + async with await conn.execute(formatted_str) as cursor: + for row in await cursor.fetchall(): + header_hash = bytes32(self.maybe_from_hex(row[0])) + ret[header_hash] = BlockRecord.from_bytes(row[1]) return ret async def get_peak(self) -> Optional[Tuple[bytes32, uint32]]: if self.db_wrapper.db_version == 2: - async with self.db.execute("SELECT hash FROM current_peak WHERE key = 0") as cursor: - peak_row = await cursor.fetchone() + async with self.db_wrapper.read_db() as conn: + async with conn.execute("SELECT hash FROM current_peak WHERE key = 0") as cursor: + peak_row = await cursor.fetchone() if peak_row is None: return None - async with self.db.execute("SELECT height FROM full_blocks WHERE header_hash=?", (peak_row[0],)) as cursor: - peak_height = await cursor.fetchone() + async with self.db_wrapper.read_db() as conn: + async with conn.execute("SELECT height FROM full_blocks WHERE header_hash=?", (peak_row[0],)) as cursor: + peak_height = await cursor.fetchone() if peak_height is None: return None return bytes32(peak_row[0]), uint32(peak_height[0]) else: - async with self.db.execute("SELECT header_hash, height from block_records WHERE is_peak = 1") as cursor: - peak_row = await cursor.fetchone() + async with self.db_wrapper.read_db() as conn: + async with conn.execute("SELECT header_hash, height from block_records WHERE is_peak = 1") as cursor: + peak_row = await cursor.fetchone() if peak_row is None: return None return bytes32(bytes.fromhex(peak_row[0])), uint32(peak_row[1]) @@ -513,20 +530,22 @@ class BlockStore: ret: Dict[bytes32, BlockRecord] = {} if self.db_wrapper.db_version == 2: - async with self.db.execute( - "SELECT header_hash, block_record FROM full_blocks WHERE height >= ?", - (peak[1] - blocks_n,), - ) as cursor: - for row in await cursor.fetchall(): - header_hash = bytes32(row[0]) - ret[header_hash] = BlockRecord.from_bytes(row[1]) + async with self.db_wrapper.read_db() as conn: + async with conn.execute( + "SELECT header_hash, block_record FROM full_blocks WHERE height >= ?", + (peak[1] - blocks_n,), + ) as cursor: + for row in await cursor.fetchall(): + header_hash = bytes32(row[0]) + ret[header_hash] = BlockRecord.from_bytes(row[1]) else: formatted_str = f"SELECT header_hash, block from block_records WHERE height >= {peak[1] - blocks_n}" - async with self.db.execute(formatted_str) as cursor: - for row in await cursor.fetchall(): - header_hash = bytes32(self.maybe_from_hex(row[0])) - ret[header_hash] = BlockRecord.from_bytes(row[1]) + async with self.db_wrapper.read_db() as conn: + async with conn.execute(formatted_str) as cursor: + for row in await cursor.fetchall(): + header_hash = bytes32(self.maybe_from_hex(row[0])) + ret[header_hash] = BlockRecord.from_bytes(row[1]) return ret, peak[0] @@ -536,19 +555,22 @@ class BlockStore: if self.db_wrapper.db_version == 2: # Note: we use the key field as 0 just to ensure all inserts replace the existing row - await self.db.execute("INSERT OR REPLACE INTO current_peak VALUES(?, ?)", (0, header_hash)) + async with self.db_wrapper.write_db() as conn: + await conn.execute("INSERT OR REPLACE INTO current_peak VALUES(?, ?)", (0, header_hash)) else: - await self.db.execute("UPDATE block_records SET is_peak=0 WHERE is_peak=1") - await self.db.execute( - "UPDATE block_records SET is_peak=1 WHERE header_hash=?", - (self.maybe_to_hex(header_hash),), - ) + async with self.db_wrapper.write_db() as conn: + await conn.execute("UPDATE block_records SET is_peak=0 WHERE is_peak=1") + await conn.execute( + "UPDATE block_records SET is_peak=1 WHERE header_hash=?", + (self.maybe_to_hex(header_hash),), + ) async def is_fully_compactified(self, header_hash: bytes32) -> Optional[bool]: - async with self.db.execute( - "SELECT is_fully_compactified from full_blocks WHERE header_hash=?", (self.maybe_to_hex(header_hash),) - ) as cursor: - row = await cursor.fetchone() + async with self.db_wrapper.write_db() as conn: + async with conn.execute( + "SELECT is_fully_compactified from full_blocks WHERE header_hash=?", (self.maybe_to_hex(header_hash),) + ) as cursor: + row = await cursor.fetchone() if row is None: return None return bool(row[0]) @@ -556,20 +578,22 @@ class BlockStore: async def get_random_not_compactified(self, number: int) -> List[int]: if self.db_wrapper.db_version == 2: - async with self.db.execute( - f"SELECT height FROM full_blocks WHERE in_main_chain=1 AND is_fully_compactified=0 " - f"ORDER BY RANDOM() LIMIT {number}" - ) as cursor: - rows = await cursor.fetchall() + async with self.db_wrapper.read_db() as conn: + async with conn.execute( + f"SELECT height FROM full_blocks WHERE in_main_chain=1 AND is_fully_compactified=0 " + f"ORDER BY RANDOM() LIMIT {number}" + ) as cursor: + rows = await cursor.fetchall() else: # Since orphan blocks do not get compactified, we need to check whether all blocks with a # certain height are not compact. And if we do have compact orphan blocks, then all that # happens is that the occasional chain block stays uncompact - not ideal, but harmless. - async with self.db.execute( - f"SELECT height FROM full_blocks GROUP BY height HAVING sum(is_fully_compactified)=0 " - f"ORDER BY RANDOM() LIMIT {number}" - ) as cursor: - rows = await cursor.fetchall() + async with self.db_wrapper.read_db() as conn: + async with conn.execute( + f"SELECT height FROM full_blocks GROUP BY height HAVING sum(is_fully_compactified)=0 " + f"ORDER BY RANDOM() LIMIT {number}" + ) as cursor: + rows = await cursor.fetchall() heights = [int(row[0]) for row in rows] @@ -578,13 +602,15 @@ class BlockStore: async def count_compactified_blocks(self) -> int: if self.db_wrapper.db_version == 2: # DB V2 has an index on is_fully_compactified only for blocks in the main chain - async with self.db.execute( - "select count(*) from full_blocks where is_fully_compactified=1 and in_main_chain=1" - ) as cursor: - row = await cursor.fetchone() + async with self.db_wrapper.read_db() as conn: + async with conn.execute( + "select count(*) from full_blocks where is_fully_compactified=1 and in_main_chain=1" + ) as cursor: + row = await cursor.fetchone() else: - async with self.db.execute("select count(*) from full_blocks where is_fully_compactified=1") as cursor: - row = await cursor.fetchone() + async with self.db_wrapper.read_db() as conn: + async with conn.execute("select count(*) from full_blocks where is_fully_compactified=1") as cursor: + row = await cursor.fetchone() assert row is not None @@ -594,13 +620,15 @@ class BlockStore: async def count_uncompactified_blocks(self) -> int: if self.db_wrapper.db_version == 2: # DB V2 has an index on is_fully_compactified only for blocks in the main chain - async with self.db.execute( - "select count(*) from full_blocks where is_fully_compactified=0 and in_main_chain=1" - ) as cursor: - row = await cursor.fetchone() + async with self.db_wrapper.read_db() as conn: + async with conn.execute( + "select count(*) from full_blocks where is_fully_compactified=0 and in_main_chain=1" + ) as cursor: + row = await cursor.fetchone() else: - async with self.db.execute("select count(*) from full_blocks where is_fully_compactified=0") as cursor: - row = await cursor.fetchone() + async with self.db_wrapper.read_db() as conn: + async with conn.execute("select count(*) from full_blocks where is_fully_compactified=0") as cursor: + row = await cursor.fetchone() assert row is not None diff --git a/chia/full_node/coin_store.py b/chia/full_node/coin_store.py index 8e6420f484..4b91d80f73 100644 --- a/chia/full_node/coin_store.py +++ b/chia/full_node/coin_store.py @@ -1,10 +1,9 @@ from typing import List, Optional, Set, Dict, Any, Tuple -import aiosqlite from chia.protocols.wallet_protocol import CoinState from chia.types.blockchain_format.coin import Coin from chia.types.blockchain_format.sized_bytes import bytes32 from chia.types.coin_record import CoinRecord -from chia.util.db_wrapper import DBWrapper +from chia.util.db_wrapper import DBWrapper2 from chia.util.ints import uint32, uint64 from chia.util.lru_cache import LRUCache from chia.util.chunks import chunks @@ -22,74 +21,72 @@ class CoinStore: A cache is maintained for quicker access to recent coins. """ - coin_record_db: aiosqlite.Connection coin_record_cache: LRUCache cache_size: uint32 - db_wrapper: DBWrapper + db_wrapper: DBWrapper2 @classmethod - async def create(cls, db_wrapper: DBWrapper, cache_size: uint32 = uint32(60000)): + async def create(cls, db_wrapper: DBWrapper2, cache_size: uint32 = uint32(60000)): self = cls() self.cache_size = cache_size self.db_wrapper = db_wrapper - self.coin_record_db = db_wrapper.db - if self.db_wrapper.db_version == 2: + async with self.db_wrapper.write_db() as conn: - # the coin_name is unique in this table because the CoinStore always - # only represent a single peak - await self.coin_record_db.execute( - "CREATE TABLE IF NOT EXISTS coin_record(" - "coin_name blob PRIMARY KEY," - " confirmed_index bigint," - " spent_index bigint," # if this is zero, it means the coin has not been spent - " coinbase int," - " puzzle_hash blob," - " coin_parent blob," - " amount blob," # we use a blob of 8 bytes to store uint64 - " timestamp bigint)" - ) + if self.db_wrapper.db_version == 2: - else: - - # the coin_name is unique in this table because the CoinStore always - # only represent a single peak - await self.coin_record_db.execute( - ( + # the coin_name is unique in this table because the CoinStore always + # only represent a single peak + await conn.execute( "CREATE TABLE IF NOT EXISTS coin_record(" - "coin_name text PRIMARY KEY," + "coin_name blob PRIMARY KEY," " confirmed_index bigint," - " spent_index bigint," - " spent int," + " spent_index bigint," # if this is zero, it means the coin has not been spent " coinbase int," - " puzzle_hash text," - " coin_parent text," - " amount blob," + " puzzle_hash blob," + " coin_parent blob," + " amount blob," # we use a blob of 8 bytes to store uint64 " timestamp bigint)" ) - ) - # Useful for reorg lookups - await self.coin_record_db.execute( - "CREATE INDEX IF NOT EXISTS coin_confirmed_index on coin_record(confirmed_index)" - ) + else: - await self.coin_record_db.execute("CREATE INDEX IF NOT EXISTS coin_spent_index on coin_record(spent_index)") + # the coin_name is unique in this table because the CoinStore always + # only represent a single peak + await conn.execute( + ( + "CREATE TABLE IF NOT EXISTS coin_record(" + "coin_name text PRIMARY KEY," + " confirmed_index bigint," + " spent_index bigint," + " spent int," + " coinbase int," + " puzzle_hash text," + " coin_parent text," + " amount blob," + " timestamp bigint)" + ) + ) - await self.coin_record_db.execute("CREATE INDEX IF NOT EXISTS coin_puzzle_hash on coin_record(puzzle_hash)") + # Useful for reorg lookups + await conn.execute("CREATE INDEX IF NOT EXISTS coin_confirmed_index on coin_record(confirmed_index)") - await self.coin_record_db.execute("CREATE INDEX IF NOT EXISTS coin_parent_index on coin_record(coin_parent)") + await conn.execute("CREATE INDEX IF NOT EXISTS coin_spent_index on coin_record(spent_index)") + + await conn.execute("CREATE INDEX IF NOT EXISTS coin_puzzle_hash on coin_record(puzzle_hash)") + + await conn.execute("CREATE INDEX IF NOT EXISTS coin_parent_index on coin_record(coin_parent)") - await self.coin_record_db.commit() self.coin_record_cache = LRUCache(cache_size) return self async def num_unspent(self) -> int: - async with self.coin_record_db.execute("SELECT COUNT(*) FROM coin_record WHERE spent_index=0") as cursor: - row = await cursor.fetchone() - if row is not None: - return row[0] + async with self.db_wrapper.read_db() as conn: + async with conn.execute("SELECT COUNT(*) FROM coin_record WHERE spent_index=0") as cursor: + row = await cursor.fetchone() + if row is not None: + return row[0] return 0 def maybe_from_hex(self, field: Any) -> bytes: @@ -165,48 +162,51 @@ class CoinStore: if cached is not None: return cached - async with self.coin_record_db.execute( - "SELECT confirmed_index, spent_index, coinbase, puzzle_hash, " - "coin_parent, amount, timestamp FROM coin_record WHERE coin_name=?", - (self.maybe_to_hex(coin_name),), - ) as cursor: - row = await cursor.fetchone() - if row is not None: - coin = self.row_to_coin(row) - record = CoinRecord(coin, row[0], row[1], row[2], row[6]) - self.coin_record_cache.put(record.coin.name(), record) - return record + async with self.db_wrapper.read_db() as conn: + async with conn.execute( + "SELECT confirmed_index, spent_index, coinbase, puzzle_hash, " + "coin_parent, amount, timestamp FROM coin_record WHERE coin_name=?", + (self.maybe_to_hex(coin_name),), + ) as cursor: + row = await cursor.fetchone() + if row is not None: + coin = self.row_to_coin(row) + record = CoinRecord(coin, row[0], row[1], row[2], row[6]) + self.coin_record_cache.put(record.coin.name(), record) + return record return None async def get_coins_added_at_height(self, height: uint32) -> List[CoinRecord]: - async with self.coin_record_db.execute( - "SELECT confirmed_index, spent_index, coinbase, puzzle_hash, " - "coin_parent, amount, timestamp FROM coin_record WHERE confirmed_index=?", - (height,), - ) as cursor: - rows = await cursor.fetchall() - coins = [] - for row in rows: - coin = self.row_to_coin(row) - coins.append(CoinRecord(coin, row[0], row[1], row[2], row[6])) - return coins + async with self.db_wrapper.read_db() as conn: + async with conn.execute( + "SELECT confirmed_index, spent_index, coinbase, puzzle_hash, " + "coin_parent, amount, timestamp FROM coin_record WHERE confirmed_index=?", + (height,), + ) as cursor: + rows = await cursor.fetchall() + coins = [] + for row in rows: + coin = self.row_to_coin(row) + coins.append(CoinRecord(coin, row[0], row[1], row[2], row[6])) + return coins async def get_coins_removed_at_height(self, height: uint32) -> List[CoinRecord]: # Special case to avoid querying all unspent coins (spent_index=0) if height == 0: return [] - async with self.coin_record_db.execute( - "SELECT confirmed_index, spent_index, coinbase, puzzle_hash, " - "coin_parent, amount, timestamp FROM coin_record WHERE spent_index=?", - (height,), - ) as cursor: - coins = [] - for row in await cursor.fetchall(): - if row[1] != 0: - coin = self.row_to_coin(row) - coin_record = CoinRecord(coin, row[0], row[1], row[2], row[6]) - coins.append(coin_record) - return coins + async with self.db_wrapper.read_db() as conn: + async with conn.execute( + "SELECT confirmed_index, spent_index, coinbase, puzzle_hash, " + "coin_parent, amount, timestamp FROM coin_record WHERE spent_index=?", + (height,), + ) as cursor: + coins = [] + for row in await cursor.fetchall(): + if row[1] != 0: + coin = self.row_to_coin(row) + coin_record = CoinRecord(coin, row[0], row[1], row[2], row[6]) + coins.append(coin_record) + return coins # Checks DB and DiffStores for CoinRecords with puzzle_hash and returns them async def get_coin_records_by_puzzle_hash( @@ -219,18 +219,19 @@ class CoinStore: coins = set() - async with self.coin_record_db.execute( - f"SELECT confirmed_index, spent_index, coinbase, puzzle_hash, " - f"coin_parent, amount, timestamp FROM coin_record INDEXED BY coin_puzzle_hash WHERE puzzle_hash=? " - f"AND confirmed_index>=? AND confirmed_index=? AND confirmed_index=? AND confirmed_index=? AND confirmed_index=? AND confirmed_index=? AND confirmed_index=? OR spent_index>=?)" - f"{'' if include_spent_coins else 'AND spent_index=0'}", - puzzle_hashes_db + (min_height, min_height), - ) as cursor: + async with self.db_wrapper.read_db() as conn: + for puzzles in chunks(puzzle_hashes, MAX_SQLITE_PARAMETERS): + puzzle_hashes_db: Tuple[Any, ...] + if self.db_wrapper.db_version == 2: + puzzle_hashes_db = tuple(puzzles) + else: + puzzle_hashes_db = tuple([ph.hex() for ph in puzzles]) + async with conn.execute( + f"SELECT confirmed_index, spent_index, coinbase, puzzle_hash, " + f"coin_parent, amount, timestamp FROM coin_record INDEXED BY coin_puzzle_hash " + f'WHERE puzzle_hash in ({"?," * (len(puzzles) - 1)}?) ' + f"AND (confirmed_index>=? OR spent_index>=?)" + f"{'' if include_spent_coins else 'AND spent_index=0'}", + puzzle_hashes_db + (min_height, min_height), + ) as cursor: - async for row in cursor: - coins.add(self.row_to_coin_state(row)) + async for row in cursor: + coins.add(self.row_to_coin_state(row)) return list(coins) @@ -345,23 +351,25 @@ class CoinStore: return [] coins = set() - for ids in chunks(parent_ids, MAX_SQLITE_PARAMETERS): - parent_ids_db: Tuple[Any, ...] - if self.db_wrapper.db_version == 2: - parent_ids_db = tuple(ids) - else: - parent_ids_db = tuple([pid.hex() for pid in ids]) - async with self.coin_record_db.execute( - f"SELECT confirmed_index, spent_index, coinbase, puzzle_hash, " - f'coin_parent, amount, timestamp FROM coin_record WHERE coin_parent in ({"?," * (len(ids) - 1)}?) ' - f"AND confirmed_index>=? AND confirmed_index=? AND confirmed_index=? OR spent_index>=?)" - f"{'' if include_spent_coins else 'AND spent_index=0'}", - coin_ids_db + (min_height, min_height), - ) as cursor: - async for row in cursor: - coins.add(self.row_to_coin_state(row)) + async with self.db_wrapper.read_db() as conn: + for ids in chunks(coin_ids, MAX_SQLITE_PARAMETERS): + coin_ids_db: Tuple[Any, ...] + if self.db_wrapper.db_version == 2: + coin_ids_db = tuple(ids) + else: + coin_ids_db = tuple([pid.hex() for pid in ids]) + async with conn.execute( + f"SELECT confirmed_index, spent_index, coinbase, puzzle_hash, " + f'coin_parent, amount, timestamp FROM coin_record WHERE coin_name in ({"?," * (len(ids) - 1)}?) ' + f"AND (confirmed_index>=? OR spent_index>=?)" + f"{'' if include_spent_coins else 'AND spent_index=0'}", + coin_ids_db + (min_height, min_height), + ) as cursor: + async for row in cursor: + coins.add(self.row_to_coin_state(row)) return list(coins) async def rollback_to_block(self, block_index: int) -> List[CoinRecord]: @@ -415,38 +424,37 @@ class CoinStore: self.coin_record_cache.remove(coin_name) coin_changes: Dict[bytes32, CoinRecord] = {} - async with self.coin_record_db.execute( - "SELECT confirmed_index, spent_index, coinbase, puzzle_hash, " - "coin_parent, amount, timestamp FROM coin_record WHERE confirmed_index>?", - (block_index,), - ) as cursor: - for row in await cursor.fetchall(): - coin = self.row_to_coin(row) - record = CoinRecord(coin, uint32(0), row[1], row[2], uint64(0)) - coin_changes[record.name] = record - - # Delete from storage - await self.coin_record_db.execute("DELETE FROM coin_record WHERE confirmed_index>?", (block_index,)) - - async with self.coin_record_db.execute( - "SELECT confirmed_index, spent_index, coinbase, puzzle_hash, " - "coin_parent, amount, timestamp FROM coin_record WHERE confirmed_index>?", - (block_index,), - ) as cursor: - for row in await cursor.fetchall(): - coin = self.row_to_coin(row) - record = CoinRecord(coin, row[0], uint32(0), row[2], row[6]) - if record.name not in coin_changes: + async with self.db_wrapper.write_db() as conn: + async with conn.execute( + "SELECT confirmed_index, spent_index, coinbase, puzzle_hash, " + "coin_parent, amount, timestamp FROM coin_record WHERE confirmed_index>?", + (block_index,), + ) as cursor: + for row in await cursor.fetchall(): + coin = self.row_to_coin(row) + record = CoinRecord(coin, uint32(0), row[1], row[2], uint64(0)) coin_changes[record.name] = record - if self.db_wrapper.db_version == 2: - await self.coin_record_db.execute( - "UPDATE coin_record SET spent_index=0 WHERE spent_index>?", (block_index,) - ) - else: - await self.coin_record_db.execute( - "UPDATE coin_record SET spent_index = 0, spent = 0 WHERE spent_index>?", (block_index,) - ) + # Delete from storage + await conn.execute("DELETE FROM coin_record WHERE confirmed_index>?", (block_index,)) + + async with conn.execute( + "SELECT confirmed_index, spent_index, coinbase, puzzle_hash, " + "coin_parent, amount, timestamp FROM coin_record WHERE confirmed_index>?", + (block_index,), + ) as cursor: + for row in await cursor.fetchall(): + coin = self.row_to_coin(row) + record = CoinRecord(coin, row[0], uint32(0), row[2], row[6]) + if record.name not in coin_changes: + coin_changes[record.name] = record + + if self.db_wrapper.db_version == 2: + await conn.execute("UPDATE coin_record SET spent_index=0 WHERE spent_index>?", (block_index,)) + else: + await conn.execute( + "UPDATE coin_record SET spent_index = 0, spent = 0 WHERE spent_index>?", (block_index,) + ) return list(coin_changes.values()) # Store CoinRecord in DB and ram cache @@ -468,10 +476,12 @@ class CoinStore: record.timestamp, ) ) - await self.coin_record_db.executemany( - "INSERT INTO coin_record VALUES(?, ?, ?, ?, ?, ?, ?, ?)", - values2, - ) + if len(values2) > 0: + async with self.db_wrapper.write_db() as conn: + await conn.executemany( + "INSERT INTO coin_record VALUES(?, ?, ?, ?, ?, ?, ?, ?)", + values2, + ) else: values = [] for record in records: @@ -489,10 +499,12 @@ class CoinStore: record.timestamp, ) ) - await self.coin_record_db.executemany( - "INSERT INTO coin_record VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)", - values, - ) + if len(values) > 0: + async with self.db_wrapper.write_db() as conn: + await conn.executemany( + "INSERT INTO coin_record VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)", + values, + ) # Update coin_record to be spent in DB async def _set_spent(self, coin_names: List[bytes32], index: uint32): @@ -508,11 +520,11 @@ class CoinStore: ) updates.append((index, self.maybe_to_hex(coin_name))) - if self.db_wrapper.db_version == 2: - await self.coin_record_db.executemany( - "UPDATE OR FAIL coin_record SET spent_index=? WHERE coin_name=?", updates - ) - else: - await self.coin_record_db.executemany( - "UPDATE OR FAIL coin_record SET spent=1,spent_index=? WHERE coin_name=?", updates - ) + if updates != []: + async with self.db_wrapper.write_db() as conn: + if self.db_wrapper.db_version == 2: + await conn.executemany("UPDATE OR FAIL coin_record SET spent_index=? WHERE coin_name=?", updates) + else: + await conn.executemany( + "UPDATE OR FAIL coin_record SET spent=1,spent_index=? WHERE coin_name=?", updates + ) diff --git a/chia/full_node/full_node.py b/chia/full_node/full_node.py index 1eb2a454f3..0eeeede688 100644 --- a/chia/full_node/full_node.py +++ b/chia/full_node/full_node.py @@ -67,7 +67,7 @@ from chia.util.bech32m import encode_puzzle_hash from chia.util.check_fork_next_block import check_fork_next_block from chia.util.condition_tools import pkm_pairs from chia.util.config import PEER_DB_PATH_KEY_DEPRECATED, process_config_start_method -from chia.util.db_wrapper import DBWrapper +from chia.util.db_wrapper import DBWrapper2 from chia.util.errors import ConsensusError, Err, ValidationError from chia.util.ints import uint8, uint32, uint64, uint128 from chia.util.path import mkdir, path_from_root @@ -85,7 +85,6 @@ class FullNode: sync_store: Any coin_store: CoinStore mempool_manager: MempoolManager - connection: aiosqlite.Connection _sync_task: Optional[asyncio.Task] _init_weight_proof: Optional[asyncio.Task] = None blockchain: Blockchain @@ -164,23 +163,8 @@ class FullNode: # These many respond_transaction tasks can be active at any point in time self.respond_transaction_semaphore = asyncio.Semaphore(200) # create the store (db) and full node instance - self.connection = await aiosqlite.connect(self.db_path) - await self.connection.execute("pragma journal_mode=wal") - db_sync = db_synchronous_on(self.config.get("db_sync", "auto"), self.db_path) - self.log.info(f"opening blockchain DB: synchronous={db_sync}") - await self.connection.execute("pragma synchronous={}".format(db_sync)) - - async with self.connection.execute( - "SELECT name FROM sqlite_master WHERE type='table' AND name='full_blocks'" - ) as conn: - if len(await conn.fetchall()) == 0: - try: - # this is a new DB file. Make it v2 - await set_db_version_async(self.connection, 2) - except sqlite3.OperationalError: - # it could be a database created with "chia init", which is - # empty except it has the database_version table - pass + db_connection = await aiosqlite.connect(self.db_path) + db_version: int = await lookup_db_version(db_connection) if self.config.get("log_sqlite_cmds", False): sql_log_path = path_from_root(self.root_path, "log/sql.log") @@ -192,11 +176,38 @@ class FullNode: log.write(timestamp + " " + req + "\n") log.close() - await self.connection.set_trace_callback(sql_trace_callback) + await db_connection.set_trace_callback(sql_trace_callback) - db_version: int = await lookup_db_version(self.connection) + self.db_wrapper = DBWrapper2(db_connection, db_version=db_version) + + # add reader threads for the DB + for i in range(self.config.get("db_readers", 4)): + c = await aiosqlite.connect(self.db_path) + if self.config.get("log_sqlite_cmds", False): + await c.set_trace_callback(sql_trace_callback) + await self.db_wrapper.add_connection(c) + + await (await db_connection.execute("pragma journal_mode=wal")).close() + db_sync = db_synchronous_on(self.config.get("db_sync", "auto"), self.db_path) + self.log.info(f"opening blockchain DB: synchronous={db_sync}") + await (await db_connection.execute("pragma synchronous={}".format(db_sync))).close() + + if db_version != 2: + async with self.db_wrapper.read_db() as conn: + async with conn.execute( + "SELECT name FROM sqlite_master WHERE type='table' AND name='full_blocks'" + ) as cur: + if len(await cur.fetchall()) == 0: + try: + # this is a new DB file. Make it v2 + async with self.db_wrapper.write_db() as w_conn: + await set_db_version_async(w_conn, 2) + self.db_wrapper.db_version = 2 + except sqlite3.OperationalError: + # it could be a database created with "chia init", which is + # empty except it has the database_version table + pass - self.db_wrapper = DBWrapper(self.connection, db_version=db_version) self.block_store = await BlockStore.create(self.db_wrapper) self.sync_store = await SyncStore.create() self.hint_store = await HintStore.create(self.db_wrapper) @@ -204,6 +215,7 @@ class FullNode: self.log.info("Initializing blockchain from disk") start_time = time.time() reserved_cores = self.config.get("reserved_cores", 0) + single_threaded = self.config.get("single_threaded", False) multiprocessing_start_method = process_config_start_method(config=self.config, log=self.log) self.multiprocessing_context = multiprocessing.get_context(method=multiprocessing_start_method) self.blockchain = await Blockchain.create( @@ -214,11 +226,13 @@ class FullNode: blockchain_dir=self.db_path.parent, reserved_cores=reserved_cores, multiprocessing_context=self.multiprocessing_context, + single_threaded=single_threaded, ) self.mempool_manager = MempoolManager( coin_store=self.coin_store, consensus_constants=self.constants, multiprocessing_context=self.multiprocessing_context, + single_threaded=single_threaded, ) # Blocks are validated under high priority, and transactions under low priority. This guarantees blocks will @@ -770,7 +784,7 @@ class FullNode: async def _await_closed(self): for task_id, task in list(self.full_node_store.tx_fetch_tasks.items()): cancel_task_safe(task, self.log) - await self.connection.close() + await self.db_wrapper.close() if self._init_weight_proof is not None: await asyncio.wait([self._init_weight_proof]) if hasattr(self, "_blockchain_lock_queue"): @@ -984,10 +998,7 @@ class FullNode: await self.send_peak_to_wallets() self.blockchain.clean_block_record(end_height - self.constants.BLOCKS_CACHE_SIZE) - loop = asyncio.get_event_loop() - batch_queue: asyncio.Queue[Tuple[ws.WSChiaConnection, List[FullBlock]]] = asyncio.Queue( - loop=loop, maxsize=buffer_size - ) + batch_queue: asyncio.Queue[Tuple[ws.WSChiaConnection, List[FullBlock]]] = asyncio.Queue(maxsize=buffer_size) fetch_task = asyncio.Task(fetch_block_batches(batch_queue, peers_with_peak)) validate_task = asyncio.Task(validate_block_batches(batch_queue)) try: @@ -1544,7 +1555,7 @@ class FullNode: elif added == ReceiveBlockResult.INVALID_BLOCK: assert error_code is not None self.log.error(f"Block {header_hash} at height {block.height} is invalid with code {error_code}.") - raise ConsensusError(error_code, header_hash) + raise ConsensusError(error_code, [header_hash]) elif added == ReceiveBlockResult.DISCONNECTED_BLOCK: self.log.info(f"Disconnected block {header_hash} at height {block.height}") @@ -2225,14 +2236,11 @@ class FullNode: new_block = dataclasses.replace(block, challenge_chain_ip_proof=vdf_proof) if new_block is None: return False - async with self.db_wrapper.lock: + async with self.db_wrapper.write_db(): try: - await self.block_store.db_wrapper.begin_transaction() await self.block_store.replace_proof(header_hash, new_block) - await self.block_store.db_wrapper.commit_transaction() return True except BaseException as e: - await self.block_store.db_wrapper.rollback_transaction() self.log.error( f"_replace_proof error while adding block {block.header_hash} height {block.height}," f" rolling back: {e} {traceback.format_exc()}" diff --git a/chia/full_node/full_node_api.py b/chia/full_node/full_node_api.py index c660210a3a..38e2debdda 100644 --- a/chia/full_node/full_node_api.py +++ b/chia/full_node/full_node_api.py @@ -1196,11 +1196,12 @@ class FullNodeAPI: block: Optional[FullBlock] = await self.full_node.block_store.get_full_block(request.header_hash) # We lock so that the coin store does not get modified + peak_height = self.full_node.blockchain.get_peak_height() if ( block is None or block.is_transaction_block() is False or block.height != request.height - or block.height > self.full_node.blockchain.get_peak_height() + or (peak_height is not None and block.height > peak_height) or self.full_node.blockchain.height_to_hash(block.height) != request.header_hash ): reject = wallet_protocol.RejectRemovalsRequest(request.height, request.header_hash) @@ -1256,11 +1257,10 @@ class FullNodeAPI: return msg @api_request - async def send_transaction(self, request: wallet_protocol.SendTransaction) -> Optional[Message]: + async def send_transaction(self, request: wallet_protocol.SendTransaction, *, test=False) -> Optional[Message]: spend_name = request.transaction.name() - await self.full_node.transaction_queue.put( - (0, TransactionQueueEntry(request.transaction, None, spend_name, None, False)) + (0, TransactionQueueEntry(request.transaction, None, spend_name, None, test)) ) # Waits for the transaction to go into the mempool, times out after 45 seconds. status, error = None, None diff --git a/chia/full_node/hint_store.py b/chia/full_node/hint_store.py index 422eb544e7..38ead43e2b 100644 --- a/chia/full_node/hint_store.py +++ b/chia/full_node/hint_store.py @@ -1,56 +1,57 @@ from typing import List, Tuple from chia.types.blockchain_format.sized_bytes import bytes32 -from chia.util.db_wrapper import DBWrapper +from chia.util.db_wrapper import DBWrapper2 import logging log = logging.getLogger(__name__) class HintStore: - db_wrapper: DBWrapper + db_wrapper: DBWrapper2 @classmethod - async def create(cls, db_wrapper: DBWrapper): + async def create(cls, db_wrapper: DBWrapper2): self = cls() self.db_wrapper = db_wrapper - if self.db_wrapper.db_version == 2: - await self.db_wrapper.db.execute( - "CREATE TABLE IF NOT EXISTS hints(coin_id blob, hint blob, UNIQUE (coin_id, hint))" - ) - else: - await self.db_wrapper.db.execute( - "CREATE TABLE IF NOT EXISTS hints(id INTEGER PRIMARY KEY AUTOINCREMENT, coin_id blob, hint blob)" - ) - await self.db_wrapper.db.execute("CREATE INDEX IF NOT EXISTS hint_index on hints(hint)") - await self.db_wrapper.db.commit() + async with self.db_wrapper.write_db() as conn: + if self.db_wrapper.db_version == 2: + await conn.execute("CREATE TABLE IF NOT EXISTS hints(coin_id blob, hint blob, UNIQUE (coin_id, hint))") + else: + await conn.execute( + "CREATE TABLE IF NOT EXISTS hints(id INTEGER PRIMARY KEY AUTOINCREMENT, coin_id blob, hint blob)" + ) + await conn.execute("CREATE INDEX IF NOT EXISTS hint_index on hints(hint)") return self async def get_coin_ids(self, hint: bytes) -> List[bytes32]: - cursor = await self.db_wrapper.db.execute("SELECT coin_id from hints WHERE hint=?", (hint,)) - rows = await cursor.fetchall() - await cursor.close() + async with self.db_wrapper.read_db() as conn: + cursor = await conn.execute("SELECT coin_id from hints WHERE hint=?", (hint,)) + rows = await cursor.fetchall() + await cursor.close() coin_ids = [] for row in rows: coin_ids.append(row[0]) return coin_ids async def add_hints(self, coin_hint_list: List[Tuple[bytes32, bytes]]) -> None: - if self.db_wrapper.db_version == 2: - cursor = await self.db_wrapper.db.executemany( - "INSERT OR IGNORE INTO hints VALUES(?, ?)", - coin_hint_list, - ) - else: - cursor = await self.db_wrapper.db.executemany( - "INSERT INTO hints VALUES(?, ?, ?)", - [(None,) + record for record in coin_hint_list], - ) - await cursor.close() + async with self.db_wrapper.write_db() as conn: + if self.db_wrapper.db_version == 2: + cursor = await conn.executemany( + "INSERT OR IGNORE INTO hints VALUES(?, ?)", + coin_hint_list, + ) + else: + cursor = await conn.executemany( + "INSERT INTO hints VALUES(?, ?, ?)", + [(None,) + record for record in coin_hint_list], + ) + await cursor.close() async def count_hints(self) -> int: - async with self.db_wrapper.db.execute("select count(*) from hints") as cursor: - row = await cursor.fetchone() + async with self.db_wrapper.read_db() as conn: + async with conn.execute("select count(*) from hints") as cursor: + row = await cursor.fetchone() assert row is not None diff --git a/chia/full_node/mempool_manager.py b/chia/full_node/mempool_manager.py index fa52d06fe0..6c5f7aa49e 100644 --- a/chia/full_node/mempool_manager.py +++ b/chia/full_node/mempool_manager.py @@ -2,9 +2,11 @@ import asyncio import collections import dataclasses import logging +from concurrent.futures import Executor from multiprocessing.context import BaseContext import time from concurrent.futures.process import ProcessPoolExecutor +from chia.util.inline_executor import InlineExecutor from typing import Dict, List, Optional, Set, Tuple from blspy import GTElement from chiabip158 import PyBIP158 @@ -79,11 +81,15 @@ def validate_clvm_and_signature( class MempoolManager: + pool: Executor + def __init__( self, coin_store: CoinStore, consensus_constants: ConsensusConstants, multiprocessing_context: Optional[BaseContext] = None, + *, + single_threaded: bool = False, ): self.constants: ConsensusConstants = consensus_constants self.constants_json = recurse_jsonify(dataclasses.asdict(self.constants)) @@ -105,12 +111,15 @@ class MempoolManager: # Transactions that were unable to enter mempool, used for retry. (they were invalid) self.potential_cache = PendingTxCache(self.constants.MAX_BLOCK_COST_CLVM * 1) self.seen_cache_size = 10000 - self.pool = ProcessPoolExecutor( - max_workers=2, - mp_context=multiprocessing_context, - initializer=setproctitle, - initargs=(f"{getproctitle()}_worker",), - ) + if single_threaded: + self.pool = InlineExecutor() + else: + self.pool = ProcessPoolExecutor( + max_workers=2, + mp_context=multiprocessing_context, + initializer=setproctitle, + initargs=(f"{getproctitle()}_worker",), + ) # The mempool will correspond to a certain peak self.peak: Optional[BlockRecord] = None diff --git a/chia/harvester/harvester.py b/chia/harvester/harvester.py index d2dcd1eed5..b63b0c7a16 100644 --- a/chia/harvester/harvester.py +++ b/chia/harvester/harvester.py @@ -64,7 +64,7 @@ class Harvester: async def _start(self): self._refresh_lock = asyncio.Lock() - self.event_loop = asyncio.get_event_loop() + self.event_loop = asyncio.get_running_loop() def _close(self): self._is_shutdown = True diff --git a/chia/plotters/bladebit.py b/chia/plotters/bladebit.py index e085cc47c1..0fc826e671 100644 --- a/chia/plotters/bladebit.py +++ b/chia/plotters/bladebit.py @@ -173,7 +173,7 @@ def plot_bladebit(args, chia_root_path, root_path): except Exception as e: print(f"Exception while installing bladebit plotter: {e}") return - plot_keys = asyncio.get_event_loop().run_until_complete( + plot_keys = asyncio.run( resolve_plot_keys( None if args.farmerkey == b"" else args.farmerkey.hex(), None, @@ -209,8 +209,7 @@ def plot_bladebit(args, chia_root_path, root_path): call_args.append("-m") call_args.append(args.finaldir) try: - loop = asyncio.get_event_loop() - loop.run_until_complete(run_plotter(call_args, progress)) + asyncio.run(run_plotter(call_args, progress)) except Exception as e: print(f"Exception while plotting: {e} {type(e)}") print(f"Traceback: {traceback.format_exc()}") diff --git a/chia/plotters/chiapos.py b/chia/plotters/chiapos.py index f402e7c174..fc24acbdf1 100644 --- a/chia/plotters/chiapos.py +++ b/chia/plotters/chiapos.py @@ -43,7 +43,7 @@ def plot_chia(args, root_path): print("Error: The minimum k size allowed from the cli is k=25.") return - plot_keys = asyncio.get_event_loop().run_until_complete( + plot_keys = asyncio.run( resolve_plot_keys( None if args.farmerkey == b"" else args.farmerkey.hex(), args.alt_fingerprint, @@ -54,4 +54,4 @@ def plot_chia(args, root_path): args.connect_to_daemon, ) ) - asyncio.get_event_loop().run_until_complete(create_plots(Params(args), plot_keys, root_path)) + asyncio.run(create_plots(Params(args), plot_keys, root_path)) diff --git a/chia/plotters/madmax.py b/chia/plotters/madmax.py index ce75682b08..c3ec020e30 100644 --- a/chia/plotters/madmax.py +++ b/chia/plotters/madmax.py @@ -180,7 +180,7 @@ def plot_madmax(args, chia_root_path: Path, plotters_root_path: Path): except Exception as e: print(f"Exception while installing madmax plotter: {e}") return - plot_keys = asyncio.get_event_loop().run_until_complete( + plot_keys = asyncio.run( resolve_plot_keys( None if args.farmerkey == b"" else args.farmerkey.hex(), None, @@ -227,8 +227,7 @@ def plot_madmax(args, chia_root_path: Path, plotters_root_path: Path): call_args.append("-k") call_args.append(str(args.size)) try: - loop = asyncio.get_event_loop() - loop.run_until_complete(run_plotter(call_args, progress)) + asyncio.run(run_plotter(call_args, progress)) except Exception as e: print(f"Exception while plotting: {type(e)} {e}") print(f"Traceback: {traceback.format_exc()}") diff --git a/chia/plotting/util.py b/chia/plotting/util.py index c777c2c418..132f0d67ee 100644 --- a/chia/plotting/util.py +++ b/chia/plotting/util.py @@ -9,7 +9,7 @@ from blspy import G1Element, PrivateKey from chiapos import DiskProver from chia.types.blockchain_format.sized_bytes import bytes32 -from chia.util.config import load_config, save_config, get_config_lock +from chia.util.config import load_config, lock_and_load_config, save_config log = logging.getLogger(__name__) @@ -79,8 +79,7 @@ def get_plot_filenames(root_path: Path) -> Dict[Path, List[Path]]: def add_plot_directory(root_path: Path, str_path: str) -> Dict: log.debug(f"add_plot_directory {str_path}") - with get_config_lock(root_path, "config.yaml"): - config = load_config(root_path, "config.yaml", acquire_lock=False) + with lock_and_load_config(root_path, "config.yaml") as config: if str(Path(str_path).resolve()) not in get_plot_directories(root_path, config): config["harvester"]["plot_directories"].append(str(Path(str_path).resolve())) save_config(root_path, "config.yaml", config) @@ -89,8 +88,7 @@ def add_plot_directory(root_path: Path, str_path: str) -> Dict: def remove_plot_directory(root_path: Path, str_path: str) -> None: log.debug(f"remove_plot_directory {str_path}") - with get_config_lock(root_path, "config.yaml"): - config = load_config(root_path, "config.yaml", acquire_lock=False) + with lock_and_load_config(root_path, "config.yaml") as config: str_paths: List[str] = get_plot_directories(root_path, config) # If path str matches exactly, remove if str_path in str_paths: diff --git a/chia/pools/pool_config.py b/chia/pools/pool_config.py index d9d1573387..ffa07e962e 100644 --- a/chia/pools/pool_config.py +++ b/chia/pools/pool_config.py @@ -7,7 +7,7 @@ from blspy import G1Element from chia.types.blockchain_format.sized_bytes import bytes32 from chia.util.byte_types import hexstr_to_bytes -from chia.util.config import get_config_lock, load_config, save_config +from chia.util.config import load_config, lock_and_load_config, save_config from chia.util.streamable import Streamable, streamable """ @@ -61,8 +61,7 @@ def load_pool_config(root_path: Path) -> List[PoolWalletConfig]: # TODO: remove this a few versions after 1.3, since authentication_public_key is deprecated. This is here to support # downgrading to versions older than 1.3. def add_auth_key(root_path: Path, config_entry: PoolWalletConfig, auth_key: G1Element): - with get_config_lock(root_path, "config.yaml"): - config = load_config(root_path, "config.yaml", acquire_lock=False) + with lock_and_load_config(root_path, "config.yaml") as config: pool_list = config["pool"].get("pool_list", []) updated = False if pool_list is not None: @@ -82,7 +81,6 @@ def add_auth_key(root_path: Path, config_entry: PoolWalletConfig, auth_key: G1El async def update_pool_config(root_path: Path, pool_config_list: List[PoolWalletConfig]): - with get_config_lock(root_path, "config.yaml"): - full_config = load_config(root_path, "config.yaml", acquire_lock=False) + with lock_and_load_config(root_path, "config.yaml") as full_config: full_config["pool"]["pool_list"] = [c.to_json_dict() for c in pool_config_list] save_config(root_path, "config.yaml", full_config) diff --git a/chia/pools/pool_wallet.py b/chia/pools/pool_wallet.py index 5f6698625c..a2df612349 100644 --- a/chia/pools/pool_wallet.py +++ b/chia/pools/pool_wallet.py @@ -43,7 +43,7 @@ from chia.pools.pool_puzzles import ( get_delayed_puz_info_from_launcher_spend, ) -from chia.util.ints import uint8, uint32, uint64 +from chia.util.ints import uint8, uint32, uint64, uint128 from chia.wallet.derive_keys import ( find_owner_sk, ) @@ -919,25 +919,25 @@ class PoolWallet: ) return len(unconfirmed) > 0 - async def get_confirmed_balance(self, _=None) -> uint64: - amount: uint64 = uint64(0) + async def get_confirmed_balance(self, _=None) -> uint128: + amount: uint128 = uint128(0) if (await self.get_current_state()).current.state == SELF_POOLING: unspent_coin_records: List[WalletCoinRecord] = list( await self.wallet_state_manager.coin_store.get_unspent_coins_for_wallet(self.wallet_id) ) for record in unspent_coin_records: if record.coinbase: - amount = uint64(amount + record.coin.amount) + amount = uint128(amount + record.coin.amount) return amount - async def get_unconfirmed_balance(self, record_list=None) -> uint64: + async def get_unconfirmed_balance(self, record_list=None) -> uint128: return await self.get_confirmed_balance(record_list) - async def get_spendable_balance(self, record_list=None) -> uint64: + async def get_spendable_balance(self, record_list=None) -> uint128: return await self.get_confirmed_balance(record_list) async def get_pending_change_balance(self) -> uint64: return uint64(0) - async def get_max_send_amount(self, record_list=None) -> uint64: - return uint64(0) + async def get_max_send_amount(self, record_list=None) -> uint128: + return uint128(0) diff --git a/chia/seeder/dns_server.py b/chia/seeder/dns_server.py index 24dc5b7b10..85466cadfc 100644 --- a/chia/seeder/dns_server.py +++ b/chia/seeder/dns_server.py @@ -36,7 +36,7 @@ ns_records: List[Any] = [] class EchoServerProtocol(asyncio.DatagramProtocol): def __init__(self, callback): - self.data_queue = asyncio.Queue(loop=asyncio.get_event_loop()) + self.data_queue = asyncio.Queue() self.callback = callback asyncio.ensure_future(self.respond()) @@ -44,7 +44,7 @@ class EchoServerProtocol(asyncio.DatagramProtocol): self.transport = transport def datagram_received(self, data, addr): - asyncio.ensure_future(self.handler(data, addr), loop=asyncio.get_event_loop()) + asyncio.ensure_future(self.handler(data, addr)) async def respond(self): while True: @@ -242,6 +242,22 @@ async def kill_processes(): pass +def signal_received(): + asyncio.create_task(kill_processes()) + + +async def async_main(config, root_path): + loop = asyncio.get_running_loop() + + try: + loop.add_signal_handler(signal.SIGINT, signal_received) + loop.add_signal_handler(signal.SIGTERM, signal_received) + except NotImplementedError: + log.info("signal handlers unsupported") + + await serve_dns(config, root_path) + + def main(): root_path = DEFAULT_ROOT_PATH config = load_config(root_path, "config.yaml", SERVICE_NAME) @@ -267,21 +283,7 @@ def main(): ) ns_records = [NS(ns)] - def signal_received(): - asyncio.create_task(kill_processes()) - - loop = asyncio.get_event_loop() - - try: - loop.add_signal_handler(signal.SIGINT, signal_received) - loop.add_signal_handler(signal.SIGTERM, signal_received) - except NotImplementedError: - log.info("signal handlers unsupported") - - try: - loop.run_until_complete(serve_dns(config, root_path)) - finally: - loop.close() + asyncio.run(async_main(config=config, root_path=root_path)) if __name__ == "__main__": diff --git a/chia/timelord/timelord_launcher.py b/chia/timelord/timelord_launcher.py index 88f0e11a5b..657cb6eb1e 100644 --- a/chia/timelord/timelord_launcher.py +++ b/chia/timelord/timelord_launcher.py @@ -90,6 +90,25 @@ async def spawn_all_processes(config: Dict, net_config: Dict): await asyncio.gather(*awaitables) +def signal_received(): + asyncio.create_task(kill_processes()) + + +async def async_main(config, net_config): + loop = asyncio.get_running_loop() + + try: + loop.add_signal_handler(signal.SIGINT, signal_received) + loop.add_signal_handler(signal.SIGTERM, signal_received) + except NotImplementedError: + log.info("signal handlers unsupported") + + try: + await spawn_all_processes(config, net_config) + finally: + log.info("Launcher fully closed.") + + def main(): if os.name == "nt": log.info("Timelord launcher not supported on Windows.") @@ -100,22 +119,7 @@ def main(): config = net_config["timelord_launcher"] initialize_logging("TLauncher", config["logging"], root_path) - def signal_received(): - asyncio.create_task(kill_processes()) - - loop = asyncio.get_event_loop() - - try: - loop.add_signal_handler(signal.SIGINT, signal_received) - loop.add_signal_handler(signal.SIGTERM, signal_received) - except NotImplementedError: - log.info("signal handlers unsupported") - - try: - loop.run_until_complete(spawn_all_processes(config, net_config)) - finally: - log.info("Launcher fully closed.") - loop.close() + asyncio.run(async_main(config=config, net_config=net_config)) if __name__ == "__main__": diff --git a/chia/types/blockchain_format/program.py b/chia/types/blockchain_format/program.py index 52c06ef0e1..3b29e6cd78 100644 --- a/chia/types/blockchain_format/program.py +++ b/chia/types/blockchain_format/program.py @@ -2,10 +2,8 @@ import io from typing import List, Set, Tuple, Optional, Any from clvm import SExp -from clvm import run_program as default_run_program from clvm.casts import int_from_bytes from clvm.EvalError import EvalError -from clvm.operators import OPERATOR_LOOKUP from clvm.serialize import sexp_from_stream, sexp_to_stream from clvm_rs import MEMPOOL_MODE, run_chia_program, serialized_length, run_generator2 from clvm_tools.curry import curry, uncurry @@ -18,22 +16,6 @@ from chia.util.byte_types import hexstr_to_bytes from .tree_hash import sha256_treehash -def run_program( - program, - args, - max_cost, - operator_lookup=OPERATOR_LOOKUP, - pre_eval_f=None, -): - return default_run_program( - program, - args, - operator_lookup, - max_cost, - pre_eval_f=pre_eval_f, - ) - - INFINITE_COST = 0x7FFFFFFFFFFFFFFF @@ -63,10 +45,6 @@ class Program(SExp): def to_serialized_program(self) -> "SerializedProgram": return SerializedProgram.from_bytes(bytes(self)) - @classmethod - def from_serialized_program(cls, sp: "SerializedProgram") -> "Program": - return cls.from_bytes(bytes(sp)) - def __bytes__(self) -> bytes: f = io.BytesIO() self.stream(f) # noqa @@ -103,7 +81,7 @@ class Program(SExp): def run_with_cost(self, max_cost: int, args) -> Tuple[int, "Program"]: prog_args = Program.to(args) - cost, r = run_program(self, prog_args, max_cost) + cost, r = run_chia_program(self.as_bin(), prog_args.as_bin(), max_cost, 0) return cost, Program.to(r) def run(self, args) -> "Program": diff --git a/chia/types/full_block.py b/chia/types/full_block.py index 0f4156cd68..25a0772d62 100644 --- a/chia/types/full_block.py +++ b/chia/types/full_block.py @@ -4,6 +4,7 @@ from chia.types.blockchain_format.coin import Coin from chia.types.blockchain_format.foliage import Foliage, FoliageTransactionBlock, TransactionsInfo from chia.types.blockchain_format.program import SerializedProgram from chia.types.blockchain_format.reward_chain_block import RewardChainBlock +from chia.types.blockchain_format.sized_bytes import bytes32 from chia.types.blockchain_format.vdf import VDFProof from chia.types.end_of_slot_bundle import EndOfSubSlotBundle from chia.util.ints import uint32 @@ -30,11 +31,11 @@ class FullBlock(Streamable): ] # List of block heights of previous generators referenced in this block @property - def prev_header_hash(self): + def prev_header_hash(self) -> bytes32: return self.foliage.prev_block_hash @property - def height(self): + def height(self) -> uint32: return self.reward_chain_block.height @property @@ -46,7 +47,7 @@ class FullBlock(Streamable): return self.reward_chain_block.total_iters @property - def header_hash(self): + def header_hash(self) -> bytes32: return self.foliage.get_hash() def is_transaction_block(self) -> bool: diff --git a/chia/util/config.py b/chia/util/config.py index 60c14a18a6..1405cacaad 100644 --- a/chia/util/config.py +++ b/chia/util/config.py @@ -8,11 +8,11 @@ import tempfile import time import traceback from pathlib import Path -from typing import Any, Callable, Dict, Optional, Union +from typing import Any, Callable, Dict, Iterator, Optional, Union import pkg_resources import yaml -from filelock import BaseFileLock, FileLock +from filelock import FileLock from typing_extensions import Literal from chia.util.path import mkdir @@ -48,10 +48,22 @@ def config_path_for_filename(root_path: Path, filename: Union[str, Path]) -> Pat return root_path / "config" / filename -def get_config_lock(root_path: Path, filename: Union[str, Path]) -> BaseFileLock: +@contextlib.contextmanager +def lock_config(root_path: Path, filename: Union[str, Path]) -> Iterator[None]: + # TODO: This is presently used in some tests to lock the saving of the + # configuration file without having loaded it right there. This usage + # should probably be removed and this function made private. config_path = config_path_for_filename(root_path, filename) lock_path: Path = config_path.with_name(config_path.name + ".lock") - return FileLock(lock_path) + with FileLock(lock_path): + yield + + +@contextlib.contextmanager +def lock_and_load_config(root_path: Path, filename: Union[str, Path]) -> Iterator[Dict[str, Any]]: + with lock_config(root_path=root_path, filename=filename): + config = _load_config_maybe_locked(root_path=root_path, filename=filename, acquire_lock=False) + yield config def save_config(root_path: Path, filename: Union[str, Path], config_data: Any): @@ -72,6 +84,21 @@ def load_config( filename: Union[str, Path], sub_config: Optional[str] = None, exit_on_error: bool = True, +) -> Dict: + return _load_config_maybe_locked( + root_path=root_path, + filename=filename, + sub_config=sub_config, + exit_on_error=exit_on_error, + acquire_lock=True, + ) + + +def _load_config_maybe_locked( + root_path: Path, + filename: Union[str, Path], + sub_config: Optional[str] = None, + exit_on_error: bool = True, acquire_lock: bool = True, ) -> Dict: # This must be called under an acquired config lock, or acquire_lock should be True @@ -90,7 +117,7 @@ def load_config( try: with contextlib.ExitStack() as exit_stack: if acquire_lock: - exit_stack.enter_context(get_config_lock(root_path, filename)) + exit_stack.enter_context(lock_config(root_path, filename)) with open(path, "r") as opened_config_file: r = yaml.safe_load(opened_config_file) if r is None: diff --git a/chia/util/db_version.py b/chia/util/db_version.py index 379f47267a..c4a8e3a88c 100644 --- a/chia/util/db_version.py +++ b/chia/util/db_version.py @@ -19,7 +19,7 @@ async def lookup_db_version(db: aiosqlite.Connection) -> int: async def set_db_version_async(db: aiosqlite.Connection, version: int) -> None: await db.execute("CREATE TABLE database_version(version int)") await db.execute("INSERT INTO database_version VALUES (?)", (version,)) - db.commit() + await db.commit() def set_db_version(db: sqlite3.Connection, version: int) -> None: diff --git a/chia/util/db_wrapper.py b/chia/util/db_wrapper.py index 53af97f960..6c1068a94b 100644 --- a/chia/util/db_wrapper.py +++ b/chia/util/db_wrapper.py @@ -1,4 +1,8 @@ +from __future__ import annotations + import asyncio +import contextlib +from typing import AsyncIterator, Dict, Optional import aiosqlite @@ -10,12 +14,10 @@ class DBWrapper: db: aiosqlite.Connection lock: asyncio.Lock - db_version: int - def __init__(self, connection: aiosqlite.Connection, db_version: int = 1): + def __init__(self, connection: aiosqlite.Connection): self.db = connection self.lock = asyncio.Lock() - self.db_version = db_version async def begin_transaction(self): cursor = await self.db.execute("BEGIN TRANSACTION") @@ -29,3 +31,109 @@ class DBWrapper: async def commit_transaction(self) -> None: await self.db.commit() + + +class DBWrapper2: + db_version: int + _lock: asyncio.Lock + _read_connections: asyncio.Queue[aiosqlite.Connection] + _write_connection: aiosqlite.Connection + _num_read_connections: int + _in_use: Dict[asyncio.Task, aiosqlite.Connection] + _current_writer: Optional[asyncio.Task] + _savepoint_name: int + + async def add_connection(self, c: aiosqlite.Connection) -> None: + # this guarantees that reader connections can only be used for reading + assert c != self._write_connection + await c.execute("pragma query_only") + self._read_connections.put_nowait(c) + self._num_read_connections += 1 + + def __init__(self, connection: aiosqlite.Connection, db_version: int = 1) -> None: + self._read_connections = asyncio.Queue() + self._write_connection = connection + self._lock = asyncio.Lock() + self.db_version = db_version + self._num_read_connections = 0 + self._in_use = {} + self._current_writer = None + self._savepoint_name = 0 + + async def close(self) -> None: + while self._num_read_connections > 0: + await (await self._read_connections.get()).close() + self._num_read_connections -= 1 + await self._write_connection.close() + + def _next_savepoint(self) -> str: + name = f"s{self._savepoint_name}" + self._savepoint_name += 1 + return name + + @contextlib.asynccontextmanager + async def write_db(self) -> AsyncIterator[aiosqlite.Connection]: + task = asyncio.current_task() + assert task is not None + if self._current_writer == task: + # we allow nesting writers within the same task + + name = self._next_savepoint() + await self._write_connection.execute(f"SAVEPOINT {name}") + try: + yield self._write_connection + except: # noqa E722 + await self._write_connection.execute(f"ROLLBACK TO {name}") + raise + finally: + # rollback to a savepoint doesn't cancel the transaction, it + # just rolls back the state. We need to cancel it regardless + await self._write_connection.execute(f"RELEASE {name}") + return + + async with self._lock: + + name = self._next_savepoint() + await self._write_connection.execute(f"SAVEPOINT {name}") + try: + self._current_writer = task + yield self._write_connection + except: # noqa E722 + await self._write_connection.execute(f"ROLLBACK TO {name}") + raise + finally: + self._current_writer = None + await self._write_connection.execute(f"RELEASE {name}") + + @contextlib.asynccontextmanager + async def read_db(self) -> AsyncIterator[aiosqlite.Connection]: + # there should have been read connections added + assert self._num_read_connections > 0 + + # we can have multiple concurrent readers, just pick a connection from + # the pool of readers. If they're all busy, we'll wait for one to free + # up. + task = asyncio.current_task() + assert task is not None + + # if this task currently holds the write lock, use the same connection, + # so it can read back updates it has made to its transaction, even + # though it hasn't been comitted yet + if self._current_writer == task: + # we allow nesting reading while also having a writer connection + # open, within the same task + yield self._write_connection + return + + if task in self._in_use: + yield self._in_use[task] + else: + c = await self._read_connections.get() + try: + # record our connection in this dict to allow nested calls in + # the same task to use the same connection + self._in_use[task] = c + yield c + finally: + del self._in_use[task] + self._read_connections.put_nowait(c) diff --git a/chia/util/initial-config.yaml b/chia/util/initial-config.yaml index 600222592e..ef6aa9874c 100644 --- a/chia/util/initial-config.yaml +++ b/chia/util/initial-config.yaml @@ -332,6 +332,11 @@ full_node: # the particular system we're running on. Defaults to "full". db_sync: "auto" + # the number of threads used to read from the blockchain database + # concurrently. There's always only 1 writer, but the number of readers is + # configurable + db_readers: 4 + # Run multiple nodes with different databases by changing the database_path database_path: db/blockchain_v2_CHALLENGE.sqlite # peer_db_path is deprecated and has been replaced by peers_file_path @@ -361,6 +366,11 @@ full_node: # this reserved core count. reserved_cores: 0 + # set this to true to not offload heavy lifting into separate child processes. + # this option is mostly useful when profiling, since only the main process is + # profiled. + single_threaded: False + # How often to initiate outbound connections to other full nodes. peer_connect_interval: 30 # How long to wait for a peer connection diff --git a/chia/util/inline_executor.py b/chia/util/inline_executor.py new file mode 100644 index 0000000000..499671bb81 --- /dev/null +++ b/chia/util/inline_executor.py @@ -0,0 +1,24 @@ +from __future__ import annotations + +from concurrent.futures import Executor, Future +from typing import Callable, TypeVar + +_T = TypeVar("_T") + + +class InlineExecutor(Executor): + _closing: bool = False + + def submit(self, fn: Callable[..., _T], *args, **kwargs) -> Future[_T]: # type: ignore + if self._closing: + raise RuntimeError("executor shutting down") + + f: Future[_T] = Future() + try: + f.set_result(fn(*args, **kwargs)) + except BaseException as e: # lgtm[py/catch-base-exception] + f.set_exception(e) + return f + + def close(self) -> None: + self._closing = True diff --git a/chia/util/keyring_wrapper.py b/chia/util/keyring_wrapper.py index 0cb3c162b0..f830de1fc8 100644 --- a/chia/util/keyring_wrapper.py +++ b/chia/util/keyring_wrapper.py @@ -548,7 +548,7 @@ class KeyringWrapper: print("Keys in old keyring left intact") # Notify the daemon (if running) that migration has completed - asyncio.get_event_loop().run_until_complete(async_update_daemon_migration_completed_if_running()) + asyncio.run(async_update_daemon_migration_completed_if_running()) # Keyring interface diff --git a/chia/wallet/cat_wallet/cat_wallet.py b/chia/wallet/cat_wallet/cat_wallet.py index 2562492896..521d3943bb 100644 --- a/chia/wallet/cat_wallet/cat_wallet.py +++ b/chia/wallet/cat_wallet/cat_wallet.py @@ -91,10 +91,12 @@ class CATWallet: if name is None: name = "CAT WALLET" - self.wallet_info = await wallet_state_manager.user_store.create_wallet(name, WalletType.CAT, info_as_string) - if self.wallet_info is None: + new_wallet_info = await wallet_state_manager.user_store.create_wallet(name, WalletType.CAT, info_as_string) + if new_wallet_info is None: raise ValueError("Internal Error") + self.wallet_info = new_wallet_info + self.lineage_store = await CATLineageStore.create(self.wallet_state_manager.db_wrapper, self.get_asset_id()) try: @@ -192,11 +194,12 @@ class CATWallet: limitations_program_hash = bytes32(hexstr_to_bytes(limitations_program_hash_hex)) self.cat_info = CATInfo(limitations_program_hash, None) info_as_string = bytes(self.cat_info).hex() - self.wallet_info = await wallet_state_manager.user_store.create_wallet( + new_wallet_info = await wallet_state_manager.user_store.create_wallet( name, WalletType.CAT, info_as_string, in_transaction=in_transaction ) - if self.wallet_info is None: + if new_wallet_info is None: raise Exception("wallet_info is None") + self.wallet_info = new_wallet_info self.lineage_store = await CATLineageStore.create( self.wallet_state_manager.db_wrapper, self.get_asset_id(), in_transaction=in_transaction @@ -381,13 +384,13 @@ class CATWallet: async def get_new_cat_puzzle_hash(self): return (await self.wallet_state_manager.get_unused_derivation_record(self.id())).puzzle_hash - async def get_spendable_balance(self, records=None) -> uint64: + async def get_spendable_balance(self, records=None) -> uint128: coins = await self.get_cat_spendable_coins(records) amount = 0 for record in coins: amount += record.coin.amount - return uint64(amount) + return uint128(amount) async def get_pending_change_balance(self) -> uint64: unconfirmed_tx = await self.wallet_state_manager.tx_store.get_unconfirmed_for_wallet(self.id()) @@ -461,7 +464,11 @@ class CATWallet: if matched: _, _, inner_puzzle = puzzle_args puzzle_hash = inner_puzzle.get_tree_hash() - pubkey, private = await self.wallet_state_manager.get_keys(puzzle_hash) + ret = await self.wallet_state_manager.get_keys(puzzle_hash) + if ret is None: + # Abort signing the entire SpendBundle - sign all or none + raise RuntimeError(f"Failed to get keys for puzzle_hash {puzzle_hash}") + pubkey, private = ret synthetic_secret_key = calculate_synthetic_secret_key(private, DEFAULT_HIDDEN_PUZZLE_HASH) error, conditions, cost = conditions_dict_for_solution( spend.puzzle_reveal.to_program(), @@ -483,18 +490,20 @@ class CATWallet: return SpendBundle.aggregate([spend_bundle, SpendBundle([], agg_sig)]) async def inner_puzzle_for_cat_puzhash(self, cat_hash: bytes32) -> Program: - record: DerivationRecord = await self.wallet_state_manager.puzzle_store.get_derivation_record_for_puzzle_hash( - cat_hash - ) + record: Optional[ + DerivationRecord + ] = await self.wallet_state_manager.puzzle_store.get_derivation_record_for_puzzle_hash(cat_hash) + if record is None: + raise RuntimeError(f"Missing Derivation Record for CAT puzzle_hash {cat_hash}") inner_puzzle: Program = self.standard_wallet.puzzle_for_pk(bytes(record.pubkey)) return inner_puzzle async def convert_puzzle_hash(self, puzzle_hash: bytes32) -> bytes32: - record: DerivationRecord = await self.wallet_state_manager.puzzle_store.get_derivation_record_for_puzzle_hash( - puzzle_hash - ) + record: Optional[ + DerivationRecord + ] = await self.wallet_state_manager.puzzle_store.get_derivation_record_for_puzzle_hash(puzzle_hash) if record is None: - return puzzle_hash + return puzzle_hash # TODO: check if we have a test for this case! else: return (await self.inner_puzzle_for_cat_puzhash(puzzle_hash)).get_tree_hash() diff --git a/chia/wallet/did_wallet/did_wallet.py b/chia/wallet/did_wallet/did_wallet.py index 363cffe5e8..c957157804 100644 --- a/chia/wallet/did_wallet/did_wallet.py +++ b/chia/wallet/did_wallet/did_wallet.py @@ -13,7 +13,7 @@ from chia.types.blockchain_format.program import Program from chia.types.blockchain_format.sized_bytes import bytes32 from chia.types.coin_spend import CoinSpend from chia.types.spend_bundle import SpendBundle -from chia.util.ints import uint64, uint32, uint8 +from chia.util.ints import uint64, uint32, uint8, uint128 from chia.wallet.util.transaction_type import TransactionType from chia.wallet.did_wallet.did_info import DIDInfo @@ -189,18 +189,18 @@ class DIDWallet: def id(self): return self.wallet_info.id - async def get_confirmed_balance(self, record_list=None) -> uint64: + async def get_confirmed_balance(self, record_list=None) -> uint128: if record_list is None: record_list = await self.wallet_state_manager.coin_store.get_unspent_coins_for_wallet(self.id()) - amount: uint64 = uint64(0) + amount: uint128 = uint128(0) for record in record_list: parent = self.get_parent_for_coin(record.coin) if parent is not None: - amount = uint64(amount + record.coin.amount) + amount = uint128(amount + record.coin.amount) self.log.info(f"Confirmed balance for did wallet is {amount}") - return uint64(amount) + return uint128(amount) async def get_pending_change_balance(self) -> uint64: unconfirmed_tx = await self.wallet_state_manager.tx_store.get_unconfirmed_for_wallet(self.id()) @@ -222,7 +222,7 @@ class DIDWallet: return uint64(addition_amount) - async def get_unconfirmed_balance(self, record_list=None) -> uint64: + async def get_unconfirmed_balance(self, record_list=None) -> uint128: confirmed = await self.get_confirmed_balance(record_list) return await self.wallet_state_manager._get_unconfirmed_balance(self.id(), confirmed) @@ -1015,7 +1015,7 @@ class DIDWallet: async def get_frozen_amount(self) -> uint64: return await self.wallet_state_manager.get_frozen_balance(self.wallet_info.id) - async def get_spendable_balance(self, unspent_records=None) -> uint64: + async def get_spendable_balance(self, unspent_records=None) -> uint128: spendable_am = await self.wallet_state_manager.get_confirmed_spendable_balance_for_wallet( self.wallet_info.id, unspent_records ) diff --git a/chia/wallet/key_val_store.py b/chia/wallet/key_val_store.py index 631641a164..0232988b80 100644 --- a/chia/wallet/key_val_store.py +++ b/chia/wallet/key_val_store.py @@ -22,7 +22,7 @@ class KeyValStore: "CREATE TABLE IF NOT EXISTS key_val_store(" " key text PRIMARY KEY," " value blob)" ) - await self.db_connection.execute("CREATE INDEX IF NOT EXISTS name on key_val_store(key)") + await self.db_connection.execute("CREATE INDEX IF NOT EXISTS key_val_name on key_val_store(key)") await self.db_connection.commit() return self diff --git a/chia/wallet/puzzles/prefarm/make_prefarm_ph.py b/chia/wallet/puzzles/prefarm/make_prefarm_ph.py index 5d5ebf75cb..f393bc69c7 100644 --- a/chia/wallet/puzzles/prefarm/make_prefarm_ph.py +++ b/chia/wallet/puzzles/prefarm/make_prefarm_ph.py @@ -26,7 +26,9 @@ def make_puzzle(amount: int) -> int: puzzle = f"(q . ((51 0x{ph1.hex()} {amount}) (51 0x{ph2.hex()} {amount})))" # print(puzzle) - puzzle_prog = Program.to(binutils.assemble(puzzle)) + # TODO: properly type hint clvm_tools + assembled_puzzle = binutils.assemble(puzzle) # type: ignore[no-untyped-call] + puzzle_prog = Program.to(assembled_puzzle) print("Program: ", puzzle_prog) puzzle_hash = puzzle_prog.get_tree_hash() diff --git a/chia/wallet/rl_wallet/rl_wallet.py b/chia/wallet/rl_wallet/rl_wallet.py index abfd7126f9..e51fe841c7 100644 --- a/chia/wallet/rl_wallet/rl_wallet.py +++ b/chia/wallet/rl_wallet/rl_wallet.py @@ -267,7 +267,7 @@ class RLWallet: index = await self.wallet_state_manager.puzzle_store.index_for_pubkey(user_pubkey) assert index is not None record = DerivationRecord( - index, + uint32(index), rl_puzzle_hash, user_pubkey, WalletType.RATE_LIMITED, @@ -277,7 +277,7 @@ class RLWallet: aggregation_puzzlehash = self.rl_get_aggregation_puzzlehash(new_rl_info.rl_puzzle_hash) record2 = DerivationRecord( - index + 1, + uint32(index + 1), aggregation_puzzlehash, user_pubkey, WalletType.RATE_LIMITED, @@ -332,6 +332,8 @@ class RLWallet: peak = self.wallet_state_manager.blockchain.get_peak() height = peak.height if peak else 0 assert self.rl_info.limit is not None + if self.rl_info.interval is None: + raise RuntimeError("rl_available_balance: rl_info.interval is undefined") unlocked = int( ((height - self.rl_coin_record.confirmed_block_height) / self.rl_info.interval) * int(self.rl_info.limit) ) @@ -445,6 +447,8 @@ class RLWallet: return pubkey, private async def _get_rl_coin(self) -> Optional[Coin]: + if self.rl_info.rl_puzzle_hash is None: + return None rl_coins = await self.wallet_state_manager.coin_store.get_coin_records_by_puzzle_hash( self.rl_info.rl_puzzle_hash ) @@ -455,6 +459,8 @@ class RLWallet: return None async def _get_rl_coin_record(self) -> Optional[WalletCoinRecord]: + if self.rl_info.rl_puzzle_hash is None: + return None rl_coins = await self.wallet_state_manager.coin_store.get_coin_records_by_puzzle_hash( self.rl_info.rl_puzzle_hash ) diff --git a/chia/wallet/trading/offer.py b/chia/wallet/trading/offer.py index 2f8a31ecb4..05d742f25c 100644 --- a/chia/wallet/trading/offer.py +++ b/chia/wallet/trading/offer.py @@ -94,6 +94,8 @@ class Offer: offered_coins: Dict[bytes32, List[Coin]] = self.get_offered_coins() if offered_coins == {}: raise ValueError("Bundle is not offering anything") + if self.get_requested_payments() == {}: + raise ValueError("Bundle is not requesting anything") # Verify that there are no duplicate payments for payments in self.requested_payments.values(): diff --git a/chia/wallet/wallet_action_store.py b/chia/wallet/wallet_action_store.py index 1abecbeb87..a1b73f16c3 100644 --- a/chia/wallet/wallet_action_store.py +++ b/chia/wallet/wallet_action_store.py @@ -37,11 +37,13 @@ class WalletActionStore: ) ) - await self.db_connection.execute("CREATE INDEX IF NOT EXISTS name on action_queue(name)") + await self.db_connection.execute("CREATE INDEX IF NOT EXISTS action_queue_name on action_queue(name)") - await self.db_connection.execute("CREATE INDEX IF NOT EXISTS wallet_id on action_queue(wallet_id)") + await self.db_connection.execute("CREATE INDEX IF NOT EXISTS action_queue_wallet_id on action_queue(wallet_id)") - await self.db_connection.execute("CREATE INDEX IF NOT EXISTS wallet_type on action_queue(wallet_type)") + await self.db_connection.execute( + "CREATE INDEX IF NOT EXISTS action_queue_wallet_type on action_queue(wallet_type)" + ) await self.db_connection.commit() return self diff --git a/chia/wallet/wallet_coin_store.py b/chia/wallet/wallet_coin_store.py index f217ed684d..8c8a7121ec 100644 --- a/chia/wallet/wallet_coin_store.py +++ b/chia/wallet/wallet_coin_store.py @@ -54,7 +54,9 @@ class WalletCoinStore: await self.db_connection.execute("CREATE INDEX IF NOT EXISTS coin_puzzlehash on coin_record(puzzle_hash)") - await self.db_connection.execute("CREATE INDEX IF NOT EXISTS wallet_type on coin_record(wallet_type)") + await self.db_connection.execute( + "CREATE INDEX IF NOT EXISTS coin_record_wallet_type on coin_record(wallet_type)" + ) await self.db_connection.execute("CREATE INDEX IF NOT EXISTS wallet_id on coin_record(wallet_id)") diff --git a/chia/wallet/wallet_puzzle_store.py b/chia/wallet/wallet_puzzle_store.py index c68df28987..f4113c3a7b 100644 --- a/chia/wallet/wallet_puzzle_store.py +++ b/chia/wallet/wallet_puzzle_store.py @@ -40,7 +40,7 @@ class WalletPuzzleStore: "CREATE TABLE IF NOT EXISTS derivation_paths(" "derivation_index int," " pubkey text," - " puzzle_hash text PRIMARY_KEY," + " puzzle_hash text PRIMARY KEY," " wallet_type int," " wallet_id int," " used tinyint," @@ -57,7 +57,9 @@ class WalletPuzzleStore: await self.db_connection.execute("CREATE INDEX IF NOT EXISTS wallet_type on derivation_paths(wallet_type)") - await self.db_connection.execute("CREATE INDEX IF NOT EXISTS wallet_id on derivation_paths(wallet_id)") + await self.db_connection.execute( + "CREATE INDEX IF NOT EXISTS derivation_paths_wallet_id on derivation_paths(wallet_id)" + ) await self.db_connection.execute("CREATE INDEX IF NOT EXISTS used on derivation_paths(wallet_type)") diff --git a/chia/wallet/wallet_state_manager.py b/chia/wallet/wallet_state_manager.py index aed351a13b..1a51de491c 100644 --- a/chia/wallet/wallet_state_manager.py +++ b/chia/wallet/wallet_state_manager.py @@ -223,31 +223,6 @@ class WalletStateManager: def get_public_key_unhardened(self, index: uint32) -> G1Element: return master_sk_to_wallet_sk_unhardened(self.private_key, index).get_g1() - async def load_wallets(self): - for wallet_info in await self.get_all_wallet_info_entries(): - if wallet_info.id in self.wallets: - continue - if wallet_info.type == WalletType.STANDARD_WALLET: - if wallet_info.id == 1: - continue - wallet = await Wallet.create(self.config, wallet_info) - self.wallets[wallet_info.id] = wallet - # TODO add RL AND DiD WALLETS HERE - elif wallet_info.type == WalletType.CAT: - wallet = await CATWallet.create( - self, - self.main_wallet, - wallet_info, - ) - self.wallets[wallet_info.id] = wallet - elif wallet_info.type == WalletType.DISTRIBUTED_ID: - wallet = await DIDWallet.create( - self, - self.main_wallet, - wallet_info, - ) - self.wallets[wallet_info.id] = wallet - async def get_keys(self, puzzle_hash: bytes32) -> Optional[Tuple[G1Element, PrivateKey]]: record = await self.puzzle_store.record_for_puzzle_hash(puzzle_hash) if record is None: diff --git a/chia/wallet/wallet_transaction_store.py b/chia/wallet/wallet_transaction_store.py index 74a6216139..6d9b91d230 100644 --- a/chia/wallet/wallet_transaction_store.py +++ b/chia/wallet/wallet_transaction_store.py @@ -71,7 +71,9 @@ class WalletTransactionStore: "CREATE INDEX IF NOT EXISTS tx_to_puzzle_hash on transaction_record(to_puzzle_hash)" ) - await self.db_connection.execute("CREATE INDEX IF NOT EXISTS wallet_id on transaction_record(wallet_id)") + await self.db_connection.execute( + "CREATE INDEX IF NOT EXISTS transaction_record_wallet_id on transaction_record(wallet_id)" + ) await self.db_connection.commit() self.tx_record_cache = {} diff --git a/tests/pytest.ini b/pytest.ini similarity index 98% rename from tests/pytest.ini rename to pytest.ini index c5834bc821..953e5cbf4d 100644 --- a/tests/pytest.ini +++ b/pytest.ini @@ -7,6 +7,7 @@ console_output_style = count log_format = %(asctime)s %(name)s: %(levelname)s %(message)s asyncio_mode = strict markers=benchmark +testpaths = tests filterwarnings = error ignore:ssl_context is deprecated:DeprecationWarning diff --git a/setup.py b/setup.py index 7677b28ba6..2c55afe278 100644 --- a/setup.py +++ b/setup.py @@ -8,14 +8,14 @@ dependencies = [ "chiabip158==1.1", # bip158-style wallet filters "chiapos==1.0.9", # proof of space "clvm==0.9.7", - "clvm_tools==0.4.3", # Currying, Program.to, other conveniences + "clvm_tools==0.4.4", # Currying, Program.to, other conveniences "clvm_rs==0.1.19", "clvm-tools-rs==0.1.7", # Rust implementation of clvm_tools "aiohttp==3.7.4", # HTTP server for full node rpc "aiosqlite==0.17.0", # asyncio wrapper for sqlite, to store blocks "bitstring==3.1.9", # Binary data management library "colorama==0.4.4", # Colorizes terminal output - "colorlog==5.0.1", # Adds color to logs + "colorlog==6.6.0", # Adds color to logs "concurrent-log-handler==0.9.19", # Concurrently log and rotate logs "cryptography==3.4.7", # Python cryptography library for TLS - keyring conflict "fasteners==0.16.3", # For interprocess file locking, expected to be replaced by filelock @@ -44,6 +44,7 @@ upnp_dependencies = [ dev_dependencies = [ "build", + "coverage", "pre-commit", "pytest", "pytest-asyncio>=0.18.1", # require attribute 'fixture' diff --git a/tests/block_tools.py b/tests/block_tools.py index 6906710501..dedd9d4212 100644 --- a/tests/block_tools.py +++ b/tests/block_tools.py @@ -74,7 +74,8 @@ from chia.types.spend_bundle import SpendBundle from chia.types.unfinished_block import UnfinishedBlock from chia.util.bech32m import encode_puzzle_hash from chia.util.block_cache import BlockCache -from chia.util.config import get_config_lock, load_config, save_config +from chia.util.config import load_config, lock_config, save_config +from chia.util.default_root import DEFAULT_ROOT_PATH from chia.util.hash import std_hash from chia.util.ints import uint8, uint16, uint32, uint64, uint128 from chia.util.keychain import Keychain, bytes_to_mnemonic @@ -85,6 +86,7 @@ from chia.util.vdf_prover import get_vdf_info_and_proof from tests.time_out_assert import time_out_assert from tests.wallet_tools import WalletTool from tests.util.socket import find_available_listen_port +from tests.util.ssl_certs import get_next_nodes_certs_and_keys, get_next_private_ca_cert_and_key from chia.wallet.derive_keys import ( master_sk_to_farmer_sk, master_sk_to_local_sk, @@ -143,7 +145,11 @@ class BlockTools: self.local_keychain = keychain create_default_chia_config(root_path) - create_all_ssl(root_path) + create_all_ssl( + root_path, + private_ca_crt_and_key=get_next_private_ca_cert_and_key(), + node_certs_and_keys=get_next_nodes_certs_and_keys(), + ) self.local_sk_cache: Dict[bytes32, Tuple[PrivateKey, Any]] = {} self._config = load_config(self.root_path, "config.yaml") @@ -155,7 +161,7 @@ class BlockTools: # some tests start the daemon, make sure it's on a free port self._config["daemon_port"] = find_available_listen_port("BlockTools daemon") - with get_config_lock(self.root_path, "config.yaml"): + with lock_config(self.root_path, "config.yaml"): save_config(self.root_path, "config.yaml", self._config) overrides = self._config["network_overrides"]["constants"][self._config["selected_network"]] updated_constants = constants.replace_str_to_bytes(**overrides) @@ -234,7 +240,7 @@ class BlockTools: overrides = self._config["network_overrides"]["constants"][self._config["selected_network"]] updated_constants = self.constants.replace_str_to_bytes(**overrides) self.constants = updated_constants - with get_config_lock(self.root_path, "config.yaml"): + with lock_config(self.root_path, "config.yaml"): save_config(self.root_path, "config.yaml", self._config) async def setup_plots(self): @@ -473,9 +479,7 @@ class BlockTools: latest_block: BlockRecord = blocks[block_list[-1].header_hash] curr = latest_block while not curr.is_transaction_block: - # TODO: address hint error and remove ignore - # error: Invalid index type "bytes32" for "Dict[uint32, BlockRecord]"; expected type "uint32" [index] - curr = blocks[curr.prev_hash] # type: ignore[index] + curr = blocks[curr.prev_hash] start_timestamp = curr.timestamp start_height = curr.height @@ -483,9 +487,7 @@ class BlockTools: blocks_added_this_sub_slot = 1 while not curr.first_in_sub_slot: - # TODO: address hint error and remove ignore - # error: Invalid index type "bytes32" for "Dict[uint32, BlockRecord]"; expected type "uint32" [index] - curr = blocks[curr.prev_hash] # type: ignore[index] + curr = blocks[curr.prev_hash] blocks_added_this_sub_slot += 1 finished_sub_slots_at_sp: List[EndOfSubSlotBundle] = [] # Sub-slots since last block, up to signage point @@ -518,10 +520,7 @@ class BlockTools: ): if curr.height == 0: break - # TODO: address hint error and remove ignore - # error: Invalid index type "bytes32" for "Dict[uint32, BlockRecord]"; expected type - # "uint32" [index] - curr = blocks[curr.prev_hash] # type: ignore[index] + curr = blocks[curr.prev_hash] if curr.total_iters > sub_slot_start_total_iters: finished_sub_slots_at_sp = [] @@ -530,12 +529,9 @@ class BlockTools: # Ignore this signage_point because it's in the past continue - # TODO: address hint error and remove ignore - # error: Argument 1 to "BlockCache" has incompatible type "Dict[uint32, BlockRecord]"; - # expected "Dict[bytes32, BlockRecord]" [arg-type] signage_point: SignagePoint = get_signage_point( constants, - BlockCache(blocks), # type: ignore[arg-type] + BlockCache(blocks), latest_block, sub_slot_start_total_iters, uint8(signage_point_index), @@ -688,15 +684,12 @@ class BlockTools: eos_deficit: uint8 = ( latest_block.deficit if latest_block.deficit > 0 else constants.MIN_BLOCKS_PER_CHALLENGE_BLOCK ) - # TODO: address hint error and remove ignore - # error: Argument 5 to "get_icc" has incompatible type "Dict[uint32, BlockRecord]"; expected - # "Dict[bytes32, BlockRecord]" [arg-type] icc_eos_vdf, icc_ip_proof = get_icc( constants, uint128(sub_slot_start_total_iters + sub_slot_iters), finished_sub_slots_at_ip, latest_block, - blocks, # type: ignore[arg-type] + blocks, sub_slot_start_total_iters, eos_deficit, ) @@ -746,10 +739,7 @@ class BlockTools: # This means there are blocks in this sub-slot curr = latest_block while not curr.is_challenge_block(constants) and not curr.first_in_sub_slot: - # TODO: address hint error and remove ignore - # error: Invalid index type "bytes32" for "Dict[uint32, BlockRecord]"; expected type - # "uint32" [index] - curr = blocks[curr.prev_hash] # type: ignore[index] + curr = blocks[curr.prev_hash] if curr.is_challenge_block(constants): icc_eos_iters = uint64(sub_slot_start_total_iters + sub_slot_iters - curr.total_iters) else: @@ -824,12 +814,9 @@ class BlockTools: constants.NUM_SPS_SUB_SLOT, ): # note that we are passing in the finished slots which include the last slot - # TODO: address hint error and remove ignore - # error: Argument 1 to "BlockCache" has incompatible type "Dict[uint32, BlockRecord]"; - # expected "Dict[bytes32, BlockRecord]" [arg-type] signage_point = get_signage_point( constants, - BlockCache(blocks), # type: ignore[arg-type] + BlockCache(blocks), latest_block_eos, sub_slot_start_total_iters, uint8(signage_point_index), @@ -1350,20 +1337,16 @@ def finish_block( def get_challenges( constants: ConsensusConstants, - blocks: Dict[uint32, BlockRecord], + blocks: Dict[bytes32, BlockRecord], finished_sub_slots: List[EndOfSubSlotBundle], prev_header_hash: Optional[bytes32], ) -> Tuple[bytes32, bytes32]: if len(finished_sub_slots) == 0: if prev_header_hash is None: return constants.GENESIS_CHALLENGE, constants.GENESIS_CHALLENGE - # TODO: address hint error and remove ignore - # error: Invalid index type "bytes32" for "Dict[uint32, BlockRecord]"; expected type "uint32" [index] - curr: BlockRecord = blocks[prev_header_hash] # type: ignore[index] + curr: BlockRecord = blocks[prev_header_hash] while not curr.first_in_sub_slot: - # TODO: address hint error and remove ignore - # error: Invalid index type "bytes32" for "Dict[uint32, BlockRecord]"; expected type "uint32" [index] - curr = blocks[curr.prev_hash] # type: ignore[index] + curr = blocks[curr.prev_hash] assert curr.finished_challenge_slot_hashes is not None assert curr.finished_reward_slot_hashes is not None cc_challenge = curr.finished_challenge_slot_hashes[-1] @@ -1375,7 +1358,7 @@ def get_challenges( def get_plot_dir() -> Path: - cache_path = Path(os.path.expanduser(os.getenv("CHIA_ROOT", "~/.chia/"))) / "test-plots" + cache_path = DEFAULT_ROOT_PATH.parent.joinpath("test-plots") ci = os.environ.get("CI") if ci is not None and not cache_path.exists(): @@ -1391,10 +1374,10 @@ def get_plot_tmp_dir(): def load_block_list( block_list: List[FullBlock], constants: ConsensusConstants -) -> Tuple[Dict[uint32, bytes32], uint64, Dict[uint32, BlockRecord]]: +) -> Tuple[Dict[uint32, bytes32], uint64, Dict[bytes32, BlockRecord]]: difficulty = 0 height_to_hash: Dict[uint32, bytes32] = {} - blocks: Dict[uint32, BlockRecord] = {} + blocks: Dict[bytes32, BlockRecord] = {} for full_block in block_list: if full_block.height == 0: difficulty = uint64(constants.DIFFICULTY_STARTING) @@ -1421,12 +1404,9 @@ def load_block_list( sp_hash, ) - # TODO: address hint error and remove ignore - # error: Argument 1 to "BlockCache" has incompatible type "Dict[uint32, BlockRecord]"; expected - # "Dict[bytes32, BlockRecord]" [arg-type] blocks[full_block.header_hash] = block_to_block_record( constants, - BlockCache(blocks), # type: ignore[arg-type] + BlockCache(blocks), required_iters, full_block, None, @@ -1494,7 +1474,7 @@ def get_icc( def get_full_block_and_block_record( constants: ConsensusConstants, - blocks: Dict[uint32, BlockRecord], + blocks: Dict[bytes32, BlockRecord], sub_slot_start_total_iters: uint128, signage_point_index: uint8, proof_of_space: ProofOfSpace, @@ -1534,11 +1514,6 @@ def get_full_block_and_block_record( sp_iters = calculate_sp_iters(constants, sub_slot_iters, signage_point_index) ip_iters = calculate_ip_iters(constants, sub_slot_iters, signage_point_index, required_iters) - # TODO: address hint error and remove ignore - # error: Argument 1 to "BlockCache" has incompatible type "Dict[uint32, BlockRecord]"; expected - # "Dict[bytes32, BlockRecord]" [arg-type] - # error: Argument 16 to "create_test_unfinished_block" has incompatible type "bytes"; expected "bytes32" - # [arg-type] unfinished_block = create_test_unfinished_block( constants, sub_slot_start_total_iters, @@ -1554,7 +1529,7 @@ def get_full_block_and_block_record( get_pool_signature, signage_point, timestamp, - BlockCache(blocks), # type: ignore[arg-type] + BlockCache(blocks), seed, # type: ignore[arg-type] block_generator, aggregate_signature, @@ -1568,12 +1543,9 @@ def get_full_block_and_block_record( slot_cc_challenge = overflow_cc_challenge slot_rc_challenge = overflow_rc_challenge - # TODO: address hint error and remove ignore - # error: Argument 2 to "finish_block" has incompatible type "Dict[uint32, BlockRecord]"; expected - # "Dict[bytes32, BlockRecord]" [arg-type] full_block, block_record = finish_block( constants, - blocks, # type: ignore[arg-type] + blocks, height_to_hash, finished_sub_slots, sub_slot_start_total_iters, diff --git a/tests/blockchain/blockchain_test_utils.py b/tests/blockchain/blockchain_test_utils.py index 38872f7b61..93152782cf 100644 --- a/tests/blockchain/blockchain_test_utils.py +++ b/tests/blockchain/blockchain_test_utils.py @@ -15,24 +15,25 @@ async def check_block_store_invariant(bc: Blockchain): in_chain = set() max_height = -1 - async with db_wrapper.db.execute("SELECT height, in_main_chain FROM full_blocks") as cursor: - rows = await cursor.fetchall() - for row in rows: - height = row[0] + async with db_wrapper.write_db() as conn: + async with conn.execute("SELECT height, in_main_chain FROM full_blocks") as cursor: + rows = await cursor.fetchall() + for row in rows: + height = row[0] - # if this block is in-chain, ensure we haven't found another block - # at this height that's also in chain. That would be an invariant - # violation - if row[1]: - # make sure we don't have any duplicate heights. Each block - # height can only have a single block with in_main_chain set - assert height not in in_chain - in_chain.add(height) - if height > max_height: - max_height = height + # if this block is in-chain, ensure we haven't found another block + # at this height that's also in chain. That would be an invariant + # violation + if row[1]: + # make sure we don't have any duplicate heights. Each block + # height can only have a single block with in_main_chain set + assert height not in in_chain + in_chain.add(height) + if height > max_height: + max_height = height - # make sure every height is represented in the set - assert len(in_chain) == max_height + 1 + # make sure every height is represented in the set + assert len(in_chain) == max_height + 1 async def _validate_and_add_block( diff --git a/tests/blockchain/test_blockchain.py b/tests/blockchain/test_blockchain.py index b72d3a4607..99927fc0ff 100644 --- a/tests/blockchain/test_blockchain.py +++ b/tests/blockchain/test_blockchain.py @@ -539,7 +539,7 @@ class TestBlockHeaderValidation: constants=test_constants.replace(SUB_SLOT_ITERS_STARTING=(2 ** 12), DIFFICULTY_STARTING=(2 ** 14)), keychain=keychain, ) - bc1, connection, db_path = await create_blockchain(bt_high_iters.constants, db_version) + bc1, db_wrapper, db_path = await create_blockchain(bt_high_iters.constants, db_version) blocks = bt_high_iters.get_consecutive_blocks(10) for block in blocks: if len(block.finished_sub_slots) > 0 and block.finished_sub_slots[-1].infused_challenge_chain is not None: @@ -611,7 +611,7 @@ class TestBlockHeaderValidation: await _validate_and_add_block(bc1, block) - await connection.close() + await db_wrapper.close() bc1.shut_down() db_path.unlink() @@ -2324,7 +2324,7 @@ class TestBodyValidation: # new_test_constants = test_constants.replace( # **{"GENESIS_PRE_FARM_POOL_PUZZLE_HASH": bt.pool_ph, "GENESIS_PRE_FARM_FARMER_PUZZLE_HASH": bt.pool_ph} # ) - # b, connection, db_path = await create_blockchain(new_test_constants, db_version) + # b, db_wrapper, db_path = await create_blockchain(new_test_constants, db_version) # bt_2 = await create_block_tools_async(constants=new_test_constants, keychain=keychain) # bt_2.constants = bt_2.constants.replace( # **{"GENESIS_PRE_FARM_POOL_PUZZLE_HASH": bt.pool_ph, "GENESIS_PRE_FARM_FARMER_PUZZLE_HASH": bt.pool_ph} @@ -2358,7 +2358,7 @@ class TestBodyValidation: # assert False # except Exception as e: # pass - # await connection.close() + # await db_wrapper.close() # b.shut_down() # db_path.unlink() diff --git a/tests/blockchain/test_blockchain_transactions.py b/tests/blockchain/test_blockchain_transactions.py index 1d0c830ac0..4f39638ce9 100644 --- a/tests/blockchain/test_blockchain_transactions.py +++ b/tests/blockchain/test_blockchain_transactions.py @@ -11,9 +11,9 @@ from chia.types.spend_bundle import SpendBundle from chia.util.errors import ConsensusError, Err from chia.util.ints import uint64 from tests.blockchain.blockchain_test_utils import _validate_and_add_block -from tests.wallet_tools import WalletTool from tests.setup_nodes import test_constants from tests.util.generator_tools_testing import run_and_get_removals_and_additions +from tests.wallet_tools import WalletTool BURN_PUZZLE_HASH = b"0" * 32 diff --git a/tests/build-workflows.py b/tests/build-workflows.py index 29f10a49bd..b9c8e2c0d4 100755 --- a/tests/build-workflows.py +++ b/tests/build-workflows.py @@ -68,6 +68,10 @@ def generate_replacements(conf, dir): "CHECKOUT_TEST_BLOCKS_AND_PLOTS": read_file( Path(root_path / "runner_templates/checkout-test-plots.include.yml") ).rstrip(), + "CHECK_RESOURCE_USAGE": read_file( + Path(root_path / "runner_templates/check-resource-usage.include.yml") + ).rstrip(), + "DISABLE_PYTEST_MONITOR": "", "TEST_DIR": "", "TEST_NAME": "", "PYTEST_PARALLEL_ARGS": "", @@ -86,6 +90,9 @@ def generate_replacements(conf, dir): replacements["TEST_NAME"] = test_name(dir) if "test_name" in conf: replacements["TEST_NAME"] = conf["test_name"] + if not conf["check_resource_usage"]: + replacements["CHECK_RESOURCE_USAGE"] = "# Omitted resource usage check" + replacements["DISABLE_PYTEST_MONITOR"] = "-p no:monitor" for var in conf["custom_vars"]: replacements[var] = conf[var] if var in conf else "" return replacements @@ -134,6 +141,8 @@ for os in testconfig.oses: conf = update_config(module_dict(testconfig), dir_config(dir)) replacements = generate_replacements(conf, dir) txt = transform_template(template_text, replacements) + # remove trailing whitespace from lines and assure a single EOF at EOL + txt = "\n".join(line.rstrip() for line in txt.rstrip().splitlines()) + "\n" logging.info(f"Writing {os}-{test_name(dir)}") workflow_yaml_path: Path = workflow_yaml_file(args.output_dir, os, test_name(dir)) if workflow_yaml_path not in current_workflows or current_workflows[workflow_yaml_path] != txt: diff --git a/tests/check_sql_statements.py b/tests/check_sql_statements.py new file mode 100755 index 0000000000..f848292004 --- /dev/null +++ b/tests/check_sql_statements.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python3 +import sys +from subprocess import check_output +from typing import Dict, Set, Tuple + +# check for duplicate index names + + +def check_create(sql_type: str, cwd: str, exemptions: Set[Tuple[str, str]] = set()) -> int: + + lines = check_output(["git", "grep", f"CREATE {sql_type}"], cwd=cwd).decode("ascii").split("\n") + + ret = 0 + + items: Dict[str, str] = {} + for line in lines: + if f"CREATE {sql_type}" not in line: + continue + if line.startswith("tests/"): + continue + if "db_upgrade_func.py" in line: + continue + + name = line.split(f"CREATE {sql_type}")[1] + if name.startswith(" IF NOT EXISTS"): + name = name[14:] + name = name.strip() + name = name.split()[0] + name = name.split("(")[0] + + if name in items: + # these appear as a duplicates, but one is for v1 and the other for v2 + if (line.split()[0][:-1], name) not in exemptions: + print(f'duplicate {sql_type} "{name}"\n {items[name]}\n {line}') + ret += 1 + + items[name] = line + + return ret + + +ret = 0 + +ret += check_create("INDEX", "chia/wallet") +ret += check_create( + "INDEX", + "chia/full_node", + set( + [ + ("block_store.py", "is_fully_compactified"), + ("block_store.py", "height"), + ] + ), +) +ret += check_create("TABLE", "chia/wallet") +ret += check_create( + "TABLE", + "chia/full_node", + set( + [ + ("block_store.py", "sub_epoch_segments_v3"), + ("block_store.py", "full_blocks"), + ("coin_store.py", "coin_record"), + ("hint_store.py", "hints"), + ] + ), +) +sys.exit(ret) diff --git a/tests/conftest.py b/tests/conftest.py index 6a0ee5f4d0..f2d3933a5f 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,6 +1,8 @@ # flake8: noqa E402 # See imports after multiprocessing.set_start_method import multiprocessing import os +from secrets import token_bytes + import pytest import pytest_asyncio import tempfile @@ -8,11 +10,34 @@ import tempfile from tests.setup_nodes import setup_node_and_wallet, setup_n_nodes, setup_two_nodes # Set spawn after stdlib imports, but before other imports +from chia.clvm.spend_sim import SimClient, SpendSim +from chia.protocols import full_node_protocol +from chia.simulator.simulator_protocol import FarmNewBlockProtocol +from chia.types.blockchain_format.sized_bytes import bytes32 +from chia.types.peer_info import PeerInfo +from chia.util.ints import uint16 +from tests.core.node_height import node_height_at_least +from tests.pools.test_pool_rpc import wallet_is_synced +from tests.setup_nodes import ( + setup_simulators_and_wallets, + setup_node_and_wallet, + setup_full_system, + setup_daemon, + setup_n_nodes, + setup_introducer, + setup_timelord, + setup_two_nodes, +) +from tests.simulation.test_simulation import test_constants_modified +from tests.time_out_assert import time_out_assert +from tests.util.socket import find_available_listen_port +from tests.wallet_tools import WalletTool + multiprocessing.set_start_method("spawn") from pathlib import Path from chia.util.keyring_wrapper import KeyringWrapper -from tests.block_tools import BlockTools, test_constants, create_block_tools +from tests.block_tools import BlockTools, test_constants, create_block_tools, create_block_tools_async from tests.util.keyring import TempKeyring @@ -54,10 +79,10 @@ async def empty_blockchain(request): from tests.util.blockchain import create_blockchain from tests.setup_nodes import test_constants - bc1, connection, db_path = await create_blockchain(test_constants, request.param) + bc1, db_wrapper, db_path = await create_blockchain(test_constants, request.param) yield bc1 - await connection.close() + await db_wrapper.close() bc1.shut_down() db_path.unlink() @@ -157,6 +182,12 @@ async def two_nodes(db_version, self_hostname): yield _ +@pytest_asyncio.fixture(scope="function") +async def setup_two_nodes_fixture(db_version): + async for _ in setup_simulators_and_wallets(2, 0, {}, db_version=db_version): + yield _ + + @pytest_asyncio.fixture(scope="function") async def three_nodes(db_version, self_hostname): async for _ in setup_n_nodes(test_constants, 3, db_version=db_version, self_hostname=self_hostname): @@ -173,3 +204,284 @@ async def four_nodes(db_version, self_hostname): async def five_nodes(db_version, self_hostname): async for _ in setup_n_nodes(test_constants, 5, db_version=db_version, self_hostname=self_hostname): yield _ + + +@pytest_asyncio.fixture(scope="module") +async def wallet_nodes(bt): + async_gen = setup_simulators_and_wallets(2, 1, {"MEMPOOL_BLOCK_BUFFER": 2, "MAX_BLOCK_COST_CLVM": 400000000}) + nodes, wallets = await async_gen.__anext__() + full_node_1 = nodes[0] + full_node_2 = nodes[1] + server_1 = full_node_1.full_node.server + server_2 = full_node_2.full_node.server + wallet_a = bt.get_pool_wallet_tool() + wallet_receiver = WalletTool(full_node_1.full_node.constants) + yield full_node_1, full_node_2, server_1, server_2, wallet_a, wallet_receiver + + async for _ in async_gen: + yield _ + + +@pytest_asyncio.fixture(scope="function") +async def setup_four_nodes(db_version): + async for _ in setup_simulators_and_wallets(5, 0, {}, db_version=db_version): + yield _ + + +@pytest_asyncio.fixture(scope="function") +async def two_nodes_sim_and_wallets(): + async for _ in setup_simulators_and_wallets(2, 0, {}): + yield _ + + +@pytest_asyncio.fixture(scope="function") +async def wallet_node_sim_and_wallet(): + async for _ in setup_simulators_and_wallets(1, 1, {}): + yield _ + + +@pytest_asyncio.fixture(scope="function") +async def wallet_node_100_pk(): + async for _ in setup_simulators_and_wallets(1, 1, {}, initial_num_public_keys=100): + yield _ + + +@pytest_asyncio.fixture(scope="function") +async def two_wallet_nodes(): + async for _ in setup_simulators_and_wallets(1, 2, {}): + yield _ + + +@pytest_asyncio.fixture(scope="function") +async def three_sim_two_wallets(): + async for _ in setup_simulators_and_wallets(3, 2, {}): + yield _ + + +@pytest_asyncio.fixture(scope="function") +async def setup_two_nodes_and_wallet(): + async for _ in setup_simulators_and_wallets(2, 1, {}, db_version=2): # xxx + yield _ + + +@pytest_asyncio.fixture(scope="function") +async def three_wallet_nodes(): + async for _ in setup_simulators_and_wallets(1, 3, {}): + yield _ + + +@pytest_asyncio.fixture(scope="function") +async def two_wallet_nodes_five_freeze(): + async for _ in setup_simulators_and_wallets(1, 2, {}): + yield _ + + +@pytest_asyncio.fixture(scope="function") +async def wallet_node_simulator(): + async for _ in setup_simulators_and_wallets(1, 1, {}): + yield _ + + +@pytest_asyncio.fixture(scope="function") +async def wallet_two_node_simulator(): + async for _ in setup_simulators_and_wallets(2, 1, {}): + yield _ + + +@pytest_asyncio.fixture(scope="module") +async def wallet_nodes_mempool_perf(bt): + key_seed = bt.farmer_master_sk_entropy + async for _ in setup_simulators_and_wallets(2, 1, {}, key_seed=key_seed): + yield _ + + +@pytest_asyncio.fixture(scope="module") +async def wallet_nodes_perf(bt): + async_gen = setup_simulators_and_wallets(1, 1, {"MEMPOOL_BLOCK_BUFFER": 1, "MAX_BLOCK_COST_CLVM": 11000000000}) + nodes, wallets = await async_gen.__anext__() + full_node_1 = nodes[0] + server_1 = full_node_1.full_node.server + wallet_a = bt.get_pool_wallet_tool() + wallet_receiver = WalletTool(full_node_1.full_node.constants) + yield full_node_1, server_1, wallet_a, wallet_receiver + + async for _ in async_gen: + yield _ + + +@pytest_asyncio.fixture(scope="function") +async def wallet_node_starting_height(self_hostname): + async for _ in setup_node_and_wallet(test_constants, self_hostname, starting_height=100): + yield _ + + +@pytest_asyncio.fixture(scope="function") +async def wallet_nodes_mainnet(bt, db_version): + async_gen = setup_simulators_and_wallets(2, 1, {"NETWORK_TYPE": 0}, db_version=db_version) + nodes, wallets = await async_gen.__anext__() + full_node_1 = nodes[0] + full_node_2 = nodes[1] + server_1 = full_node_1.full_node.server + server_2 = full_node_2.full_node.server + wallet_a = bt.get_pool_wallet_tool() + wallet_receiver = WalletTool(full_node_1.full_node.constants) + yield full_node_1, full_node_2, server_1, server_2, wallet_a, wallet_receiver + + async for _ in async_gen: + yield _ + + +@pytest_asyncio.fixture(scope="function") +async def three_nodes_two_wallets(): + async for _ in setup_simulators_and_wallets(3, 2, {}): + yield _ + + +@pytest_asyncio.fixture(scope="function") +async def wallet_and_node(): + async for _ in setup_simulators_and_wallets(1, 1, {}): + yield _ + + +# TODO: Ideally, the db_version should be the (parameterized) db_version +# fixture, to test all versions of the database schema. This doesn't work +# because of a hack in shutting down the full node, which means you cannot run +# more than one simulations per process. +@pytest_asyncio.fixture(scope="function") +async def daemon_simulation(bt, get_b_tools, get_b_tools_1): + async for _ in setup_full_system( + test_constants_modified, + bt, + b_tools=get_b_tools, + b_tools_1=get_b_tools_1, + connect_to_daemon=True, + db_version=1, + ): + yield _ + + +@pytest_asyncio.fixture(scope="function") +async def get_daemon(bt): + async for _ in setup_daemon(btools=bt): + yield _ + + +@pytest_asyncio.fixture(scope="function") +async def get_temp_keyring(): + with TempKeyring() as keychain: + yield keychain + + +@pytest_asyncio.fixture(scope="function") +async def get_b_tools_1(get_temp_keyring): + return await create_block_tools_async(constants=test_constants_modified, keychain=get_temp_keyring) + + +@pytest_asyncio.fixture(scope="function") +async def get_b_tools(get_temp_keyring): + local_b_tools = await create_block_tools_async(constants=test_constants_modified, keychain=get_temp_keyring) + new_config = local_b_tools._config + local_b_tools.change_config(new_config) + return local_b_tools + + +@pytest_asyncio.fixture(scope="function") +async def get_daemon_with_temp_keyring(get_b_tools): + async for daemon in setup_daemon(btools=get_b_tools): + yield get_b_tools, daemon + + +@pytest_asyncio.fixture(scope="function") +async def wallets_prefarm(two_wallet_nodes, self_hostname, trusted): + """ + Sets up the node with 10 blocks, and returns a payer and payee wallet. + """ + farm_blocks = 10 + buffer = 4 + full_nodes, wallets = two_wallet_nodes + full_node_api = full_nodes[0] + full_node_server = full_node_api.server + wallet_node_0, wallet_server_0 = wallets[0] + wallet_node_1, wallet_server_1 = wallets[1] + wallet_0 = wallet_node_0.wallet_state_manager.main_wallet + wallet_1 = wallet_node_1.wallet_state_manager.main_wallet + + ph0 = await wallet_0.get_new_puzzlehash() + ph1 = await wallet_1.get_new_puzzlehash() + + if trusted: + wallet_node_0.config["trusted_peers"] = {full_node_server.node_id.hex(): full_node_server.node_id.hex()} + wallet_node_1.config["trusted_peers"] = {full_node_server.node_id.hex(): full_node_server.node_id.hex()} + else: + wallet_node_0.config["trusted_peers"] = {} + wallet_node_1.config["trusted_peers"] = {} + + await wallet_server_0.start_client(PeerInfo(self_hostname, uint16(full_node_server._port)), None) + await wallet_server_1.start_client(PeerInfo(self_hostname, uint16(full_node_server._port)), None) + + for i in range(0, farm_blocks): + await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph0)) + + for i in range(0, farm_blocks): + await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph1)) + + for i in range(0, buffer): + await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(bytes32(token_bytes(nbytes=32)))) + + await time_out_assert(10, wallet_is_synced, True, wallet_node_0, full_node_api) + await time_out_assert(10, wallet_is_synced, True, wallet_node_1, full_node_api) + + return wallet_node_0, wallet_node_1, full_node_api + + +@pytest_asyncio.fixture(scope="function") +async def introducer(bt): + introducer_port = find_available_listen_port("introducer") + async for _ in setup_introducer(bt, introducer_port): + yield _ + + +@pytest_asyncio.fixture(scope="function") +async def timelord(bt): + timelord_port = find_available_listen_port("timelord") + node_port = find_available_listen_port("node") + rpc_port = find_available_listen_port("rpc") + vdf_port = find_available_listen_port("vdf") + async for _ in setup_timelord(timelord_port, node_port, rpc_port, vdf_port, False, test_constants, bt): + yield _ + + +@pytest_asyncio.fixture(scope="module") +async def two_nodes_mempool(bt, wallet_a): + async_gen = setup_simulators_and_wallets(2, 1, {}) + nodes, _ = await async_gen.__anext__() + full_node_1 = nodes[0] + full_node_2 = nodes[1] + server_1 = full_node_1.full_node.server + server_2 = full_node_2.full_node.server + + reward_ph = wallet_a.get_new_puzzlehash() + blocks = bt.get_consecutive_blocks( + 3, + guarantee_transaction_block=True, + farmer_reward_puzzle_hash=reward_ph, + pool_reward_puzzle_hash=reward_ph, + ) + + for block in blocks: + await full_node_1.full_node.respond_block(full_node_protocol.RespondBlock(block)) + + await time_out_assert(60, node_height_at_least, True, full_node_1, blocks[-1].height) + + yield full_node_1, full_node_2, server_1, server_2 + + async for _ in async_gen: + yield _ + + +@pytest_asyncio.fixture(scope="function") +async def setup_sim(): + sim = await SpendSim.create() + sim_client = SimClient(sim) + await sim.farm_block() + return sim, sim_client diff --git a/tests/core/daemon/test_daemon.py b/tests/core/daemon/test_daemon.py index fb6fe11465..28d4226d5c 100644 --- a/tests/core/daemon/test_daemon.py +++ b/tests/core/daemon/test_daemon.py @@ -3,62 +3,16 @@ import asyncio import json import logging import pytest -import pytest_asyncio from chia.daemon.server import WebSocketServer from chia.server.outbound_message import NodeType from chia.types.peer_info import PeerInfo -from tests.block_tools import BlockTools, create_block_tools_async +from tests.block_tools import BlockTools from chia.util.ints import uint16 from chia.util.keyring_wrapper import DEFAULT_PASSPHRASE_IF_NO_MASTER_PASSPHRASE from chia.util.ws_message import create_payload from tests.core.node_height import node_height_at_least -from tests.setup_nodes import setup_daemon, setup_full_system -from tests.simulation.test_simulation import test_constants_modified from tests.time_out_assert import time_out_assert_custom_interval, time_out_assert -from tests.util.keyring import TempKeyring - - -@pytest_asyncio.fixture(scope="function") -async def get_temp_keyring(): - with TempKeyring() as keychain: - yield keychain - - -@pytest_asyncio.fixture(scope="function") -async def get_b_tools_1(get_temp_keyring): - return await create_block_tools_async(constants=test_constants_modified, keychain=get_temp_keyring) - - -@pytest_asyncio.fixture(scope="function") -async def get_b_tools(get_temp_keyring): - local_b_tools = await create_block_tools_async(constants=test_constants_modified, keychain=get_temp_keyring) - new_config = local_b_tools._config - local_b_tools.change_config(new_config) - return local_b_tools - - -@pytest_asyncio.fixture(scope="function") -async def get_daemon_with_temp_keyring(get_b_tools): - async for daemon in setup_daemon(btools=get_b_tools): - yield get_b_tools, daemon - - -# TODO: Ideally, the db_version should be the (parameterized) db_version -# fixture, to test all versions of the database schema. This doesn't work -# because of a hack in shutting down the full node, which means you cannot run -# more than one simulations per process. -@pytest_asyncio.fixture(scope="function") -async def daemon_simulation(bt, get_b_tools, get_b_tools_1): - async for _ in setup_full_system( - test_constants_modified, - bt, - b_tools=get_b_tools, - b_tools_1=get_b_tools_1, - connect_to_daemon=True, - db_version=1, - ): - yield _ class TestDaemon: diff --git a/tests/core/full_node/config.py b/tests/core/full_node/config.py index 54c7a57c36..2cbb1c0883 100644 --- a/tests/core/full_node/config.py +++ b/tests/core/full_node/config.py @@ -1,9 +1,4 @@ # flake8: noqa: E501 parallel = True job_timeout = 50 -CHECK_RESOURCE_USAGE = """ - - name: Check resource usage - run: | - sqlite3 -readonly -separator " " .pymon "select item,cpu_usage,total_time,mem_usage from TEST_METRICS order by mem_usage desc;" >metrics.out - ./tests/check_pytest_monitor_output.py Tuple[aiosqlite.Connection, Blockchain]: - connection = await aiosqlite.connect(":memory:") - db_wrapper = DBWrapper(connection) +async def create_ram_blockchain(consensus_constants: ConsensusConstants) -> Tuple[DBWrapper2, Blockchain]: + uri = f"file:db_{random.randint(0, 99999999)}?mode=memory&cache=shared" + connection = await aiosqlite.connect(uri, uri=True) + db_wrapper = DBWrapper2(connection) + await db_wrapper.add_connection(await aiosqlite.connect(uri, uri=True)) block_store = await BlockStore.create(db_wrapper) coin_store = await CoinStore.create(db_wrapper) hint_store = await HintStore.create(db_wrapper) blockchain = await Blockchain.create(coin_store, block_store, consensus_constants, hint_store, Path("."), 2) - return connection, blockchain + return db_wrapper, blockchain diff --git a/tests/core/full_node/stores/config.py b/tests/core/full_node/stores/config.py index 08d539dc1b..a36e5dd8a3 100644 --- a/tests/core/full_node/stores/config.py +++ b/tests/core/full_node/stores/config.py @@ -1,9 +1,4 @@ # flake8: noqa: E501 parallel = True job_timeout = 40 -CHECK_RESOURCE_USAGE = """ - - name: Check resource usage - run: | - sqlite3 -readonly -separator " " .pymon "select item,cpu_usage,total_time,mem_usage from TEST_METRICS order by mem_usage desc;" >metrics.out - ./tests/check_pytest_monitor_output.py SubEpochSummary: async def new_block( - db: DBWrapper, + db: DBWrapper2, block_hash: bytes32, parent: bytes32, height: int, is_peak: bool, ses: Optional[SubEpochSummary], ): - if db.db_version == 2: - cursor = await db.db.execute( - "INSERT INTO full_blocks VALUES(?, ?, ?, ?)", - ( - block_hash, - parent, - height, - # sub epoch summary - None if ses is None else bytes(ses), - ), - ) - await cursor.close() - if is_peak: - cursor = await db.db.execute("INSERT OR REPLACE INTO current_peak VALUES(?, ?)", (0, block_hash)) + async with db.write_db() as conn: + if db.db_version == 2: + cursor = await conn.execute( + "INSERT INTO full_blocks VALUES(?, ?, ?, ?)", + ( + block_hash, + parent, + height, + # sub epoch summary + None if ses is None else bytes(ses), + ), + ) + await cursor.close() + if is_peak: + cursor = await conn.execute("INSERT OR REPLACE INTO current_peak VALUES(?, ?)", (0, block_hash)) + await cursor.close() + else: + cursor = await conn.execute( + "INSERT INTO block_records VALUES(?, ?, ?, ?, ?)", + ( + block_hash.hex(), + parent.hex(), + height, + # sub epoch summary + None if ses is None else bytes(ses), + is_peak, + ), + ) await cursor.close() - else: - cursor = await db.db.execute( - "INSERT INTO block_records VALUES(?, ?, ?, ?, ?)", - ( - block_hash.hex(), - parent.hex(), - height, - # sub epoch summary - None if ses is None else bytes(ses), - is_peak, - ), - ) - await cursor.close() -async def setup_db(db: DBWrapper): +async def setup_db(db: DBWrapper2): - if db.db_version == 2: - await db.db.execute( - "CREATE TABLE IF NOT EXISTS full_blocks(" - "header_hash blob PRIMARY KEY," - "prev_hash blob," - "height bigint," - "sub_epoch_summary blob)" - ) - await db.db.execute("CREATE TABLE IF NOT EXISTS current_peak(key int PRIMARY KEY, hash blob)") + async with db.write_db() as conn: + if db.db_version == 2: + await conn.execute( + "CREATE TABLE IF NOT EXISTS full_blocks(" + "header_hash blob PRIMARY KEY," + "prev_hash blob," + "height bigint," + "sub_epoch_summary blob)" + ) + await conn.execute("CREATE TABLE IF NOT EXISTS current_peak(key int PRIMARY KEY, hash blob)") - await db.db.execute("CREATE INDEX IF NOT EXISTS height on full_blocks(height)") - await db.db.execute("CREATE INDEX IF NOT EXISTS hh on full_blocks(header_hash)") - else: - await db.db.execute( - "CREATE TABLE IF NOT EXISTS block_records(" - "header_hash text PRIMARY KEY," - "prev_hash text," - "height bigint," - "sub_epoch_summary blob," - "is_peak tinyint)" - ) - await db.db.execute("CREATE INDEX IF NOT EXISTS height on block_records(height)") - await db.db.execute("CREATE INDEX IF NOT EXISTS hh on block_records(header_hash)") - await db.db.execute("CREATE INDEX IF NOT EXISTS peak on block_records(is_peak)") + await conn.execute("CREATE INDEX IF NOT EXISTS height on full_blocks(height)") + await conn.execute("CREATE INDEX IF NOT EXISTS hh on full_blocks(header_hash)") + else: + await conn.execute( + "CREATE TABLE IF NOT EXISTS block_records(" + "header_hash text PRIMARY KEY," + "prev_hash text," + "height bigint," + "sub_epoch_summary blob," + "is_peak tinyint)" + ) + await conn.execute("CREATE INDEX IF NOT EXISTS height on block_records(height)") + await conn.execute("CREATE INDEX IF NOT EXISTS hh on block_records(header_hash)") + await conn.execute("CREATE INDEX IF NOT EXISTS peak on block_records(is_peak)") # if chain_id != 0, the last block in the chain won't be considered the peak, # and the chain_id will be mixed in to the hashes, to form a separate chain at # the same heights as the main chain async def setup_chain( - db: DBWrapper, length: int, *, chain_id: int = 0, ses_every: Optional[int] = None, start_height=0 + db: DBWrapper2, length: int, *, chain_id: int = 0, ses_every: Optional[int] = None, start_height=0 ): height = start_height peak_hash = gen_block_hash(height + chain_id * 65536) @@ -171,10 +173,11 @@ class TestBlockHeightMap: # in the DB since we keep loading until we find a match of both hash # and sub epoch summary. In this test we have a sub epoch summary # every 20 blocks, so we generate the 30 last blocks only - if db_version == 2: - await db_wrapper.db.execute("DROP TABLE full_blocks") - else: - await db_wrapper.db.execute("DROP TABLE block_records") + async with db_wrapper.write_db() as conn: + if db_version == 2: + await conn.execute("DROP TABLE full_blocks") + else: + await conn.execute("DROP TABLE block_records") await setup_db(db_wrapper) await setup_chain(db_wrapper, 10000, ses_every=20, start_height=9970) height_map = await BlockHeightMap.create(tmp_dir, db_wrapper) diff --git a/tests/core/full_node/test_conditions.py b/tests/core/full_node/test_conditions.py index 266a521091..2cbae3bb1f 100644 --- a/tests/core/full_node/test_conditions.py +++ b/tests/core/full_node/test_conditions.py @@ -73,7 +73,7 @@ async def check_spend_bundle_validity( `SpendBundle`, and then invokes `receive_block` to ensure that it's accepted (if `expected_err=None`) or fails with the correct error code. """ - connection, blockchain = await create_ram_blockchain(constants) + db_wrapper, blockchain = await create_ram_blockchain(constants) try: for block in blocks: await _validate_and_add_block(blockchain, block) @@ -98,8 +98,8 @@ async def check_spend_bundle_validity( return coins_added, coins_removed finally: - # if we don't close the connection, the test process doesn't exit cleanly - await connection.close() + # if we don't close the db_wrapper, the test process doesn't exit cleanly + await db_wrapper.close() # we must call `shut_down` or the executor in `Blockchain` doesn't stop blockchain.shut_down() diff --git a/tests/core/full_node/test_full_node.py b/tests/core/full_node/test_full_node.py index 4d02d7a375..5c324c3540 100644 --- a/tests/core/full_node/test_full_node.py +++ b/tests/core/full_node/test_full_node.py @@ -5,11 +5,10 @@ import random import time from secrets import token_bytes from typing import Dict, Optional, List -from blspy import G2Element -from clvm.casts import int_to_bytes import pytest -import pytest_asyncio +from blspy import G2Element +from clvm.casts import int_to_bytes from chia.consensus.pot_iterations import is_overflow_block from chia.full_node.bundle_tools import detect_potential_template_generator @@ -33,26 +32,24 @@ from chia.types.mempool_inclusion_status import MempoolInclusionStatus from chia.types.peer_info import PeerInfo, TimestampedPeerInfo from chia.types.spend_bundle import SpendBundle from chia.types.unfinished_block import UnfinishedBlock -from tests.block_tools import get_signage_point from chia.util.errors import Err from chia.util.hash import std_hash from chia.util.ints import uint8, uint16, uint32, uint64 from chia.util.recursive_replace import recursive_replace from chia.util.vdf_prover import get_vdf_info_and_proof +from chia.wallet.transaction_record import TransactionRecord +from tests.block_tools import get_signage_point from tests.blockchain.blockchain_test_utils import ( _validate_and_add_block, _validate_and_add_block_no_error, ) -from tests.pools.test_pool_rpc import wallet_is_synced -from tests.wallet_tools import WalletTool -from chia.wallet.transaction_record import TransactionRecord - from tests.connection_utils import add_dummy_connection, connect_and_get_peer from tests.core.full_node.stores.test_coin_store import get_future_reward_coins from tests.core.full_node.test_mempool_performance import wallet_height_at_least from tests.core.make_block_generator import make_spend_bundle from tests.core.node_height import node_height_at_least -from tests.setup_nodes import setup_simulators_and_wallets, test_constants +from tests.pools.test_pool_rpc import wallet_is_synced +from tests.setup_nodes import test_constants from tests.time_out_assert import time_out_assert, time_out_assert_custom_interval, time_out_messages log = logging.getLogger(__name__) @@ -98,56 +95,6 @@ async def get_block_path(full_node: FullNodeAPI): return blocks_list -@pytest_asyncio.fixture(scope="module") -async def wallet_nodes(bt): - async_gen = setup_simulators_and_wallets(2, 1, {"MEMPOOL_BLOCK_BUFFER": 2, "MAX_BLOCK_COST_CLVM": 400000000}) - nodes, wallets = await async_gen.__anext__() - full_node_1 = nodes[0] - full_node_2 = nodes[1] - server_1 = full_node_1.full_node.server - server_2 = full_node_2.full_node.server - wallet_a = bt.get_pool_wallet_tool() - wallet_receiver = WalletTool(full_node_1.full_node.constants) - yield full_node_1, full_node_2, server_1, server_2, wallet_a, wallet_receiver - - async for _ in async_gen: - yield _ - - -@pytest_asyncio.fixture(scope="function") -async def setup_four_nodes(db_version): - async for _ in setup_simulators_and_wallets(5, 0, {}, db_version=db_version): - yield _ - - -@pytest_asyncio.fixture(scope="function") -async def setup_two_nodes_fixture(db_version): - async for _ in setup_simulators_and_wallets(2, 0, {}, db_version=db_version): - yield _ - - -@pytest_asyncio.fixture(scope="function") -async def setup_two_nodes_and_wallet(): - async for _ in setup_simulators_and_wallets(2, 1, {}, db_version=2): - yield _ - - -@pytest_asyncio.fixture(scope="function") -async def wallet_nodes_mainnet(bt, db_version): - async_gen = setup_simulators_and_wallets(2, 1, {"NETWORK_TYPE": 0}, db_version=db_version) - nodes, wallets = await async_gen.__anext__() - full_node_1 = nodes[0] - full_node_2 = nodes[1] - server_1 = full_node_1.full_node.server - server_2 = full_node_2.full_node.server - wallet_a = bt.get_pool_wallet_tool() - wallet_receiver = WalletTool(full_node_1.full_node.constants) - yield full_node_1, full_node_2, server_1, server_2, wallet_a, wallet_receiver - - async for _ in async_gen: - yield _ - - class TestFullNodeBlockCompression: @pytest.mark.asyncio @pytest.mark.parametrize("tx_size", [10000, 3000000000000]) diff --git a/tests/core/full_node/test_mempool.py b/tests/core/full_node/test_mempool.py index c72e490eca..0961a61532 100644 --- a/tests/core/full_node/test_mempool.py +++ b/tests/core/full_node/test_mempool.py @@ -79,7 +79,7 @@ def generate_test_spend_bundle( return transaction -@pytest_asyncio.fixture(scope="module") +@pytest_asyncio.fixture(scope="function") async def two_nodes_mempool(bt, wallet_a): async_gen = setup_simulators_and_wallets(2, 1, {}) nodes, _ = await async_gen.__anext__() @@ -94,7 +94,10 @@ async def two_nodes_mempool(bt, wallet_a): guarantee_transaction_block=True, farmer_reward_puzzle_hash=reward_ph, pool_reward_puzzle_hash=reward_ph, + genesis_timestamp=10000, + time_per_block=10, ) + assert blocks[0].height == 0 for block in blocks: await full_node_1.full_node.respond_block(full_node_protocol.RespondBlock(block)) @@ -235,6 +238,8 @@ async def next_block(full_node_1, wallet_a, bt) -> Coin: guarantee_transaction_block=True, farmer_reward_puzzle_hash=reward_ph, pool_reward_puzzle_hash=reward_ph, + genesis_timestamp=10000, + time_per_block=10, ) for block in blocks: @@ -255,7 +260,7 @@ class TestMempoolManager: spend_bundle = generate_test_spend_bundle(wallet_a, coin) assert spend_bundle is not None tx: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle) - await full_node_1.respond_transaction(tx, peer) + await full_node_1.respond_transaction(tx, peer, test=True) await time_out_assert( 10, @@ -277,17 +282,17 @@ class TestMempoolManager: (ConditionOpcode.ASSERT_HEIGHT_RELATIVE, 0, MempoolInclusionStatus.PENDING), (ConditionOpcode.ASSERT_HEIGHT_RELATIVE, 1, MempoolInclusionStatus.PENDING), # the absolute height and seconds tests require fresh full nodes to - # run the test on. Right now, we just launch two simulations and all - # tests use the same ones. See comment at the two_nodes_mempool fixture - # (ConditionOpcode.ASSERT_HEIGHT_ABSOLUTE, 2, MempoolInclusionStatus.SUCCESS), - # (ConditionOpcode.ASSERT_HEIGHT_ABSOLUTE, 3, MempoolInclusionStatus.SUCCESS), - # (ConditionOpcode.ASSERT_HEIGHT_ABSOLUTE, 4, MempoolInclusionStatus.PENDING), - # (ConditionOpcode.ASSERT_HEIGHT_ABSOLUTE, 5, MempoolInclusionStatus.PENDING), + # run the test on. The fixture (two_nodes_mempool) creates 3 blocks, + # then condition_tester2 creates another 3 blocks + (ConditionOpcode.ASSERT_HEIGHT_ABSOLUTE, 4, MempoolInclusionStatus.SUCCESS), + (ConditionOpcode.ASSERT_HEIGHT_ABSOLUTE, 5, MempoolInclusionStatus.SUCCESS), + (ConditionOpcode.ASSERT_HEIGHT_ABSOLUTE, 6, MempoolInclusionStatus.PENDING), + (ConditionOpcode.ASSERT_HEIGHT_ABSOLUTE, 7, MempoolInclusionStatus.PENDING), # genesis timestamp is 10000 and each block is 10 seconds - # (ConditionOpcode.ASSERT_SECONDS_ABSOLUTE, 10029, MempoolInclusionStatus.SUCCESS), - # (ConditionOpcode.ASSERT_SECONDS_ABSOLUTE, 10030, MempoolInclusionStatus.SUCCESS), - # (ConditionOpcode.ASSERT_SECONDS_ABSOLUTE, 10031, MempoolInclusionStatus.FAILED), - # (ConditionOpcode.ASSERT_SECONDS_ABSOLUTE, 10032, MempoolInclusionStatus.FAILED), + (ConditionOpcode.ASSERT_SECONDS_ABSOLUTE, 10049, MempoolInclusionStatus.SUCCESS), + (ConditionOpcode.ASSERT_SECONDS_ABSOLUTE, 10050, MempoolInclusionStatus.SUCCESS), + (ConditionOpcode.ASSERT_SECONDS_ABSOLUTE, 10051, MempoolInclusionStatus.FAILED), + (ConditionOpcode.ASSERT_SECONDS_ABSOLUTE, 10052, MempoolInclusionStatus.FAILED), ], ) async def test_ephemeral_timelock(self, bt, two_nodes_mempool, wallet_a, opcode, lock_value, expected): @@ -392,7 +397,7 @@ class TestMempoolManager: assert spend_bundle1 is not None tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1) - status, err = await respond_transaction(full_node_1, tx1, peer) + status, err = await respond_transaction(full_node_1, tx1, peer, test=True) assert err is None assert status == MempoolInclusionStatus.SUCCESS @@ -403,7 +408,7 @@ class TestMempoolManager: ) assert spend_bundle2 is not None tx2: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle2) - status, err = await respond_transaction(full_node_1, tx2, peer) + status, err = await respond_transaction(full_node_1, tx2, peer, test=True) sb1 = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle1.name()) sb2 = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle2.name()) @@ -415,7 +420,7 @@ class TestMempoolManager: async def send_sb(self, node: FullNodeAPI, sb: SpendBundle) -> Optional[Message]: tx = wallet_protocol.SendTransaction(sb) - return await node.send_transaction(tx) + return await node.send_transaction(tx, test=True) async def gen_and_send_sb(self, node, peer, *args, **kwargs): sb = generate_test_spend_bundle(*args, **kwargs) @@ -575,7 +580,7 @@ class TestMempoolManager: tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1) - status, err = await respond_transaction(full_node_1, tx1, peer) + status, err = await respond_transaction(full_node_1, tx1, peer, test=True) return blocks, spend_bundle1, peer, status, err @pytest.mark.asyncio @@ -590,6 +595,7 @@ class TestMempoolManager: guarantee_transaction_block=True, farmer_reward_puzzle_hash=reward_ph, pool_reward_puzzle_hash=reward_ph, + time_per_block=10, ) peer = await connect_and_get_peer(server_1, server_2, bt.config["self_hostname"]) @@ -919,7 +925,7 @@ class TestMempoolManager: tx2: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1) - status, err = await respond_transaction(full_node_1, tx2, peer) + status, err = await respond_transaction(full_node_1, tx2, peer, test=True) sb1 = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle1.name()) assert err is None @@ -1459,7 +1465,7 @@ class TestMempoolManager: tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1) - status, err = await respond_transaction(full_node_1, tx1, peer) + status, err = await respond_transaction(full_node_1, tx1, peer, test=True) mempool_bundle = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle1.name()) @@ -1506,7 +1512,7 @@ class TestMempoolManager: tx: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle_combined) peer = await connect_and_get_peer(server_1, server_2, bt.config["self_hostname"]) - status, err = await respond_transaction(full_node_1, tx, peer) + status, err = await respond_transaction(full_node_1, tx, peer, test=True) sb = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle_combined.name()) assert err == Err.DOUBLE_SPEND @@ -1556,7 +1562,7 @@ class TestMempoolManager: # assert spend_bundle is not None # # tx: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle) - # await full_node_1.respond_transaction(tx, peer) + # await full_node_1.respond_transaction(tx, peer, test=True) # # sb = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle.name()) # assert sb is spend_bundle @@ -2449,7 +2455,7 @@ class TestMaliciousGenerators: coin_spend_0 = recursive_replace(spend_bundle.coin_spends[0], "coin.puzzle_hash", bytes32([1] * 32)) new_bundle = recursive_replace(spend_bundle, "coin_spends", [coin_spend_0] + spend_bundle.coin_spends[1:]) assert spend_bundle is not None - res = await full_node_1.full_node.respond_transaction(new_bundle, new_bundle.name()) + res = await full_node_1.full_node.respond_transaction(new_bundle, new_bundle.name(), test=True) assert res == (MempoolInclusionStatus.FAILED, Err.INVALID_SPEND_BUNDLE) diff --git a/tests/core/full_node/test_mempool_performance.py b/tests/core/full_node/test_mempool_performance.py index a8a7766aff..b887863e55 100644 --- a/tests/core/full_node/test_mempool_performance.py +++ b/tests/core/full_node/test_mempool_performance.py @@ -1,11 +1,9 @@ # flake8: noqa: F811, F401 -import asyncio +import logging import time import pytest -import pytest_asyncio -import logging from chia.protocols import full_node_protocol from chia.types.peer_info import PeerInfo @@ -13,7 +11,6 @@ from chia.util.ints import uint16 from chia.wallet.transaction_record import TransactionRecord from chia.wallet.wallet_node import WalletNode from tests.connection_utils import connect_and_get_peer -from tests.setup_nodes import setup_simulators_and_wallets from tests.time_out_assert import time_out_assert @@ -35,13 +32,6 @@ async def wallet_balance_at_least(wallet_node: WalletNode, balance): log = logging.getLogger(__name__) -@pytest_asyncio.fixture(scope="module") -async def wallet_nodes_mempool_perf(bt): - key_seed = bt.farmer_master_sk_entropy - async for _ in setup_simulators_and_wallets(2, 1, {}, key_seed=key_seed): - yield _ - - class TestMempoolPerformance: @pytest.mark.asyncio @pytest.mark.benchmark @@ -87,4 +77,4 @@ class TestMempoolPerformance: if idx >= len(blocks) - 3: assert duration < 0.1 else: - assert duration < 0.0002 + assert duration < 0.0003 diff --git a/tests/core/full_node/test_performance.py b/tests/core/full_node/test_performance.py index 4a1ce2260c..58e1edeac3 100644 --- a/tests/core/full_node/test_performance.py +++ b/tests/core/full_node/test_performance.py @@ -1,15 +1,13 @@ # flake8: noqa: F811, F401 -import asyncio +import cProfile import dataclasses import logging import random import time from typing import Dict -from clvm.casts import int_to_bytes import pytest -import pytest_asyncio -import cProfile +from clvm.casts import int_to_bytes from chia.consensus.block_record import BlockRecord from chia.full_node.full_node_api import FullNodeAPI @@ -18,12 +16,9 @@ from chia.types.condition_opcodes import ConditionOpcode from chia.types.condition_with_args import ConditionWithArgs from chia.types.unfinished_block import UnfinishedBlock from chia.util.ints import uint64 -from tests.wallet_tools import WalletTool - from tests.connection_utils import add_dummy_connection from tests.core.full_node.stores.test_coin_store import get_future_reward_coins from tests.core.node_height import node_height_at_least -from tests.setup_nodes import setup_simulators_and_wallets from tests.time_out_assert import time_out_assert log = logging.getLogger(__name__) @@ -39,20 +34,6 @@ async def get_block_path(full_node: FullNodeAPI): return blocks_list -@pytest_asyncio.fixture(scope="module") -async def wallet_nodes_perf(bt): - async_gen = setup_simulators_and_wallets(1, 1, {"MEMPOOL_BLOCK_BUFFER": 1, "MAX_BLOCK_COST_CLVM": 11000000000}) - nodes, wallets = await async_gen.__anext__() - full_node_1 = nodes[0] - server_1 = full_node_1.full_node.server - wallet_a = bt.get_pool_wallet_tool() - wallet_receiver = WalletTool(full_node_1.full_node.constants) - yield full_node_1, server_1, wallet_a, wallet_receiver - - async for _ in async_gen: - yield _ - - class TestPerformance: @pytest.mark.asyncio @pytest.mark.benchmark diff --git a/tests/core/full_node/test_transactions.py b/tests/core/full_node/test_transactions.py index e00dacd22a..b2c88a2a78 100644 --- a/tests/core/full_node/test_transactions.py +++ b/tests/core/full_node/test_transactions.py @@ -3,7 +3,6 @@ from secrets import token_bytes from typing import Optional import pytest -import pytest_asyncio from chia.consensus.block_record import BlockRecord from chia.consensus.block_rewards import calculate_base_farmer_reward, calculate_pool_reward @@ -12,28 +11,9 @@ from chia.protocols import full_node_protocol from chia.simulator.simulator_protocol import FarmNewBlockProtocol from chia.types.peer_info import PeerInfo from chia.util.ints import uint16, uint32 -from tests.setup_nodes import setup_simulators_and_wallets from tests.time_out_assert import time_out_assert -@pytest_asyncio.fixture(scope="function") -async def wallet_node_sim_and_wallet(): - async for _ in setup_simulators_and_wallets(1, 1, {}): - yield _ - - -@pytest_asyncio.fixture(scope="function") -async def two_wallet_nodes(): - async for _ in setup_simulators_and_wallets(1, 2, {}): - yield _ - - -@pytest_asyncio.fixture(scope="function") -async def three_nodes_two_wallets(): - async for _ in setup_simulators_and_wallets(3, 2, {}): - yield _ - - class TestTransactions: @pytest.mark.asyncio async def test_wallet_coinbase(self, wallet_node_sim_and_wallet, self_hostname): diff --git a/tests/core/server/test_dos.py b/tests/core/server/test_dos.py index 9985e29993..de87635e35 100644 --- a/tests/core/server/test_dos.py +++ b/tests/core/server/test_dos.py @@ -3,7 +3,6 @@ import asyncio import logging import pytest -import pytest_asyncio from aiohttp import ClientSession, ClientTimeout, ServerDisconnectedError, WSCloseCode, WSMessage, WSMsgType from chia.full_node.full_node_api import FullNodeAPI @@ -15,9 +14,8 @@ from chia.server.rate_limits import RateLimiter from chia.server.server import ssl_context_for_client from chia.server.ws_connection import WSChiaConnection from chia.types.peer_info import PeerInfo -from chia.util.ints import uint16, uint64 from chia.util.errors import Err -from tests.setup_nodes import setup_simulators_and_wallets +from chia.util.ints import uint16, uint64 from tests.time_out_assert import time_out_assert log = logging.getLogger(__name__) @@ -33,12 +31,6 @@ async def get_block_path(full_node: FullNodeAPI): return blocks_list -@pytest_asyncio.fixture(scope="function") -async def setup_two_nodes_fixture(db_version): - async for _ in setup_simulators_and_wallets(2, 0, {}, db_version=db_version): - yield _ - - class FakeRateLimiter: def process_msg_and_check(self, msg): return True diff --git a/tests/core/ssl/test_ssl.py b/tests/core/ssl/test_ssl.py index 798df4c64c..24a20efcfc 100644 --- a/tests/core/ssl/test_ssl.py +++ b/tests/core/ssl/test_ssl.py @@ -10,15 +10,9 @@ from chia.server.server import ChiaServer, ssl_context_for_client from chia.server.ws_connection import WSChiaConnection from chia.ssl.create_ssl import generate_ca_signed_cert from chia.types.peer_info import PeerInfo -from tests.block_tools import test_constants from chia.util.ints import uint16 -from tests.setup_nodes import ( - setup_harvester_farmer, - setup_introducer, - setup_simulators_and_wallets, - setup_timelord, -) -from tests.util.socket import find_available_listen_port +from tests.block_tools import test_constants +from tests.setup_nodes import setup_harvester_farmer async def establish_connection(server: ChiaServer, self_hostname: str, ssl_context) -> bool: @@ -57,29 +51,6 @@ async def harvester_farmer(bt): yield _ -@pytest_asyncio.fixture(scope="function") -async def wallet_node_sim_and_wallet(): - async for _ in setup_simulators_and_wallets(1, 1, {}): - yield _ - - -@pytest_asyncio.fixture(scope="function") -async def introducer(bt): - introducer_port = find_available_listen_port("introducer") - async for _ in setup_introducer(bt, introducer_port): - yield _ - - -@pytest_asyncio.fixture(scope="function") -async def timelord(bt): - timelord_port = find_available_listen_port("timelord") - node_port = find_available_listen_port("node") - rpc_port = find_available_listen_port("rpc") - vdf_port = find_available_listen_port("vdf") - async for _ in setup_timelord(timelord_port, node_port, rpc_port, vdf_port, False, test_constants, bt): - yield _ - - class TestSSL: @pytest.mark.asyncio async def test_public_connections(self, wallet_node_sim_and_wallet, self_hostname): diff --git a/tests/core/test_daemon_rpc.py b/tests/core/test_daemon_rpc.py index f5100eed89..5cf5780eae 100644 --- a/tests/core/test_daemon_rpc.py +++ b/tests/core/test_daemon_rpc.py @@ -1,15 +1,7 @@ import pytest -import pytest_asyncio -from tests.setup_nodes import setup_daemon -from chia.daemon.client import connect_to_daemon from chia import __version__ - - -@pytest_asyncio.fixture(scope="function") -async def get_daemon(bt): - async for _ in setup_daemon(btools=bt): - yield _ +from chia.daemon.client import connect_to_daemon class TestDaemonRpc: diff --git a/tests/core/test_db_conversion.py b/tests/core/test_db_conversion.py index 4a9e943666..5d85efa26e 100644 --- a/tests/core/test_db_conversion.py +++ b/tests/core/test_db_conversion.py @@ -10,7 +10,7 @@ from tests.util.temp_file import TempFile from chia.types.blockchain_format.sized_bytes import bytes32 from chia.util.ints import uint32, uint64 from chia.cmds.db_upgrade_func import convert_v1_to_v2 -from chia.util.db_wrapper import DBWrapper +from chia.util.db_wrapper import DBWrapper2 from chia.full_node.block_store import BlockStore from chia.full_node.coin_store import CoinStore from chia.full_node.hint_store import HintStore @@ -54,13 +54,13 @@ class TestDbUpgrade: with TempFile() as in_file, TempFile() as out_file: - async with aiosqlite.connect(in_file) as conn: + conn = await aiosqlite.connect(in_file) + await conn.execute("pragma journal_mode=OFF") + await conn.execute("pragma synchronous=OFF") - await conn.execute("pragma journal_mode=OFF") - await conn.execute("pragma synchronous=OFF") - await conn.execute("pragma locking_mode=exclusive") - - db_wrapper1 = DBWrapper(conn, 1) + db_wrapper1 = DBWrapper2(conn, 1) + await db_wrapper1.add_connection(await aiosqlite.connect(in_file)) + try: block_store1 = await BlockStore.create(db_wrapper1) coin_store1 = await CoinStore.create(db_wrapper1, uint32(0)) if with_hints: @@ -73,20 +73,27 @@ class TestDbUpgrade: bc = await Blockchain.create( coin_store1, block_store1, test_constants, hint_store1, Path("."), reserved_cores=0 ) - await db_wrapper1.commit_transaction() for block in blocks: # await _validate_and_add_block(bc, block) results = PreValidationResult(None, uint64(1), None, False) result, err, _, _ = await bc.receive_block(block, results) assert err is None + finally: + await db_wrapper1.close() # now, convert v1 in_file to v2 out_file convert_v1_to_v2(in_file, out_file) - async with aiosqlite.connect(in_file) as conn, aiosqlite.connect(out_file) as conn2: + conn = await aiosqlite.connect(in_file) + db_wrapper1 = DBWrapper2(conn, 1) + await db_wrapper1.add_connection(await aiosqlite.connect(in_file)) - db_wrapper1 = DBWrapper(conn, 1) + conn2 = await aiosqlite.connect(out_file) + db_wrapper2 = DBWrapper2(conn2, 2) + await db_wrapper2.add_connection(await aiosqlite.connect(out_file)) + + try: block_store1 = await BlockStore.create(db_wrapper1) coin_store1 = await CoinStore.create(db_wrapper1, uint32(0)) if with_hints: @@ -94,7 +101,6 @@ class TestDbUpgrade: else: hint_store1 = None - db_wrapper2 = DBWrapper(conn2, 2) block_store2 = await BlockStore.create(db_wrapper2) coin_store2 = await CoinStore.create(db_wrapper2, uint32(0)) hint_store2 = await HintStore.create(db_wrapper2) @@ -133,3 +139,6 @@ class TestDbUpgrade: for c in coins: n = c.coin.name() assert await coin_store1.get_coin_record(n) == await coin_store2.get_coin_record(n) + finally: + await db_wrapper1.close() + await db_wrapper2.close() diff --git a/tests/core/test_db_validation.py b/tests/core/test_db_validation.py index 39e28d42fe..aa5fb1bf23 100644 --- a/tests/core/test_db_validation.py +++ b/tests/core/test_db_validation.py @@ -16,7 +16,7 @@ from chia.full_node.coin_store import CoinStore from chia.full_node.hint_store import HintStore from chia.types.blockchain_format.sized_bytes import bytes32 from chia.types.full_block import FullBlock -from chia.util.db_wrapper import DBWrapper +from chia.util.db_wrapper import DBWrapper2 from chia.util.ints import uint32, uint64 from tests.setup_nodes import test_constants from tests.util.temp_file import TempFile @@ -129,29 +129,27 @@ def test_db_validate_in_main_chain(invalid_in_chain: bool) -> None: async def make_db(db_file: Path, blocks: List[FullBlock]) -> None: - async with aiosqlite.connect(db_file) as conn: + db_wrapper = DBWrapper2(await aiosqlite.connect(db_file), 2) + try: + await db_wrapper.add_connection(await aiosqlite.connect(db_file)) - await conn.execute("pragma journal_mode=OFF") - await conn.execute("pragma synchronous=OFF") - await conn.execute("pragma locking_mode=exclusive") + async with db_wrapper.write_db() as conn: + # this is done by chia init normally + await conn.execute("CREATE TABLE database_version(version int)") + await conn.execute("INSERT INTO database_version VALUES (2)") - # this is done by chia init normally - await conn.execute("CREATE TABLE database_version(version int)") - await conn.execute("INSERT INTO database_version VALUES (2)") - await conn.commit() - - db_wrapper = DBWrapper(conn, 2) block_store = await BlockStore.create(db_wrapper) coin_store = await CoinStore.create(db_wrapper, uint32(0)) hint_store = await HintStore.create(db_wrapper) bc = await Blockchain.create(coin_store, block_store, test_constants, hint_store, Path("."), reserved_cores=0) - await db_wrapper.commit_transaction() for block in blocks: results = PreValidationResult(None, uint64(1), None, False) result, err, _, _ = await bc.receive_block(block, results) assert err is None + finally: + await db_wrapper.close() @pytest.mark.asyncio diff --git a/tests/core/test_farmer_harvester_rpc.py b/tests/core/test_farmer_harvester_rpc.py index 0b81bdb465..226c6542be 100644 --- a/tests/core/test_farmer_harvester_rpc.py +++ b/tests/core/test_farmer_harvester_rpc.py @@ -14,7 +14,7 @@ from chia.rpc.rpc_server import start_rpc_server from chia.types.blockchain_format.sized_bytes import bytes32 from chia.util.bech32m import decode_puzzle_hash, encode_puzzle_hash from chia.util.byte_types import hexstr_to_bytes -from chia.util.config import get_config_lock, load_config, save_config +from chia.util.config import load_config, lock_and_load_config, save_config from chia.util.hash import std_hash from chia.util.ints import uint8, uint16, uint32, uint64 from chia.wallet.derive_keys import master_sk_to_wallet_sk @@ -244,8 +244,7 @@ async def test_farmer_get_pool_state(harvester_farmer_environment, self_hostname ] root_path = farmer_api.farmer._root_path - with get_config_lock(root_path, "config.yaml"): - config = load_config(root_path, "config.yaml", acquire_lock=False) + with lock_and_load_config(root_path, "config.yaml") as config: config["pool"]["pool_list"] = pool_list save_config(root_path, "config.yaml", config) await farmer_api.farmer.update_pool_state() diff --git a/tests/core/test_filter.py b/tests/core/test_filter.py index 3448b4b42e..db953e4bef 100644 --- a/tests/core/test_filter.py +++ b/tests/core/test_filter.py @@ -1,17 +1,8 @@ from typing import List import pytest -import pytest_asyncio from chiabip158 import PyBIP158 -from tests.setup_nodes import setup_simulators_and_wallets - - -@pytest_asyncio.fixture(scope="function") -async def wallet_and_node(): - async for _ in setup_simulators_and_wallets(1, 1, {}): - yield _ - class TestFilter: @pytest.mark.asyncio diff --git a/tests/core/test_full_node_rpc.py b/tests/core/test_full_node_rpc.py index ee6a58c30e..e2bff665c9 100644 --- a/tests/core/test_full_node_rpc.py +++ b/tests/core/test_full_node_rpc.py @@ -1,9 +1,7 @@ # flake8: noqa: F811, F401 -import logging from typing import List import pytest -import pytest_asyncio from blspy import AugSchemeMPL from chia.consensus.pot_iterations import is_overflow_block @@ -16,22 +14,16 @@ from chia.simulator.simulator_protocol import FarmNewBlockProtocol, ReorgProtoco from chia.types.full_block import FullBlock from chia.types.spend_bundle import SpendBundle from chia.types.unfinished_block import UnfinishedBlock -from tests.block_tools import get_signage_point from chia.util.hash import std_hash -from chia.util.ints import uint16, uint8 +from chia.util.ints import uint8 +from tests.block_tools import get_signage_point from tests.blockchain.blockchain_test_utils import _validate_and_add_block -from tests.wallet_tools import WalletTool from tests.connection_utils import connect_and_get_peer -from tests.setup_nodes import setup_simulators_and_wallets, test_constants +from tests.setup_nodes import test_constants from tests.time_out_assert import time_out_assert from tests.util.rpc import validate_get_routes from tests.util.socket import find_available_listen_port - - -@pytest_asyncio.fixture(scope="function") -async def two_nodes_sim_and_wallets(): - async for _ in setup_simulators_and_wallets(2, 0, {}): - yield _ +from tests.wallet_tools import WalletTool class TestRpc: diff --git a/tests/core/util/test_config.py b/tests/core/util/test_config.py index c3484ad650..e2493f8c86 100644 --- a/tests/core/util/test_config.py +++ b/tests/core/util/test_config.py @@ -11,9 +11,10 @@ import yaml from chia.util.config import ( config_path_for_filename, create_default_chia_config, - get_config_lock, initial_config_file, load_config, + lock_and_load_config, + lock_config, save_config, ) from chia.util.path import mkdir @@ -54,11 +55,11 @@ def write_config( if atomic_write: # Note that this is usually atomic but in certain circumstances in Windows it can copy the file, # leading to a non-atomic operation. - with get_config_lock(root_path, "config.yaml"): + with lock_config(root_path, "config.yaml"): save_config(root_path=root_path, filename="config.yaml", config_data=config) else: path: Path = config_path_for_filename(root_path, filename="config.yaml") - with get_config_lock(root_path, "config.yaml"): + with lock_config(root_path, "config.yaml"): with tempfile.TemporaryDirectory(dir=path.parent) as tmp_dir: tmp_path: Path = Path(tmp_dir) / Path("config.yaml") with open(tmp_path, "w") as f: @@ -88,8 +89,7 @@ def read_and_compare_config( if do_sleep: sleep(random.random()) - with get_config_lock(root_path, "config.yaml"): - config: Dict = load_config(root_path=root_path, filename="config.yaml", acquire_lock=False) + with lock_and_load_config(root_path, "config.yaml") as config: assert config == default_config except Exception as e: if error_queue is not None: @@ -257,7 +257,7 @@ class TestConfig: # Sanity check that we didn't modify the default config assert config["harvester"]["farmer_peer"]["host"] != default_config_dict["harvester"]["farmer_peer"]["host"] # When: saving the modified config - with get_config_lock(root_path, "config.yaml"): + with lock_config(root_path, "config.yaml"): save_config(root_path=root_path, filename="config.yaml", config_data=config) # Expect: modifications should be preserved in the config read from disk @@ -274,7 +274,7 @@ class TestConfig: # multiple writes were observed, leading to read failures when data was partially written. default_config_dict["xyz"] = "x" * 32768 root_path: Path = root_path_populated_with_config - with get_config_lock(root_path, "config.yaml"): + with lock_config(root_path, "config.yaml"): save_config(root_path=root_path, filename="config.yaml", config_data=default_config_dict) num_workers: int = 30 args = list(map(lambda _: (root_path, default_config_dict), range(num_workers))) @@ -296,7 +296,7 @@ class TestConfig: default_config_dict["xyz"] = "x" * 32768 root_path: Path = root_path_populated_with_config - with get_config_lock(root_path, "config.yaml"): + with lock_config(root_path, "config.yaml"): save_config(root_path=root_path, filename="config.yaml", config_data=default_config_dict) with ProcessPoolExecutor(max_workers=4) as pool: diff --git a/tests/core/util/test_db_wrapper.py b/tests/core/util/test_db_wrapper.py new file mode 100644 index 0000000000..ab7b02a07e --- /dev/null +++ b/tests/core/util/test_db_wrapper.py @@ -0,0 +1,225 @@ +import asyncio +import contextlib +from typing import List + +import aiosqlite +import pytest + +from chia.util.db_wrapper import DBWrapper2 +from tests.util.db_connection import DBConnection + + +async def increment_counter(db_wrapper: DBWrapper2) -> None: + async with db_wrapper.write_db() as connection: + async with connection.execute("SELECT value FROM counter") as cursor: + row = await cursor.fetchone() + + assert row is not None + [old_value] = row + + await asyncio.sleep(0) + + new_value = old_value + 1 + await connection.execute("UPDATE counter SET value = :value", {"value": new_value}) + + +async def sum_counter(db_wrapper: DBWrapper2, output: List[int]) -> None: + async with db_wrapper.read_db() as connection: + async with connection.execute("SELECT value FROM counter") as cursor: + row = await cursor.fetchone() + + assert row is not None + [value] = row + + for i in range(5): + await asyncio.sleep(0) + output.append(value) + + +async def setup_table(db: DBWrapper2) -> None: + async with db.write_db() as conn: + await conn.execute("CREATE TABLE counter(value INTEGER NOT NULL)") + await conn.execute("INSERT INTO counter(value) VALUES(0)") + + +async def get_value(cursor: aiosqlite.Cursor) -> int: + row = await cursor.fetchone() + assert row + return int(row[0]) + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + argnames="acquire_outside", + argvalues=[pytest.param(False, id="not acquired outside"), pytest.param(True, id="acquired outside")], +) +async def test_concurrent_writers(acquire_outside: bool) -> None: + + async with DBConnection(2) as db_wrapper: + await setup_table(db_wrapper) + + concurrent_task_count = 200 + + async with contextlib.AsyncExitStack() as exit_stack: + if acquire_outside: + await exit_stack.enter_async_context(db_wrapper.write_db()) + + tasks = [] + for index in range(concurrent_task_count): + task = asyncio.create_task(increment_counter(db_wrapper)) + tasks.append(task) + + await asyncio.wait_for(asyncio.gather(*tasks), timeout=None) + + async with db_wrapper.read_db() as connection: + async with connection.execute("SELECT value FROM counter") as cursor: + row = await cursor.fetchone() + + assert row is not None + [value] = row + + assert value == concurrent_task_count + + +@pytest.mark.asyncio +async def test_writers_nests() -> None: + async with DBConnection(2) as db_wrapper: + await setup_table(db_wrapper) + async with db_wrapper.write_db() as conn1: + async with conn1.execute("SELECT value FROM counter") as cursor: + value = await get_value(cursor) + async with db_wrapper.write_db() as conn2: + assert conn1 == conn2 + value += 1 + await conn2.execute("UPDATE counter SET value = :value", {"value": value}) + async with db_wrapper.write_db() as conn3: + assert conn1 == conn3 + async with conn3.execute("SELECT value FROM counter") as cursor: + value = await get_value(cursor) + + assert value == 1 + + +@pytest.mark.asyncio +async def test_partial_failure() -> None: + values = [] + async with DBConnection(2) as db_wrapper: + await setup_table(db_wrapper) + async with db_wrapper.write_db() as conn1: + await conn1.execute("UPDATE counter SET value = 42") + async with conn1.execute("SELECT value FROM counter") as cursor: + values.append(await get_value(cursor)) + try: + async with db_wrapper.write_db() as conn2: + await conn2.execute("UPDATE counter SET value = 1337") + async with conn1.execute("SELECT value FROM counter") as cursor: + values.append(await get_value(cursor)) + # this simulates a failure, which will cause a rollback of the + # write we just made, back to 42 + raise RuntimeError("failure within a sub-transaction") + except RuntimeError: + # we expect to get here + values.append(1) + async with conn1.execute("SELECT value FROM counter") as cursor: + values.append(await get_value(cursor)) + + # the write of 1337 failed, and was restored to 42 + assert values == [42, 1337, 1, 42] + + +@pytest.mark.asyncio +async def test_readers_nests() -> None: + async with DBConnection(2) as db_wrapper: + await setup_table(db_wrapper) + + async with db_wrapper.read_db() as conn1: + async with db_wrapper.read_db() as conn2: + assert conn1 == conn2 + async with db_wrapper.read_db() as conn3: + assert conn1 == conn3 + async with conn3.execute("SELECT value FROM counter") as cursor: + value = await get_value(cursor) + + assert value == 0 + + +@pytest.mark.asyncio +async def test_readers_nests_writer() -> None: + async with DBConnection(2) as db_wrapper: + await setup_table(db_wrapper) + + async with db_wrapper.write_db() as conn1: + async with db_wrapper.read_db() as conn2: + assert conn1 == conn2 + async with db_wrapper.write_db() as conn3: + assert conn1 == conn3 + async with conn3.execute("SELECT value FROM counter") as cursor: + value = await get_value(cursor) + + assert value == 0 + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + argnames="acquire_outside", + argvalues=[pytest.param(False, id="not acquired outside"), pytest.param(True, id="acquired outside")], +) +async def test_concurrent_readers(acquire_outside: bool) -> None: + + async with DBConnection(2) as db_wrapper: + await setup_table(db_wrapper) + + async with db_wrapper.write_db() as connection: + await connection.execute("UPDATE counter SET value = 1") + + concurrent_task_count = 200 + + async with contextlib.AsyncExitStack() as exit_stack: + if acquire_outside: + await exit_stack.enter_async_context(db_wrapper.read_db()) + + tasks = [] + values: List[int] = [] + for index in range(concurrent_task_count): + task = asyncio.create_task(sum_counter(db_wrapper, values)) + tasks.append(task) + + await asyncio.wait_for(asyncio.gather(*tasks), timeout=None) + + assert values == [1] * concurrent_task_count + + +@pytest.mark.asyncio +@pytest.mark.parametrize( + argnames="acquire_outside", + argvalues=[pytest.param(False, id="not acquired outside"), pytest.param(True, id="acquired outside")], +) +async def test_mixed_readers_writers(acquire_outside: bool) -> None: + + async with DBConnection(2) as db_wrapper: + await setup_table(db_wrapper) + + async with db_wrapper.write_db() as connection: + await connection.execute("UPDATE counter SET value = 1") + + concurrent_task_count = 200 + + async with contextlib.AsyncExitStack() as exit_stack: + if acquire_outside: + await exit_stack.enter_async_context(db_wrapper.read_db()) + + tasks = [] + values: List[int] = [] + for index in range(concurrent_task_count): + if index == 100: + task = asyncio.create_task(increment_counter(db_wrapper)) + task = asyncio.create_task(sum_counter(db_wrapper, values)) + tasks.append(task) + + await asyncio.wait_for(asyncio.gather(*tasks), timeout=None) + + # at some unspecified place between the first and the last reads, the value + # was updated from 1 to 2 + assert values[0] == 1 + assert values[-1] == 2 + assert len(values) == concurrent_task_count diff --git a/tests/core/util/test_type_checking.py b/tests/core/util/test_type_checking.py index 775affbe66..8e90f8ad4c 100644 --- a/tests/core/util/test_type_checking.py +++ b/tests/core/util/test_type_checking.py @@ -57,7 +57,7 @@ class TestStrictClass(unittest.TestCase): assert TestClass2(25) with raises(TypeError): - TestClass2(1, 2) + TestClass2(1, 2) # pylint: disable=too-many-function-args def test_StrictDataClassLists(self): @dataclass(frozen=True) diff --git a/tests/pools/test_pool_config.py b/tests/pools/test_pool_config.py index 5dde4aec04..798d6071f6 100644 --- a/tests/pools/test_pool_config.py +++ b/tests/pools/test_pool_config.py @@ -4,7 +4,7 @@ from pathlib import Path from blspy import AugSchemeMPL, PrivateKey from chia.pools.pool_config import PoolWalletConfig -from chia.util.config import get_config_lock, load_config, save_config, create_default_chia_config +from chia.util.config import load_config, lock_config, save_config, create_default_chia_config def test_pool_config(): @@ -37,8 +37,8 @@ def test_pool_config(): config_b["wallet"]["pool_list"] = [pwc.to_json_dict()] print(config["wallet"]["pool_list"]) - with get_config_lock(test_root, "test_pool_config_a.yaml"): + with lock_config(test_root, "test_pool_config_a.yaml"): save_config(test_root, "test_pool_config_a.yaml", config_a) - with get_config_lock(test_root, "test_pool_config_b.yaml"): + with lock_config(test_root, "test_pool_config_b.yaml"): save_config(test_root, "test_pool_config_b.yaml", config_b) assert config_a == config_b diff --git a/tests/pools/test_pool_rpc.py b/tests/pools/test_pool_rpc.py index 647fefd636..00fe311fd9 100644 --- a/tests/pools/test_pool_rpc.py +++ b/tests/pools/test_pool_rpc.py @@ -90,12 +90,6 @@ async def wallet_is_synced(wallet_node: WalletNode, full_node_api): PREFARMED_BLOCKS = 4 -@pytest_asyncio.fixture(scope="function") -async def two_wallet_nodes(): - async for _ in setup_simulators_and_wallets(1, 2, {}): - yield _ - - @pytest_asyncio.fixture(scope="function") async def one_wallet_node_and_rpc(bt, self_hostname): rmtree(get_pool_plot_dir(), ignore_errors=True) diff --git a/tests/pools/test_wallet_pool_store.py b/tests/pools/test_wallet_pool_store.py index a35e285933..8d5c43c7ae 100644 --- a/tests/pools/test_wallet_pool_store.py +++ b/tests/pools/test_wallet_pool_store.py @@ -38,7 +38,7 @@ def make_child_solution(coin_spend: CoinSpend, new_coin: Optional[Coin] = None) class TestWalletPoolStore: @pytest.mark.asyncio async def test_store(self): - db_filename = Path("wallet_store_test.db") + db_filename = Path("wallet_pool_store_test.db") if db_filename.exists(): db_filename.unlink() diff --git a/tests/runner_templates/build-test-macos b/tests/runner_templates/build-test-macos index b8d42f4a5f..6031c07ef4 100644 --- a/tests/runner_templates/build-test-macos +++ b/tests/runner_templates/build-test-macos @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.8, 3.9] os: [macOS-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_TEST_NAME steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -54,7 +57,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: # Note that new runners may break this https://github.com/actions/cache/issues/292 path: ${{ steps.pip-cache.outputs.dir }} @@ -76,7 +79,23 @@ INSTALL_TIMELORD - name: Test TEST_NAME code with pytest run: | . ./activate - ./venv/bin/py.test TEST_DIR -s -v --durations 0PYTEST_PARALLEL_ARGS -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test TEST_DIR -s -v --durations 0PYTEST_PARALLEL_ARGS -m "not benchmark" + + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme # diff --git a/tests/runner_templates/build-test-ubuntu b/tests/runner_templates/build-test-ubuntu index f53a61b15c..512d848740 100644 --- a/tests/runner_templates/build-test-ubuntu +++ b/tests/runner_templates/build-test-ubuntu @@ -29,10 +29,13 @@ jobs: matrix: python-version: [3.7, 3.8, 3.9] os: [ubuntu-latest] + env: + CHIA_ROOT: ${{ github.workspace }}/.chia/mainnet + JOB_FILE_NAME: tests_${{ matrix.os }}_python-${{ matrix.python-version }}_TEST_NAME steps: - name: Checkout Code - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: fetch-depth: 0 @@ -42,7 +45,7 @@ jobs: python-version: ${{ matrix.python-version }} - name: Cache npm - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} @@ -55,7 +58,7 @@ jobs: echo "::set-output name=dir::$(pip cache dir)" - name: Cache pip - uses: actions/cache@v2.1.6 + uses: actions/cache@v3 with: path: ${{ steps.pip-cache.outputs.dir }} key: ${{ runner.os }}-pip-${{ hashFiles('**/setup.py') }} @@ -75,9 +78,26 @@ INSTALL_TIMELORD - name: Test TEST_NAME code with pytest run: | . ./activate - ./venv/bin/py.test TEST_DIR -s -v --durations 0PYTEST_PARALLEL_ARGS -m "not benchmark" + venv/bin/coverage run --rcfile=.coveragerc ./venv/bin/py.test TEST_DIR -s -v --durations 0PYTEST_PARALLEL_ARGS -m "not benchmark" DISABLE_PYTEST_MONITOR + + - name: Process coverage data + run: | + venv/bin/coverage combine --rcfile=.coveragerc .coverage.* + venv/bin/coverage xml --rcfile=.coveragerc -o coverage.xml + mkdir coverage_reports + cp .coverage "coverage_reports/.coverage.${{ env.JOB_FILE_NAME }}" + cp coverage.xml "coverage_reports/coverage.${{ env.JOB_FILE_NAME }}.xml" + venv/bin/coverage report --rcfile=.coveragerc --show-missing + + - name: Publish coverage + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage_reports/* + if-no-files-found: error CHECK_RESOURCE_USAGE + # # THIS FILE IS GENERATED. SEE https://github.com/Chia-Network/chia-blockchain/tree/main/tests#readme # diff --git a/tests/runner_templates/check-resource-usage.include.yml b/tests/runner_templates/check-resource-usage.include.yml new file mode 100644 index 0000000000..ee33af3aa5 --- /dev/null +++ b/tests/runner_templates/check-resource-usage.include.yml @@ -0,0 +1,4 @@ + - name: Check resource usage + run: | + sqlite3 -readonly -separator " " .pymon "select item,cpu_usage,total_time,mem_usage from TEST_METRICS order by mem_usage desc;" >metrics.out + ./tests/check_pytest_monitor_output.py aiosqlite.Connection: + def sql_trace_callback(req: str): + timestamp = datetime.now().strftime("%H:%M:%S.%f") + sys.stdout.write(timestamp + " " + name + " " + req + "\n") + + # uncomment this to debug sqlite interactions + # await c.set_trace_callback(sql_trace_callback) + return c class DBConnection: - def __init__(self, db_version): + def __init__(self, db_version: int) -> None: self.db_version = db_version - async def __aenter__(self) -> DBWrapper: + async def __aenter__(self) -> DBWrapper2: self.db_path = Path(tempfile.NamedTemporaryFile().name) if self.db_path.exists(): self.db_path.unlink() - self.connection = await aiosqlite.connect(self.db_path) - return DBWrapper(self.connection, self.db_version) + connection = await aiosqlite.connect(self.db_path) + self._db_wrapper = DBWrapper2(await log_conn(connection, "writer"), self.db_version) - async def __aexit__(self, exc_t, exc_v, exc_tb): - await self.connection.close() + for i in range(4): + await self._db_wrapper.add_connection(await log_conn(await aiosqlite.connect(self.db_path), f"reader-{i}")) + return self._db_wrapper + + async def __aexit__(self, exc_t, exc_v, exc_tb) -> None: + await self._db_wrapper.close() self.db_path.unlink() diff --git a/tests/util/gen_ssl_certs.py b/tests/util/gen_ssl_certs.py new file mode 100644 index 0000000000..753114414c --- /dev/null +++ b/tests/util/gen_ssl_certs.py @@ -0,0 +1,113 @@ +from pathlib import Path +from typing import Optional + +import click +from pytest import MonkeyPatch + +from chia.ssl.create_ssl import generate_ca_signed_cert, get_chia_ca_crt_key, make_ca_cert + +# NOTE: This is a standalone tool that can be used to generate a CA cert/key as well as node certs/keys. + + +@click.command() +@click.option( + "--suffix", + type=str, + default="", + help="Suffix to append to the generated cert/key symbols.", + required=True, +) +def gen_ssl(suffix: str = "") -> None: + captured_crt: Optional[bytes] = None + captured_key: Optional[bytes] = None + capture_cert_and_key = False + + def patched_write_ssl_cert_and_key(cert_path: Path, cert_data: bytes, key_path: Path, key_data: bytes) -> None: + nonlocal capture_cert_and_key, captured_crt, captured_key + + if capture_cert_and_key: + captured_crt = cert_data + captured_key = key_data + + print(f"{cert_path} = b\"\"\"{cert_data.decode(encoding='utf8')}\"\"\"") + print() + print(f"{key_path} = b\"\"\"{key_data.decode(encoding='utf8')}\"\"\"") + print() + + patch = MonkeyPatch() + patch.setattr("chia.ssl.create_ssl.write_ssl_cert_and_key", patched_write_ssl_cert_and_key) + + private_ca_crt: Optional[bytes] = None + private_ca_key: Optional[bytes] = None + capture_cert_and_key = True + + print("from typing import Dict, Tuple") + print() + + make_ca_cert(Path("SSL_TEST_PRIVATE_CA_CRT"), Path("SSL_TEST_PRIVATE_CA_KEY")) + + capture_cert_and_key = False + private_ca_crt = captured_crt + private_ca_key = captured_key + + node_certs_and_keys = { + "full_node": { + "private": {"crt": "SSL_TEST_FULLNODE_PRIVATE_CRT", "key": "SSL_TEST_FULLNODE_PRIVATE_KEY"}, + "public": {"crt": "SSL_TEST_FULLNODE_PUBLIC_CRT", "key": "SSL_TEST_FULLNODE_PUBLIC_KEY"}, + }, + "wallet": { + "private": {"crt": "SSL_TEST_WALLET_PRIVATE_CRT", "key": "SSL_TEST_WALLET_PRIVATE_KEY"}, + "public": {"crt": "SSL_TEST_WALLET_PUBLIC_CRT", "key": "SSL_TEST_WALLET_PUBLIC_KEY"}, + }, + "farmer": { + "private": {"crt": "SSL_TEST_FARMER_PRIVATE_CRT", "key": "SSL_TEST_FARMER_PRIVATE_KEY"}, + "public": {"crt": "SSL_TEST_FARMER_PUBLIC_CRT", "key": "SSL_TEST_FARMER_PUBLIC_KEY"}, + }, + "harvester": {"private": {"crt": "SSL_TEST_HARVESTER_PRIVATE_CRT", "key": "SSL_TEST_HARVESTER_PRIVATE_KEY"}}, + "timelord": { + "private": {"crt": "SSL_TEST_TIMELORD_PRIVATE_CRT", "key": "SSL_TEST_TIMELORD_PRIVATE_KEY"}, + "public": {"crt": "SSL_TEST_TIMELORD_PUBLIC_CRT", "key": "SSL_TEST_TIMELORD_PUBLIC_KEY"}, + }, + "crawler": {"private": {"crt": "SSL_TEST_CRAWLER_PRIVATE_CRT", "key": "SSL_TEST_CRAWLER_PRIVATE_KEY"}}, + "daemon": {"private": {"crt": "SSL_TEST_DAEMON_PRIVATE_CRT", "key": "SSL_TEST_DAEMON_PRIVATE_KEY"}}, + "introducer": { + "public": {"crt": "SSL_TEST_INTRODUCER_PUBLIC_CRT", "key": "SSL_TEST_INTRODUCER_PUBLIC_KEY"}, + }, + } + + chia_ca_crt, chia_ca_key = get_chia_ca_crt_key() + + for node_name, cert_type_dict in node_certs_and_keys.items(): + for cert_type, cert_dict in cert_type_dict.items(): + crt = cert_dict["crt"] + key = cert_dict["key"] + ca_crt = chia_ca_crt if cert_type == "public" else private_ca_crt + ca_key = chia_ca_key if cert_type == "public" else private_ca_key + + generate_ca_signed_cert(ca_crt, ca_key, Path(crt), Path(key)) + + patch.undo() + + append_str = "" if suffix == "" else f"_{suffix}" + print( + f"SSL_TEST_PRIVATE_CA_CERT_AND_KEY{append_str}: Tuple[bytes, bytes] = " + "(SSL_TEST_PRIVATE_CA_CRT, SSL_TEST_PRIVATE_CA_KEY)" + ) + print() + print(f"SSL_TEST_NODE_CERTS_AND_KEYS{append_str}: Dict[str, Dict[str, Dict[str, bytes]]] = {{") + for node_name, cert_type_dict in node_certs_and_keys.items(): + print(f' "{node_name}": {{') + for cert_type, cert_dict in cert_type_dict.items(): + crt = cert_dict["crt"] + key = cert_dict["key"] + print(f' "{cert_type}": {{"crt": {crt}, "key": {key}}},') + print(" },") + print("}") + + +def main() -> None: + gen_ssl() + + +if __name__ == "__main__": + main() diff --git a/tests/util/network_protocol_data.py b/tests/util/network_protocol_data.py index ae053e9428..8d8c818ec3 100644 --- a/tests/util/network_protocol_data.py +++ b/tests/util/network_protocol_data.py @@ -488,12 +488,8 @@ request_puzzle_solution = wallet_protocol.RequestPuzzleSolution( uint32(3905474497), ) -program = Program.from_serialized_program( - SerializedProgram.from_bytes( - bytes.fromhex( - "ff01ffff33ffa0f8912302fb33b8188046662785704afc3dd945074e4b45499a7173946e044695ff8203e880ffff33ffa03eaa52e850322dbc281c6b922e9d8819c7b4120ee054c4aa79db50be516a2bcaff8207d08080" - ) - ), +program = Program.fromhex( + "ff01ffff33ffa0f8912302fb33b8188046662785704afc3dd945074e4b45499a7173946e044695ff8203e880ffff33ffa03eaa52e850322dbc281c6b922e9d8819c7b4120ee054c4aa79db50be516a2bcaff8207d08080" ) puzzle_solution_response = wallet_protocol.PuzzleSolutionResponse( diff --git a/tests/util/ssl_certs.py b/tests/util/ssl_certs.py new file mode 100644 index 0000000000..3f36372729 --- /dev/null +++ b/tests/util/ssl_certs.py @@ -0,0 +1,57 @@ +import itertools +from typing import Dict, List, Tuple + +from tests.util.ssl_certs_1 import SSL_TEST_NODE_CERTS_AND_KEYS_1, SSL_TEST_PRIVATE_CA_CERT_AND_KEY_1 +from tests.util.ssl_certs_2 import SSL_TEST_NODE_CERTS_AND_KEYS_2, SSL_TEST_PRIVATE_CA_CERT_AND_KEY_2 +from tests.util.ssl_certs_3 import SSL_TEST_NODE_CERTS_AND_KEYS_3, SSL_TEST_PRIVATE_CA_CERT_AND_KEY_3 +from tests.util.ssl_certs_4 import SSL_TEST_NODE_CERTS_AND_KEYS_4, SSL_TEST_PRIVATE_CA_CERT_AND_KEY_4 +from tests.util.ssl_certs_5 import SSL_TEST_NODE_CERTS_AND_KEYS_5, SSL_TEST_PRIVATE_CA_CERT_AND_KEY_5 +from tests.util.ssl_certs_6 import SSL_TEST_NODE_CERTS_AND_KEYS_6, SSL_TEST_PRIVATE_CA_CERT_AND_KEY_6 +from tests.util.ssl_certs_7 import SSL_TEST_NODE_CERTS_AND_KEYS_7, SSL_TEST_PRIVATE_CA_CERT_AND_KEY_7 + +# --------------------------------------------------------------------------- +# Private CA certs/keys +# --------------------------------------------------------------------------- + +SSL_TEST_PRIVATE_CA_CERTS_AND_KEYS: List[Tuple[bytes, bytes]] = [ + SSL_TEST_PRIVATE_CA_CERT_AND_KEY_1, + SSL_TEST_PRIVATE_CA_CERT_AND_KEY_2, + SSL_TEST_PRIVATE_CA_CERT_AND_KEY_3, + SSL_TEST_PRIVATE_CA_CERT_AND_KEY_4, + SSL_TEST_PRIVATE_CA_CERT_AND_KEY_5, + SSL_TEST_PRIVATE_CA_CERT_AND_KEY_6, + SSL_TEST_PRIVATE_CA_CERT_AND_KEY_7, +] + +# --------------------------------------------------------------------------- +# Node -> cert/key mappings +# --------------------------------------------------------------------------- + +SSL_TEST_NODE_CERTS_AND_KEYS: List[Dict[str, Dict[str, Dict[str, bytes]]]] = [ + SSL_TEST_NODE_CERTS_AND_KEYS_1, + SSL_TEST_NODE_CERTS_AND_KEYS_2, + SSL_TEST_NODE_CERTS_AND_KEYS_3, + SSL_TEST_NODE_CERTS_AND_KEYS_4, + SSL_TEST_NODE_CERTS_AND_KEYS_5, + SSL_TEST_NODE_CERTS_AND_KEYS_6, + SSL_TEST_NODE_CERTS_AND_KEYS_7, +] + + +ssl_test_private_ca_certs_and_keys_gen = ( + SSL_TEST_PRIVATE_CA_CERTS_AND_KEYS[idx] + for idx in itertools.cycle([*range(len(SSL_TEST_PRIVATE_CA_CERTS_AND_KEYS))]) +) + + +def get_next_private_ca_cert_and_key() -> Tuple[bytes, bytes]: + return next(ssl_test_private_ca_certs_and_keys_gen) # type: ignore[no-any-return] + + +ssl_test_certs_and_keys_gen = ( + SSL_TEST_NODE_CERTS_AND_KEYS[idx] for idx in itertools.cycle([*range(len(SSL_TEST_NODE_CERTS_AND_KEYS))]) +) + + +def get_next_nodes_certs_and_keys() -> Dict[str, Dict[str, Dict[str, bytes]]]: + return next(ssl_test_certs_and_keys_gen) diff --git a/tests/util/ssl_certs_1.py b/tests/util/ssl_certs_1.py new file mode 100644 index 0000000000..0c2c899fdf --- /dev/null +++ b/tests/util/ssl_certs_1.py @@ -0,0 +1,684 @@ +from typing import Dict, Tuple + +SSL_TEST_PRIVATE_CA_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDKTCCAhGgAwIBAgIUZnoqyaLGQMl08azdwpafGGfEGR0wDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMB4XDTIyMDMyMzE3MjkyMFoXDTMyMDMy +MDE3MjkyMFowRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8G +A1UECwwYT3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAmal1SzZpSVae9RShUcN1MjM/B8rJD47K0c49Uxj/YUD7 +oGuSKWpYw/nM7aylODTqfJt660KN+Q5AeiZemKZ+YfbiQJ+1YUZazTcjoqOghXFl +E70KM6xyOiTr1SBSS1zf161BHPvTmbBQpkqsUStSZISBKaqU4lhJnBsllei8eFFN +mHEO+bgGQbTnjVWwHS+xgdajMiemK+Cql+pIpaoduTTtNyfwp9m2wF45EUT4DyUu +cU8En3NOOrarkPPG7x+FEANo0/UrqJwozY91Qsv6EPkhFUbBvF8l/p7uNCK0CIBK +yTOoPkeHvEeWX+LZlbICpdJQXIdiZJAqIu56yOPqAQIDAQABoxMwETAPBgNVHRMB +Af8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBiRATAkJaW55BPdZ6TKMYfSFlJ +9lO3K0eS6miuX6HG7OI6DHCBf18fjDLxg7O/HeVxSgI5txB4iEulRBcv35veDti+ +R6PuebE1+g0QTMlw0WXlRMg+6bVaV2XwXoWQhhSnDexdQtcDPKd4xC6VGfK3sPjQ +ZSriMmrerVhGL9d1pYBtxolDbk9e/AwrnWKLPUDrR8W5DA+yJ/lL+k5pPrACNR82 +cljDU3YA+bE+9LpNtfatPZwceaM7GupXJy9lngwlNAM42XFvWsTjH8Uy7ZJFOi0B ++3rLUOIXxCdpb88qeUGBN6BAUMhItoflSktN813vgKkiV7I0gNoU3XnUqG7w +-----END CERTIFICATE----- +""" + +SSL_TEST_PRIVATE_CA_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEAmal1SzZpSVae9RShUcN1MjM/B8rJD47K0c49Uxj/YUD7oGuS +KWpYw/nM7aylODTqfJt660KN+Q5AeiZemKZ+YfbiQJ+1YUZazTcjoqOghXFlE70K +M6xyOiTr1SBSS1zf161BHPvTmbBQpkqsUStSZISBKaqU4lhJnBsllei8eFFNmHEO ++bgGQbTnjVWwHS+xgdajMiemK+Cql+pIpaoduTTtNyfwp9m2wF45EUT4DyUucU8E +n3NOOrarkPPG7x+FEANo0/UrqJwozY91Qsv6EPkhFUbBvF8l/p7uNCK0CIBKyTOo +PkeHvEeWX+LZlbICpdJQXIdiZJAqIu56yOPqAQIDAQABAoIBABWbvuLUw/mMNM5C +GG1nDxQAINz3p06Ixfy7A+Srnz4N5VSpy+QHEHR+rFK/9Hvy9QaQ1rg+o7hiSK7k +tmjBAQTFswtjah5DxoEVP+2fFPOu/ofIDac2mNmUV5Wg9fGjHdc2hfGNeDQklzLL +TXAcp3l7KK6zTjyGLdPF/YMXN2mzzWa5Z/D66q9xXAIZnY0ggj4wJ2oOJvbq5Vec +1/NaXZcKZ6uS8a7AJ94133ItmxeBxJASgy+yF2T1YPOq0lK7OpU4qrG66iHAtB+z +LKao6dXiYZG5uuJ1j30Gk2V/QkT+NJSDnNcliK5pmmjUKHrDi8ow9m+dl7AjQTlj +CBw7AAECgYEAzH17mJR2/eO5MHGhz53QI+R9fcb7DiDT7o3M/rj8VK+sk5o5hqQn +D+5Ryy9H3UVTeXwDIayM23cpEmJFCBZ4cRnz+T11ZZ6P9RMIbfPxO6ooLFciHyHj +MGvOGdH14Mj9asBa8pSthlPNF9zHQ2OuoS4VBclPrmiQFGRfQBcq/FECgYEAwF5T +Rv7z0dttLMo2jaTCroorqD8FApGqK/hGol0PF6ozDXJqC77CBfocfoxK9VAg7Vn9 +IRwWQFiIGdHpPuoN0bn4U75X43cUe7eodpck88Sy+KDwurWVPQ6ltO/hDcvxRqAs +rAfCAqG/lRx7Gx08Fmtim3KpRyiV0yvGTH4UlrECgYEAqgouHFJYIAacl4vl4Z54 +1V/Keixb1wO1N0jyjV2FdWYfOx2jeDJHyReDLFHEkFp1by+P6xBwkI4luQO+I1uM +C4BpP3e7hySy0DdjawrOLa7weO57kSe8oycB2racnq6DC6Gn/s9i+6/ze0Q67e6V +57FKCeW8PGr2Y/6StdiOBgECgYEAoNo+qE7nccMZNyqfEzGB2JCQkM6hUdSbhsjD +x2ApDpCyv7u8ELYhZv4MdYS56QZnghCNKPJjaMqeg3iSoJj1lTj7/Ipc00bvScP4 +ibE4pN0FCgEJShYsBDILPZCXjwHJblThBbg28hxuJjD6f2GirNx+R51JDsdRAJLJ +7Yw/iwECgYEAqNgShZvjTVsFz1hRKTPfJbhJZseqquN+xypJMZyoYJHNF5Urk5YE +ByHQAzAIcMYzsSvqGQbDK22UVP/I3aqcz9JAf1sl6pr+KGRPeIumVOPssKMIhP+x +ivPcyK9bCjrJiirx+TSiRy1698pdp+dDwFhcaHRBFf6FJgxwFHgM9Gw= +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_FULLNODE_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUT5GDbvyrLH9Vkb7sFWPi1uFfhnEwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyMFoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC8vFVDrrbPlVphmwXld9chzAuCt6cUwFYBTxaIW01Ex5Ft +sJvGti6ve5BFx+B+wwA19Y1t6QOOnOn56x0Phm5/NqYidqYCBcrrHK28OH3kBhiO +NZiJi+tybGhxg2kjZldPBmoVA2r9MU1qA0PrRpozYi1mH8W2f/7yCstAHaYxZcjn +T70KkjWc7jMpV2g/6wLUaKJEgryQWqMr1Ru6BR2Q7IVIe688ptO53JRutPj/Fh6t +J9jWyF7b0EwoYc0Un2lRrzYgGQ0gGXGJCax3pWjZAokvVG5PQEPqK9TXqWVj/J+c +aA9jPEQcfivNW0nU8LmKHZyOaG/q39Y1wd9EhfOtAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQAvyyCobTP0LbxqcCcNhY+3 +/GPpUfYgjZdRy4uRtSLjcY3v604Azyuv07rMlT8qkvyYTuTzGXqpqVN1XJnllklH +psdkdA4uhlzx2ewhZw6usGV8QZEcOl6kMUeZK7TDMRkE10EnH2Qzg7R24coy9cEr +anGHgti6QrTK62aNT7aBGIDmteI3BRXc8Pb3BClDKLPpOC8DwRPD7nmQ/0awF3nN +B7caCwX4NCUuL1/Kbpz5Nt8wZepCcnXwF8BrSsiBFoUI01tGTm4BQVc1mufCmAlX +G8mCVW2JuymC6yia/bAUbvFhowbUrX55/z8SVEKQTLRQK2CglORjOTko0UbUcgN+ +-----END CERTIFICATE----- +""" + +SSL_TEST_FULLNODE_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAvLxVQ662z5VaYZsF5XfXIcwLgrenFMBWAU8WiFtNRMeRbbCb +xrYur3uQRcfgfsMANfWNbekDjpzp+esdD4ZufzamInamAgXK6xytvDh95AYYjjWY +iYvrcmxocYNpI2ZXTwZqFQNq/TFNagND60aaM2ItZh/Ftn/+8grLQB2mMWXI50+9 +CpI1nO4zKVdoP+sC1GiiRIK8kFqjK9UbugUdkOyFSHuvPKbTudyUbrT4/xYerSfY +1she29BMKGHNFJ9pUa82IBkNIBlxiQmsd6Vo2QKJL1RuT0BD6ivU16llY/yfnGgP +YzxEHH4rzVtJ1PC5ih2cjmhv6t/WNcHfRIXzrQIDAQABAoIBAFnEbf2CJPs4u0M/ +W5+Xz2AIz9S9ix+Il5+JwVrbqjWzgg0c+gqabjwS1j0KY1GHaBtCDqGfOYzkPzka +RbkzpGynTn+H1U+S97+55Txn1iDVcWp6PXH2deb3fvm2mhQ3QgGZOG2EMaf5giuR +IAXQj9kusg8nv38dA+KVlbSKJZjKUXVYrlpixfpzz9Z/CuhouRundF/yNBVbSnzR +v70ywjVGykf0YD6y5ZDW3BRAg7lRJ/fF1bK3L/sbLj4BugMs9gjt+cMRcusJdoP6 +nWk5Z6Mo5VdZspb351EcpNs1AbTb40MaqNQuNg9jIgs9rZd5ZOMR0a77QufSMzML +qNFBQqECgYEA9AmL1/goSocUEUYRiioMrMkm0OA5/xwrpp8lcOYUVAhL2VD+lFNa +V4htxyUOuE1czQPXSmfioxQrbfHm0uxPMYUDWygdc/zyOlRbvMqmgimNFqRBiGh/ +85NuYMSf6AOe7i+hwqZu/ZLDlzA7mEQG0csVLkPphe5HEBu0d5Wu1LUCgYEAxfzM +0xXeyocyuJblLOQxSfnwonG9d8F4hEO42lCEEDh8zVIk23vJ5E72YPwuiRU49Zrp +PoKiM9TjzsmnQIRany7BmNjtuhlvMirwIte0Helc0ks4IpzjymWSl12msOE4Jssl +6cy3xcX+E+JE8rVcrxDu2aAOiBC1fmLLQJlhNhkCgYAzbWuWCMrc4dh9x2lc132y +T/WpIQe31kTwqSsnvqTcDJ+HXYU41tP8DFkuFYYjmtIKtluBZ6EgQtjgI5FEM96A +jgpmBG8oiU62sh5fC8nJNl5wPg89YuBMAW7KX8VfDJxKj6kkLxTGxU4Ip3Z3oSZa +wdRl2pP00IETSPNgHCAq3QKBgFWw1cHirFvB6k0EWkp0tXSMLf9Q9S042n18hixP +Pul6WWHQVM1+JWKgXniZjVadjdqXYq5Agg2m7bZZhv8gicxtwzLxaOrsCTmQZgDe +lUGA+EC4d6JbfyfhkHHdAcF6qP/5Wv53MW7zA8X9X9QgdO38iTQ91yxC9xqtjcT2 +3aE5AoGBAJ7clDveQugUC+OoXgru0emb3sXRk8kXDqUTjUlsjU1m4f3D8ZIx7+E6 +4xVBExXHddMx9QYiJ5uVkcNB6UxhppqlsJPoKyj8dvDTYeC98Zm/TFl0B/P4iY8D +3w/REN/c8t2oYOpy8/0kgp2szliDeQDxqiijo9LeRRmxvTWYAJMI +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_FULLNODE_PUBLIC_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUBV+nxo/NCVdtZFyXlpmq8HplFQQwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyMFoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDXf+htQ1YfVlp2jqHJ+EUmB6bhxE1tYl5i2VaZVanzjYgA +9LDKeRhvUnaOWvLkGQbyzqvnAylXHXSNe9KAZrphoxDP40Ogu4IEGatxkAKafJ0s +KKAB3QwJlnOm2NJNuH9vOirw66ihkpz6Ydg7hmdWCF7bJgG82qwzQvEtIABUxZeq +EMJHLuTlVC5fyuIyggzzU1h+ss3bleM6oqT54yxJPoZYmvy067jeLGiyPg95EP+s +nuxLFhzeW1OZHMGmniDvO0zKGr9chiXKUSgugtT3MHUndociVCmc2OQaqjmWKwGr +O0mU5+lMgP2SojC7wpItyHSfn62YTLQ5VduDd5+fAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQBeYWzDc79lXdOi2iopi50n +Hoc+91TiUr9Ubbd8lHWhidHcRYYWo1vFwM3of3eJ4rhAKPgwx9aclkryUEcZ05U9 +tzs5OrmYsgnzdoX+zJenx/7NwuMO7Oe+XBAd16/4vGgSU9vPge1Ny4zN+zA1vn2V +zVlSBuGzmJI1ugPOVK9e0XAzJNsG5/pPRB29mbWWrrmFBmHvf33+PJms19aSfKrV +lJXYQV4Q9/xt5ehTPo20HF2r2CDiEjhV+P9QVRnwymuE/Zap+e1v+N+iWJVUB9hR +il4RskorFB1oY+FcNvDlsfO2bl29hGX3nNBQ0o8k1fjvuLz55MUNyGTeeqBGKkU2 +-----END CERTIFICATE----- +""" + +SSL_TEST_FULLNODE_PUBLIC_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEA13/obUNWH1Zado6hyfhFJgem4cRNbWJeYtlWmVWp842IAPSw +ynkYb1J2jlry5BkG8s6r5wMpVx10jXvSgGa6YaMQz+NDoLuCBBmrcZACmnydLCig +Ad0MCZZzptjSTbh/bzoq8OuooZKc+mHYO4ZnVghe2yYBvNqsM0LxLSAAVMWXqhDC +Ry7k5VQuX8riMoIM81NYfrLN25XjOqKk+eMsST6GWJr8tOu43ixosj4PeRD/rJ7s +SxYc3ltTmRzBpp4g7ztMyhq/XIYlylEoLoLU9zB1J3aHIlQpnNjkGqo5lisBqztJ +lOfpTID9kqIwu8KSLch0n5+tmEy0OVXbg3efnwIDAQABAoIBADq0WF+zcTmWL4yO +bFp1rHigqwBjlmgO3QF2jVW19Vconf0Mq0Bs3pAs2akL85DZlH/+duu2e8OEfaSx +L3XVBj7kygantVuK2O8/AuorvdnRyosmAfif+9B80MKJ3DhZ4zUsllgNCmIBa4v1 +rY8BnRLdsuFmKCEHPNO2D7coOY7dyIc+MHF249nKyPYMjfeyKyALqF5EcQPL/2Kp +lSaR6dJoQyMo/f+IvF3r2UCfLMWWpK2MDuLpSvAISy+GF4OtL4wBZ+R3BG8p2dw2 +tesFIVLfKYafpZiVQz6Pa1CIQvp150EFtilZwSbJByK5qyubKTOT1u4V+ANF4gii +Sfh9FxECgYEA/gjYjm28swTPlh+7s4BUSbWZMJ5FgYjFuGHaRKQbqD8kyfEIMie9 +Pu2iOaS5Ym+0Z/cI7mqmepQdfkL5NfkosHZVA0KR4P1QhrfcnXbIinfYDlPaG4Ee +syWkDYIJDawTWDMQvBnGlyAi3eO7nUJoWke5ozHg9VxRWe1NWDNqFtcCgYEA2Sq8 +3DK0H16YMztn7aKIWMS/17E11F8hZaSWiRXTNgdnTcye64Y+wLzfQaw/nLFw+rSO +qHjcTK333l90l0gKflJBePORhEZ7/5p/o3xOCdsRKH8itH+21aq/K+p4XmvodgVd +tnY93QcRid6U7e/ZDW3od6pjMLllJNUkKjJtTHkCgYA3p4x6N8R9m/I2u6ENxHGy +7FwxcJtds69No/KD00hT5fGTZIEdK+OkI7/EzTfoPvzRQifsw+TROh30CYw7rOij +MGmTm0QGfLjlquZkgR+SZospKGnCWNl2+iok43ZEToy2aAmkjCkb9uhsoHX8EA54 +qPocrNLSLnWMNBcb2bfGZQKBgGuUwm6LJ7QKlnd6zGdqhwUCos7lWPdWESNbP7+1 +ciZn0IM4BNpEbL3qUucjv3eOZ5uq6qkHBott+0bMHuP6qkgd05VphAL1L+RV0zlY +EQjM31kicjzcr+R1a7MDupF7/3LIAb6sIMVoBQY5n6mnke0XL3xoii7PCQ4QEJRe +2spxAoGBAIWBbVLqYSzFZzzmxhPdGi8tNLgj3idkVAO+Ovuwf4RLiulatJcebI5A +HAuJZY7XMzGKsrTX0ZY/j5uYuParAy0kzyBpXlh4FvxswFC+R2GiAMXXJCqXL2N9 +tbM0dgomIxudh/4gfrCUid4mNEtYALqorXhMwJLPDaGZ1KbyytSw +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_WALLET_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUXxPjAJgu/kDoq+EOobX/wSYZjW4wDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyMFoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQCzYrIdaNeAReJVfaMXpHtY1JgjpAAP3XipZfrmRj0SY4pS +zHfEDSZByX7LLwde8B2ivQHDDmmIgDhL9TZ3pZlYmk2Vq0BQHJMciaI/fzF1+FNQ +imkccmvsC+LXft3SMG61ldFszMkVWGOLdflBzBudGa7z034czq3/Ucj2mE4jEsPI +OxnFH06DBadMDtGfaiyFPvEc1Ywr+LdJQ24LVrih1IZ2dmQtS40n2K77UUsvUs3s +jNx27qISfUI/tspa8DnKujuY/9x9AIzo5ldq8N20Ccns6kXxSewsxX1vH2uNH9RP +ReReTFsZU3z8xicFx8SBE4VcRXXTTsqm974QMYJlAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQA52jQ4+CoZILaTRP3mFYpg +1OmD/bwzBsHbDZhB1co6d6lWel07fj3uNekBigyHgnciMGvXm2wSJIxEvsMoXIPh +yyBjdLb8IwaZRldnLPewUuTuA6WQx6eNwA+qEn6vT9tBVLMO0pRNXy1201c7oeCj +QCJQzn+tZweNdGuX06xgPX5q196gFS+BZDw/sn3ctQ/xCXC6gno21NRqyM2VdSCM +UIzCBQLoL9DVvpmC0atV9BO7LTvOYlEuCF58IXpBBi7P+3i1Q2z4SLamsKKcU1Pp +dJkK0lA+FfIYEGsUV09ddxGXRghU7YV0kU4iPMRs/ckin95kPiUOQx4lLo3N6u8+ +-----END CERTIFICATE----- +""" + +SSL_TEST_WALLET_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAs2KyHWjXgEXiVX2jF6R7WNSYI6QAD914qWX65kY9EmOKUsx3 +xA0mQcl+yy8HXvAdor0Bww5piIA4S/U2d6WZWJpNlatAUByTHImiP38xdfhTUIpp +HHJr7Avi137d0jButZXRbMzJFVhji3X5QcwbnRmu89N+HM6t/1HI9phOIxLDyDsZ +xR9OgwWnTA7Rn2oshT7xHNWMK/i3SUNuC1a4odSGdnZkLUuNJ9iu+1FLL1LN7Izc +du6iEn1CP7bKWvA5yro7mP/cfQCM6OZXavDdtAnJ7OpF8UnsLMV9bx9rjR/UT0Xk +XkxbGVN8/MYnBcfEgROFXEV1007Kpve+EDGCZQIDAQABAoIBAE9OfQx/g3bUbqH5 +L5eOQnIdWz22jch105ig23He77UniMneV7y3S4ieOo49tnaElbWS9ip0Prf4Z+s8 +992hus/vOAnJcl94opllR/PmmclcBgl/h8Tp2Ui8YIeBMTRx8SAaokIFr4jeUPQh +Lhem0zZ7Wlu1zvWRcl+EmuJap4DdVu3jpbddccJ00nfuw+GDgynhbJjRBmrS+2f+ +a49qfH2HSoxDEHeAJuLap4b7svvyGl1G685aDGgx/mqsHxPJXiavFYQaVY1MBUiq +NMx8NUZtxFahZIsj4ScuzOx6mVhDudMlqtfBZ0c4ae0OImWqWDRyx6kJOA++5RNE +0gLxuukCgYEA5qoghL0ZLJk8UIyBI1/XECK1DP0cbOVTPSOuYBu+9ur36BhS9XPG +Ut4M3YAYLccfvV9wqolZz3811kT1E0vqWHNgyZ7I2VWP68rW1+k+F7vZld0ThXrm +T8QbH8IFGjGwPEJ/BE2OYp6r6wAaAQ2Lr8r08b0XegZLbYX+eoX9c9MCgYEAxxax +0G6uqy67z/b5/OrP6S3/XSIGEYwCrAqHikDBX22QeTop5Medzf3MFHmxS7VOYZ0X +Tuo5oieSE5DHY8Ih6DJ1hc+8LyP2aVd144A0f5SIQFJxfIxMJCp2w/9rKgyYlwRs +RqsdJ75a3jBpo7NhwbQhr4+xKdxTUWBKNBRtpecCgYEA2tIyHzq1ExYbnd5s8/4L +rAcA8t17heLX4HxlBE/ODbhCji/lI209i4eTdN38EhGBDsnnvCCozqvDiw3H4RJ3 +soliHGNB7su4yNuYjSN8AE/4zq73wf0hWDKV+L660Gqq4b/Dd3WLygr01O83vB/5 +kD9dt6bHCr/F9pTTIbDTDHkCgYEAqbXE2gKfzrjFzN+h9mFL3mAhgQiR179cP7+y +Dr5omKpTL6PPNoCbGo+wufuKkRj6uecpiVHM01ecBCW0cmt4b/EjkW+l4SFs2ht+ +GPKezeqVww8EQsFt3p58I1PFzFB0ereAfTU8Yza3SxRF2Q/+0xp0ZK2+vgpc08+b +MY4Ach0CgYBM1qpAPFDx1fkIUc6uCr5+CJmN52djuNh5PQkBuoN4S9c98lKWXi+q +eVrsNKfDS5+92E2O4iKgWd9aCRzqxxq/0mIgT+3QLUj84SyXxlrkrV0QiU3xMrnQ +L/CjF5cbKXcixbuIlTfKwoqpRj/igThAKNtBGLKZqw0eV6uISbbDNw== +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_WALLET_PUBLIC_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUIlcBc0KB9zljlWlercBlXSmz7i8wDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyMVoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDFXFmZ+JAM+10oeWht8WutI9nkQRV2oMtCwmdJYerOQXEx +NGNAsUZAYQi7pUi3WFfKIOXcr+hwCFdCaoXG8A07kpAXnKlFYO8agYCwcyiYGx1Z +raB2UtUik/6j1/N6bluG4uMljojWRIAK5umAVALAmEHj4Qu0QSsv2Bi9cjqlPn80 +/mM0iMqXhuQ3u+ae3t8yxbI8pQ2Zt6WJV1q9idiu6JB1ZBkm1VSO2m80rVIia4JS +nK5y/psDK5xzhi2NMp6WrCAc9ll0uNEysW2c+1ZZ5K5Sx6aEuOJadDGmZwxaHBdg +EUxrKtCTFRppHmgsr/pBwwXtI1g6rHY/Zm/8SRsDAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQAn8BB5RX1ZvKsKEY+UMEEZ +7u/yoXiocrxFsRyHGgjaB3Lh4ArMsFM6I3xIbeKjojidci2d5IxWACM4V4A2MQoG +FTiX192lg0a0VgutjcylGfXQuQuC4vQux+WaShksDTYn+CKl4vSDaZIkGi6j/MNb +lqgULuMUuilLJyNPqGobz/b1jE2N6uqMD6YUJHakD4ph/oVKOcxyvlcV9jGIdOgd +UlEk/zn3PPC6CadBQ3diEm9LYoLi3QPcsLYIFRSt2YcmdvMSl/9+uLAlP2Ja7RQr +8KPvq4WWGh7S/9tblPBrPeab+Zw405qBc3RfAYuLvk4+DXA0iXIBO5yNSDpXzN3U +-----END CERTIFICATE----- +""" + +SSL_TEST_WALLET_PUBLIC_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAxVxZmfiQDPtdKHlobfFrrSPZ5EEVdqDLQsJnSWHqzkFxMTRj +QLFGQGEIu6VIt1hXyiDl3K/ocAhXQmqFxvANO5KQF5ypRWDvGoGAsHMomBsdWa2g +dlLVIpP+o9fzem5bhuLjJY6I1kSACubpgFQCwJhB4+ELtEErL9gYvXI6pT5/NP5j +NIjKl4bkN7vmnt7fMsWyPKUNmbeliVdavYnYruiQdWQZJtVUjtpvNK1SImuCUpyu +cv6bAyucc4YtjTKelqwgHPZZdLjRMrFtnPtWWeSuUsemhLjiWnQxpmcMWhwXYBFM +ayrQkxUaaR5oLK/6QcMF7SNYOqx2P2Zv/EkbAwIDAQABAoIBAQCNG2cwz+fmcD39 +9zf0C31qEEz0hpga9gH93FLOw8SG7YFJpeQk19qbowUEbLtd4zr5WKYgMGEm4L/K +y7CUOQOtCTAewbLA2Pp7YAYrolpuzkwg1yP4FWcvztJsQLVjXs3v1f6D1rH9SIKn +yMtAJlDFdNb/X+LnYQTIs1+U67wEcjONZqCEjVedUvQr1ciraOKIwPRuMZK4rSjC +dJbIeD4LOyafv3SKVptaWfP24tGBLHCYcTbMDnyDNfdRvLtUK9d/9u/Wgmrjm6mP +bemtc7gnhvZ6nWySVSvzpo8V+VtVJL5ypsUcs8csOfZJpzuRput2BOYC2ffSv96q +1aHdEWfpAoGBAP/sbXcDOa9G8DmiE27FTTuOB5//ZPooJI1xTa7dnt5xNGzisGWN +ZX4U5JxgaVXR3uE8PlSdTQP5wgJV8b5bFRY3cnpAt4EgH7FcktvxeQUzDjzn/IsX +B1xO+facsl7Ssk84QWciS1w+oHteVEmZGYbHrUyk5HBbBSvnmE+LS3TPAoGBAMVr +cZRRW7cjnxPLiIEb/YJwUtmz7rFx2TFp3f1tT7Q4F3cFpYtS9phTG62NlLSmnttE +okmRkZI4PKmSvinnUe8sRrvgIlF7Xn1p3q891BiFmw+bj305qUAbwXV0mdFkxk6r +IqmWsGo6Xe8tKDnP9h7gQShqTKXnfV4B6xyj9SuNAoGBAJPvG7uOzrpl3BjEek0u +mZ1SVVAENl9v8ukb1Ja/HsVgVLiYNPUOzdsawqcuB9WG0joKM9F/d/RTW/UzruCl +D8Re2rqWTDzEz+0bIP0oURdTUuicBNx1vFh8gnsuSuELE+09DHlMVpmEzgliFoDQ +kfPZ2nASZMYZpxyg6+cXEs/7AoGAfNfpR4X7neDk5Du94we0VRx7CDkFJSl91AXC +4FSUJr+h9x6XBXg9gS5tPl9ePq9vnfHVPvjTOchedE3b+9vQsJMrV/vxN93wbxbY +P7G1wpwa5s/U+bfRFD15JbHK4+P6lB0dGmm0vjiS1oGUAptEZVojWk9+kRvG6AAG +kmIM1LECgYB7Gfaz9h0a7mbyiiMd7gXjYV760/7sgoJhmeg353FrKGxfRyowndXu +O8I4aDwSbCqtLu/Q2XOZoW+jchmvHqs/Kg9PWait7lb8bWcAxhcuC0d76OpCyp5y +S/qbLTKwRiskQR68jBd7K4TM0vYLiyc3GUEhaCUXGHPNoKtvZQyVXg== +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_FARMER_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUH4ybLZJDdYBBZEXa7rRC0r1WLYUwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyMVoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQCr67MRDiKgPiH15yQ6ZJeEcghZEoYXb98sCwHKTk7cDMp+ +9Q92IP761jOmqXn1BTXNZQc62a1kZ0yIBUdqCxH5R3+BGF31fDwK0VPQhSh7Np85 +iv3SHlrJBmNF+JX6A+aiKf0f6Zaq0pK1NiTaY7mfXMynSVdxJwwTgqQR0qfvqXEm +XWBeARhXpUelIyUexXHrGpXumAWY4wn1YEW+SpcGNXElidd/HLbJ/OHkCExd0nge +yKDQBabCAiIb6fm0wmL6HcD++mqsEt9II8U1qoUPfpUWxFpUSWBoZWcATqrPIPYu +LeHPvl3ZctQCuTthWHvum1zRK3G8YUXcTWwWsNBHAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQAb3eNfxvPPv3QjmDEIcOhv +fyGS8orMzygz0eCtX0ODKsIWEBZw7bSym6fhEYvkltSf41KkeBInjDJnqiCJ2Yef +VvXcGLyHw/klmkafcvcVCoa95TNTuKb9ElJbdIuoQ3EWk4uQEK0ARH4K+mXA5lzh +RVbG9EWvmdYXaG9BrnX9Hr/lCEPXynGtbgKvglpFn8mAWz2ru44BsrkiZgMFBpPF +R6VJV3SRCTib0nsYXkLXyRgG5JcH/VPpFfyS+sLi/98AIG2mTWXTpj4dT5f9epTr +Cn00kytB4+9ZUvCMUrg0BciQkCz6lr46gcOwbMpzoxXWnK+cwPcr9zu+LLEs1NiZ +-----END CERTIFICATE----- +""" + +SSL_TEST_FARMER_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEAq+uzEQ4ioD4h9eckOmSXhHIIWRKGF2/fLAsByk5O3AzKfvUP +diD++tYzpql59QU1zWUHOtmtZGdMiAVHagsR+Ud/gRhd9Xw8CtFT0IUoezafOYr9 +0h5ayQZjRfiV+gPmoin9H+mWqtKStTYk2mO5n1zMp0lXcScME4KkEdKn76lxJl1g +XgEYV6VHpSMlHsVx6xqV7pgFmOMJ9WBFvkqXBjVxJYnXfxy2yfzh5AhMXdJ4Hsig +0AWmwgIiG+n5tMJi+h3A/vpqrBLfSCPFNaqFD36VFsRaVElgaGVnAE6qzyD2Li3h +z75d2XLUArk7YVh77ptc0StxvGFF3E1sFrDQRwIDAQABAoIBAHmFHQmNKESEJpUe +UKlFuSPRRr1PLqEaXnFPRnCtcWhxUiDzL36cTB8ZkWDYom/iwujv5HBgtQMnUR1E +Pfpi4M2HEEU76A5BRl+PHuNhe/+72EhgSpFfC2TUsw8ea0RRxZAShe0su2b7eN/F +6b7EhsxyV+ZXHQvKQer4iOhgMnxf68BuYpL4eyYfPlKFlSN1YcBCpuh+BPBuVdqV +JSHBumr4SBHFrG/Gn+IpzAJ3EyB7idTYn3jzr/iXqtwjhSI+9Hmh8rs4ctBElrxO +of57t3uPO2Z12cQtMN29kJTplXud6AJBacM1AWlY3jbUcAYlqQtyFGNlWwqjUdP+ +zXyAtoECgYEA3EXfLDNnulR4so5Ab6rYhxRmb2c+5He7BNc1fCri5U/bE7GPh0Ew +uHDLa3mc3XrHEwd6B1DpnzpiV8a7Lb9U32xPYoX73753a5RaLxr/yrZZZyuirtTE +vKdyOVufoOzD53XDvlUtkDwYLywFKpiIVp++wsf7BeKuuJ7oHpPuwfcCgYEAx84n +7sr6MsKizGMELYtjIQ24pHdzDQW6Uk3U2BU2glvzNJ0KIOgdYN3nQ/4LBhENgRL1 ++mtDgQ/+NF9Q4DgpriAQCp8Kth4hosgHOZZ9mbPwMvL40XxXOtk1POHWN8SXWdU1 +tHw69yMk4vS1IgjGsG6QvNfoNlscNjzW7/GD0DECgYAjmadYHXbGRqC7OwJvCc21 +BzcHCki/5Bn1zlJ2nvfM1/swU6I+2epl5NT7qcwQf6dtC+hNBma7tVPvm87kteeh +tH+gDMeIgeALIw7wTgzJVm9cnVDNsNWbJ/TuEEDcYWfIIOBiAqI6jXvbI+Ix4DUo +yuip0mhfqyNR81zQlFgiQQKBgEs3KUM0d/Fp4d0tHSKECWIlBzAqo03wrQ5UrF5X +xfhW4vwYbfqrRnvzrR6kYMP84WeImr6VaIkKWzid9RUjL1WUTlWhP2gFecYMpOOh +6lBVM4QKgW5i73eA0xDDN2AxCoTPxXLXHV9xhG5HjnRsd1dtl+DvKkRkEf+88XDM +K0HRAoGAIOufId2qbyFGxWld5DpWTb2RPt7ghbxYK6SNXk5mzKOdKA6c5La9evDF +btn0mfIQf/4qftgACHTYcx/IYtOHzl83rLvuP0YE7+8ErU8TCUta1lAOIBqm/WO2 +RjFbl5GxJxthIxT0CK3BEj8rSuwk9pXsnawEPN9/Ca0BuseIy5o= +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_FARMER_PUBLIC_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUQv7oQqnVOgMJxwGj1o9mVlDjSV8wDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyMVoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDWc6RPgLnigv9641Ig8ro/KxVnUM3ORHs2hgp9Cj4lljnn +3Pl1IOlZu4pI8nQ0MGNVaiRTH5iqi1PmxfngFSsCAKjLFjty/Av2HpFiuYXQPxrC +suMPbF+KTpxi0QyxM/04inX9sZZpAPXbRtJ7XuFq71jB1mHvvyq/7/0mzTMwdUnX +LRfTMSN8TKVc+x0nGaQynIQbFxW2UcWLShaeNpfk0++2MeHOqrJo1LRta3uN8MBT +tdd7ISMv85gbwBajJ833BeE5/hxbDuohWnN6NOko+lKf+iaiVZG6LIqg4YLO8nEC +3eCtPSqZDeMcojF2TpfAs7RYy/uPTnrurq1I3M1VAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQBQPItY6FjeAmX7cpd0BPdo +lWYb1yYOUVdVkHV5S160tGhLCcipZF511IOvjH+UUh/YVRUPyAhb+tCURTxWMAmz +xKiMESk5uJWoxWKZYOTkEE1SzTHdOLIO4gVz+z5ewovgSHOQ6R95AtCCeFNf+G8K +JZux2BbxkHZTiUK21UiarheTIOvdwn4W3NaGnDaxgIQncptLlLUSHKcc5FbLNhU9 +4dlPe/VMglwI6R7euYFBdcJCpAnyhkeGGiEGZMPgu7oG8AY/PnbiAq4EFQa5rwB9 +KtZGtuEvHhChxuCJrdhS3arkhq7qNPQc2iYRUeAnzK+CqVMMP+j9SqJA47YEoLKN +-----END CERTIFICATE----- +""" + +SSL_TEST_FARMER_PUBLIC_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA1nOkT4C54oL/euNSIPK6PysVZ1DNzkR7NoYKfQo+JZY559z5 +dSDpWbuKSPJ0NDBjVWokUx+YqotT5sX54BUrAgCoyxY7cvwL9h6RYrmF0D8awrLj +D2xfik6cYtEMsTP9OIp1/bGWaQD120bSe17hau9YwdZh778qv+/9Js0zMHVJ1y0X +0zEjfEylXPsdJxmkMpyEGxcVtlHFi0oWnjaX5NPvtjHhzqqyaNS0bWt7jfDAU7XX +eyEjL/OYG8AWoyfN9wXhOf4cWw7qIVpzejTpKPpSn/omolWRuiyKoOGCzvJxAt3g +rT0qmQ3jHKIxdk6XwLO0WMv7j0567q6tSNzNVQIDAQABAoIBACsYXiKj6bb9QD3/ +xJdeb9MV4105vcH/vQr98Mmj7006XTSdEXxaOsqPh4CVSIjcWHnntJkHtnQ/P4MW +sdo4JsZmP4VgWF4JDJZPGkROp/drVwNdU4fb7W8r0P2CqRxLKE3edUugDmvXh5Cj +MNUeAgqtQpbhcBjvv7WGksbjYbAQ43UH8/zDFpSDmMbPjUHOnKoCZSFC3IfCoUPg +8U55AWBQVQnqP5E0R38PpAeTmHr80HFBPppYteCH7/OATr8/7ffv7Vd10/bVL1DP +Lqa8YZdNP2UOtKCDnbxq4CLFm9gQ2jIwhjL5c6YDVvXeOWiN5PKybhgU0yX3mQZa +UMFL/RkCgYEA+9l7oRtXt4Me1AkSLSstQlyGaMEEnYAwf6iU/HBu9dH7ZAadte2g +an9sciJUlODvcj3fK8rIewgJFY/wzdZPuCQv3fQGghrM9gXMgz8NiU1hK0AK/XI2 +zUwVJpiFXjemRly41Ss5UG1H3tHQObl6QyEeAzpJZrNENALFL6exwQ8CgYEA2fxi +BRGr3yHq9t/RsClpPlSHuE1IM1l8G1hXxrkROo83dILEsvIcHInntoJ03SPJI9NT +0Oa/XQ/Q/21xPOmjYl+b3jKBn9Yaad0l/mwoG1M+NXEniZ2/Fok3EGqu0hoaPpJ/ +ipCtnNWurA8BaSnQJD/2Fu0UnZdexlHlsr32A1sCgYBZpHSjyJa1RB+R+1ST7T1j +1Ikm+iUJZppcpgW5wM9OAhrH5K74FYe2wHo6Ocv/Xfz8ndc0wC4R1K9fFGfy7Chd +88tx5iz23FE99JxxztyjlX5Tpa0Dv0aQVldk8H7wJUCy5MgJYCQ7Y1pkjivekA1b +nYsQPQvpWT+af63uI3NaswKBgQCKMry98/cf7nP1ce6RnZ9weczVpoFItMm+2GJF +xZzLoHKK9kDYJjB2U2PIzKpkbMSfZuIzhab6zAU3et4YvRLtUioSU7jkaauzRBZL +V6yRrlO5M/TaBV1ZX0K+sLQG1a+fzeb4JUM8NCiaQqUlU/H2mWpeHI4+XvIiD1ft +2wr2EwKBgQDMM22ppSf22Cv9aw7VQW2OJHI3+22LyL7SCqQDqKGPnnDlyKtLz/sK +iQozbZbSmVHFbz0DJMNMpIWm7irD44cdpnDxxO5KDd1FJjH2Ha/RiPA6QAiJkiOT +oAFJ/tFPZF+faEhscTBdGU4yS6frDVDGJpyFgqAvTxi7H7PRrfRP6Q== +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_HARVESTER_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUCg9lMTGr9/8DyLNEaafobyIYAS0wDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyMVoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC7v3qmcCjmcREbWhZbtKpeZEwUPVkFpHg9yd0YQW0ZACZf +BZsJn5S9fkpfpJ9E758wRqvntAoKUwh0yntqjSNVEF+IwPs8eVV85yJLjZWzRlYN +FyZnr4ihtKAleDkXnSwDKKuWI3tm68GCmGlvzRvv8gR9/8Wut01JB4LjUslzaL5B +dM36gzjWGSxUD1A0gdG6leCMbJkRV6VQDLKMzMqfkrkleNZMfarrh4y2odaxGSlt +YGvIkeJg4R/vhUdWWnSCSZk8EtPZTC2ic/dMh0TZTw6zsaq0kkSf17a9HQ7exjgj +AMzTl4/O2mPQ1/j6t3nLqxXAMKRmQwe0RhW47fCzAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQBSd5/DP0a3Pi7gQeYounMW +9qa/ZCn2JyIlCSKPiQ2lRJeFLzXzG/e1hEiNtSBWS0oMi5HtyhsBSbmPeEp4Enl4 +Ri7UR4OhyEOddOAI98IEPtditV7YVczQi0h8a3/518yxvqVcUUOmIsABIvNWWtB+ +jov5sHygh2gQ9LK/9SXWxguvI4U0AiFteJvLKSFqqcUWbNXQn09fJNyM8Cx6mnTG +5pba3FCnr39CdRgzn21Zp+plodI6xu2T/VmvkBcU4jFVY/i36LJkJ0EBjcaUiE3h +/1+POQXMivBuERizoRvtIx/xmsfKaFSp26iBW0I/AkQjCAJiVS+RF4DfaHLzg8jT +-----END CERTIFICATE----- +""" + +SSL_TEST_HARVESTER_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAu796pnAo5nERG1oWW7SqXmRMFD1ZBaR4PcndGEFtGQAmXwWb +CZ+UvX5KX6SfRO+fMEar57QKClMIdMp7ao0jVRBfiMD7PHlVfOciS42Vs0ZWDRcm +Z6+IobSgJXg5F50sAyirliN7ZuvBgphpb80b7/IEff/FrrdNSQeC41LJc2i+QXTN ++oM41hksVA9QNIHRupXgjGyZEVelUAyyjMzKn5K5JXjWTH2q64eMtqHWsRkpbWBr +yJHiYOEf74VHVlp0gkmZPBLT2UwtonP3TIdE2U8Os7GqtJJEn9e2vR0O3sY4IwDM +05ePztpj0Nf4+rd5y6sVwDCkZkMHtEYVuO3wswIDAQABAoIBAEZ5IXjIMRIO7vTt +Y+cYcbrsuwH95SSRD/FhjHRGWsU/oSeZ2xBJrnNSrGgqSv59U6uzW2Ol2P73G/16 +48ijIdgURUf36FZS1RwFRoJFqyOYC0Tuo6PX59mLC3IFJqkOfi7RXVcGCpQfeoui +2jD1NL9kgPsqvvFOLNx0zVS3Bpci3L+HgQHRgSBJVjCuLnB+CF5nlb8abzh4gv5n +zE7vyx+sZNJW+qk3TN8yM7D144YxKXZpzzK0tQCjmf2m8P2L4vuJLhuoi43kFgfm +fgWUNFSfNrtSkVcYh9VEiaN0ZtpZbDgfNOixXIDq5N0whK3HoJSM0osST/C2Cz9V +uyXAwUECgYEA8FUVMek74XOXKWDrvC6wenyKXQ0xnHJy3qAvH5amO6LvnXWLr0Ex +ZbDz+BSzHBbjyY26m1z48BUS3GRY52mROVTlWJT+RMzdjEDWZdxjbCqrlCvx6mfI +ZmnAJJ2oAw2ndw8a/2vtoVAzayxz62LUOY2m1HwotXh8/RS9/0UcoXUCgYEAx/zQ +KSp6WB2MrwK+r5fLlmJtNVZEvqajjcD8g/1EggFN5QD5a/mLeoaYYREOu/mmWeJH +GSK2FnSCeiTYzcVbao3BD7u9pt/6s+ev/QpiBAxCnyKAQ7zTiVEvzvruEhLi6TBq +3rjvjzsOz0PYgNTzK01x/ZU8BIr5czcKRJ78HIcCgYEAvkiPRHpHCAUOLRvo6ZEJ +96D9qBkXK6hOHMg1J0yPB27FSyVTWIpEgyBsugIhod7Zsa5+jh45l1UIHulwnqCt +8/essssc2vpde3umhPXO3kiWmvWET7SmLbgTAqq06N35tsGF/a/FcNBgNb33depE +3+Cws1IupSflxjeTCzb8KTUCgYAqFvI0h8UiAG4Yc0pwqFDnwKVdYV+shGPNtL0w +hkBB4EZlmRPlfqq1SdiOLUndlAhHyJDQIHcUOMcxL8oVXKEFxvnH9upOUbtw26U1 +a1b/pRjsZxV5rCcVMmoOdM9gLGtnSpJjd6arjXFre8r4KllXVsBT73GnPxyK/B2E +HbXPxwKBgAkjgd/D6v8LLneuqLOYvuEwcecCuOrkkVl6S24y/Gn7hS4awojpraoj +lZk1ZlWJwEj3KYp8toy7Wpz5bvVmZT6nVDudP2uMy3BrifIK5zZ/mKZZ4JmU7WSV +R5+9lwCKYXUDvK7dVBY6M8oh8WD5F6tHAX1EV/b/PEnqRpaqsjGi +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_TIMELORD_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUZZmj3NMn41MJf/JZnA19S7GWBEcwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyMVoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDiAHh3GaeWWIKsNlwDE6s8EfKs8AKvq7ThxFGtTAbZs1MT +ckyg/7/phaihOVXmpdl9Lhul9nUxr3pFkW3pDuCXWeF/QB4pJqbbDUdOl1fu1g6z +8H3hLIKK8+yKm8SliLKGlYlm0lrCh+bR1gn46ACImMxs2PiLJydaG6TH/rnQZo8k +8S8unwpjrI09dwnwdhTGG6F3789bEHyZbwzmitHRrzYUKDviazaWvyspDNg6CJ9x ++ufdVyY3vTAVsQZaGyTZMqxE/3cLtT3CHCGZaMddlVmicEIkgKh4vCYV//6suVbW +cQnzBXYCbAC0jp+TaHFoLztoB++ODJbQ02kI6xylAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQCMUxFYqgEUN06caqVcTTZ5 +rW3V8oRETxkCZ5okxRnKKJk6L9YhdkiL4Mjsbn+9ZwmWwEZJjlqOGUC8uZZgrRjr +fqyftmYjvRVMZNZoh1wqp3kcEDXPLOqM7ixpK/D/ScOZc8G0EpiTykj4lmgF8/7t +11fCyv6vHYLqsDFNC3BJ8g8E09Zej2bEBwTXp6g52J/YCuJ2xpu9g8mOF2xs3ECv +M74JEGlF0eNjuAQ+R5J5DaNwojHDoVYMYT5X/KaPxmLLl6b6n7ZvKuCZHs1CoLFn +1Jg1JGLOczrHvHnRPr4zLqffdnq/SFQP1MLFs+QUORLpHved+PPZJogSbRn7HzGQ +-----END CERTIFICATE----- +""" + +SSL_TEST_TIMELORD_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA4gB4dxmnlliCrDZcAxOrPBHyrPACr6u04cRRrUwG2bNTE3JM +oP+/6YWooTlV5qXZfS4bpfZ1Ma96RZFt6Q7gl1nhf0AeKSam2w1HTpdX7tYOs/B9 +4SyCivPsipvEpYiyhpWJZtJawofm0dYJ+OgAiJjMbNj4iycnWhukx/650GaPJPEv +Lp8KY6yNPXcJ8HYUxhuhd+/PWxB8mW8M5orR0a82FCg74ms2lr8rKQzYOgifcfrn +3VcmN70wFbEGWhsk2TKsRP93C7U9whwhmWjHXZVZonBCJICoeLwmFf/+rLlW1nEJ +8wV2AmwAtI6fk2hxaC87aAfvjgyW0NNpCOscpQIDAQABAoIBADgCidhqgUAfe3MW +ncMdcsiWYiA980x6L3/sWZmrR99YM/ST1S3pdDR5rYsXXJSm8bm2XZ/J7s17gcAQ +BL9Hsp2P5vTUfSURsTSEm/F8TIyifE5YAbp2f3vUbAEGDbxAno4ALWdQJrIjYC8M +7rfDN66iv7cSJrbF41jPlQ0DsiVVbkmUVQmb40o5iymROxj1as8ovDFqPC2mPIux +94gpKNf0FcwN/WPhz6uqHdkD26E5lIKSHy4G0Ko0uBWyITYPDQnp+57IRsm5goz9 +8FzzKKlQOOh/MP4jondCjNbQXUMND2E/MUZoa/WH5JOthkrGnrupayQ9WSPWjmDd +Ru+DMxkCgYEA98ESR2Qaxu+LvdjLTl4c/G+I6/6pKmKpAhomWS1s5a4oz5llJZeM +3bGxQJYM5Zk9f5lhBgHtM30N4W5sX7aKgixeK+rITqneX0jE9eyH/WisI4WHOwxw +EXWuWhOK5MkctZPuruzCkaLAvhxtsmOQKhrSO5oCsBes0VK/dlglRJcCgYEA6YYQ +Suam/OckqmYlbu+N1km4AtRO6O+qbkRsDT88vH1Z/PAIIbS0XYlzhfc/jStZtUOE +k5UmEVqMeDHHHHg/ejczbNPVaTm0oWfWYH6D1UQdaQsI+AFDfYbuVc69ik9idnpb ++8yUHyI7ikjowKvf0f/4rgHmZX4B7Ga5gtVupCMCgYEA6fp/zcZfd4MhYSDOGGvP +SiP3lpDBqFLWtDKIBu5ciqkox65hlNgEZBZ9hLZw5aEMMGZk9+x33Il8w2qqlNXr +BzbplOY9V/UbGre5s1s3rv3cnAtuBDkh2YtfJpiQMrMwFtfnsXHN6wZequxkOPXI +X8tGwp0XbsBdKK7SPOzP/W8CgYEAxUSNCtjhg462+IMlaBtRVA4eNbWnmzqqXE/M +fzxGUGwL0pHqLJ78Jm/weOCufNB8DZWlrw41hD9bnkVej/w8kz+CX5JrG2K15gtT +m1wEfen2dj/uKaLXoniTaUUl9GqvIKqofYMKNWqzpVOF2wzWHA4Bwuyz9lSFx2/X +kmA+AMUCgYB4x8hb035umUb+lh3EyS06edJPZdrHV3teJAZ25RAU76OQzGzfndCS +VhgssI9LPWYXaO1vS7u9jSg56f6zNPHtpngSOZc9uySdSIIKM7pbucYmJB0Jrdhb +3HmdkTpb6wlZD/69AF6++09b3iFk67xsQCSSST1jW/66ZqLBkp57fw== +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_TIMELORD_PUBLIC_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUCo4bPbI2+6ucwAKVWOVvza/5Ve0wDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyMVoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDTrCQBeTfXl3xKstyCxQpGelFNEagDRZLaJe/dPLN9FiBq +N25JmL0mMiJfSSI1HQQoMMM0ayilEU8epeqWkWLi+Pw2aR7nuayPzlqfY411pOVy +I0lZWi/M+w+ytyHA+/ORZHqSUf3Zccs8PouexC7bU4ScLHo6X7bOSiLfezNsqPAc +RngI9C1rPLrzQQHUd1m2aQOhvMmbXfawaofZzSRZT/Ipdhm6TsTy4325XM8BtoXm +CQtEUyM8xgmOkQF/4m/N51/+7Jnchcb3pBP1RujmibOwH4fAlDwu6A5kwe1oFMaq +ql15KdElfkRvzbVDdyAVjUnW2j0WZ3WnumM0uTSbAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQBGVJ1SnI7UT7M9BSt6Sfnu +noJa96HgjVJTwMBkGIP7phGY8sm2B9OSVlaVUC6tZkJaXSPDqejdHRFleFrMn+yS +eY3apM70u+GHRIjozf6FtQQ8D9AWY3sL1eDVfoNh/w6UPaLtt0GtvLXhR9gCvPgH +WKNJ7/5hSsJHRVKBRZtuLwrU4nIwrdvcFHh9btAeNU+ZQ9BPx+jD7G0b3MC4aePg +M/mUQkCBShhQPFIuPO5B5hYmyqvSfKfRCCXz3yObo0/DmEk1XlWu5fUStUXMoBRl +JQ8AxL5aH9GLLkdhMqzInZiiEgFEEEF9OjeA0FpwG7qmRMwL0d6Mp/VfyMV3CwqT +-----END CERTIFICATE----- +""" + +SSL_TEST_TIMELORD_PUBLIC_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpgIBAAKCAQEA06wkAXk315d8SrLcgsUKRnpRTRGoA0WS2iXv3TyzfRYgajdu +SZi9JjIiX0kiNR0EKDDDNGsopRFPHqXqlpFi4vj8Nmke57msj85an2ONdaTlciNJ +WVovzPsPsrchwPvzkWR6klH92XHLPD6LnsQu21OEnCx6Ol+2zkoi33szbKjwHEZ4 +CPQtazy680EB1HdZtmkDobzJm132sGqH2c0kWU/yKXYZuk7E8uN9uVzPAbaF5gkL +RFMjPMYJjpEBf+Jvzedf/uyZ3IXG96QT9Ubo5omzsB+HwJQ8LugOZMHtaBTGqqpd +eSnRJX5Eb821Q3cgFY1J1to9Fmd1p7pjNLk0mwIDAQABAoIBAQClwrZnmP/MC0tA +TBU3KwrC6mLkkaEa/s7jmrXecPy2Ri+YPlRVuhDV6ojUSbdKFLD+sEENuaUYrxdg +jtnIk4325LjN+0BCgzrJWvXIv/M1X6521X9JQ8EPKsS+VX9PW38AKsl58E90ixJ2 +2RwJduSiySKeEo6dS/siTRhGHnrE6ZFG9QsMTKhsLU0WfQFY3h9NzmAv5hN5eOta +vVofMnOLRPeAEpvw0SzmnHf/oBs0cV/JTez/G1LB/xtG6QX2ko/DbjjtlKPr8kT+ +Jz8i2pJvh3IA4ZxJYa7PiBxLszKvDgiOvbI/P6yKAwbeB0O1YWeiEdzQwujdEpzy +0+tNlE1RAoGBAP1qNZvUBJDGCVFKLKN+MU31K63nzGETV4kDsurvxMSxhSeOJILb +aSx62dCWKyU/mrqE+uUrpAoV37Tp2rzyDeqyOSBoW/d7shsYk0Y+/oYQp3t4DB7J +g8CQdL3ihgUvONwBUcG7MW7/RyXP29Na2eASlkkRdLPlP+jG9Wlzt1qHAoGBANXU +69QRx/4g/LyYCinkgeHqNqu4VORbyd5bnfCXkPwDppV317rJuMOJjye8IQngX6G0 +fOdFXaxGWHE+w26bGI5gRvuPrG44NnD6xLfp2fFa+iUaW8qtY9z9qLK5w6RK7rGf +oMV/cxofWpSrEVQu4ZojswpgBQH+hxo+c6280bZNAoGBAOLrgVepcfEltGA7WF+K +d6IEQXm3UFc5F7BURJmF3J/5CnASI3Wd/b7bv0G9xqLTIr2UqIogGwMA9VIt+jYp +VfbsYqU3berds+35gp9rd0Ubkq3IIKpM7pK3iCIkvrfTwkmXUNt2wVxQcShVydWn +y+OPIU4KuIMCbMkHp+gmu2/vAoGBAMWw2m7wGYQbn04FCrB8cJAa53yPKP0O121a +KoT6u7Ii9eoOKEaqpMUy8kT8K1dkN0XbBfcTLG1PhAj+y9QAVA2deUKuK+6izcJa +NXELJNF9GPMgkWiqMT9ozISgNf44wME7IXo2QIYQIsB7/8NirHTDOI4JA9g6J1He +Fziy7vepAoGBAOqr2nikLpb8vBozfHmXcTx72cRHOm53L9u3UwUwnyQML0JwDNe1 +xrmKS/sKZgVk+TcjEIakfLn04wmk2ZmEPA/n2z9Xc17DQlstlC10Mg6eIga/Aw/s +ocV3tE/6LBAtsPRjqR4U7JK4so6w64zHc6vbG25YBZunSnuegy73OM/3 +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_CRAWLER_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUZXUt4iAbkAXAUd0mDEZSMXmcl3YwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyMVoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDxVh9zMP+GF0XYDAqC3vehKpK2gTXSZTdgQWn0YMOkKQFZ +NNHHkWAtePO5p7wSbysSUnurh9GlYtsK4kDnkj1eVBCWfVyPM/0cfkbhIcv5Jpkr +qKABv+6b3v1mikl+erJ2SE3GEWY7wThZuPvNh8kDAYs7MuN766jQ59wSIxvCPlpp +cObzbz21dHRrxDl8zCzNOk2z41sY12sGvtR1fWTIByqxnNy7mfa15/uEtY5qVaVz +uQBm+gYV+lRoW3sHBJz9TEH92s+VnSpZj/hHbL8kpN8y0zichH9vG17E78LcCfCR +B6fd/Civ8mZZNhH1cCGlm26w8y7qM2PnEwvsVJ/xAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQAyQKtGaSz4s/U85m3zSqTm +fykoZVo9+BhqPEK3bqiA/wQ4RnQushPEuaLqdD/qI9l6h6jKgnx3hyJ0Ht8CYo4r +KAEhRVSoImdqW8TpFIOG2vNgK09HuI0ahwT3NfmXz8uI87IkzHco+QS/i7AMvU7V +vjyFXSjWWQYmnzb7gWw/LEcpqScMB6/4UOam3G/xznMiFCmUDn9CEh/VNFaE6YK5 +9VcfE2mcOftm8/jstoOgz5a/XduxJGObE/esMf2XeLLvfhIJV5yL+AkyVUrgESeB +/SVfSH0gcu98o+jp3fT8zKF6Q53D4Uyf28HUY261pvvvZFnshprKR3Tzfjo+LcpW +-----END CERTIFICATE----- +""" + +SSL_TEST_CRAWLER_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA8VYfczD/hhdF2AwKgt73oSqStoE10mU3YEFp9GDDpCkBWTTR +x5FgLXjzuae8Em8rElJ7q4fRpWLbCuJA55I9XlQQln1cjzP9HH5G4SHL+SaZK6ig +Ab/um979ZopJfnqydkhNxhFmO8E4Wbj7zYfJAwGLOzLje+uo0OfcEiMbwj5aaXDm +8289tXR0a8Q5fMwszTpNs+NbGNdrBr7UdX1kyAcqsZzcu5n2tef7hLWOalWlc7kA +ZvoGFfpUaFt7BwSc/UxB/drPlZ0qWY/4R2y/JKTfMtM4nIR/bxtexO/C3AnwkQen +3fwor/JmWTYR9XAhpZtusPMu6jNj5xML7FSf8QIDAQABAoIBAGjyLZz2+rcB2dJ4 +cf21HfQMwl3w1EnYz/rgl0W46nqxhi+Xo33oPu2nQj1CrqtJgm5mRfcyib0kvuH9 +v4Gz+1HQtqHqg9yWHARO+V2fR8bhvQvaOTJpl0Za8tCrZAhHLOH40TFHkbB8dpe1 +tHINESFog3ZLy9awhOnLWczdTY3qnVLl/SuK7hK8WTjthl5ZBIXiv+gvXs77eahl +Daa9q3KQRwlaDpjrkHiM8H3T645TREhatMBvpExO89bnMHPNTiLh5UF9SBrjF7RR +xJwfYrgKmf/GPSeWvb4+RBGUwCHCmuFHibyqJ/VLT/pKeTzQWLKPxavrgmEIJyqN +9R47Xu0CgYEA+Jx6iKhdJM3Egp6k1mLOLQ2m+yjTU5D39/DjIhdEu/fI8zBGSwwO +JtAGj9qUpNG0m74wqd3y8++LIxJmTjSqG9Z1jxT/sri4UvT3bqZy6Ry4/iwk+KZr +8IOYLzNmdxDhazSTa3UeHouvNmeLwmzCCNCQkHAN2jKsdjJiIe3ZkL8CgYEA+IJL +diWOyBcMtcIH+bCaU80OYRiMOatexktBHu07r1eCETlXJPn3ifmcrM9JXhCKqlVc +9ZLunPq0NwqHdNGVTBtU2gau0DhomrXr7y4WGOdiB27cV1FsuU9PmpvL18/8AWxZ +jEqmd3LuXphYdHWhn9N79Yxwdl7YKHAUXYB3S08CgYEA1VIfaiddVPkixxmtQy+g +zdPLFfOf8TKRMzSFEHl6xvcEfHdNuZNsiS0ylDjwFsTB/mkhhIAnudwvPTbKhgx2 +clCAqvdPuGD7+GKt9Unpi9DTg3UJfDoAoG2qJcYrA7t+UOjaHfhukbM18q7Co1+C +1uFvSiB8ImAcz4bH4WkfqC0CgYBz3WwJneFAcV6/r8PAKxMJV2YI50UZ7ki184hd +PwbA7e/6z91NpC5B6lueRtdSQCwm1r4M0YDnOAymTQZy9PTDE0swjEUdV++Nkpx6 +W+Z5nggapxmcrJ4gmFXpJBKagKJil3345yVONAvnluhHBEFjH1uAVQZqajYmRHt6 +TNdSCQKBgQDB8Q+Vmqt34P/5gipoYFHdBaipLGupamJ1CBX1KoqtmMEWDgSxhGI4 +Xhtm4AC2f6xwlo3S9R74QipeDyU0gN1LfGMdX8nsWUP2gcy6b1m1kSHI/e4AzJ4l +aDkjJwkopaytAEq/SVAhqNPHdtH0ihLkBOoi1xkl9u1tNpMwZHv0NA== +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_DAEMON_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUQBjubkcEz8Ame+evhVR/P+08N7IwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyMVoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQClp3iVfH6FLpZut6UdSrfkIfqED7h0aj8rkUi934BDFQiP +I87MuuAl7N3Nj3U3my+vppp3se0kt4cro79KStORGGuKm6EftkWJj9PIx/UKU0jv +PmtU2T7jzmohwM0RFwXSUUpAnInGUptSNlngbDJSQo92KYqCnCCw2Kllh8tSnaqn +/cVeBeOQ6ippM6YwJGs4rVMzS0v93aUvTXsKHaqq+wLe7Jcbiy2iAZT2HWZcuIt/ +uhWDTRiDMxFsSl53O2dtG5tlvxS+kjZ0YOZbhJMcddHBNg0fX6oPeEzMB0DMs7Nj +3Q4CDrPXYIaLryMccGDljrF8xZ1+rlOLar1A8pufAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQCKnK69Hada53vK4LIQS8mk +PqMiGLkrNsdqo+8/zm31wWQaL+XfWEzdEWfpSy4nPAKN8PriBafoRJynxUzNKNfP +YwzSpdwh49I/hQXgTg43Ps/Ud8eMAOwZ8hQFjtpxwMN5KMCNUZ2WkN7gyHN4eCFL +Vi52fq0zSvKIgCiB/G5oauC+4oesD3KhNFNdGDM+u4cZowfJP0ytetW9YRppUDyL +Di8vN8lRfLQmt/yvEF0Qgxuz1w/4D090mSHNwkiQFvu1+A21PEkk/FGsOqaEXyjN +a/hVuQii73GQQJgDCbeBECbmNz32rXYhzm0/Gg2QQ3B592qNnyDfU0Jxsq/IJtcU +-----END CERTIFICATE----- +""" + +SSL_TEST_DAEMON_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEApad4lXx+hS6WbrelHUq35CH6hA+4dGo/K5FIvd+AQxUIjyPO +zLrgJezdzY91N5svr6aad7HtJLeHK6O/SkrTkRhripuhH7ZFiY/TyMf1ClNI7z5r +VNk+485qIcDNERcF0lFKQJyJxlKbUjZZ4GwyUkKPdimKgpwgsNipZYfLUp2qp/3F +XgXjkOoqaTOmMCRrOK1TM0tL/d2lL017Ch2qqvsC3uyXG4stogGU9h1mXLiLf7oV +g00YgzMRbEpedztnbRubZb8UvpI2dGDmW4STHHXRwTYNH1+qD3hMzAdAzLOzY90O +Ag6z12CGi68jHHBg5Y6xfMWdfq5Ti2q9QPKbnwIDAQABAoIBAQCYEW7uu4Rhumy6 +YreedjLtqAuTI+NOayJmWk6OjxftfOeIj3SOGJcf+Zt70s/mJf3Wn3h5nMp3xEq/ +0ugNyTcCoYpHiaqVs/uN1oyyam0V93KivYhGMdA7zAc9yQH3SE09zwX83jbT6o1P +ITnMfUaMoTGVZXkTgUO5VIvc+pW51iyZ3mD8eH4MmkV/GoeOBkD7T1TMrTiMpeDD +K18lhmmEeMMqp7lhZ781pnfu9WzHeY6b37kap24EGBgDUDNtTdhu2bN2ejW4g+VH +0CzZcYJ02jwY1UE9fxfN/GXkfdQ5vPDy8xdo7mE3N0oMqfD+I5MZdZqG8xDKnofg +qSNv2LWxAoGBANcmVHsmAMvt0FXQ1j3GD/wJk5y/ty+UEqfVq7bmdpFYSxS4CKO2 +mTlRgc+7NEYz5x/2y/7Pji4l7wICBymbgvx+Gdr60HEF/RO6wdYgZNmRcR5doHc0 +RBt+8F3YCryN2AonA0abpa/mRu3QNNZNr8Vobw5v3khrhB7eSZAtkRL9AoGBAMUb +Vk1DDTElgPMzeXjjWD2UOBpLgNJBK9Ku6eGu870eOD3/oN0MwYt6WroEEpkC3EU5 +Q2ATqei5Tg0I4tldlT7bA/RY3bhY17rkN83v2Sp09xAn5TvVRMaIV9m1GsSRkuCq +hgKMAoZJwjuAaEsoAa5IoyFmu2/gFICTOEF4iNHLAoGAN1lpCnVwZwY7PpiHRUUa +/6AHFaBMpDTXx820a01G24V3a1EdB+EF8jUBzEtA236myxZWzKrgzQZ9Qmr7JL0Z +KZPXWvqDfVApF1ZIX6ndyAseqs0zZvdPPjOd6saVnIRxO8tlkFiie2omfS+/KBK8 +UXDYgUJOURs31ikhi7HtTJECgYEAneKX7quXFZcFA8pnsv3o4OqpRebU+ZZalBio +H68UbpiWVJM/N9HP9vm7UuWQQCCacJi972fQ4ioM60QC8jqUIhUtxbypXdFMfNfy +G3PUcL3gaYCLjrH2tVDhjfITzwEMtgnh7ohYPVk3zJG++PTC4+grQ8YWvjawNY23 +sjnq3qECgYEAsrKp9xPdTpG6Y4LhhBF1O7fP2IT/8aIWMNCPoTTbhkhULlYoRXf4 +hKpYRnpWkntdGqej0bq1IBt89j3LF8KLAG4d0zhyEQlFucWifd76srOPw60j86AO +Ix29DNjD9RATOzpDEvgp7R7H4/bazcqcpo/Pz0kE3/UwuCi+ebFyt+E= +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_INTRODUCER_PUBLIC_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUbJaDX38rnF2BylBTXCWNjn1E4kkwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyMVoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDfTXQTHHDgCbBC8m1oybg5od+wH7Pfh4duI9m/I1JZLZoz +74GaQZlDG2bTHwwa3ccXDF5N3BbVG5BWGhFKquy37Od5mB88pDLngazumte0DaRC +MvM542TUwBVwLruT2jNDIPtXFZ5b7XMZh+dyLXHbvP9wyEUUBKcSi5kRgp02OYJC +g053dKazEAFtmOHoPNlCWlqqjfpMAXsbiFUBCoXmqYcyRBnNpzV1ET0nZC9W6Don +racpKDIvCGQPvZ6PL1iP/SLGx2n8QQ6y+MwRO+f4A+5dabTJHgLBQ6s3nL8ijPUU +V8jLUAkP4Yzrg127RqfHRolf644d3RqMyxGabOlPAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQBKXvslWP38FdHCrH4uZq6C +r38iUHhM83Bd5PWOWpJLSepoDuAuV6FaLsDVqjQxI8M1sv6uLfBbfsCBZY6e61QM +vWI8vzDiCaUicntxozI02gSedAOyecUksADYkoL0xTPWlWHoD3EwASbwTC9Giip6 +0A3Aja5mgDxB6vwRjhXs2hX0ERTJ0kmXG4As2gPhuqoXYKo5E2y+z8PkvEkjEeUx +laMTDrnaYZjfk1Vq5qED49CwAZljaIghe+Bad84JtEOckAEUteoCtsG7Th2/nQ9t +Qs81jLixhO1sYJmhoYxM8kwtv8/hC18u9qvKxZfqZfa178G3eePvbYNeS3LRlhg6 +-----END CERTIFICATE----- +""" + +SSL_TEST_INTRODUCER_PUBLIC_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEA3010Exxw4AmwQvJtaMm4OaHfsB+z34eHbiPZvyNSWS2aM++B +mkGZQxtm0x8MGt3HFwxeTdwW1RuQVhoRSqrst+zneZgfPKQy54Gs7prXtA2kQjLz +OeNk1MAVcC67k9ozQyD7VxWeW+1zGYfnci1x27z/cMhFFASnEouZEYKdNjmCQoNO +d3SmsxABbZjh6DzZQlpaqo36TAF7G4hVAQqF5qmHMkQZzac1dRE9J2QvVug6J62n +KSgyLwhkD72ejy9Yj/0ixsdp/EEOsvjMETvn+APuXWm0yR4CwUOrN5y/Ioz1FFfI +y1AJD+GM64Ndu0anx0aJX+uOHd0ajMsRmmzpTwIDAQABAoIBAD13nJQGKCwDfrlu +8h7+J+/1VxWsJF9Ld0QiKjYrCufxXZkePJaxp/aI/GzxBuv+UGdPyEW2Z7KRu9F3 +q3raQf7+/1jBPxf6OujvESM9DFNLzgNK8xjkN0U4+q2+r3OrhKDd21HFaan0WtKU +TmlniQfrpoTtG9a+0R6RvrjLM2tRNW/562bPR+tUmo9CHGXIwPWEb3r7sD+8UTf1 +yS/xwq5HWLancjiOfEbNk5hweXI+d2x8Jb8vPM4Dm4frdfFWIt5Mek37aSE/Dn7f +9DxKfYp3wrKX378P9S60gV8qqOTEMQlBQoDOkPJxcokGYtba4Mln6ApASqV6Ocna +yQoREEECgYEA/FMVleoa1Yt/YX4UDco4Bwyh3CNflnJvTMRadKBb7ql1OvK/dSWb +WnTIc/Nmi5yAvfhUCQtzw2jdnOH1be7JQ+MkfYVgpeKanAtXGxMldgv80FtQFXQY +qipGnibAHjOWniomutV1WW6bGBiA8RUdcxh+cVCd7oRiflp6NjnopssCgYEA4o4l +eINvoccBC4DD5ZoHczaqda5qgz9zvh3c6qCOFdHHyCH/zlH75LBzGNAH1IFqacB/ +nfSJsMV657Xp0uZi16YoVPVCHCFA9bFNo2w5ubaYeFdSPQi8ZwbJgmYtAPvyDoWT +UHT81RQ+GSyRaWVey39RcHcsoay1ilCs/6LmMw0CgYA0Bc1Fg2bU8FXq+9uWnELA +8VHN2V0z35Qi97jOouFRa47IAJSIyqAlHj7V6TETR8kjYbexxbKwb0aBufSoHbtR +S9uSJZWvnfDSi2QCKQhoNkCBlNIGGlGbg+vbX5HsqCY9peMmUixHrA4+AY9UJU5V +FI+9PSnSq2jDNFROKdJV0QKBgH9KSndZseD9hPLHmElqr4DmWAPiyWmQvyE0eilB +qFNOGKezopxzp8mn8iMgzyVwyS89vvYqrSoq6pFBvmyGkUaEzuhdHJXdgTgKNIr7 +hbt4glYrCcPNIr3oLFQdwG9rH2dVWZ28/UljJDjUt6a2E/rWQBWmf+ceuKlMBsdi +6WAJAoGANzWzy3eDpkIWgDZJ2+kCiwSAYYmcyh0YhZENiomHdv5SCxAZzpomHI7V +kZlHSzGYnaHaUqRW1TVXN1PgYxI4HKdGlY5kKQlw0aVhUEPwJNF2HhxAltLsFiqe +RrjJMJLNHQwsrOGfhn+JCUlprbuThjUekSqNtOpNh3qqwEAtC9A= +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_PRIVATE_CA_CERT_AND_KEY_1: Tuple[bytes, bytes] = (SSL_TEST_PRIVATE_CA_CRT, SSL_TEST_PRIVATE_CA_KEY) + +SSL_TEST_NODE_CERTS_AND_KEYS_1: Dict[str, Dict[str, Dict[str, bytes]]] = { + "full_node": { + "private": {"crt": SSL_TEST_FULLNODE_PRIVATE_CRT, "key": SSL_TEST_FULLNODE_PRIVATE_KEY}, + "public": {"crt": SSL_TEST_FULLNODE_PUBLIC_CRT, "key": SSL_TEST_FULLNODE_PUBLIC_KEY}, + }, + "wallet": { + "private": {"crt": SSL_TEST_WALLET_PRIVATE_CRT, "key": SSL_TEST_WALLET_PRIVATE_KEY}, + "public": {"crt": SSL_TEST_WALLET_PUBLIC_CRT, "key": SSL_TEST_WALLET_PUBLIC_KEY}, + }, + "farmer": { + "private": {"crt": SSL_TEST_FARMER_PRIVATE_CRT, "key": SSL_TEST_FARMER_PRIVATE_KEY}, + "public": {"crt": SSL_TEST_FARMER_PUBLIC_CRT, "key": SSL_TEST_FARMER_PUBLIC_KEY}, + }, + "harvester": { + "private": {"crt": SSL_TEST_HARVESTER_PRIVATE_CRT, "key": SSL_TEST_HARVESTER_PRIVATE_KEY}, + }, + "timelord": { + "private": {"crt": SSL_TEST_TIMELORD_PRIVATE_CRT, "key": SSL_TEST_TIMELORD_PRIVATE_KEY}, + "public": {"crt": SSL_TEST_TIMELORD_PUBLIC_CRT, "key": SSL_TEST_TIMELORD_PUBLIC_KEY}, + }, + "crawler": { + "private": {"crt": SSL_TEST_CRAWLER_PRIVATE_CRT, "key": SSL_TEST_CRAWLER_PRIVATE_KEY}, + }, + "daemon": { + "private": {"crt": SSL_TEST_DAEMON_PRIVATE_CRT, "key": SSL_TEST_DAEMON_PRIVATE_KEY}, + }, + "introducer": { + "public": {"crt": SSL_TEST_INTRODUCER_PUBLIC_CRT, "key": SSL_TEST_INTRODUCER_PUBLIC_KEY}, + }, +} diff --git a/tests/util/ssl_certs_2.py b/tests/util/ssl_certs_2.py new file mode 100644 index 0000000000..ffacbd4594 --- /dev/null +++ b/tests/util/ssl_certs_2.py @@ -0,0 +1,684 @@ +from typing import Dict, Tuple + +SSL_TEST_PRIVATE_CA_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDKTCCAhGgAwIBAgIUbFhRlgpIM3M+ZYuTigQ1Vbmi6P4wDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMB4XDTIyMDMyMzE3MjkyMloXDTMyMDMy +MDE3MjkyMlowRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8G +A1UECwwYT3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAsc4R76dCSzj3MR7adSLI+Mk9cX42bTHiu00c964rUXr2 +eGpYy1fmtdiq71kkVFRCtX+m8tc0jA5RCOCJsVKPZ7a2zQVcUkC1HJDCg8lufI2p +hS33zpjP+BePGmxQDhBU744cmFA/TVN+VTEhTlbmhFo62eX2Repbl2coF3MhoKTz +cilUgiCww+DUa6IQk06Zkh8TFJ8iPp67QRM1wEhMEcKrnRNxPGHDxa9ZxhwrmKft +UOFrat+ijftQDexMkVZLUXPoksM/7afjqvP9fkFpQEJZ3R1p3uwSX+oIr4yE/0il +nnLnunvUcWYTmvVcwrV5Zu+IOtV+yBbJxmFsobiecQIDAQABoxMwETAPBgNVHRMB +Af8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAgxl6fGre+yFpKxEVcJ554klsg +Hefei1tv94BDMqdzfdeocTBiYmN70j9KEZr5CoMUhpRh0sESpgZ+6JD506Crpa6y +CwkhfQXwOH58E6pbqLLpG3F96BeIBQ/IS0iGvRaerK/9hybt4NJAyrXX1idJikiJ +h4qck731LOSiCw7T138yjlVEXm4DdCj/MYJDJJznMYDXJrJEE7tDHHvPaPU3Snrd +CeAYwXaZlvoCbU0f0DCyAXS5+/HgzY5qVrvDXCHTAEnMSEQyIhESSL2xmumTGNCA +BBlbMJ6oLn3fOHrB7qQortCwcAQkbk/MiZhAkL/+NDz6gdIZqgXLDDVZxext +-----END CERTIFICATE----- +""" + +SSL_TEST_PRIVATE_CA_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAsc4R76dCSzj3MR7adSLI+Mk9cX42bTHiu00c964rUXr2eGpY +y1fmtdiq71kkVFRCtX+m8tc0jA5RCOCJsVKPZ7a2zQVcUkC1HJDCg8lufI2phS33 +zpjP+BePGmxQDhBU744cmFA/TVN+VTEhTlbmhFo62eX2Repbl2coF3MhoKTzcilU +giCww+DUa6IQk06Zkh8TFJ8iPp67QRM1wEhMEcKrnRNxPGHDxa9ZxhwrmKftUOFr +at+ijftQDexMkVZLUXPoksM/7afjqvP9fkFpQEJZ3R1p3uwSX+oIr4yE/0ilnnLn +unvUcWYTmvVcwrV5Zu+IOtV+yBbJxmFsobiecQIDAQABAoIBABilM59AU9QRZVIN +sMIjvC+f1UBx+iFQlNjZa3Z5Uc/Nd3RhaUVmPbhe+/KJLJvzwfteYkmuwr3XDixo +0y0dAHuju9rXL2DHT1NSTWPu+72P9Ttcj8i3Lbx5p4BGGyKX6O37iMMj/GI/fHda +g/9T1EfsKdQiJ+yw+1kVF12Iu9SETXVSl+xtEv0D0nj3vvSCzHf3wPELNMDigb1k +R43zsbzT/QF03rlMy22xkNWDyxki1EdmkuU93+8DQCso5r5OwI3hGDQzWW2c5nPm +49+m7lHe3apYUxjhbdLAWfyviEI5ysIhf9qwRXZJTHj7qncrkYZMm4wI49TWb318 +Sw/EwnECgYEA3021Gg6lqwfL3++mUKYyGEKVwRFPK9cZU6+xMT+yjPtahnbRlueL +pZ/rRYKUe5iIGYNdHoQgLqsE9hh0iZbjiNLQ0HLvMBt0QdMey+F6vKlzkSiBJsmf +mZXgQMI36uHbuJcm9Dm/nSoxQT0rmHk1rdW0hpJZOtUKMlm1SdjUH+8CgYEAy9bl +tTyq8oMwXJ7dp3UfLtSL4y5ekPLe8o+/cMTOHjaZBDFdPXgFN3DQLqrhvPAQHl1G +PI+zsjLoZYBtrOgIJ0Dt/4N9jijSdfhfZtwpXcVxWPXSjh/hTmY29pD3IDV9sbyq +PyLxpMaCL8BrUXPTpLyuuUUpanPxhzG5FXs6x58CgYEAtruiXcZqr8Dbh09XbFv0 +VoH2hl2hyiBla2Q0vjZ/6HqwI6UL8k9cqZZqMyGeXF3/0dD73MMGiuoMT07H3ugJ +HqhVlJ7ZOSbeRhd79h94DvcjyT+6IIGSB17selH07FMTOMUIbYbsVLJ4SAjEqitW +UAC3kAAm4MwBYh6jCeFUBSUCgYAkuSeTOkXWARqSZTCrvacLidFV8YGp/Yd7DbjA +uUQlH1L79WTF8TyHW3S2I6Udo+ZTghxoRr9qCE/kEXow33CwmbsHAIp7NRGNnVya +rGlrcmnUTB1N66JsvG+EhmNvUxO9FK9bRpFgTT8hGTp8ZzCnCjM0P6iRfCf0Ylnk +69mQIwKBgQC0lu/wkUsJtbMaUDW5v05XoVw3c+aHd3fFX7WW10d4aDqzFXYMjdxT +tKpkYxpBuoco9E1PZMF248wGMsIltykwPvy7QI3gRbsZIW6gTwUBsI3xTYOybu2x +trfVO6ksP0sIoYOJH2JbJfIyzy49hA90x1cIA7i/HdJWRGitJ/xKkw== +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_FULLNODE_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUJBzmO7OHvvlimGi0mXLrh/8TPeMwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyMloYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC792uVfc1mFbJluKxzWxZ0r5yaKGjR8azECVrNTcegAjLF +Qd7+iZS+7DZwEA6Xy/h8T9DZd3Q1m0Rjlgg73ngO50leCvLqWEvrhueuEIWLdbef +4NaX4qkusMI/orYE/ItKgL86HWkGUELnmf3TkMccohR63vS+Fr6dZDvIw3g+gBPL +P9MlK7sdXq1I8CIcV+2du4jhmkA4mJ278TdQZOfXnX1hhe1wPuyhJyBN1sV2ntLG +TLcRl8WQSIh3j4vhMilEU85rA+q4TuqrOlZtKPTPNGeACwrD7qQkWihsEAKWMdQJ +e++9+CdigL/S3IhMmdTwHHNht31oYl1vAqbQbCEzAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQAttszf/gjwRvkxZs8Iq474 +aoBzfsF/NKCKBNRoTdVwQc6DycJylA9JL45BFhc39tka00ttcKGbXmbnOzltnFsH +QuD/1B4pQOESZzUEcsHHCn7tKxIrCn4wk9OiiqcIwHwavFy+guHFSw71jVFhv6im +ILe/K+wzpgc+pUeYiQlWRSuoR7YABZekL8bjpCpuq1kXzP4bV9pnq0sMayCHdH+q +enRnvo4u6PtMUGdX+bye3sp609uFgH53v06ufl3ylkoK5TRuaOj84yYuJDBrAAG6 +ZYZaosM/CKXoumetH90Sc2rAvWp2HniHe99STfaw1aNK9YV1T9SjIqhzyzoMzGRP +-----END CERTIFICATE----- +""" + +SSL_TEST_FULLNODE_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEAu/drlX3NZhWyZbisc1sWdK+cmiho0fGsxAlazU3HoAIyxUHe +/omUvuw2cBAOl8v4fE/Q2Xd0NZtEY5YIO954DudJXgry6lhL64bnrhCFi3W3n+DW +l+KpLrDCP6K2BPyLSoC/Oh1pBlBC55n905DHHKIUet70vha+nWQ7yMN4PoATyz/T +JSu7HV6tSPAiHFftnbuI4ZpAOJidu/E3UGTn1519YYXtcD7soScgTdbFdp7Sxky3 +EZfFkEiId4+L4TIpRFPOawPquE7qqzpWbSj0zzRngAsKw+6kJFoobBACljHUCXvv +vfgnYoC/0tyITJnU8BxzYbd9aGJdbwKm0GwhMwIDAQABAoIBABntdxmX0M1UENeX +MbJ3zhEqaB+bk1niTEJ+R9gp8m9P3lD3VRsnPy1Wx+uNS3YE3LHJELXulEkQsc5K +07fuaAEmRiiCuh85Lr++TBbmkIU8J6gWC4PH8C5Qk3rTpufpLg2I1NffVq1YROJN +i4WzYsPAV7LbLkdKO+DaAqUe0WdNZph8Fhrg/WhjGC5VAajRgfVM7cbnW4SjrQzz +lqoVB3GQPWLgUhHoBj6yRMBKP7D96h+oqUZprn19ilEeaoDVvDMx1Uqj57PGCZ8k +c166dctWvSVxLKwbau20HLAZCZWQylhOugk3sEIceEhkiP95LYNfAZAHiU1Aqfpe +PgKSAYECgYEA8uvqkXwejuFEMGJWo/JUH/pETc420gatwVD222LYYFeNhk3C6k/E +iHa/iE8v9jKHTv7xmlG6ybBkluDGsaK2vngzKpc97nCYfg3mFjS3CN/leZDMwUDX +Bj1XgFhYM9yLVojwVJl3PkA4B/WYmnxgSo9u9oCy9K8HdSMUcCcPQgcCgYEAxhYU +9OPA0VmKYwipWfpZlir5LrvLkwJdcmAV5UhKVXkMXr+M9ByRRLYrr++6SxipjOjO +Zi1t1hB79pxtc2mFBCT9gtnbNvcgEdkxSo08U/uj3xcp1oCZAN9Vu3Dk19Oi3jUT +BAlE1V+Le3b0mPh9IytPjpO7xjWstpi5ar6obHUCgYAH0x+QJh5Z3dmzcUd3KnQZ +P5d5ph3P8BUit/froyhzGf7eB50yrPUYrDKJMnvKA2CmY8HmhaFto7fpwD3GNQaL +5hVH1u1Qw+G1lb8GkhYfPA8JNmfSBcOnWMx7vtzAducqF2keYH8dyzXC099hgoYb +gLlDSWv6Q7UKyeF7p1ZvewKBgCnWbCK1H/qXoOT95Vb9y4IuHWdDfuHT9Ay+QqGk +vR6EbJpudsTwa7ZJi7yjM4O898KtQTrPiY1W+ffCXlOsC84uSeUjQmu/kmRyrTiD +0CQk2B28dLe7fZVzllX6qDr1lka8iwGlO4adoYY4P703bqbI9Qq2JUjd+VavtynW +jxgpAoGALXc4mrAJl4ckfso2OOXo0UHYuO7XCVO3Ll5bzGZbaiRuCYG6ilm2wKRf +FnrYRd9KtvrA100LxTTepdo0tTVcdAWY7STJpBIycUN72OMQOCI3VWSTkSpJHGjp +WBqJDcueUhUe8x5//qsMtXJFgXc2ZerODemObr+bRT1nBYMiZQI= +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_FULLNODE_PUBLIC_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUF2mq+KA3KYyp6bso3F79MnD6AacwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyMloYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC5wiF41CixaxHM2oHf3nYkuGmLeG6xBdSogQuaSMAw6KCy +AvCfLDBRgfbvWjXV5teUv61+xgyLctNLmJQBg0owYQhhZnwIZK2jK9h5CvquI9UC +xAdgtvKc6yFKlWS435xSt+ja2w5eHsE0QE6U9SL9qm7OnehvF0baDA7CjQNKQ8SR +lkrl0+mQZCEc5lfroYlpOJ1XKrmLhfX4KV+RcNEuLF4roY1TdkUfCOk9Jq8/DrCD +rAOuFaU/GShqmG9REt3HKIGBO254/xoTcSkGIOHOGI/2uZI0MVUDK8tNDwAaDLcg +RAclaoGQ1++jcjnmjvopsqySEJwJrDJMkpqKd0SzAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQCImPY2TwUGre7AM6nzBqrh +WCXTEct84E1jfJtgWZ5xYdVMNd0Ujg6A89LZnc//KW1xVDImmTrsxwHj/vR7lRdr +L7ADGbKOepqKMgUdT8Im67jpMen9Bnrx/q5dtW8qmUMc+EpGwvMOASYEa5jxQ1Uy +Bxpyk3lpeZs5HZJPG0WVFQnNXtlG8LMlmlj1JAEB79hbK7PqPvat6rnS6NTCHGtC +vjAd8mHjVQJkla6u4dV4oI+niEJk12d1yJ9dMSZ8hO3CiBJBieZJ2v2S04N8UUMh +PQEX/yYT94hLaYWYextZRDxNWnjS68Ju1xv8j8GKdMLE693Z6K5kJkspBy0sEtxk +-----END CERTIFICATE----- +""" + +SSL_TEST_FULLNODE_PUBLIC_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAucIheNQosWsRzNqB3952JLhpi3husQXUqIELmkjAMOigsgLw +nywwUYH271o11ebXlL+tfsYMi3LTS5iUAYNKMGEIYWZ8CGStoyvYeQr6riPVAsQH +YLbynOshSpVkuN+cUrfo2tsOXh7BNEBOlPUi/apuzp3obxdG2gwOwo0DSkPEkZZK +5dPpkGQhHOZX66GJaTidVyq5i4X1+ClfkXDRLixeK6GNU3ZFHwjpPSavPw6wg6wD +rhWlPxkoaphvURLdxyiBgTtueP8aE3EpBiDhzhiP9rmSNDFVAyvLTQ8AGgy3IEQH +JWqBkNfvo3I55o76KbKskhCcCawyTJKaindEswIDAQABAoIBAAWr8LuwtqFcJIn9 +rfN45mCOpOJWRgLvq6ONdR471Gpp3+YvgstJXRxP/IsoVPZ3+uMWyyRQxbdIRT1M +plA5gv1hKRFYQLc847RUtWJUvHyuqWVROOxyCYxS/Yw6bX3bjflUli6Ae7rR85I1 +2HBh37ShDIsQdTVXH5muvpCgH5aX18gONUYsQt+xDbnuDW1Cdl6MFYCNCOzL1W5k +6kccejG2aDvNN4f9FZdtvft4sQFp61LGxClZGml9zlFuOav/dJx3eXU47Z8DVADw +OJmtXJend7A29uPFyyoQ44uE0F1SG0dzNmmrxrD39c90w3BTvyGsilmjkr1diRkv +jRHl4nECgYEA4qHmHJlA0Liu6z9Wg+/n6Z7+OnZAfTqvCUayPhD5lKu8WWC6LsI3 +7m2AhkkREaVHWu+9Slte4c5A3stH4eEkSKSWSef5axdlYZc2ST3UNOFAzMkPle2A +kZAYWZ7XkBzptJhztgBiQUBJLrQ1SuXayvnrpgqIIYkeuKuRYc89zWsCgYEA0dRP +rMdz3+rHlGmNWgU038G57qGlWFr6NLEqSITYz/7Xp19hP/bfuD44PvniH9N8x/3a +IlgNqaZLU5IyFzIfYE6yuPsUXC0nNzxcc9FCiLedH7d+247jDOcbbQXOi3pTa8Ar +rkwHTzAbQXT8VuAOcs+cjDMa6rW9IsvHvuD4r9kCgYAqDOAlbkoYcCwEejwTPvBI +6LdDIa3Vjo3rqrJn0b59V2AbNVdWVbMLCkZOpEAGhiQ3O0RkB5ATVbGzpQQxZRTW +ZbN9Aw3EURL+iJAKBu7Y4PKlDKlXqDmyyIm8FzzoAHVcjOzrWCbi9Iqfn9BDlWKD +RtvycwHPNyH8IdlXzJwrAQKBgHirKVrKpSe7hCUkgoangd3AMiY6zbS/NS7CR/fG +dk0/WFPHtUyss8Hn/j6xQ8pbvGHi6eRgURMkMCOSar4ONB8VgxCATBgqW2gXjW+J +g0LOnUyVIR4w0QAllA8hjMOHiJvpuvUUgguXNcVx+oAXgBekr3mtFiiudWOiX2+1 +Py8ZAoGBAKPAc1n0UbvdNjQHllxm9Ehok3hcVvJZRRBtcXytKWwl3FI6/I50/XAy +8PaI4gbysiPgMl+zTU9mIZGIxyMHNy6vr5/3g+ZceNadAsIQnJQLTMM95WP/nKcQ +XsAuSwTFviI2LBxC7Scnpc8JHugzP6a4oiRs8yqSfKXYGck8jaAf +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_WALLET_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIURlqEdkPWX2ld1ZkYRM10UTM191wwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyMloYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDKHNdtHZzYGVJlTaAmiJDMsNdVpyo3sHewUF23K2zMTUZh +2DBX1heO09RpOIoGIdsgm2P2T/+731O6Hi1+pJyLBq/7LtoPX5fZL/AT1uQN5yDF +xBUvmaFmnapEyRC2tg6H/YNBCTrHO3OKWzF5Zn5dZDmS8D5FcnhPups13k6YYklZ +ZewRTTUxUlnorKdDh2Ur5UPHnpxfG+yRYow/prs6sfQNj1Hdv4nsjEwTPwJQVIC7 +xViZMiSWUaYMx0giJe1wggkuVYTBQ6tYCOtbO/FKErYS+NrZ5lUfUzmpzlXIM1bn +Ux+4SwMYddcbedVywMap7mzupD8ZQNCuio9Z7nc1AgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQBghZflsoqx/js1oQC2JfNc +gD5HWNqlS6JbupJr2zt7KaKFVQfXmMEUNcVsEr9PXIGA3vqDnpT3L7Ybk0R9knYP +yGb1c5uRFn5A7moAcJjgwUrDE9GQBx59KRXmK4DofcwinUPEe6BU8sn9VfqjTprQ +WFFLyt941YCxaCCGPgZTyGbHWK2pTQY0aBSQAyNppk+dsca6l2HkelkmUrS6I30p +r4nhJq+eXmehrtn8+zXT6qxmr/vw+F7cwnYyxLswBMc8ijcmvBbkcSEcFbdP8TMN +A4FFYyh0rIijlKTsoEyvUP7LGBBJv0d3RU30jHPBm4faJ1wWXLm6p3hQEJmLzM0i +-----END CERTIFICATE----- +""" + +SSL_TEST_WALLET_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAyhzXbR2c2BlSZU2gJoiQzLDXVacqN7B3sFBdtytszE1GYdgw +V9YXjtPUaTiKBiHbIJtj9k//u99Tuh4tfqSciwav+y7aD1+X2S/wE9bkDecgxcQV +L5mhZp2qRMkQtrYOh/2DQQk6xztzilsxeWZ+XWQ5kvA+RXJ4T7qbNd5OmGJJWWXs +EU01MVJZ6KynQ4dlK+VDx56cXxvskWKMP6a7OrH0DY9R3b+J7IxMEz8CUFSAu8VY +mTIkllGmDMdIIiXtcIIJLlWEwUOrWAjrWzvxShK2Evja2eZVH1M5qc5VyDNW51Mf +uEsDGHXXG3nVcsDGqe5s7qQ/GUDQroqPWe53NQIDAQABAoIBAHiLmzFJaDK7Z5lk +IxDYgwSStNwxR8zPQ5O1Wy/Uhp+Tt1bESpEY8BQP47CeODRQHRHlnElcjXrQSG/J +b/kI1RVWd7+owgZJTZgML3Slxn9ESxepS7mIN+usPdGo2n8fNquFWLOBfb02iEMN +AQUXTGcHUA+DmqBxFbD363rFjLr1VM0+N1vjw20auYGpvWOFWbhXjgWGBHuJhRNn +tgkXSsrOsPzbGIWw3GEt/Tlw50ehVNTSGA1jdxUlNHF7sGfFLVYjcO5AjCx7661v +w+w1eBwWI+SrYxXp1YgHlaJS1/u0vCvQ0kLcc2Ry+zpmesvi4aKVodKXWn7ZEsKb +qv+pYgECgYEA5pchaX88w6FiH80fzF+mcCcDnliw83kRtIWRE0XmhIL5ocnWuOcb +pgSFr5kEw80pPDt+IYrKHxyh/fVZV33n8JJ2fjNsHFwpZykIDhO2H2CmkXm+fTxu +gD5HIGzPx9qxvni8xjjXfSFCGvKuwGa975XGL45P0LsT90iAumkNnAkCgYEA4GJd +oRpSdxxDYuTvDHkvdlgTYSFAy/4njk7MsfnEsbn2l/p/xDx5H2nKrql/7J26pHKc +ODZcQXaRGaOi83K+vYAmHPC8zdmuEgh4hlSqJ04IEcU+gadxeCDh/RcBUPMvtBe8 +nDl15HrGi/k1MxsdrrL4Un1mrvtwvfjbvX+tZM0CgYEAhS9TeBiqox/qig2zSRsS +CgMuvt3hTq9l/4uKEMS18WGpB76JzACIYqqIALV0IBe2snh2UK9WMQQbuJBmivdI +6RXfZOMUlYjRzSjQ4ziVX6g2bR4RXUpzVJUkBeFzXa6+LRKVjjQ0mqyD/wae0rhF +CkXK05ryFNCJJrH00DZvSukCgYEA2n0N3Jxr5k2gFEEFwGiUXbEflbmyhbBCRiDW +0wp5i/Gfe5dRJ/0WmA8EbBTiWr2viweKtHXCWYAhhAzB1DpMHuwUsKN9xRgMlsSm +z27LjKA/3UXqOoeYRrgGNdJb1r4mGj/uyVRuRn+Cq7OLKOtjeMQOZwxymzp9Ko6T +Ma+MYJUCgYBeY597VeXh9vwMlfgjIz0vbGjrIgGSS0YqM//SgfziHDv9Bh/sQY/J +zy18xbkjdbCulGGyro7zNDXmOcf5CUsgei2cc/vgESQEZpoMSnVvG1MWQ30xq32M +g4FlmGzdEiQiRxA8+9lzOPJRcQdUgS+Le7fOWH85q2aXrv7wp6lT0w== +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_WALLET_PUBLIC_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIULNQ5Bq+zPWOGPtKDkjFf9aHtCBYwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyMloYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDmIHrbtqy5/pMJq5NZmVRFbX8wHSciOLyUwWY6K6BgOtZH +8WaKoOS03X8KVnWKqXGcUY9DKWar8iQ+VbGP7YLw9wJjr4hNsW1DqN7uzxla3XIF +upT/tKAhZpiqOHKstGEoKwjVD3Dym5xmSP6ERQTfMolo7WaakTpANCGKW0tKM2Rs +6pSaHV4GIvbHSer/apt1zr2IBFQI7Sj9KSXZ1OhOZERSE4FigTAJvW5PEcuVsjwR +LB11vpPKiF7YkLmsj0MQRHlFqZukrSdlvR9ZLaAREJLgk7SwCwUSYGQEGhjiEkH6 +vWXT/35IYCkiYNI/vcdCQlN4xBOOAXgO3c1HtikFAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQByHJaF2w67743OsMwKbQ5j +oWAt+rqivYmqJ6tVKEpCAZu3aMPdchcoZdfWRfh/tRP0SwkNE7PwIyRxo0qynrPO +gXhGR17ezrgz3a5AzQ42EXg0xb75QzpkXdrOZK9ynjer4jlMx+a+IJniYlSpyCxc +AnEKvnH22S4j1xCYC9zMDUF6Jqm51h+Pnrz2sHr7NyRu7Lq9cJ62rfyT9kFW/aZX +1/xAwzw2GmyYRpw7ZEiRN9Ipkjs8Nn6yCWOvs/wa6el06mXB/i/IvOdMI7/B3PJS +sOvOjmtIS04kyR2ZB4Qhkty5WSHrF0Se/9WH28L6a6bjFKLRMKLTRLdeZ3ybEOFN +-----END CERTIFICATE----- +""" + +SSL_TEST_WALLET_PUBLIC_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEA5iB627asuf6TCauTWZlURW1/MB0nIji8lMFmOiugYDrWR/Fm +iqDktN1/ClZ1iqlxnFGPQylmq/IkPlWxj+2C8PcCY6+ITbFtQ6je7s8ZWt1yBbqU +/7SgIWaYqjhyrLRhKCsI1Q9w8pucZkj+hEUE3zKJaO1mmpE6QDQhiltLSjNkbOqU +mh1eBiL2x0nq/2qbdc69iARUCO0o/Skl2dToTmREUhOBYoEwCb1uTxHLlbI8ESwd +db6Tyohe2JC5rI9DEER5RambpK0nZb0fWS2gERCS4JO0sAsFEmBkBBoY4hJB+r1l +0/9+SGApImDSP73HQkJTeMQTjgF4Dt3NR7YpBQIDAQABAoIBAQCTXdlPOfwCX3Pp +jWYeyoGctDHurbyRvaOF3xOHzMg213bBO2VfAQl0iSMBi7xZv4hxggksCScmlTmA +cX/zmzVu+b8d9xpiJmzCFzIr25NxDL4nzQP9e73PpdO9rchBsIFHJ8fQKMM7mUre +dYAHU+t6wvIbr2s1MCsNUlToNO5R5MBRrJjxqvDteLMrcH9Q6ae6f4sWscqs/oyy +yXa7Qve74dGh84PfNCDeXljQjXRE0080OMWBfY2F5Oy86Vf42q31M563ufKIcCBM +lMLKBZjc5L2AqFZKOERITBfax4GAoV3xfiRfClgAOA6cuQ385tp18LxG0IYf8Qcj +xQuhvyoBAoGBAPbmLyianEJV3j7gojm6dl5rcYblzqU6rDrCOGNSRh0N1bGBP/T7 +OEe9bi7apK/09JN4sm0c4LhhyJDanCfaRQ9DRn0OKU0plELSWGvJ3XIAiCoeZSg2 +I40A0CSg5SDnsFYIBdBqFi6E3oLwM3VsntQz3WH9O81k8KWraFdgMgipAoGBAO6c +Bv7k1hmvbc2j4CLdcf1hkpDGuv5bCBG/cPIg7EZUmpfeKnkP+7TyOzJJJufKE4U4 +GOjkN9k9sYoNb7VubkWpdO74ylIszqo7bTI/6iwY8N+ZpJmi53poU3Fp2PTOJy0g +UcDDtaOiOaD+gEF1+5LxC+uUonL0g6bUmS9lpQr9AoGALGL5e21ARlS1ncw4nfQ9 +r3/VaxEJc37206FzDbgOzs5b6ot3+gzn803E7ztzfAanqZN7UE5uv/ckXZZPmIKP +A81ucLEJD8w30UOLjeU+oG4kDJ5mRTJmdcT9pngeeSnt86mBkhRgZICSmCuitKuQ +akngtOsXwzcwZDhKi9rJY/ECgYAoC6mk59UC9I1SIPnCADZcVx7ZC3FgtPhyuhWD +nYDqANL9P/0S2lrdMHY850gPSLvj9NlBZOP2osMEL2MbKRB6wojsfna+OeTpbxXR +hCaSBhGPBWM5obyFr7KpayFNXLf4e98cofv/HX/chDoUQm/ZZnkgrY5iCqV5v16C +NOXxJQKBgEHFazeFqKKFnIc7oWhZUKvU+UQ04KKGFIuRg0IKhIjxySQGqiJQIvJA +DfNrpsARfWpfCo+dSVxBIcSUATKvA3LMVPaaYAZSj8n7YFA8M/2oCegtM68QM5DZ +Rc8M9EbKkv9/LE48h4gc9ywIw1PD14SGq30il8wldWRSYyry7/9t +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_FARMER_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUTnXTzqEOILFs1Y6LuvX7UkxgI1EwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyMloYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDWr7824CNwPS2WHAlYs2QpHVtj+nMn/nl02e3JIX9utKfz +2sVXy9dT0sW7VcDaeUYBi6pDZz8DecwGjvnBMAfh+bkEx9gCs1tY8Iqitgmekoy7 +e7+zHJ1zuo0J+p/zeW+Lwg6D0FztarME2gm2tuw1c5FTIfWWnwotYetXxUWCeKNc ++TgeK8WnfUjRcULzyFRAA16n6AmqihfcfVmT/Jyr2eubKeyCJFGUx6jIClb+OFUU +0h4VCZzhHOx/R/X6B9HWJTWgdoKUxQcMt1sdlNuntOkgg1JsJPVPM/+NnijCdHEC +Wsk6MGCiVVH/vtR6ek3sDitsJfk36m5NjiDzeK9dAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQCj7q/5jVqInWNHENfekLWU +u9N+cSMhDMyq/ANc/wm3OcOAYUODAmfgZDuGAmHW73BSeoEuXQdsnxQTCM0bVF5v +9hKcQkLY9v0tez7xcDwicFQfg/SzjCehbeKtKZGnrANLg1tEm2QFUuqmepbhatF1 +NREBmX1EtUrZ8l9e0i1oDk13eOJvdkZ5pfQC7UOK2N7dAHQmsWJtJgHpGu9KgdDV +eKRf55N0tiDKFjumdFucvMQVaOtuZX+4bKrLuDE3y6lG/Bzt+ZHZkbCsYAqCtubp +PfGozr3jW+plZvnRz4X2GxQRWFw2jVBcBzu8f8Ahp7q62nT9bEfJ6fsKqwhX/KSx +-----END CERTIFICATE----- +""" + +SSL_TEST_FARMER_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA1q+/NuAjcD0tlhwJWLNkKR1bY/pzJ/55dNntySF/brSn89rF +V8vXU9LFu1XA2nlGAYuqQ2c/A3nMBo75wTAH4fm5BMfYArNbWPCKorYJnpKMu3u/ +sxydc7qNCfqf83lvi8IOg9Bc7WqzBNoJtrbsNXORUyH1lp8KLWHrV8VFgnijXPk4 +HivFp31I0XFC88hUQANep+gJqooX3H1Zk/ycq9nrmynsgiRRlMeoyApW/jhVFNIe +FQmc4Rzsf0f1+gfR1iU1oHaClMUHDLdbHZTbp7TpIINSbCT1TzP/jZ4ownRxAlrJ +OjBgolVR/77UenpN7A4rbCX5N+puTY4g83ivXQIDAQABAoIBAEOfWgiL8z2wV4KX +1C3XW65Dq/zC77DiTBmNZ4PaBEy3pMt/1ndAItQpaNUIPtXSK0XjWz8d71BF9gj+ +0haS7Xi1cxzZYeX/3r8WDWURF9iV6rRHV2uwkLvaQACrq+RCFOudtXq5j/vMhxT5 +JOQjnCV+AIGCCdxmvgrrc/jSj4F3sFiIpMh5z7oufTmT3vmcx8dk4dSCujpMywHm ++xFj7OQm3DGVY5sqF/tevkD2OTal0pWHj+EfvDaNWVWa9buCsjy8h7urPplLX+pd +ie+BIS1sID5YTRmFQrxzzbrDuE7lXB7yV47f0sj/+23S9yVqIpUIEqLhIFnrP2rG +iVFbISECgYEA+3AoJOcKXvWZYOHP4OeF63Qu0yUq780sk1I8DUSto0idoJPJZG33 +RB1/11is+DvfQDt8/C5SpfNONvRLfDs3uKyJ8aCps4dyf4Mp97nTpibRkXfUSc6T +1cR6HWw9d6Om1bqDAgp1HceWM0pGRg57tPmLzFxO91Qh65Ttp0p2w1kCgYEA2pTk +QYUzoOgbJhQAkYnzGSP4caYst0lUq/rfFIYvL6eejoLcqowst0iX0tPfD429wJcV +P45/JGN2yQz8QrPbctflsUCPVQ3E521oem5FLNcsKr97oxzy1HF1PWjHX6xhZ6/7 +tfVXaP2cCAeAKKCVvph3vDI7SzfU8ek0DK3NH6UCgYEA5KUdHFGtMKUOEPfHXbGs +KmzAl+lYnjBptJ43Val6bN1/2aIKpXUKQbrBokZVJHbtkS+HfJtzNM2H9pk4e4Qu +K5Va64s6RrOI/0N7SnaFbLYoJKxfM67S6LV+hnsDemQrNngg4h44WhhBEesc9F// +RpcW9YOLm4W6QsxvQI2KaiECgYA33Kd9Kzqnm8occC45A8VyHmRHP03cRcxy63mJ +uEVk63S1PTKCD7L54H6Urfsq8XGWP8Z5aMSLmzPna/8oWOjzr8OPCk3XUd6Jusdh +yr65GAC8qBVD+YkBzEFHQXj6tYZrRmmQ9jOxrGbtEmWpfGjovfSTz06iCZHNhWj8 ++Ioc1QKBgQDTA8/Hw9zpG80MY5e51AHF9amNOYGa7/OkhDBAs+U0zjQcF1O0IlMK +eooQuhSf6RX0/DI2JgSs4Yf9Gx3jvCGW4w4LGTN3veiyQeLocqbNlGijaz+R6bcP +zOfGG0s1vdq/thQbnBerx9sjoyE9RIeOmf2c7Sv3vn+uQDTR7QIpVA== +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_FARMER_PUBLIC_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUR24x4LgpE1t6Nmpk9Lbcm2p9bZ8wDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyMloYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC2ye4u+jn4ldMnKFJTrpndM/mgaOI9irWCQ9/kES44RvYz +SCWgNIqU83XC7siCkDTAfmQ5dPDgwExGp9mqbBjLa3QuWLiBSmstk/RdvWyYTyv7 +Tk3BXjmYU6nbBr0p310+D5Jw8RKB7O88wM603E5Cb48GKmh71DY5+JxwaIJbFATs +DmPXQ5tIO+z2WZmzB/Zba7pYOILk1XDR4YPLgVdvOGlaMCkfMALYKtdW9ek6hIFS +oPlm/mbzbIld80PYP9E3Sf9iX55GVytuIt5B0u6PbUYFcrKyNld9K1UEA9fyNECa +KUVe6UK1Kc+LYGdkRv/qAmMG85zMM4CHs1dP2jRFAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQAREhwgP+CXusazRom0cMeb +KfKZIY2TMHWTYceAB21vUDSor8dfDNZNaJGqNDWJiwxMdqCa6k5u4ClBts2silfs +qYWGQvUpygD9dq9Nazsf8GATZJ/X5OfVKSb/j9OsmikirngsB3KfoOVUz77aALec +yuH9tji46NtYUXEMYsCvQ+8SAmLQNra/jqzM/SHAL1Rz2JNxXY2ldBpsWuwaau8n +j4FqvQtT97zC/RV32B/Io4/LJnD2bvPd41Wf5YutTOJXUFuVDQPD9rI0VkZk87a3 +o7oGLlusWLZ1ZIqTylCNVtv/Lz0JXwImhYIsDcNswVhNIWiKHSJkR4aS3gqVt4Sr +-----END CERTIFICATE----- +""" + +SSL_TEST_FARMER_PUBLIC_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAtsnuLvo5+JXTJyhSU66Z3TP5oGjiPYq1gkPf5BEuOEb2M0gl +oDSKlPN1wu7IgpA0wH5kOXTw4MBMRqfZqmwYy2t0Lli4gUprLZP0Xb1smE8r+05N +wV45mFOp2wa9Kd9dPg+ScPESgezvPMDOtNxOQm+PBipoe9Q2OficcGiCWxQE7A5j +10ObSDvs9lmZswf2W2u6WDiC5NVw0eGDy4FXbzhpWjApHzAC2CrXVvXpOoSBUqD5 +Zv5m82yJXfND2D/RN0n/Yl+eRlcrbiLeQdLuj21GBXKysjZXfStVBAPX8jRAmilF +XulCtSnPi2BnZEb/6gJjBvOczDOAh7NXT9o0RQIDAQABAoIBAHu/0BpL3A142aBs +AviWf6KrenfoKisCCopri1trakA9gpcLZDXG/H+FKBfV8ze5i406xH3FtwJiDgHT +x2BCmLK3R8vM0vTtPgx4W3tPMAMZrqwPwkKEmTeQhLE9Kbn8d7L5deoyu5Xso7cc +zZTShcUio9DHyz7yV9f9gWP0zTP8/qYIlWTS6laSsBKlcemsMmSklopj+aR0Sbkl +8qF2rlywc4994+ZmD/TEQMSJ/BhPfUkQqCQdoOj2tPIOPtXFqckvZkfvYC4pWJLl +61GXxv18+y+QB5uMOUcTQ7vvLVPwbfXd7TS1bhUiOFSJw/fxmMtOOoGDOirxnfLD +8vBeVUECgYEA7BVUmT35dGp4tEvvvl/RUJtmBdj0prgMOjadO5DX0ZbqNYWFakuw +p9X456G1T3lgRqRp5YddJpCFSYH8YnKoOSCzZ80jIUbjDW/0mnESZCb5e8TXyj2d +TxqZpOrVkuE+Dadn2O/iEROz/oBXN/QpG58GqptsDuSJ+P3OjVW1TnUCgYEAxjWa +V/NcMWqY61TJabAy5wlGlF78YjdhNjS0a1vq4NgQcO7k0+Jd0ErLkMpTN1B1t+Yw +MW2BMz1E58AFKUzHd/f6eeJGzFjEV4cirwViNPkf0X7/mIGAAR/6DZLay/IxW3fC +8kWe0cqKFsXAa2TAtgr0q7ji/XaBmmRihqo1NJECgYEA2d3VdJX837JiMgDh/o3u +XLUMMdlF7ZVrs00zTQUeJg1floTh2nZ/UGPmj9xrtiwM7SRNlcSV8kDswCl1AGVP +WWkUJ3boNI12e7AVy3ENx98v3UiK29iAk7+4irks35995JvY+hpmRdwo/3TxCHIK +fbMEM+26iwPdUCrpswSljQECgYBZMf4G3ij6w/GU1U7eFMCTX4U3d5czy6AfeJBI +T9De5dxgNeEbyJ5XAZGh0qqoFbkjzJ6bX5/oowXDFJI+B6MrxZgeCUm646dXjCR7 +hnyvQfyjlfcHdh9YYj9wpEl5xb+YXciIpfPWjMKfhNYWffyK71sze7wKO64PAGWm +HCpdQQKBgQCftgQ1tpeLhjiA3PCkYUpj0XnErP0+FWhLq0pEkwsVKfprxoMO/foY +Ku3/XVtRat0w6/CdQpmN+pk9PDFle/rnD9emxqkeo8pkDxIo7bYSr5wF4oV9c36j +TTp/SFMfM0rMkuoMeNM2uVXroCXOExSbMmBcWfthFwoCJv8tOCGLhw== +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_HARVESTER_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUQsRmXdBM+Yt81O+qtGzJpULDwhcwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyMloYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDc2huslrMBGoEROWCsfrd4LwHPSXrehqP8uthUzpsxhxJP +HU2bDi4Q56IiAaXl33txbDnKE7zOE205rp0h/k3mvnbo9zBFHZakIZuySP5L/+ry ++Jyld9QuggpD5mWWHW6lCmUtGfY0UJJJbr6KPyMqzzQ0xrjLAPWqVvNR19Iapd5D +GsWgBSpKyUIwPUf8JpkFvSv4udZlrONoMA+/PAVEeCgOKbWdwi8vrpR43VcUPSe0 +TbxE/bWHgOSDW1FtE46logzJLOzvx/k3Lhvumfrr+znNsZyjk14peqkdAUtOA0dm +VEhs/wHthVkw/47MO7G96DzB0NI0++anRhNXLiAZAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQAVNEaquHBV5LaHJDGrr66p +xPuM9sjaahXr01VfAFBqFGzr+8ZH2T7VL0bg0vO3aimM+Kp45eRGM+gffZ70ab0q +94CVT++3rhoro6nXhx1U1lHRNRqVOyGImwMbz/MtmIAeme7My+kZDcNlFg+MC5DY +0pjN/EAoBslrhGp7yWzEh6oo6cKsYajfqcrewwMRrY7shqrpH/fs9gAB4uzryCVV +54tBj69C9JVi0d06YijpLcUT5czScd6yPlX61XKR9lpKUDyEGbRU+4f4DP2oJzzq +6tsME2HXXcZr2fsxkBeCjZpDEsKPMxsHBnebwSTNESCLQgdQc7wJ8QVzgOkAGoNg +-----END CERTIFICATE----- +""" + +SSL_TEST_HARVESTER_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEA3NobrJazARqBETlgrH63eC8Bz0l63oaj/LrYVM6bMYcSTx1N +mw4uEOeiIgGl5d97cWw5yhO8zhNtOa6dIf5N5r526PcwRR2WpCGbskj+S//q8vic +pXfULoIKQ+Zllh1upQplLRn2NFCSSW6+ij8jKs80NMa4ywD1qlbzUdfSGqXeQxrF +oAUqSslCMD1H/CaZBb0r+LnWZazjaDAPvzwFRHgoDim1ncIvL66UeN1XFD0ntE28 +RP21h4Dkg1tRbROOpaIMySzs78f5Ny4b7pn66/s5zbGco5NeKXqpHQFLTgNHZlRI +bP8B7YVZMP+OzDuxveg8wdDSNPvmp0YTVy4gGQIDAQABAoIBAEYIa+oox468Bt2d +YkiQzkEwNtSyqmHSNEI6Rctu0Mu911J7KlbXAkieC03ZU/A3E//9n72y0JZQlrxJ +4M4cxDs9fpuVdxsTrOdTOPoqJ2mWN7zglVvrSb+NwQ+TCfe2UZXIXBkXOHmSazEa +CxXvu4kht55cvdCx9zUS6Ym0dI26IGBybmr7zwOnCg7Kz4WTfO2JB265mLu/B6wV +V+W5cLPeh8bDKl0Za4+v4XXdzMmUliBmyGyyhT+VcuqQWwFwp2OrsPKAth73S4rN +pxMd1DrOyrZtAMgkdfzkNTJy7oFW54ns6OxG9p/p/t5N19HCL/kpUGcBoGUQFhXb +YxrLy/kCgYEA+xQRNVJTQIqoK0tCEv5dIyziD0ZfzsDDhc5+qFV+7uKsfdyRhLGR +GBP9JfQ7Yc0U1W2omreUGRSwVxU6YpqMQQS7tEQQhiQp3yHuP45mVKG20qqFzMDG +zeACkTOSIyh0BMkaN+nxkS4PnqlRaqUsyuBRsomof6y87g86cELreYMCgYEA4S5c +uf76WFOg6IFwM+1d0P2EDwa+jeXOvZI9fQ44rzyUNkMZfsvFw7+h8hsZHihrKhTR +hCemvEcgDIfiCmsCYMRpoI4oJUQGPCeD4mCu8I/ackIX/UCsm7OmoYyNX9KEPJ4C +eUCocYaETc31wjOyXqHzjIGynZd9fCFHRUjyeTMCgYEAoveRe9SlqNzW7tL4Xi+v +8GbvjA6XnTFNN4qid0yXCSMj5sXFxiUjEkfXJk1yRbbBcQ6uQ04o2GavVra2oM3D +f2g9FXKgbxEGBIiXhbU+Amy8p9x64D24TGS8Bdc9YYieVYTaebRlUWBeTxODfv8b +JcuX+5SSQ9yw/KvxuHAXO1UCgYEAjhG2JxMb14ZLyuV/aQOlYSnRm7lhmB0ZZrlR +WgkS8lyCFgoXl8vwpiPNhPZbzo8prY8c8QgjRj6Jld5VWsVQ5sSE7+tAoOJeHK3B +o53kQZpA9D2G7R1UyZd61gnbWE11aNk4LlAA9j8sUfpTx4beTp5XDpr1mj/tx9cn +JCt178kCgYEAttYPBKitz4UVAVfFNdJk68N/Tuw3KoZH06l0TCy1Ygof0S2GZpE9 +iWNVNino9Jw+AjQWK0FgKUVurK6fiBTlvtZHZk72nJRTGpeIGwa2kZbeL3qn9nQm +bsUE07d0gn+0Ztdo5iI8hB+y3xTN1tq4hIa6xCXKHz5Dnytqkon2h/Q= +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_TIMELORD_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUXa72z76zyiyFs6cTa7GIU/m41T0wDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyMloYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDTSy0YIggCwTF96eLR2AxXmpXg30F1eG4SZzr6xWd5sXiL +crUjSc6V9YZRPF+g6ODEryNYjSxWlYf0EtFPD1MGLW+7ssUJrWK1BX+FFCLvjQX6 +ShfRFoOqmkAhWp813xYaWihdLLv2UglphfekREFhRw5h8ikfk5JA3AgTFVGFjB/q +1pZ7gWVamhjjzvrbhiXdqcHDqMuNUMQoCuPLlMOq1D59nzYhUUYZOTP8aAOD2dj8 +a8plM6OQwAuQarqt9DW69Tm7AxKbFrXnzXqTT4Ccp4rEJxscV8OIP2DVioFLV37B +EWq3pVcarIJku+Lxcpf4C7jXvhBUYAFVeQLMmjzXAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQCSc1CA9sp1CEbEV+7+8EOc +5v3DU1rTEW4dG94MiWDXH/s8B+nWb2lsXLd9Gmau8S+/c3c8rW3eejS7YZ5w7lnb +NOdc8SUwPDM+/f89UCiEeuk9fUIe9EK3pER60Fn4H/0ZXQhVob+1lGScnIyx5vr0 +Hq5rPO99qnZ3kgLeYRfHQygSpFQ28XHOkQGVSklgCbCBdE0lNWKpaw8oxw+Ki2zb +tSGF5Uoel75Y3e2ZqtonZCuvE9Q02LGmDmmfSrRuS9jW2hvV/CHpRnv02GMPQT4+ +JTKtqOeY6+hI/eg4UKBYbGLY2Sn1irKMRFwAzftgB2eeU+Bhxb4ioksFlhDvzkMf +-----END CERTIFICATE----- +""" + +SSL_TEST_TIMELORD_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEA00stGCIIAsExfeni0dgMV5qV4N9BdXhuEmc6+sVnebF4i3K1 +I0nOlfWGUTxfoOjgxK8jWI0sVpWH9BLRTw9TBi1vu7LFCa1itQV/hRQi740F+koX +0RaDqppAIVqfNd8WGlooXSy79lIJaYX3pERBYUcOYfIpH5OSQNwIExVRhYwf6taW +e4FlWpoY487624Yl3anBw6jLjVDEKArjy5TDqtQ+fZ82IVFGGTkz/GgDg9nY/GvK +ZTOjkMALkGq6rfQ1uvU5uwMSmxa15816k0+AnKeKxCcbHFfDiD9g1YqBS1d+wRFq +t6VXGqyCZLvi8XKX+Au4174QVGABVXkCzJo81wIDAQABAoIBAQCK0TwqO8mJjcXn +VK9JcKkDMTPBDsyh0eJ3Qs00DleiUx/AdjddnNMWIL4DRygIvpdVgT82oWF87Tbp ++yb6yzWfvGBJL/VWG0zbY2ZZV1ZwjfVccCtfmmwcvMTfZPtu2EdcPtmABbDj7xfx +9SszCAjwUU+4t/GepkSTSjwf1YS+uJRm8JmEVJdysRo2p34hps0UQEQSQNpSEPsA +lG3aYtR0spLQUXXoDGBxJ/mHFjV8mlmYm9bVhfAdjLSaaY4z+e60LgiTUVApyLuO +Mm8OP86aIxK7Vy4U+okg0ZlzL3xgsXiReCfLDR4BaTbXYS80wsIg/tqB1soLzzSO +qGsMXMIxAoGBAOxnudUSXgv+bboPdA8cxfvZfJNc23/uBXLCtnEMHQCYok0jGro8 +o/Lsl9HkPRyX0DQXCaOwO3CkEXx2i3J8NKjTJuyLvfVefqclpGSxewq8+N09Ins9 +wxOow/3nJcDPJrbdgZP48cIqFleNbmF/CmsPFf5HWb6j5tTFhFWcwR8/AoGBAOTO +nBDqb8HjWXBOGufitEG1kUwjbsZQ9wnfbqdlugni1QurY1X7JlbAG9QyOQmLXngK +6NQVqIkvu0aWdiFavg3UUVaTnVmgKmmmO+npCvJmHUvwkKQaDpbScF4d1wLfaWe8 +pkaoaXUjuTQMF/lPh7xBDNMPz3cvSqjO+TDjrJRpAoGBAN/rr/2+lA5QRKbEFG5s +Fqvi6Ti7771ROx/khuK1UpNKABGIeryEy9ZBe9x3j9sRgUiVua+uMd8TyOxXbOZX +95khx/CuvJM5mkXAReKKqb0WGbOVQJ/zdF+er2ZEF2J11HnJff8nAfej3d24PSFk +L/4QIAjmlH8ayH4pSJu/Cr4JAoGAB7ZTGlrck3t3S0rGq2Q/0Ssuj5NuK28VNJb8 +YtYR9D1aEv+e5IoHm8rz5S4gMAsrjv5HJMbqHF2ogVOW/b7SQyMR7sog9qFobJE2 +2caKIOuCN0oPhgh+z2Sedv2ofqdLJTz9mcoZa+JdXry9niCpIZZLuV2CD7FfYdtA +GP7DlWkCgYEAllfMeW5fWwJsio/N8PDQRISlN8yh5HA9DPfl343c8cGCx5ENl9n7 +QOqa6xCTtTWPdDwnTQ8oCf5v/97bGPwpWrYxFxqzld+BIc8UHdtBEMwqzptvw2TD +i90QCyFVv/7y+izXLsrTUimCAM++muTYyXhfq6Z+trMr0PzAz5yxNmM= +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_TIMELORD_PUBLIC_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUfuygNa26jw3yA1o8IQkLYCW31D8wDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyMloYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDlsfb6//PmK5sQ+v3l3+IIjiTdRcoIxHB3e+fMu6kZPD0r +xLiIbQtw06CZsX4yVF3DaiIPobGKfI1fv7pxyHM5OldOAn52SFIWjnU5PNGfrw7H ++6Z1yCnB6lC89UO39ArbfiNrYGpf0Lq99ECHd/EjRP/mMd717fOQ//2zkhzeenXC +9jRffLZhkhblPCyFepVBAmBQPKB0rNmnhblwtueUM86LWPq0FrDp0MfP/HbgPQ/v +VxY1Pd0mBQ23xXnKCQDg4buXAqv9IVd/kNxzG7H8+5k2Ji1QSoSi301XWWa66kXu +svWc4125avodKiC5t3Czbce7kLAq8mvU32GacJ+fAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQA5M3qJYfjlVzdXzu/JTmG0 +4Mp2G8cjAXcSWEPwz+FI6gImLrA4tZz5MER5WxMQF9ALKKPt58qi3hk1b8Ko8OUa +wq802DBkg+LpurAmPNht3IZ8s4oTkSWOP3b0FYA+/rYqM4+EGBcso6cGSl6msayc +0eyUO+AlWYg+2Bw9AiDEiAiLMaODgmMh6ztmycNluMhP8TNOzQRqFlrEs6YvL/z6 +tryToIqZVjIZogcU5Bko8KMcLOEWbLprSzSd4CIJEtuao3TdbU40TZmhUgcorX0h +GKaAgtGOxcYjApuavtzr3BA1X/HKLOUNOMDo/27lFPSL2PhSBBRZGGU56FQm2LB4 +-----END CERTIFICATE----- +""" + +SSL_TEST_TIMELORD_PUBLIC_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEA5bH2+v/z5iubEPr95d/iCI4k3UXKCMRwd3vnzLupGTw9K8S4 +iG0LcNOgmbF+MlRdw2oiD6GxinyNX7+6cchzOTpXTgJ+dkhSFo51OTzRn68Ox/um +dcgpwepQvPVDt/QK234ja2BqX9C6vfRAh3fxI0T/5jHe9e3zkP/9s5Ic3np1wvY0 +X3y2YZIW5TwshXqVQQJgUDygdKzZp4W5cLbnlDPOi1j6tBaw6dDHz/x24D0P71cW +NT3dJgUNt8V5ygkA4OG7lwKr/SFXf5Dccxux/PuZNiYtUEqEot9NV1lmuupF7rL1 +nONduWr6HSogubdws23Hu5CwKvJr1N9hmnCfnwIDAQABAoIBAGKeWDZIMoW+byOJ +P/20dC3MKdO/JRFCli8Wyd1DLUUicfkay0f32ZOlqSyT4mTliCRgqyMe/0VAWMql +XP2BXMdTXyylMXrDbks0+uuKS05OMQB38W5cdGFHo0ad32dZple6/qYZjVJ6IdNw +zUvcmXHVLDG/c8UPVyYIYvr4XuC9zwc8QyY6HS5FLL2YeuDWXMFqhzNHRPuLUebP +cFHxM/doBHuL/hOvRJiwuaG//od+f/j/2tAjpg9Aw0+H9Swyzjbf8SCh40B3oNHH +C5FfU+F1C5vY09oq1HCJnuNuYyKz1TxUHcm6FZQbbaFcqMYK9u7Ys++ZCm0N6RJo +JMSP7uECgYEA+UO5pmJGai89V2/OgghxCjJCHy2eZ88Cn3iz2G6DU/ispiSOig+r +i9LRmoI2s9ip0mNL8oVjXABHpbohyWTn6PNFZq74VNvfGFyH179nXPJZwNszLueg +Aky47Sjmfbr/EZwPsaSXWNJVx+c0o7AfJuvDOC3PDvRIvCooB+RCwckCgYEA6+be +kZG8Hd2ys/hRzbQ27YS0Rp0uqLWHda7HxRVUcIB4eYFVn/kb3Ll+WJslO9/FZL7w +e+IWrU0N09qsXLXGN/4Tn/W27kf40F1kIcHaUGmgEgdQ9fmcBQIMGxmHr1OX8J0o +CnjMaqvdHkwQgiBAVoAtZry/ci0IuRJCP465SicCgYBgMygaM8FzR6oH7cmoW7Os +uLrWJ5gD/lvHyiC2vegHZ2jScjdkxylwvDtSw0BzZoIcBWCRR7OSFTWRm2VgwYXT +XNgDCjIjJfxS/Zsbw+4TbCEBkleNma0iVhPky60xBxNb63wPFjOm/v5GOVASgG11 +avYb32oTHmpX3Hk4mnq9KQKBgFrBNi0wsPuYeBCu3uHRjDQykpx8CiBTvipzNF3J +B/REKJUuQb/KuYJgRpBWF6wCOdG5d5FheLHxa/luLlN4hyqxb+FhSaBARiP7WfN2 +vcOj7zYgZHBNOE3g7MFcQAwej9y8yVPGB3aeafIm907ok3fz1gOpZ8nIM4vnz17e +TMCPAoGBALrKGVHHstz8NNtCwgthyRrOsh6shgSQrQ545wi6FVyXT0AEM9mI0x6D +hoErSrwA3WAikT4homKcF8skuk8IEEureOBLN3mj8YsrG8Ga5fUmGqxSMzf/IBK8 +pVPqryaTVINRh3Yk9EEZixme+u/YZ4D0owyCdph9yG6ojNqMr6oI +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_CRAWLER_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUWOfPmS17sBQ2KK+z+yx4bCQgBiswDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyMloYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQD9vVqZL4co41Wj3v05i+zWg7J+9ODBraJDHeEaw3T7fXDD +I+ZmzNDER6uWmEGqFOvXHdwi2b0mDa6+LLOB2ksOiLknMME7rAF1BusxhYLypF7t +8uQXq1aGQ4fb8LN0llRR3EagfB9mQEJtLHksK50Q39tL+00L/Te56zvjwJR4IwME +MifXGQF0TbN5ofVPOxVczpo5cULvVyLst8S7C4qCs9iHxWFe+o7CXlJRtedNL00+ +SdqkTllHXeEYM3nmSoj15telQDTW9AJyHQUTB34qEt8o2Oa6nrrEBRNHZGlBmwcF +EJt0EPpp6A4lHd8Iq/aQAhrweud/kWzde9oMBx11AgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQB0VYSPGkkpREqo5NXcXn3h +vhVmZwV+M1ZZac0/P5g/ILxhRSIWn1JTLd0y6eFznEPOYrQHZws33jsfZlU4OyT2 +8Ypxp6v2TRZjY4RpEPy85VAqu5JU0+FZpJkHt4PXaLSnOX3Nd1XZi0AXtQHLvrTK +qEe0A4v0hkwAQK1Ds02udRn2eyHSZVfMVchMPJSD2wrlZ5Mz7uIWNu1jdTrNzHsY +sSBZlwrOzUYSgYP9YucbzEquj/tmn2rhZXNDaFZZ4/Rw1kcKH96vBTIxKnf/ocla +bYmP7j1r3Auw6AxLR5zUtybAj2M9tdE1c+qSP5mvN/ckCBhwOP1XuGjHs40bAiea +-----END CERTIFICATE----- +""" + +SSL_TEST_CRAWLER_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEA/b1amS+HKONVo979OYvs1oOyfvTgwa2iQx3hGsN0+31wwyPm +ZszQxEerlphBqhTr1x3cItm9Jg2uviyzgdpLDoi5JzDBO6wBdQbrMYWC8qRe7fLk +F6tWhkOH2/CzdJZUUdxGoHwfZkBCbSx5LCudEN/bS/tNC/03ues748CUeCMDBDIn +1xkBdE2zeaH1TzsVXM6aOXFC71ci7LfEuwuKgrPYh8VhXvqOwl5SUbXnTS9NPkna +pE5ZR13hGDN55kqI9ebXpUA01vQCch0FEwd+KhLfKNjmup66xAUTR2RpQZsHBRCb +dBD6aegOJR3fCKv2kAIa8Hrnf5Fs3XvaDAcddQIDAQABAoIBAHmcMTnN76eHHVqG +2zKjf4VoZTo3vyjUQTqNrX+YQg7ulgbQw/JtI3mPKAvrOT18/XOCWilR1jfQwvle +j0IjD2oN2T+RPGuPCru97ycy6AnHAcBlczBs6/E5mHmvKTMtgYgiXK86DgqBrdSJ +RiIHXSXjREVsUgb2+6hdt7x2ZjIVEWTbepfJ+gA1y/4GHgrntC5CtDkm+uh3W9rM +HnI8fmnpTB7nT32IynVbQy4/+ZHflDYMoKLCIiamvyk4L/mSghYD2YFduoLlfAqG +r/G/lA5gzpnrzuPmudIil//yrEeEcir8xkeuCC6dYQU/T8AKJh/o9jEcwHA2SBVd +XK/UPgECgYEA/12P3hhGEST5j61iNQQtSr5p4vX12o3Ov2FSJYi/qzqDyz5GU1r5 +EGYej4lBQvR+C98hR4bVjJp+nciOcAejtaa/Oz+UU8nyfS6Z2NXqV0REZyAEeGLo +dVvUIFM24j/mNI2B20kJvAvBAz8Jy9efbBphTA/38JxBGSLKj8VTGbUCgYEA/l7B ++xXACCPGeF3UCWBghjB4vsut+LXiyf39b1n7BCaHiWGoiVKF86yUlaJu8DGxMIDx +U5jP0hjSww8I3qBY2K8iAegyMlH5O3RspEGNL+mIRVFMditUKRHT2wUsf6MkF5os +GxKPAw+nFheUmLsdin3Z4B9TgDp7s01ejFUjTMECgYAd8NZhb+8nK3KnSejt1mOJ +E/JOThBZY68N+VcsV3BBn0a8mbydIVl6dr62jZ09QHVW5v576G85YRPfZBhvQjYL +olVhmP7HJDJuQvx+0/X57WMnxDVB+DbRK8cfUyJoPJ29I6pKD7I4fhhPTSDU6Z8j +iaRGysiDSY7IZ6/gU35+0QKBgBt12VUk1PVL/2oRHwngGKuD4hUe4eoeoJwTyl9S +BHI/QpSHMW2ZthJHSEcbIQTXKHzG/sZ6kbzppx8dqWR3RQAnb/FqwriB9vj/KZdV +6EsK2AY7r5h2NwC0Bv33AgXJc+UEZMyLZVr8Ppp48zbFxHul+HZki1wldCM4MAPQ +UR5BAoGBAO+FGYfEeYmTVo7deE2GstA990IbuJxYUbXapSDGZehlu6calWGSg+dd +l/hugFQ3HiUxps8veJIHP5W+2LSgsN5zBT53I0YRvfK7/juAqG8Y8bUcDU2nG8BQ +/v8mMVAlIqNeGoD3szW1/6BBnvHBi7bKrAEoZGcIiWzb89av7upM +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_DAEMON_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIURUSWnNQeBOShv/Sz9MuDq2t6VVwwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyM1oYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDEDI/6MSomdp0AjdEuQgP6og1bMKOb/X0G9mEpvKjyIl+8 +SSijACXVRhSG7Nx0tU61pebjXF2ax6jgqpzSrrlv/w6WxSmRcqbrdZFSUWMG5FFc +dYfSKyrMmF/p0o0kXQRaBSeIhkLnGS43Zna1w5b7ak76EttzQd5uiJ6bG7vCpGn0 +hXNgdXtRIaruK4TWt740F2vyhIRtsEIUURaLe8MPT8ey4lm4Fz2URnUvfdMma7GS +rZIsT17kw7SQBlaqoGXslYNB2yMdnAWRJzuh6cvnxQax2Mfciwit5fkFQlnVPdZx +W/rLffyCCef9Z0m6WArb76OTwcCq4pmwh3dfOi/ZAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQBu0wa4sLoqzpBt71pELonc +siZZ+dCLuFCXvyt8nQcN8arR7Dd5/eb+kn1AFNRFggbnf/z/jTc6ujISUrHIzAkz +mVbuwzyA3gKzZfyTgv6H8N6qvqLPBTWMgs82UXdKE4gXuheUT9+lAp6z81FbuFK9 +PSX+gebb/WwxdEP0w7A4mws6udBnOpPW9i0ArZKNKgWl8RiaVxoJWt74AG/t6HIx +TV2iONXfZJO1k4rJb/jsmOavfXDYeEVrqXJ40f20Ex1wWPGd5Hm/yOrFutF7nvye +mHxa/DuK2vpqPuwcJLYr2FHatClZNiCza6JLeMq1CWgEJ0Io9fte87JuP4ZWi4Q+ +-----END CERTIFICATE----- +""" + +SSL_TEST_DAEMON_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEAxAyP+jEqJnadAI3RLkID+qINWzCjm/19BvZhKbyo8iJfvEko +owAl1UYUhuzcdLVOtaXm41xdmseo4Kqc0q65b/8OlsUpkXKm63WRUlFjBuRRXHWH +0isqzJhf6dKNJF0EWgUniIZC5xkuN2Z2tcOW+2pO+hLbc0Heboiemxu7wqRp9IVz +YHV7USGq7iuE1re+NBdr8oSEbbBCFFEWi3vDD0/HsuJZuBc9lEZ1L33TJmuxkq2S +LE9e5MO0kAZWqqBl7JWDQdsjHZwFkSc7oenL58UGsdjH3IsIreX5BUJZ1T3WcVv6 +y338ggnn/WdJulgK2++jk8HAquKZsId3Xzov2QIDAQABAoIBAFHGz7PUGDntFjZp +8YxzGwfL2vhjxItH5IQn94WaXXqK3hZDCgFcCWv6DIvvd1HzYv6gUjwahi0PBaGZ +aUr0eQN/h81aNqmmAnyLEPAeZMk2Kb4AhIQlX3fyQ2fcXOWDK1KFfeUT5ApT1ZRk +WDYffPYodQMZJJLiMe83a7lViy93+1/6fT/Rr1taSnIZOp0qsYlwKoi5Yzi95mrI +X4sppl3QCRKUQ0sIOHb7L4jI25yLxP94yLM6f0F2cV41flBIz4y/oEi2MFVRqF1f +hI3//VpZEEqyqNsSKzUriJf99EdcFa/SpkI1Gn4SJwep1kYBcbJJ2/L5m1metMA4 +IaKbYtUCgYEA+yYWnIkesYbWRreNp3WxcSm5y3kVXrf1ijCwXeKPNpEYLR+uCyaG +eoVihfAO7r39R+q4DVEC19uPO9AuQYhiRWgSkOTBxj2oDKQCo8DQDhzJLLC7drLR +a4ubYbpX/JwaTf3cnghGwTgGpxur2HMH1eGDm/zxSfTg5C3k4iljsRcCgYEAx9YC +nEWnkzG60pvjckghcTvB5NPcBUdw/UZB+gUNFfhpfXbOxvKf7Y2FkAwtU7PQD8gj +SqCgvSBR0mjIX4wDv+qj4bg4tw0XKHq/Ab3A4wOWwTfvca3swrhjuk+yFvn2OgYF +r/flx/jJmqJANt+AAbM+79eQt0JOef1XK84KXI8CgYEA9OAiU+ZugvHRo4n9GDZt +GMVyXq5k48HCK0dl72Sj9rRqOjUVYdHidTvw4F88cBPXDXQSmQlQGF//vHYzY7oy +9zGOSLCDL2OWoxyXZkrtkZUHogeAATBBePbaPeOPPsKF811+6qdvNZ4G/pDAcX9X +OHd193YdXdriHBmTfeCVT2kCgYEAnt6vOJnPvZ+9jQ5N5l8d5y3A2jDsLG49j725 +WhGF87+H7izz+wqMxojKdFiZ+H9tm/5awEuvPmxhYEvZcMyZdowOObcBr9WCYbYk +ADhhDpmd0oKro87H+Y4qCsatKMMUU9DR2LHWRgKuFHeFYZqR48gi8v6HmInoZedY +1AR8DFUCgYEA1OGjovhcCK3UsqlN3tGVqS3fZieFBJM7JrQ7NJnsHw3NeUc3qmQo +trUJEr862rWLazcnbRvy/Z8WgwwVOEvbSFpmigTLRQMxhvw67NcCqwgh/A077r/+ +9JL8ek8G8zw0L4PSjoChSwE4hM0QxhFkkwPxjUuBuLmd9XvwrHKJg+s= +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_INTRODUCER_PUBLIC_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUPwUT6RFj3c1lZddwvYGkWtbwHzIwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyM1oYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDPobMhkfO6/94LcS9llcyUkzxSeRcWOnmtEXgJxwe8biHW +5CWrNu5GMiCFSs6Z9os8M4Xl1s3DvYCfxiG5XaA7SqLX1183QMS/a4zOPbozuVL7 +tyLpGx511o6gQrHMPFIqc50SVPeW2gMd/PW9WcYXI2rmMOGMfUhI5kGSZFXIWZzT +DRdIEyFYsMh0vNPuMGhcuWglXD1Wv6LGEoDsvFnmvqzbplxgZeSilvUyEMhxx/gJ +XwhsdXnxwVcdg7DWA1adELbiwx4TrA8ws+r5EOK3uvmemxMhwcjMtKPU3LvafBzK +R5MkMQpxY4RehqO5TiCAsJXMrkLoKkMGCtfW2TBNAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQA466vxCP9fhomcXQolSuIj +speXwl0h7xPZvT+0dk+HVJbr/peTKMlg7szvwbNmjJHijwlHD5oim+GB6+WBiSXS +G9ceIe7bBLoPRizsw6b963u8jvKHPRXux8HNspYw18MV8E4SxMB6Sqtk+i8HWgcU +kSu6wjQurRjBMuZtu7abRn8gGhaRWMbu0TRrJlYRDpI6zQJfo+HWc4Wn8knJ0PGo +BqLKD7kCrTqp9eES6WUKMBJ/xLRdIK516I8gw4mQJxO//Hej0o98bkFihcSZMT0o +y4QKE9FN6TjHYPTllouTn4G8e43PnqYT4K8pium+tIuO61W+4OsgvRnk7ykFJpgj +-----END CERTIFICATE----- +""" + +SSL_TEST_INTRODUCER_PUBLIC_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEAz6GzIZHzuv/eC3EvZZXMlJM8UnkXFjp5rRF4CccHvG4h1uQl +qzbuRjIghUrOmfaLPDOF5dbNw72An8YhuV2gO0qi19dfN0DEv2uMzj26M7lS+7ci +6RseddaOoEKxzDxSKnOdElT3ltoDHfz1vVnGFyNq5jDhjH1ISOZBkmRVyFmc0w0X +SBMhWLDIdLzT7jBoXLloJVw9Vr+ixhKA7LxZ5r6s26ZcYGXkopb1MhDIccf4CV8I +bHV58cFXHYOw1gNWnRC24sMeE6wPMLPq+RDit7r5npsTIcHIzLSj1Ny72nwcykeT +JDEKcWOEXoajuU4ggLCVzK5C6CpDBgrX1tkwTQIDAQABAoIBAC/N6gFTqksmuAfo +YmJAMB8RGzVd3dvnULZxLDMMGRLgRHhGhQm7lvagee5Wf+Tg58PPlQeLAksL6X5f +zsnv7YFZOM77Llf5WJM9/uhJPALGq31699W1wbid0q7BTFBanwxZHBPpbivUPB1+ +bVHQRpRzOhyPqo5/FdJ6+SPsZ/e9h809qKLgqDP9qX8H1lcvyvWev8+63JmTWxJx +d5+J4fOZzfdOqH7D7gqSKlS1f9QX/9mfsiy4PnXZ3lQm1C4l8n1t9iHcM7Cv1hVA +FELsLWTUVUPhn9BgWaIqbq+oSHzaJfWexys7v9dtO0ndO7uFKm8T2hHMFh5mkwkz +jd/dD10CgYEA9J7Q+dc1haY3+DQXHDThhEh2iFyOFWVj3V2a7PCLBqy71CxHr9XR +qVakwiG6Q1Bnwz/XmjKUWq3veXkVErmZOAABU+HIFA9QAO56cTRyyfNO5NTilE30 +VE20rf+zGOupyidMXfKS2rAjfK9RPY/48eKlT8mWj4oEIRIatTUQ9dMCgYEA2Upi +ddMcXTNMDIVe9pDGLSljixlU3EizQPmRczlC/tAC/VAPqqr6FPHrxWF45qhpQAIV +m+zqHG4Tlsq9GMI0QjgAwKRoj/LTJNsejxPKWw2m70XC0N/7OqrOENdNBmtTA1vD +MIuBU3t3u/apGNoAXq2Lzi/qAzxF5wz8nvf8zV8CgYB8ft+IZ/j7Xg8aKRih6F/l +/SMmX0SIqyNaJCuW7w0yhnLJlwec+8tKzafojVXIsIE+o51NAvTx+ZfpULBi6UaL +c6U5Va2IWAq1jqmON8077rJ2T8pJBCuXRDzyWTKDOl0dX0bEgZIv7nkBGhDUrhNa +t6i+pLAVuX5EfnxNQQaytQKBgB0MJZdsrlkDN4Jg/e3mMqfs5YK90ytTiKsB8eC+ +YedgdVXZsw50ptPP912+hwQGtXM6FBtxE2bTjEjXN2os5AGKLQeTsuqzYmiF5lLo +KV/8tjk8USvNFW+lT8DOl1xpUoKbbL97lsFLOxlkgvxwgCYn+w2IODdQgmO9x7OU +oTXvAoGAa1tJJy74pmt1INKATcDst9nJzZ0KqV6p9nFXwWwdjpv+qvc3JQ90LtJN +dYFLGEzMhp1zi5fSez4SoA6m574UgLOJCZSwWMXyC02a5THmRpCzLQ8ZZfHFEyie +QD+oEewAG5ucttPsaj2iK9YI3RonLcuQGaFuvRqsAuNWMwQyDtM= +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_PRIVATE_CA_CERT_AND_KEY_2: Tuple[bytes, bytes] = (SSL_TEST_PRIVATE_CA_CRT, SSL_TEST_PRIVATE_CA_KEY) + +SSL_TEST_NODE_CERTS_AND_KEYS_2: Dict[str, Dict[str, Dict[str, bytes]]] = { + "full_node": { + "private": {"crt": SSL_TEST_FULLNODE_PRIVATE_CRT, "key": SSL_TEST_FULLNODE_PRIVATE_KEY}, + "public": {"crt": SSL_TEST_FULLNODE_PUBLIC_CRT, "key": SSL_TEST_FULLNODE_PUBLIC_KEY}, + }, + "wallet": { + "private": {"crt": SSL_TEST_WALLET_PRIVATE_CRT, "key": SSL_TEST_WALLET_PRIVATE_KEY}, + "public": {"crt": SSL_TEST_WALLET_PUBLIC_CRT, "key": SSL_TEST_WALLET_PUBLIC_KEY}, + }, + "farmer": { + "private": {"crt": SSL_TEST_FARMER_PRIVATE_CRT, "key": SSL_TEST_FARMER_PRIVATE_KEY}, + "public": {"crt": SSL_TEST_FARMER_PUBLIC_CRT, "key": SSL_TEST_FARMER_PUBLIC_KEY}, + }, + "harvester": { + "private": {"crt": SSL_TEST_HARVESTER_PRIVATE_CRT, "key": SSL_TEST_HARVESTER_PRIVATE_KEY}, + }, + "timelord": { + "private": {"crt": SSL_TEST_TIMELORD_PRIVATE_CRT, "key": SSL_TEST_TIMELORD_PRIVATE_KEY}, + "public": {"crt": SSL_TEST_TIMELORD_PUBLIC_CRT, "key": SSL_TEST_TIMELORD_PUBLIC_KEY}, + }, + "crawler": { + "private": {"crt": SSL_TEST_CRAWLER_PRIVATE_CRT, "key": SSL_TEST_CRAWLER_PRIVATE_KEY}, + }, + "daemon": { + "private": {"crt": SSL_TEST_DAEMON_PRIVATE_CRT, "key": SSL_TEST_DAEMON_PRIVATE_KEY}, + }, + "introducer": { + "public": {"crt": SSL_TEST_INTRODUCER_PUBLIC_CRT, "key": SSL_TEST_INTRODUCER_PUBLIC_KEY}, + }, +} diff --git a/tests/util/ssl_certs_3.py b/tests/util/ssl_certs_3.py new file mode 100644 index 0000000000..cb3bf0677f --- /dev/null +++ b/tests/util/ssl_certs_3.py @@ -0,0 +1,684 @@ +from typing import Dict, Tuple + +SSL_TEST_PRIVATE_CA_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDKTCCAhGgAwIBAgIUeLxDdxR+RmiMMvvCxRfsQJAL7vUwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMB4XDTIyMDMyMzE3MjkyM1oXDTMyMDMy +MDE3MjkyM1owRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8G +A1UECwwYT3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEA0Bvshi5y4VEw+k32NOOMFZJaraLoJx5N1WOJDYGqSDPe +7ICPjz4IWDQN+yPrFv+ms+es3Ys8WOKEOMWR8U9mAxG21t+n8LH7NAMlCRNscBZ/ +Si04bqfrBc3adznorQLtShOpYxEfRdu7kpHo6+D+4Av96qMpMLsPKiZWjjy9O3ai +oNzymj0mwlZ/1gaxpvfmvuqNNR9Kog8o7crLbp/x0ZPiU+Q0y6Kj4saZwu5Nq2cO +JqLn6ex8w576/UOAN4u28S3m2pVgoYkqGqJSXORUqZj38Ro0zAYywIHjiIfhLp5a +dhqDyf/IUCawltEzdXoOp3irYaV0SmAB8+e2ILZJawIDAQABoxMwETAPBgNVHRMB +Af8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAchOBNfaAIoP97Lmyk/S4Hu94I +bGqj/BT6/q+UnWYcIt3UO6/d9a6WO7xtSPKiuObip8M6UQYVKQC8YecnAvXFwI6Q +r4z2TdGx2MjsxfQSNX0BYASlv5EWd3LYJs+Ayi2lxh+3XLSH+BK/7R1nL1MaN161 +vAN2rGOo5J1niWyixyGK/jrKTtsRTxDcpFeIYdk1r/qGiY5uxwg6ny0JYHXYhSNm +AyADKnZoXw/kb6+mEHJHZaTR1JpNHkQ7azhNYyVMUseCi+5vYuzA2OoxSgBegSj+ +1fRUZI+j46hkr5Qspw9P++dDLzEGgarbxruRf6VsosU3sSYxq6LC+a9UHXNG +-----END CERTIFICATE----- +""" + +SSL_TEST_PRIVATE_CA_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEA0Bvshi5y4VEw+k32NOOMFZJaraLoJx5N1WOJDYGqSDPe7ICP +jz4IWDQN+yPrFv+ms+es3Ys8WOKEOMWR8U9mAxG21t+n8LH7NAMlCRNscBZ/Si04 +bqfrBc3adznorQLtShOpYxEfRdu7kpHo6+D+4Av96qMpMLsPKiZWjjy9O3aioNzy +mj0mwlZ/1gaxpvfmvuqNNR9Kog8o7crLbp/x0ZPiU+Q0y6Kj4saZwu5Nq2cOJqLn +6ex8w576/UOAN4u28S3m2pVgoYkqGqJSXORUqZj38Ro0zAYywIHjiIfhLp5adhqD +yf/IUCawltEzdXoOp3irYaV0SmAB8+e2ILZJawIDAQABAoIBAQCDVHvpGbrpsiEk +dLqhGdA3dMrAtQOoXBlmRpAg8+kP85wEyATQsqb1crQ3/qzHMMJ02glfLhUBSsGC +SjwVerO30CAAbdg/rzIF2s4uchGGksv1daAdRN6uJQBvKR5KwIQasVm96PpBTa+L +iYTiBnUR0r+EqT6/P+0L/nG1BWOt98bITaxO5Cn2mXGP1ZZ8iA9RBx1pxMAUDG4d +5Y4+Xt8YMP8OfEeVIFO/djRTh0OSTugSGwjnJReF+clX19+dJ/aBXOUHrLdNCV8c +9GjqHDEy6rXIb9N8UY6nVVvzbC/ypY6k2VtDhnWUYaLcpuHekmrONJRKXc0lKR6w +8FDACpvhAoGBAOi72c+PH0FjT2pyVQLc/Ht5UDt0jvsGPEa+EvYYC+ZFEViXj98+ +KGxtIrc6Jab3Si/eCMS+qPAO3F8wC1J+qHq34g6B2v2SH3d5KOWXZwMFkEcM3psO +xBawVtH5suhTK86Lq/qi2EE5yT0NNlM+NM8zyhYtm/w8kjnly/5J53DTAoGBAOTp +3+mvSyah3pBTDHLlLUw92baOAQRMR+7DHOmtsyVwzbZXzES1IVMt02ZH5FNN2nk7 +8XUldTNUkvnHPrGVogI3d8DlWctfh7ri0T9SgydudIOP9ETmdr379uepAHQavE8q +fyxi5o1Ypp69rPWZWmicTbiNyhAoTqFhauA7XCYJAoGAayDlLuSLl5a2HKKKPSop +0lBSPTv3ANeq8UlXAw6ok5NhW61QXYuIIfjOjRbn9AZKkOQclyvIKdA9YleELrH8 +rZhtJw5hFm2nrGAKEjzx/vMVqY7j/O38FxGOtVLCJqz6MjYasOE6uDN4TXECe6jb +uDD3qePOtHnROXNsxh2Qul8CgYAq87tA9NRMDmldeUfHszrZqG1WdLS6IroIkfG1 +4xLPPqhKw5Sfe8EiA2I8Odcczmnk/5th2MJx/DeLyJf56FK6yb+doStFHsqwBWkv +0YKsfmw8V2GFIB09rq54b1yXbIDS9e1g3bnW4cB53qs6dijhohpvO6OjfnyqiUXt +hxXWSQKBgA//yaex8PP/QQNzTYVgFGLmy+TuI7rbrVtVRs1tUzpitzL66Cd4qdL5 +qKeMxbohv6aeXDYQweemm5QFvrP63syIyphe/ZPwF5q7V5ZtFwUVwXYW96hwRdVk +lA+tw7ba6RnXdDI+i2PoHfmdP89WJWeucidP8VcmhY0RiAYpG/vd +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_FULLNODE_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUFhEfo/xtdcjm/XhkbuouJaZUBEAwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyM1oYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDQEygAVJgviM/8f0wuEsmCJoiNJ3gvrX8EckcllVXeyg23 +iXiIadXqtCdPOXQlJHw2fZ838o/WuJkI9TsrtUkG3e+VEJKku3GtDez7gDufVZd9 +e7jmqbO1mMwvpbFwEUzR9IumsxiOqDVAzSJIJGnWKhiOLYkXdKI4D+dyniEMKVFk +Y1TcI1huQngH+dBYujHlJZ4USOB+xVv5LfgrKYiZyHdKmRchIdhcjft5b7gBp38z +helydqA+mEU8zFqL5iwpNOALmije5IQKDrVHThIVmlg+G96DakoVBcpEqttfHb0N +E/oX3v0yAeV6IJ94VwCsSzndHt/KEG5PjsqQ60KHAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQB63tKOcuBjL8tjnIlDozpm +t+LRcNiubKRc/rhTBYIoO6cTMN61ITe2FvogzNAPR/wmsaDO/sqG1oEHrrnJ7hXi +zNVj3GC7XYlqXvoRsCTdqoZE4ATPVZkJqhDx+/5IruWo1Q7F3nPzjLcS3mpwu2xc +Tl2HBEwCX2gTuG6lB5DUztrgGLNh27pqRLoGW4fzmVtHD/z54SFsQvPw0flYMRtc +qA/4eoWLvQNGoqsfA2F+eFTlXiPr/jp3jFVJvqixlwEN1DJkTi7hfMTEty7xrlZq +dZUmYxygqt4sy0AMbwCbemYJmvONlW8lN5GYo5NjB0BaMYsGMrehY2XHZg2npy+U +-----END CERTIFICATE----- +""" + +SSL_TEST_FULLNODE_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEA0BMoAFSYL4jP/H9MLhLJgiaIjSd4L61/BHJHJZVV3soNt4l4 +iGnV6rQnTzl0JSR8Nn2fN/KP1riZCPU7K7VJBt3vlRCSpLtxrQ3s+4A7n1WXfXu4 +5qmztZjML6WxcBFM0fSLprMYjqg1QM0iSCRp1ioYji2JF3SiOA/ncp4hDClRZGNU +3CNYbkJ4B/nQWLox5SWeFEjgfsVb+S34KymImch3SpkXISHYXI37eW+4Aad/M4Xp +cnagPphFPMxai+YsKTTgC5oo3uSECg61R04SFZpYPhveg2pKFQXKRKrbXx29DRP6 +F979MgHleiCfeFcArEs53R7fyhBuT47KkOtChwIDAQABAoIBAE6dPjrJu2oSPcq/ +ac/qhznmRydVp0IUQe4zIxBfGL+BBae3h9O6cPkpMcTsBybVXxzTX6mquo+81Q0e +YknER6ARkCh4x3731x40KbpoG566nu7pJNX5fg15eoPyDVUzJBwbUfwcpIWZpe0i +0/X/1AD3jKmDKM204mleEOssNX47G7z5GlLY73hRN93+LAFmiVzIRsNAmkgEOVKV +NI7kj4Eax+1i6LfU5EeSi5XbqaEopWyxuUg/WtNFJzaTtVSnZMqUvMS7R0b3hWqL +KeJCe+H5JXn/GUUiHUcKaFW4yTXLEGMOSXrxevEUt/+PwEKByVIa3Y3ljVh4eHMg +eSykGAkCgYEA6WiLDxSPmSYzQRHkD968bztk0x/XSEbCoJdS8msGjwApJ7eZbLBz +hW+4k/HhIPez0atU2TBm6XR3YauWxtu+p93KjvqieMHgudZ95+4hK3jkUTpnN4Lx +MNfZsEsUpiZ34kv8sjJxr56gWPBdMUdyAorRqeQGYua3Ddg6nLFXbZUCgYEA5Dbk +PewvLZLX7lbN7Y7r+uSLIOq2CuQLMirLuDKooaQFLdjhbxZqpQ1UlLIb7V66PVTW +TJCWr9M3btWMwUSvWquyCJi0ppwCRB3JOiO66eUqUwjT6gv8jXy9HDJLRc8jHjbF +Xvr+g2IxPr7tpVClBIq+NJnP0vAhPN0DGVGM0KsCgYAEo/53y0nbmqXUOl3VbvFC +KOUlSXHHTxjZhoiwpy4XM8KdtonHXm69jW4XCu0V8bbSiVyDgPHa3GTvPTEfPQk6 +Xy+CzjriucAVEc2pCdQBAENR1h5tPR48gV4joiqD7yndBvO8O0KFYlr/ya+gpjH/ +GPF4Nj9mQf4LuWvY57G8TQKBgQCAfZNmdeteKnZfIAqTvUuKGFFpOB1E5n6TQVsw +G32sfK/Zz2ml5SYoReggTGPC8vnC/FgoBaSB3FcylRPJ4UUltNPpWSklQWNZPLgG +fwWHGVsKI0dFWHhapSfIj1yoMmbgZRAdWQ4hpRB69n7Q/CXc98z9yrgjWMYuAXX0 +NGEnPwKBgDpMnmFVf9YqtIrjb2dfUFXi/xRM/0C5/fKOxLdMAqelQrHUCzkfjnq5 +sRf+TU0gV63g0vmDkrHPDew7NAr8m/cehPgELvtBvouEbGNQOuvNDunVwLU6vaIh +OqtmlgNu99SfZUJUg8pIOD2oAJKSSg+iw11bnPuKJxPyWd9HtMZl +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_FULLNODE_PUBLIC_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUO/5znSza9Dx7FlysyCyStw2FDwQwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyM1oYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDFUvDaklLh3JqASKA1I6H/cULbcPCiXDy5CTtXJUzSRc8Q +ckjI4pepWm2/qPKkmiW+6V3irdc1sGF5ICB0mh41UAu5338+0nuQ2n6LWChL4OG7 +JNU4uBIbf5PXmlZhj8BHAfpAi0rvXIdlEUyVhDnjfnOnYK/2Eivh5gOvnmoHA9EA +BI1KCvhIdv9H4Vdrl+iFTL42hPe1X4TBRcg7HuFVZ14kzxWQ4x9Ep/tzzq8eaLSM +rlrRmBlrXMgN66ib65deEbuGPxVdHwY4OkR7hxal41ON6sduZ7d5ypHWGUwrT0eY +Pga4/b10/trBHGlk7cFmLmqTDVEtPMgrHFrtM4YJAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQAk17NlkhSre6JbKzlUdYB4 +GOddsueSKsnathkvevXLM5Q2zhY1GKdeT6chlflcgLs1q810LwyAvVD/A5k3jOZM +YxR9mQMAARuk1qZsxeYfu1ARZWEU77HJj2foWw0r5+1FmT5vCPZoqnINElXHMbuy +DtgYUjAS/31pqHtFKrqFAV3IruQyosYoVOFmKb419s+7ST6u+FQZpiouKKnSpqfc +0K9+O4pcCvPgcrj8rTK5cxLeIYd7LwL9grxE9DrIJhsaoKUkwM4+tiimr+7OSYov +byhFnXiLH9MEZgJXtV9jwQJideTpcI7rdVFVc4+tEP9A5Prru6asNC2UsXbg4kZy +-----END CERTIFICATE----- +""" + +SSL_TEST_FULLNODE_PUBLIC_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAxVLw2pJS4dyagEigNSOh/3FC23Dwolw8uQk7VyVM0kXPEHJI +yOKXqVptv6jypJolvuld4q3XNbBheSAgdJoeNVALud9/PtJ7kNp+i1goS+DhuyTV +OLgSG3+T15pWYY/ARwH6QItK71yHZRFMlYQ5435zp2Cv9hIr4eYDr55qBwPRAASN +Sgr4SHb/R+FXa5fohUy+NoT3tV+EwUXIOx7hVWdeJM8VkOMfRKf7c86vHmi0jK5a +0ZgZa1zIDeuom+uXXhG7hj8VXR8GODpEe4cWpeNTjerHbme3ecqR1hlMK09HmD4G +uP29dP7awRxpZO3BZi5qkw1RLTzIKxxa7TOGCQIDAQABAoIBADJ/m2wUbmmnD1Mt +QvLWf6rjzXxjVvH2MQQZvLn8rcBSZT+MP9xJQQ7yOYwHLLG7UVWeW4ybeKwgy5E4 +C5ZLqtdx+M5EyEfHjh/wCtqWYRmqH5rJPlgZo2iuKaPPt7OYGlkRxH2oKDFBuNTA +rJzHDhmOTwLS17VdySUyvFbBb9kDSQwaH04yRhsGoMuy+qmBc75eOCl6FtOFHtJ4 +7EjdnpRp6L6lKU/pMflVx3kwepAjGul+xZXhkXdfyLfGsAVsZQwePiq8aMZ/S/Gj +yqrCMQ+EqeTb57SSXWK9XYrOIsQZSJjuqiOOYgqKofv7HqJlmC1cLhgoMG5o0jP2 +bTKvOxECgYEA/0ythY6A5KxT06gdYltsMlIcuamVw5EjoDpf8oyBwD6cbUm8Mb2t +VOtPbbHxx4NqGSn/uxT8UgmOGZ4C04CwmgWmMmODCT/c9LBHNbWOTiy4OLIJdcUv +01x1tYZvdbe1FYKxga+hR+UnKJT1t0m5UjKjhXnIYGR+weXpm2hco2sCgYEAxd2K +ggTm/xNtDHNxjygKik4FfEhGcgafnpCrm6dCGyLAe5+T9YOt6owGTS2AiJiG5PJR +GmJxyJa44je/r1+LLVN8SmsLXTX74UizjoVNaCoy9Ze3Xb4RNsPYXe0wIgCi+hBP +PEmFZvSxlxXpHP0ppknCxI08wBWXH6goSkcrDVsCgYAx/69gH7eIkWNdaWhP0f3P +oRs1FUxaX7ttbuFJnFDw+JIkKTOtPiuLHQaSQi5K16bYxMvrtMFxw6NLyxFcoLB1 +ibOx3KFWF2bLmRZpI2R6VPHDUMLfiL3EFDCNW4XKtS7GxrDC6EWa0fsoTHwO6GZd +/cLeqiofDq9wg/mLURYLfwKBgQCcywLAJ1xZUy59yFl7pLI9iLgmFSvlncQNJf0m ++jKTSEWZcQoRash9bXps3BrXo255rF+CdfJOjslxUdYPBbpHL7n1SsAVm/q+Ohs3 +XADMA2ygWxpOKZiAek9RluwmdbSwTg5L6sLQpCS6Yf15IFBJ2neBw54ZZMJ9roZG +3gCKswKBgGRoPW6/tJRuf/OfVM9szhruhNa1tUJre2RrKnXzp4P27nfLHKUuHFoc +A0NXSDu8b1WDFHi2d/GIQm/ldiShGqx8HLY4fgBKTMLZ6nJXZ4uhv98xjOYy4jdI +X3HwYl1ukULFfhMVlS4qF6dQS2FF2ZxbkVwKYCjFrtyEJOjYcce5 +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_WALLET_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUBN4qin5jD3jO3rKq1yvO8YTCOM8wDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyM1oYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQCkLFKcf8jK2dB0dVNFO8ULxmS+4939oXH/TSF7JiNmUxGI +WkPyUSgHQOatbhAK7Z91ZnmWyVrnGzXjccvW64uLLrLFA5mL4q0iiwroxPnaP0qv +w5ZnZmDgH/SPrzt5yw8ndagkfpxLekG0Pwbh4Coffg1VgEw/gqjv//moUTSQB66i +daNHd4bN0KVDXmycUdqI2ER5iqnDnb6Fi4DTQXSkwd29t/mRaHcQLrwiV58YqsBF +YcpE70UWgV7j+e5qYUlzJ0P6Te8QU1pjqigWoAuJNptq7E9wenSJ+7RZB1c+R+48 +bBuQpoX+UVQfTHIeJ2NSKiMN8deLUhPj+fQrCp+1AgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQAccb5ZaUOWhp4FAwQ4iTfo +5RHaPGD770BgpIvl5yKAmfAN04iF6GgcCvZP69m5lFlNuQNaz0kOTIY8cNvrksHF +OYNbm7aHHdCGKs8sjdXxrJrL07MwRsN+XdWIDECGQBIHmvcOeY3HLdxcGr1lSpuP +xdT79hYrYeMBaHF3RVItts6fNVBGFmA9hf6/cDEIRt6TDbfBy+PCIRQO3OxKa+ch +sIemO+3tJsyB6xJz+iG7lO8QCI3qtn02XoGM82WMjgJVorWMzTSoMIP9UWMECoDw +Q9zy6Fqy4cOWT2qduWD/7r+5e2jmI22wEU9LW3QlNt9XziVBGqnZEiKfOdnf3XdB +-----END CERTIFICATE----- +""" + +SSL_TEST_WALLET_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEApCxSnH/IytnQdHVTRTvFC8ZkvuPd/aFx/00heyYjZlMRiFpD +8lEoB0DmrW4QCu2fdWZ5lsla5xs143HL1uuLiy6yxQOZi+KtIosK6MT52j9Kr8OW +Z2Zg4B/0j687ecsPJ3WoJH6cS3pBtD8G4eAqH34NVYBMP4Ko7//5qFE0kAeuonWj +R3eGzdClQ15snFHaiNhEeYqpw52+hYuA00F0pMHdvbf5kWh3EC68IlefGKrARWHK +RO9FFoFe4/nuamFJcydD+k3vEFNaY6ooFqALiTabauxPcHp0ifu0WQdXPkfuPGwb +kKaF/lFUH0xyHidjUiojDfHXi1IT4/n0KwqftQIDAQABAoIBADLetP5fLgWE9m2P +iSzTt1vNrpvjmX6kjuEvsicpiyCCrtUUOyeTdBbDSncEup3YQWesSBKr86nWqZz/ +Ps0qkUOgRa58ThClPUaN1OSJXG3+3JKXxTvm4i+wVyRKhOBZRinQ8DfWr3FHwaIr +QWOuBP9bHKCYr4eiYdxz8ZTxDJtv9trGCajRnTv/zENoAHC3Jb9g4SPZ+bCNP54n +gBEwY9c9tP9DKtGDMS0wfLO3La/VDO4Ft0KGMMur5hyNzi6xA0v+HJmaQS3h5nkO +H3MbDQBDbuvjpAk4IlYKExFsiXbT3v+M1Fq3G1z/32Gucx9AraMngdOOyoxe2NvZ +KgtD4wUCgYEA0lwkaXW64p+NE2hEorqBadCDyKmHnYhKjzG5/PuoOxlBsAwtx7Ce +fJ40C1yu4OTANufR7VXWOgH1eaO5lCEe+VhX1NyVb5otuJrnAzKQ8da3lEIOLPcb +fDkGS9LKdEWSIeA7gIRdi0S+EFHbBqgg2hsWO4LVAc/6N9OlPNnfmQsCgYEAx8rd +AEw0mqE/UWvofI60b3pceDkcWtOZef2WqkVLYRvWjh72S2KSmhbJxB7aAQrSgvka +9aCHS616yo6tai07evd7VCRNmPzozRnG1NlwIZW/eFL0JYOXuuH0C6Iqi6q/VLtY +iBfz7114IYGA8Nqj9GKRfZXFGuBZ0sbSetNhoj8CgYAf1NuZrbv64QPbBPMl4K0G +kwvuCGFCIEaQBolLU9VwI/FBr4YZ6osA9nuPoJXB6DuB03B7xnplSriXkIPbe2uR +daHMzxg5zA3RGneMj1FJlyEuaRR2D2p0ULi4Lox+LazgPWsjlmQFWACevZQ0HKrj +9idWGAUdghgt7HPbkmh4YwKBgDvzGkdplmtDsS0sVPFzHJ9Ktw54DJMQZUAeoKPs +8QZthP7WOY87P8QuzFIl88JWTf5w4u8LQS2rG2pGT7DJa8ylEAOadRJP6UcJ0giy +Shw5w99F/O54wwGXpVQMT/nivVCeep0zmsWbZV2gb2FWKdY98WwekatT4IAHmsay +QNyfAoGAVetKQkO9H3VvM8dloVF/Bh5ui6uKlYO/zNop01ClUH3KBc3WwdVXCasq +BEsJ0HiuHTU5N3UPicvLddCdxkAJKTQkwqOFqcuHAv6HR6RFBWaWN/iz0a78Q1Bh +gwCYEHjiPevWb3rLufd26SWtG/tIsrIEjx3BttKDRqqngLKSUvE= +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_WALLET_PUBLIC_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUU/+7JgmNQiwRivfB+ypu3OtSTJEwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyM1oYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDT/HGxRGnq6IATEXgdHTrT88mmY+JRNzeBnD9Uh3uwBkai +kJam31eY3oxEsQWVZRJ+Qsynr+VBgxFquNBnHmQ27JOqAH800oM1CC0bq4Z8ac6X +O1SjCdUQdaqpjScUNfxWgk6gG3e9KiuHcvyOezdIvPb5Z8Lgz1Wk53IiUpjOBRrL +jvBYVebvpAog12q8Flbf3Myu27ZsL3lUhVWpfl91sEQ7rEz3ollxl52Mz2JA1B2+ +TzaU/iDctTQnRCk75RqDmVshnKXKXGNnClwZXtIea4mfVVJB4mJhwGvgsLRRj7eg +BM6E+jzBfz181Cr0PrhpzGJnfuOtEepby5F71GbPAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQA5+/o35BCJRvrfMIp311Xv +ybio+Yq7Jpp4wDOT+6XlpGMMIHGtDw3fYXhZeXDLJQ144reDOnLWBEN7of1M0NHu +Y5ccTVeYaepZnvncyXtgokDtPZjegXj96zs1IDr5JU4F3x7xw3+zppTAZCgGQ4A9 +rMwwFjsm+fbjITR9T5fLppUSW1aTCSii3i0VBzGyXZlLDuCqdOLYCOX6WFtx7j3y +jQYZlqXqv5idx1BiEJT4vqC2N8elpmPsZ0TIR7xIFft5HvlU/U+aCO4NRetJaRj9 +JK9D6Jt3shpKLbyJOfa7foY6LBf+qS5MpC3kTnfoeVNpI6DHKWKE6d5+au48ARy5 +-----END CERTIFICATE----- +""" + +SSL_TEST_WALLET_PUBLIC_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA0/xxsURp6uiAExF4HR060/PJpmPiUTc3gZw/VId7sAZGopCW +pt9XmN6MRLEFlWUSfkLMp6/lQYMRarjQZx5kNuyTqgB/NNKDNQgtG6uGfGnOlztU +ownVEHWqqY0nFDX8VoJOoBt3vSorh3L8jns3SLz2+WfC4M9VpOdyIlKYzgUay47w +WFXm76QKINdqvBZW39zMrtu2bC95VIVVqX5fdbBEO6xM96JZcZedjM9iQNQdvk82 +lP4g3LU0J0QpO+Uag5lbIZylylxjZwpcGV7SHmuJn1VSQeJiYcBr4LC0UY+3oATO +hPo8wX89fNQq9D64acxiZ37jrRHqW8uRe9RmzwIDAQABAoIBAQCbj8xq1paXcQjT +dWVckB+kfGlFNlVVXhzYey2qPUYSFXjuQQac7JbesqnimrlLOYGJsEF46MZm/eTh +GUCt+4p1F8UA4x52R+lLGHXpsUSethKJvltMzaFSU9bqV5AO79L+NN+39JA4++I3 +orUdZeRa93iR64gB64Sg38tMzqodvB/9vD1CgD/UFT/dy/FjMkg3UMU0oBZ0Zgjd +WRZUePFIiMQ+/VtEq2PVuFfwPqyeKEy6DUgd1wVliQNomgqoUhxc4lPFr1KhWvAE +q1Z8+H0Pd+uYzNTOUJWhhH1pLpinOu7V+AhtXWEhe0QXpoBELlCiqB5lMamTfg6j +hY6wJV+pAoGBAP6WFITgdZHTrOtOMiflKW14kyuEXcPmUo3V6L+esH6r85JRAspb +ceJulRsf/KlTZzh3wRRUb7xTNE/S8/w2WSoVuMbsmY3hs96oXByAhHS9SSMaQ8ms +2+SjxpSerPr6qGOxg9bzm0s2z3b+ZcgJrZ+bKtrKPvacpZItKO/BbW7jAoGBANUp +zbhCcOzbKvNvRWc2BIMFy+x1PzW2ebq2XtyxETnqBVxW+iGbzBdiE/cpPn+P6Tch +kiFnuOaul5Q0N+KzIa1q8MtwTKPPZcQQc3Rv4xw96tldja3ZCnOo5WlW2UuJgacK +XXtQ2KQegTj15dytPhR+41v4GksjFnI5gPvb7SAlAoGBAPjHW+HFHd6UxQNj9Gs7 +6tHI47fAr4gBiGaFw92Mitgd2/T9KQbpeU5V1WseRN6KW/G4RHtDT7Tucc4XTMkH +qvYPJ/NrvVoCVqycRPatN8KEPfYJcnifbHnu+Ny+ejb/vpE9JKJmhzhmpTGYw4lI +u9ud27DVtdVzmfBQJRK1J+UVAoGAFw+Is/BsKxOi1+cnyPytDEeqQhCFIBh3nt1v +8cwuIufQYKcANHaYY8c2hbyuiDpXbqFxH7AK7tngiCYGDb53XD1/g2LIx8f+KHHn +K6eXGE0ShSV72FzspoqVFwpQQ73CiwGyD081wLuUG0du8KrFVo5Lpn12yr4nBYB3 +Fcg7JQkCgYBLRw82I1NXVnqODF47PHuAuyNKY/ZT76zRY7UuVpraXrqY3Vc7j6kz +0ZrV5NxAxbZMpJVGEfc6B8YIQz3np3P5s5ME4+bbIzOBQcmIJXLWeMq+oZhTBcTO +u300qymEVtlVqhWGtHlFbxSPtV+d1BFCptUShuE5BpvqUiyRIZHokA== +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_FARMER_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUbgDpFoeaeAbCjZcmf9YI/M3IB1IwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyM1oYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC4vhXYgLWi/5xCrTP3efRW65MPn/vzynsCul7dya5vmTiO +BZV2BkzUBRfZygARIUy7z9VsX22c4I/xRtJUkjAtDaSw02bnlL0BZSjZg8DYWjZO +woO++FNweJ2SxvaPQypDCyRQuiIMGBcsqMX89owC2y0cQtYbB8kA90WXNeaSXXzB +WTpPd0pRDx+VOs60hGIfH5y6S/MkgDPHLkXYCGMqRK0vBbKr9yWq7YNkFmgGd6oV +qAspX0ykx3KOiubBO9WV9pw6Tn6Bzm+5yD2E4p+wmR6r25MEHExB8mzULoD3wQWE +1xRQDZ2dF9dr0CXSnDlOpCf3LcHX0z1NJzG93/M/AgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQC7rOkhmH/14hXD8dFxw7fv +MBE07KvCbbYxoupD3pUIHO27Nuwy1ZtcppHB1yLztFVy1gk4u5HfRPkliVrsUlCy +IQ6JiWl11TU9vPQHU6ZxAVYrmS4UhxKjOVQWJ9ZXHcQWamNZS31uCfEpG1AvLcQp +rP441aWGVl9pn4DvYCcrGA9iOIh4t4+IP9KdcehXwf5aIip6j7FR7lRgoS65xx18 +aekW99yqzJtyqtx+UCn64a9lGFlCvzdUvh1N8qtv5O1FGC0u5erCkTpdR4mwbljh +Wl7fa/81yeoV1PM6sHrp3mEK1qY5yElHIEKlsoJvnoy0GRJXY+bhfEcZVEDvl9rW +-----END CERTIFICATE----- +""" + +SSL_TEST_FARMER_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAuL4V2IC1ov+cQq0z93n0VuuTD5/788p7Arpe3cmub5k4jgWV +dgZM1AUX2coAESFMu8/VbF9tnOCP8UbSVJIwLQ2ksNNm55S9AWUo2YPA2Fo2TsKD +vvhTcHidksb2j0MqQwskULoiDBgXLKjF/PaMAtstHELWGwfJAPdFlzXmkl18wVk6 +T3dKUQ8flTrOtIRiHx+cukvzJIAzxy5F2AhjKkStLwWyq/clqu2DZBZoBneqFagL +KV9MpMdyjormwTvVlfacOk5+gc5vucg9hOKfsJkeq9uTBBxMQfJs1C6A98EFhNcU +UA2dnRfXa9Al0pw5TqQn9y3B19M9TScxvd/zPwIDAQABAoIBAQCzrr4Uq2r+tFpJ +R6jppMYP3GRWqCYoAeIOzzIByW1NwdsN10R9XLdQ5/tAqoXSI288pHJSS6aTFJ8r +7tQXyW/uAf0Styq5RyNlvfwzQ0BHrcZwaCQ3k9Oj6sxnu/iHcq4iMy4JDmCbHrs7 +hpO67BlVldOUTzVraPEJbXdUEOrHo1fMtWwb78sIYYTItX8a/rP5wuJs1EaQiVHR +Db/NoGpJX9fdriLweRgi7pvdRo2So1ZoC/95fQNFstx8KdMXTj8QKHnXV5LOndMq +5X8EmtACBU/Bjcrjij0YAh1g44NRQN4jmGWEJZjLdTsyoE5tI7rsCt1QGqPs7gWT +7JX0rNghAoGBAPWfjVQkn0ZTer7672frYhATzHypX9wW+SvUMS3id4hqKjch9Q2w +Z+t0lrpKSOtKghNBzrFms8CPhuAy417BmmuA6HRFaqp3Ac0uAyA1NN8QaPNeHf1/ ++Uub1uNdaN8pA4W8qKvRMb7dVJQ2gjbcr/ALpwQx9T3M9Xxy9hCyoGkpAoGBAMCM +GaIYczaeMV+jTkUSYdISC1rttJjFxEKuMWvNwajapl05kHw/fTt/UXcEsy+SBMQk +ArQHx1w7NGbkBNaffE+zyPcUjlKwHoix45Tnqwj4VIha9rNVxPDZIeas+pzhcmgo +KHWy1wflDIgBkeIWQr8Y/QWWvt+Qq3oD1MPlOD4nAoGAScL1bTxmPHdbWDkBZkLQ +uyVG9nTi3bRkdZ4OesoUvXmsXcwrzEWan6HuldkzFr3UXDYZ/TprZrtzdKazk0Qu +vHQE2s3x32lHuDdGJwjzbL1/1v3/oZ4p3mPZX4QwtzuY3DOwr5BuEPRkrvHDnvgd +Ocg2CtN542pGmm3nqVILTCkCgYB0X7jWaaSo7C+3OAKEaLnKt7E5QdYXR+B41MN1 +/qP/pDdMvRAAqHbOUQMxxhtusvhCe+lOWi06J2ZikYoDFd2SZn0eKMRkYaHyyGFe +jC6pez3MM/5LIZmoX/PHceD+lJwLK8pYaMDiOqO6SAid9wpcaYPzrsqqYMvjMRGV +XKMDnQKBgQDdmgTf1Ga4rBBXlc01bhQCz+TVD5eoKG2jy04eMxX94CagK4r2YFeh +DnF5ARyYEZBE3GZfXRVR9qyW4YxWzW3k+nloAE3WqKbWYbmLqjZdKd+ppAhXpgfG +7FPIfDJX2VcARnCR0CkxXF6f/6eNKg0lKfkuEA5q83Cp9HQCVXj+3Q== +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_FARMER_PUBLIC_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUcSw+1Ww+zDNNx/vNquiiebp0nRAwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyM1oYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQCj34tYd0hFq2vNzARK5oT3ZU9MX0GNLidDDBPpDkXEYZnR +yVqdLe61OWuU1dY7Imdoc72HCDQLEd3bV2dux2jE3ktHP0zELRIucyhBJvx5zl68 +ZO004prWYH84O1GlTHsz/OQZeTyN8detpOgEmjZYJnPOWoMW063r5YAxfZ5BRdlx +MTmnJjLIxX2q60RjoVZXNtl5DOOxnYdGX6w5L6KXMr/A/65AePP1RYW6ugkQwcKA ++PsAbDz9T7qDmgu9gHcDtGUg30ua6kLgHPx3ZrL5RI9KxfP9l/r3TEXg1XhlVyv9 +ogb12SQHitHR9HFcs2y1CraEw7HGTTfn1wqbqtzFAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQB4Z7WQTY5irFfCZzVsLjpa +ntAiAe/EdaGbx/12Hy07efLQ29D7eMWOvjjlDUjAZFDefH6SPB3bZXY5rhY1qHnC +7l3Fut2SqToPy4/8m895GNOtvPJQJgw3nUijKA4k+tSdN9XZz39sDYGKzHPMuAk4 +D0S6MWIrT00zEUMJMUoFfCF7W1II5phrlAZTczdEiXo3fn6nSgsDXGgZS6Y4QXh/ +5HCPCuI/F1qZWK3eVdrrQaB7u2LLo3+qfku7unZ7+/EgomRL27pMukrL/N2kGU0U +7P8mpcs7j+Sn9POI9h2fSbB4IElbHP1AM/mTfLc38bKQNt1bnXzMKfhnOWHshBrm +-----END CERTIFICATE----- +""" + +SSL_TEST_FARMER_PUBLIC_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAo9+LWHdIRatrzcwESuaE92VPTF9BjS4nQwwT6Q5FxGGZ0cla +nS3utTlrlNXWOyJnaHO9hwg0CxHd21dnbsdoxN5LRz9MxC0SLnMoQSb8ec5evGTt +NOKa1mB/ODtRpUx7M/zkGXk8jfHXraToBJo2WCZzzlqDFtOt6+WAMX2eQUXZcTE5 +pyYyyMV9qutEY6FWVzbZeQzjsZ2HRl+sOS+ilzK/wP+uQHjz9UWFuroJEMHCgPj7 +AGw8/U+6g5oLvYB3A7RlIN9LmupC4Bz8d2ay+USPSsXz/Zf690xF4NV4ZVcr/aIG +9dkkB4rR0fRxXLNstQq2hMOxxk0359cKm6rcxQIDAQABAoIBAQCFaZo9hKcPKVcT +7bPU8sVv0Ef16lsowFlwiWWwSFFeZwNeuuoNqvZ7Deta+Zh2/jRn4kp7o58TIBGZ +4BeyJaBTHpL0x0ENOZBixpgQKthDplKUWCqR8qaSP29zbT+0LobjNVDSuFQnT6wC +j43hKVdy/qMrbZ7pt54Rvf9Wy2lKw3CSLuN9nijyzRdI3Y7Qgp7j5mbYTodagBEw +rZUNxZgZ1Drtl1cGOpFzDhYfIgOBgBTMcfDJh7QHgrGNBEqdOTngBN8TcrK0jGT6 +4Tzxra7yhmyJmCa5nzk/I3ZZ3DMdVG70I9earH/MukI1rH4BmLLKFjy7XGWRs13c +EKe46T3hAoGBAM+RSuQbNZBY6QTQ5b0ppG8C1b+LT1+UOFlWnywNNgB3yc51zTcn +TNF+YkNRb0q3VDcdYWxzMrU0F/30UEPqx3QguXZ4YYmAAlE4G9j3OlbX59CAEmnp ++aWRq9sAxdzzQ+vGn7iTWkDPdgf8jsSm0BYP/NdKk57wS8j1+PPc2GG5AoGBAMoc +Phx8XMUwfkCZeWNnaLHZGMbVJz4lC82GlaaLfdqR2fitxZSB9YAyNe3SE3FlThi8 +sW1D7CxuGqQRKtql8XlpZhik9gGYtd+vricF2UiO3c2OKTg5FPiHanh8WtYCER6A +QwdATKjIUyE5wS9Cnv96xg0DISlcwliOFbV4x8ltAoGBALMqDYPRvK1pIVGn4vYh +0K6FuuzIGe49aVor+96xVJCY1VfhtQ5LXPJjbfv/edn7XrToJmTPFtD0M1VgojvN +lvY1HQEWrdJa7SUgEmF4HSJC4PTG554GeReiIr4575BlZpZIbyuJ/Vh9+rqwFKfH ++Uth53QKClwhvLitIIOWeCv5AoGAedR2eFNa1J67rBMXgh0mlfZIoiqA4kwQhk53 +TRJOxf8fRnDxZejE5QbfTUFR6Qvo/K5ZwYStC8c/FeEnVO+s1MP9ACQICsRT9cd/ +khRLexprh2oHXNXD12BBhOlpFBHg4eLtBKT00NUYjzGyStu83kHSuqtFRRqeKCVV +3rM0sy0CgYB5QvJ4/TSqWhVodM6DVxSnYzoF77E3t2umW440Hu8grLsDJrA8SBMZ +0WKME6fXcbNm3p4eYZ+2sPiLpVf6w2JlykY+sDa+S1MtBAkgHwJqTIpQDd0egSvs +kgCFy+t4irJ+X3Oou+pERFHP/cMiQGAMvstgpz76/4CQdTsAejQsMQ== +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_HARVESTER_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUcr5lcnpo87wW1R4tGOd5W3U3m7MwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyM1oYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDFYItZq3rmZTSdcJK7m0sPbVSyexV4mIVkR1JLSYDkRUfC +xWqPB2ZY1sc6a+Tns/0qVOEddjfD8j5GrRU1g9VluSnKp2bg9NgQkqTEuyLDPF9C +iP1JOQudPSPQTeSwyOk2bQQ4LP/nRZXzZ+NnAEEHTkTD7D6LvFTGrIEShLIqxHdY +5EeFXF3zTpp6LOQYii91joqN6i4BUbbMr6MoRIgVUZeEdmKPHkyaIg2LJ+HiqrNw +xc8Yg1ksRBYAKBbPptLsIPXp0T5ja1SUEUkyDaFclzZnAfQhB57+0VuA4/pIJcLV +9p1avjw1PyrHqV48AGB/NqWA/+4kXEkZ+DrrY1D7AgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQBIvNub05nXZoxHcysNf39o +DudZ8wmn1urJpYQQUhFfZ7eGyTTgNiEI9Mz+kVK9f+BR6ylw5yDGpIC2BY2uDdR3 +r+y6bs2loQzfIMWAOEsx86zMG1XmYj8zQ7pjZ/AOInu/Cy/w6AwNIt7U3B8+nZEA +qPatVOMPh0yWJ3CGjY3lP9mjhREyUBwBsUOq813JYXLsq/euFm5HPVptYf70Ms2Q +3qkSmyZFozJbW2/wqsb083kJ3djkVliqSDVQ2TnQCi8PT/9uE8LfMTrnWbVZlTO3 +hxByAQAco0fiTQ7BN74FuhzqBLBadcnQ6HnWe87E/0OI9co3+vJR1H6xHSebJ9pu +-----END CERTIFICATE----- +""" + +SSL_TEST_HARVESTER_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEAxWCLWat65mU0nXCSu5tLD21UsnsVeJiFZEdSS0mA5EVHwsVq +jwdmWNbHOmvk57P9KlThHXY3w/I+Rq0VNYPVZbkpyqdm4PTYEJKkxLsiwzxfQoj9 +STkLnT0j0E3ksMjpNm0EOCz/50WV82fjZwBBB05Ew+w+i7xUxqyBEoSyKsR3WORH +hVxd806aeizkGIovdY6KjeouAVG2zK+jKESIFVGXhHZijx5MmiINiyfh4qqzcMXP +GINZLEQWACgWz6bS7CD16dE+Y2tUlBFJMg2hXJc2ZwH0IQee/tFbgOP6SCXC1fad +Wr48NT8qx6lePABgfzalgP/uJFxJGfg662NQ+wIDAQABAoIBAE67ShrEukt5B1nd +88n+EhzfQa/IRTJLtLnhcUQy18U2lX9t/Cl9jCfX1LTLIQ4Dz/K41OtJosj4sjrD +A/jK0662A6Ogzvrg7+b8d9k5xI4YYO9Lca1poeZg4w5OY/DY054wMkSuPo3kRgJH +6H/HrCjb4bY9YF2hDDgLy5i1cdR4wsWlVCV2NkLQSYifPQxGHY4jcDGbyUNhY0wZ +Nene3YvzbYLaJJtISX29K/k6Pfatteu8gu0AqzxNLJa51gPyrNFjmlj4hLhtR/Ty +75T6lIAciLkW0nswCb3ZgRh9xGgASyK9rqtrEVqW+mG4TCVd45aK1s83EBxs3RFO +RcZzmnECgYEA4SaQpH0F3WU7aQMBw6T+jQrSwJnNlES2ugyDSrLX7Exu1tVgrz4y +HzArBg1xHyKnHQmaLrlMPowcDhCtBO+YC+j+gGak9UbaeJbR4vcVuv2gHDQ1Wqd1 +wvxoV1FnCNNta/TwKKoQfEZasTEq294i9krbpWh8sqR61dEsKDAV/OcCgYEA4GvK +Az9jh3VkXv4Vlgvoc3fnnhx/NEXzd51TcBFp81zD3zH1GJ37bUMK2jm2JFW1PYK0 +AyVEJUA+MWEISt7lOrjI1s6HZk3Xsh0Qqdv/WPA9OrG3eJxPH4Bo/M1HWVG72oWD +tbjoOViXYKYd212hKTdUCMqGaW6i0kWIajFUVM0CgYBw2TOGPmPCJAszBx7LQNeV +OeeIQY6Y0hgECGGF/z3aYjTr2Ocs7q+QkkP+NJ6OTIAWPcnZwWZFs1QceJ8/6hb7 +YTyufsQPbAP0jSOF7vIlVxn5CPH1DhooMPrbSSGres1NXudAenzozRqH1Wz15tD/ +QWX18fkOUQKASOco/XEH4QKBgByDtZQ6DqRcdxdWw1lgQ/W/6278gfEbXjb5h2t6 +2vJv+/c0+sZY9GRKm2tk3864ESIypDquFn2BLyXJBWu17HxMlEAu16dZBqn75W0f +pc8gHzeA8yXg/nCrOSu9zW3845h9VGHXj7IRnpJKKQsBV4PMIuJHEVL+GrQK361W +fTeVAoGASnt6kmfgDED1kdDZGRMgb0GvyAVObjLRBu9eRX8nQEKKpFydBmdDM1+Q +coUvrLhjqLb81znytV8Erb2Luq1xzlnZrWK3uXuPJW7T/m+DL+Oa2+e8pgRq2/Xi +QJbqzpOmiuAeJzdT9us1UALoXHxdzAw/oSC9Xq3j66O1vArAm9A= +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_TIMELORD_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUPDgBpxOAo73yMiUGMFNbK0SvFvwwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyM1oYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDDT7pUEKAS2A96fkLb1IfDbHZCpOTUgKk7+uNQXTKarZv0 +yys2/K/StPGJ3+mFlN1+dqubVHUILhPUpfFNHH3zintDsCjwu1GPKRuqgPla9ZAb +zBft+KKm2CewqvVotYOcfIAUqZMmfWuyxZFL/ITJqnJKHqYU3yO8pNO3k9c9tKVe +AVLlarcHJitjSkKz+s+3XRJYC/x6BsguRiNGSPVPAM/jV9PGhaQqlhWtQT0/kcEs +MRICpIPiPd01bX9NWbSoEbCVN2mBBxPi7fV4V2Y+xkdjj0QtkLmJJTnatNNK9UjK +5npRqHyw1ogyguno10Jx6e5vd+3hWiJlBOzpqiT1AgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQB5xd/q0Z5SfPECusnXmAwF +X48KLYhjc1/483R1gz2Vy1XNPWzDDs9I8MWD02BWr0dMMuhV6iPFmmQcJ76ejJD0 +NMtBpjDFfCknFuMavbog9ikPEXhL3EtzXP3jC+xsdvYwi35hkBgGs5hnAkheKklp +cjRurmsBAHJBlEsUc2C6kxq8FXcLM+WzJJYOitzE+fpyxrmeOIfpUd8Vwiu90Ta0 +/w1mGD5vlXBTiFCwLEc2fVR7OPm3QxKvJ+eUdLTh+X4VgJ5vvdiqCodgAeqDZw/Z +x4hOnAEktgEqadUz5t7fJzxuWWpNTL8OQLJgW1cE/Kt/P8F9IQ5rC7PS+XU+Ds7U +-----END CERTIFICATE----- +""" + +SSL_TEST_TIMELORD_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAw0+6VBCgEtgPen5C29SHw2x2QqTk1ICpO/rjUF0ymq2b9Msr +Nvyv0rTxid/phZTdfnarm1R1CC4T1KXxTRx984p7Q7Ao8LtRjykbqoD5WvWQG8wX +7fiiptgnsKr1aLWDnHyAFKmTJn1rssWRS/yEyapySh6mFN8jvKTTt5PXPbSlXgFS +5Wq3ByYrY0pCs/rPt10SWAv8egbILkYjRkj1TwDP41fTxoWkKpYVrUE9P5HBLDES +AqSD4j3dNW1/TVm0qBGwlTdpgQcT4u31eFdmPsZHY49ELZC5iSU52rTTSvVIyuZ6 +Uah8sNaIMoLp6NdCcenub3ft4VoiZQTs6aok9QIDAQABAoIBAQCO9vlJN7I0mPsb +ividuYB3SBl4xwLJmjRGt2tVFCNKnfIeyekkIusArXpwlfp10XYgb/VFihjwl+nk +KmPrMgPwFVoNPhF5xWP6Cvk5YZclQcLu1gJeKzXEM006QKnKr7NbBLcsaMRR1FTV +U1D78iexBpcKMk0X0g5ys6RWKF3Rx/PqdcDnH71hlZFKUVaKVeXvPdAF+Jo2D7Rv +a3PktRMjB1c3JtVI5wGvvkIs50n2pZsIkh88qhwZRurvJiY/mUSyi2CgnIkLJLQO +kziMr8gOPOmRzy1sDY3fUYaoI3cnQ2va0zqLg8GkQDfLg3UbirFYXchaRPkoYRSw +fPGpnXsBAoGBAPvFlKjzh4Anob4CgYNgKnZHTeDHEY5iGQECbcFWnv9TJ/PapRUC +MOPjW8c/SxZdz8neBt+pyl57nVrwvOWO4Q6ccJr1a+1a6Lc/BxL+wUw6fCxjfQN6 +s3VLKkrALxgmbWjhAOACDOs9Uj4O1lhLxbhPStaSAMh7nc7OAOubi20FAoGBAMaX +aYz+zF8lQnQUzO0zg+4VbS7bR5KfjLoMXF4B+TJ/n21oJUjKSPRTcBZmvSSxu2Hv +8Dj4guxTVezxis+h/6NFf0xrPD7zxqKNMZ71bszR0qfNzEkMix4inj10gUCPhgA9 +k8buLFm3pIAJ9NeiEIKgZT4H9TItItLCfQC8i9sxAoGAX69Ah1E+XwMw4jC7nf1P +RfJlc5bUYkN/8zVEFyVfefPVjES9VpWllQZUXA3+8HoovTSHcjtqMKxUKjqx36CE +gfQMi6fYI7XYGcR3YM23EsxrYsdQvKDGUT6GzS/q9gesrx5MIdZFqKV+ex1Scu4h +L6Ha9F86svbgC7eY+/H6dC0CgYAODRaFyF1zefJqvjIFsnhqNw/jmdZFlI5jd45t +hFw6a3c/SXgh31YsG1855okJeJ3WfyCTF1pEGF1jB3AX4tFwnvEz2f6IQb1TMQRK +x/jP+ySZhOEoZf/N4QsrM/wVMlJ739992so+itTTzmCJhUj/xROEwRFjPHhTSzmG +/NA0cQKBgEE19gpbOu7f+6/mBWrS6AR7eGjZ7M2wRap7Eoh9M2VV/ou3tV8Z4bHW +qcLBFa2HW3E/Qgh2jz2q+aWrRKlbJfzH/EtoQpwkUeKaDnONK5O6V/kR1VNBnUrB +0+C+ngvuEff4uTk3zmaCc+a04HXWXhuzSuG9LA4V7twmgNo9AlSs +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_TIMELORD_PUBLIC_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUIDNyJc/WIgjFdIWtYp9/dZyhDFwwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyNFoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC/em2gGo4JEdff7eRAMG3two7JlNvEzuTn95dcxWo3Pydz +OJ83gPrGCM93zBvxsCOppyER+c34D9toxAvu5N7S/68eGOPlvbqS1aUJtMRXIoGg +ghIlz1w97VOmQ2DS4PZX1Yw+563ah0T/kmKvrJ6Ti8MOqvJ28GNnDObBP1hSfezu +/iRbiaGJUF0wRULFaPX8uNnOT8oxDXzsyBRKmZLN/O3bwbpX3hzIK2D7BBpqUza0 +AuO4/zemr3J21QFu4rD/Wbd5/zX4uxSOAIXbT2haDT5KZEUYQv2jXbHY6+tzpMRC +v+Bb3yAeFGt6K44fzqi0fj1pzoHZQ7pgqKwRKA0tAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQBuL8MMR6mTzcL/0OOWVnQ1 +phT2S9L1l6VmsZYK0/+kUNRphtglqiUg8TuHDUvXY6Bq5r+NY9De6ZhJMhsVYt5A +XRkBjEwIPLC5+JZi8iv9uip5qyqsfrt706zGz1NfVIk6pS97Nssj4d2WkdB8BrD9 +fnngf6tnQJX4K7fhE/NWcE6YMSBA4GG/JvpH9ouJx4aN77zF6PKyX+iO3GDHXqNH +BAdEbHgr4pUPZuUg6c2x4T20NKnMNkx7C3Tx7tp2w49VamUwnwvm7vuzjajd2st0 +q2O+l3iNwRuvzL+KaDhqexf3shDSCxuYSaInne2XmCiJjVW7QRfQmyA1LiUk/vfP +-----END CERTIFICATE----- +""" + +SSL_TEST_TIMELORD_PUBLIC_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAv3ptoBqOCRHX3+3kQDBt7cKOyZTbxM7k5/eXXMVqNz8nczif +N4D6xgjPd8wb8bAjqachEfnN+A/baMQL7uTe0v+vHhjj5b26ktWlCbTEVyKBoIIS +Jc9cPe1TpkNg0uD2V9WMPuet2odE/5Jir6yek4vDDqrydvBjZwzmwT9YUn3s7v4k +W4mhiVBdMEVCxWj1/LjZzk/KMQ187MgUSpmSzfzt28G6V94cyCtg+wQaalM2tALj +uP83pq9ydtUBbuKw/1m3ef81+LsUjgCF209oWg0+SmRFGEL9o12x2Ovrc6TEQr/g +W98gHhRreiuOH86otH49ac6B2UO6YKisESgNLQIDAQABAoIBAB8r4h7XU9ocIoWc +57SfbbXwH2inqCNg/xjYULbUmJcH2/dA94KEp86Hbqb0/nOZFiUvRQ31GdfRVQm4 +KK0qay/0WeDPcoJbIb13tFdhKzl4L5wesK+hE0YtlZmSjHeoEdJ4vE0dUEssDEqC +3Tf2JRamAQopQDGmrrf+/K3nDwzWlRr+UcQF6Muw75vBvYVkfkCiImiV8oGlXRJ0 +CP8+0XPOmgcSmDcGM/qWxjDNZNoKt5SBx83xMticdUTvUKBIvDmSMj2VxTsMPbcy +elEncnbiG//Smz/tU8sggtrwhIv7zCZP02TJBFSNmE+orZFmHXAIBsDfW+27vN8w +75B/ES0CgYEA4d+9mpNDtxcphunjnoegwLDB7OApGY5SACCvt2HXQiWXl9DvPSU5 +tAreJdMV6OOTkTwFTGQhOEP0uSd1iDrm0DUvtUjgrPd5JyVAlMyMpc4z8fEoB+jk +lDoXOmqnP1t9w/GJB7YX2KI8qWsT/qvNGCa6XNBEFlp0fVzOzLJARr8CgYEA2QRG +vBEtTTGi4fe+A8Lhb2izc4YHhMJQBZJceSTxO2hN+BxSzltyf/7QMyC98sUGfOmG +bPzISZT9uFdA0ZXZjaoe+boa5HQJf1WxfAUlAOy50eetd+90+TmQ/qFePS23Im9m +dXyR0O+eiKhMfMJnkf1s8xQB2Lec9G7AloMlcxMCgYEAsoW6P+/g91bRNZaqluOv +hFywCV5qXY6E9SDggNpN3jQECrPSQsunPcvRJKgfiwBD4+hCb8w8DVJ4m9a6KEAV +qb4/xNKi8VJvaSciUfkRuQKvP6xQ7V9/OkBnl34wTf0r+7Btk7CyTEB+HZFKLmDv +KwWBClZ5WgmIRIUT1emUr9UCgYAJMhYxN+UchULqok3J6QMWbnBUL9S3umgbpFUI +yRjztHrBTanwlo1mgQyfbf6+f7zDpD2O9rMh8w9BNWlIuDnMt+2yFUG4dnZEkAQC +RlGIFX/WNiPylhH10YukToAoxXwiGGhWCB5BpTWpgsAi9TXgSMXKEwn0/erHrL26 +Yvo+QwKBgEI2e6WELLT2ebBK/x9pxj8w0IevV0oHg3Msod20iw1omrkCyge/Tt1+ +ABTK7xhmMPLJHD8ZiMl8sjEKTx8PkAZoKdfZV0Qr+BIhMneO3QTLcdZiuIbjb9Mo +3QvOzzxKKksub2JjN/VORKTqMuuSDQLeEBtv+sRGtkTHJrFtnqwo +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_CRAWLER_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUMqlg7Aqc99ifdKynHggljrPnQjIwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyNFoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDr7NWQ0b8tQSlXzaa41vexl0Zc3WrfF8aw4mEaMcXM6lkO +hX5QLZpuTCs0RGwLXVAuqEcbQqA7GIbhq/ch4c9PSkh+yBUOB8SHx3UanMe9sH7S +80rZCX+8HFMVMce5mMEPIRA7WmGRPf7+Fh0yHMAaIsaqDbI5f9DqLdWE+FsrFrdC +kp0RYTYQsYEl3YEPJfcYbfrX3I9GxKLSUX1iKsMlyohrFSlw/t2LlG1jeuxd5oLR +L79QY35LkCAsofDK/lThovM0qqnescGx4feZsLMCL4rv0td2GWNhA+4UofhTdul0 +zRcaDZVrNEhCJk0RNf4wXtidqJN90Sf3dvIjx1qDAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQCWj0tol4kMluTkz+sGjfpU +xTnbVkoJhaOVI3tdK5+Z8WkCS/IlFLFoHX1I5CoAtFDUTCrp1tU/5e0BzA2VfLME +B3+qgLQF1+Z2Qy+OBTRToUuOSg0n7qSQdG5zIsspKwRl+iobFKaxqw8j218/NKaa ++RJTdhRRrmrokiBxpz5AJK1WnLjYe65N/ZdfxHYoBMDtzrkCrPsoZQpHaUf/9K0p +v0tv8s4nr2NcAZrQeALoTvR0oJ5QlmRxfHY6xC170dLV9KHJTbV/FXXFmFQL1WkI +L74vcnYPvpD8tdY3kD8AXUFoYNb3sjjjmM5QS1pYva9PQUiuHqr8MAqAF4sHvnLF +-----END CERTIFICATE----- +""" + +SSL_TEST_CRAWLER_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEA6+zVkNG/LUEpV82muNb3sZdGXN1q3xfGsOJhGjHFzOpZDoV+ +UC2abkwrNERsC11QLqhHG0KgOxiG4av3IeHPT0pIfsgVDgfEh8d1GpzHvbB+0vNK +2Ql/vBxTFTHHuZjBDyEQO1phkT3+/hYdMhzAGiLGqg2yOX/Q6i3VhPhbKxa3QpKd +EWE2ELGBJd2BDyX3GG3619yPRsSi0lF9YirDJcqIaxUpcP7di5RtY3rsXeaC0S+/ +UGN+S5AgLKHwyv5U4aLzNKqp3rHBseH3mbCzAi+K79LXdhljYQPuFKH4U3bpdM0X +Gg2VazRIQiZNETX+MF7YnaiTfdEn93byI8dagwIDAQABAoIBADXUNrIxOSZxLKas +9HJOEfvCITrFBkJaoWnwbOlWG+RyP9mRWc2fahHqbR0i02gQZWAP4xF0NSzmnrfU +zbE8XVmhAEN1EWC/Ivc76hslVGmSYI1vF0/H3A4mhEpcrk5JbRsvlw2DxKkn9Qsy +Ln0llCsibiOUtmpqIFeeF46cP+jneMayLw4CCWoOSDPHcVLcdcD47qfkTJKlG83s +AVhALyiTbLSnKLj0tkAeIMiCecQbFQDdp5scemRgaRscQ1dGi1qaX7Zj1LqIxZBL +wQ/cqEKOZSx4apzv7U6U8WSZ248jUXTxBM6RxToAnYMITv8T/pDaB6QepvOB1E80 +Re7yNuECgYEA+RUVa4So6gYBYoXLFNvgmX/YUDOCM0D2lbNmS2WVZjr6VHu3mGP/ +TI6dFnJ94O8Fxssj2Ei4F48isXXT8vag3M3GHSbWzo5cREdWmXUUM2vQisWdjQHM +kRBLHOAAxJ0M/3h8uu5jbQeaKiKvB9OU92W7FAPFIUOzJ3UrMFXZ/zMCgYEA8no0 +sXyKJovzlhtchIGDtQ5pd+IfsoPz6edd2G0Jp3r00YJPuhpyivb3s2oTc08oEquf +dE+OaHNYIGWYwbpg4eDq0Wsfu1xt75/nKSUlmILKltwyq4U5Cxye3P3+ly5/aCzK +XRokBgyzuIl6WgSnHD72R4jiCobNhcXcHPdfd3ECgYEAm1rXHVSEtlJAkt64J65s +i9D9bihyUN137y8R4nzdjgHDGOaBQH8+QNXCjLmkYaMziyYwmTnh+G/CR8UiCSxi +cNW3d38+A18vlTaZgOVRUDEyxRs0hTpWCTSMZNoiIH+EF+NiiIUfZmWTdixj1xHU +m+nLoVQoo/LBzx55bZBeg5kCgYEAz6w+6SxjHjSLQarZiFtstGtNhXHT+A7vnwub +4rswo5K5j57uLdRs+fwfljhpxD6tcaAwB2wD6g2wEr8xH+tDAvKh6w62tL+rIKpx +T1oTYxXR8XdSpniJrKysm1Wm8VDPqieCgk7bP5stagXFFsgZYCXExOvFvYJLECGw +LdbomuECgYEAkiL1w+snhDZaGUfmA41JbMiAp+fWf6dgBfTieY2PLeB2PHOIQR6D +M3cX0bxsuFEqvTSer6/8Ocu+q5zAqEh5YxxRPiQ3zdqeYEMPGUWq+CGvtKY6IEN5 +0ITdHQVmzbREwX9F5wiYXy0VzjhzMbXdTK8XpYfNm34B1tfTJRg9ZyA= +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_DAEMON_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUO9NYo6D7Fn6nsq5uHYKUMvoi2dwwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyNFoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQClBJSKiguayx4ifSydXnEMoDWK+HeUkK/38DBFn/psx0fp +joXEUFXWcDba1WH9RtExs7PYD2n4w4BPSQjz6yIh1oNWc2HOpyHl0Kk5pL68yxWp +3jFzAJQHJGgkeRdMH36lUQwEnQ3U8a6YNqd0j5qp24p2qyv9AGARvcrCgp8GeyS5 +t6/tedqzzyujUNiOWzwdfCsdKo7Bv6VbPtx18b1EDQylQefSg3yxLXDgZEPlFPkM +91/B/p2Om5p2Xi1ybITT7dgexHqqVo6bPzL7mYUZKSZ+dYZIb36mTxY7GWDf8ifE +kMO6+/8Wetwn+hw5ap4mzsAJGZU1a0lUOsQa+T1pAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQCqtpCsF7eS40VB/wdjpn2o +jxGRfet1uP4QIAA3cNwGG4eWu4xW5lBk4duE6DXZYkD30qZYjHEsIPkefEc4sni0 +O3IDSeomhw8Ek/GCgPdk47JF0tJEKRIe4hjMGKI3H0Gmczqp6F78QJNUvn5n/nBH +9WWefV6sMsBLJ56CKRoakwYJzti0aSbAaaT1f/iwctTTxg7Jg4begI7XJyxTvs36 +hwnNCv0+XSol4rerpLVaMm2IKbzfpCHygqxUQ/erch3NJ7mRLQgT/biYM1atPLAF +b1BApc+IIrwDbDMeZd9DG/Ov1Kbns+3Lg5H1eNXhCf1DW9HQNu0Z3XzbARmxxQM6 +-----END CERTIFICATE----- +""" + +SSL_TEST_DAEMON_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEApQSUiooLmsseIn0snV5xDKA1ivh3lJCv9/AwRZ/6bMdH6Y6F +xFBV1nA22tVh/UbRMbOz2A9p+MOAT0kI8+siIdaDVnNhzqch5dCpOaS+vMsVqd4x +cwCUByRoJHkXTB9+pVEMBJ0N1PGumDandI+aqduKdqsr/QBgEb3KwoKfBnskubev +7Xnas88ro1DYjls8HXwrHSqOwb+lWz7cdfG9RA0MpUHn0oN8sS1w4GRD5RT5DPdf +wf6djpuadl4tcmyE0+3YHsR6qlaOmz8y+5mFGSkmfnWGSG9+pk8WOxlg3/InxJDD +uvv/FnrcJ/ocOWqeJs7ACRmVNWtJVDrEGvk9aQIDAQABAoIBAB80a4Z7LlCaQluR +QiOMHWKe1SEvdSVx6uS+1dIEu41gbdfbrK3/5wuC8syU90+22Y5FhifAWnDBP30+ +uWOuviiZ8QIjFYbHkiBsQeP1pF/9I16Y9s7heByVpN/oyiAKAJ/wYI5qyJfREAwW +obnoAf5G1rs0CUBxlrkkI7h+jOXji6E9EetW7kHI9owvZRgNMEEW2d/46Fh7zeph +00h8S6/AcsaeG0d5Wr7Dtpur28RSNUfiXJ1jccaQTgSQlE/CtTuD6T3CEbdPjIuL +xInR+ITVusVQmaouh1VZ72ciHFckgHMlzBJnUJmCN6iLEEKHtEwJ4Op5UjR77kxa +63dGc4ECgYEA2k2L0FEsRJnXmvYSh7LLuT6AH/FsCQ6sS7SMw3ATZBRuVFFEoLlk +2FHOXSrSsAZDumSFCK8NK09aGZOmZfJXi8C8BEvGTlbYQA4T2kAqkB3kc3jpq7D6 +r2WuVv0JDSveJHxj13ljfEpaPkpqG/u2pr5QF2XfV8e8oguIwzpW7VECgYEAwYN6 +fXYnLEhLttOqko7LQ9yrNtfR7uA/u8Rn0p44qA2DRuEjzgmCvZJH7wPJUkK22oMG +G9XcFW+SDZT5U3F6JnQSebSPF3R0yXptV+oWMAXRoNe+Ei8C6vn0k9dOXsp5Msd6 +dswiEIxSf9smwiz4wdmwxev0jOuACRaOhMm06JkCgYEAmNzCMX4VtHfRjPYQZasi +krWcPEHud60pot1r0BKz0VmpJCvAFZeccQlfqseovo+0b1mh+kGxxAkNu2kzlKGN +AhRU0+FHnGWdicURy7sw0rfL17vsTEhiUd2upcULyIhWRlBADYs3ybm61XGAOdYZ +wUr0hF3Wdf4sLYBMJQC+C/ECgYBtEjlZO95qhDlAzF8pChkhn+BVIiIuvPDPWa2X +Nh0DA9LJgZ6XxB6P0UKAQqcXmYjM8urfh5Pr9R3iT+SUFrLdt7CuLoo0kyw8X6f/ +1G47FRyJxvBX+W1wmgAz0DhZD1BuwaaSDQ7qOt1JOXHIImb3hEax2APX5ekdtjwQ +NkykiQKBgQCvrWTglqks5qiSAprEJduXZDuE8RUpyikfRgyTht9/yJ1ZLroj3g0w +ichdRSbSmj6F3dfUDYKZWEfFA8idT9nGDvvr4YVmuVmalc2AHDun1+SiY61ktGYE +jWBtNKr00MGo1LojGaaNp9Ru6w5o8Ae7vsbW1lknomm05kcELEPjFQ== +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_INTRODUCER_PUBLIC_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUKrZllgClUfhW5LVCxMSaWdpORVUwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyNFoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQCxiqJHT5HiXBr1CxICYNvxLMEOaxEV+k98RIt1zrjrcfCk +GlQX8Y4nqF2gn/7s0wgW2lkPAjTnFH9r29lFzTx6sVqGuTal5efJiUqDxMYmWkuw +hVXcqSc0ocxKtL5hRikp+UifMW6YUQr0XDBrszSvVZRKiRtcwGBX7CUJ3pR40HxH +hdzF3K0XnqtymKa/Dz7egwpAms8EH16ndvNgt0Oy74iLLqbLSYIMqtRe99V7kClM +QpDpzQX47iQyxL047xpS0nArTgOfE2wCL+4lWa220O9TZf7Mon3XtX7SJb71lEkj +iNsQ++9S0vzM0BcWGeV+Y7H0MqBmbI0sYLltHG4dAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQBWXFmtsc6tZu5VmqMEjOZ4 +sPaf2yJgEDaPv70R8SiopJSXHNbn14+ksehjdLa4Z3R2QhzCicVMnhvovtXeXUi3 +HuOnF6X5Xrk92wfw+1WW8DUsCLFFAjXggRxU5PDbXNafMSoP8005Jt7ai9S02JD2 +yrbE1tgvCm4HYoliURCXh9//w1fen6D3WddcHuCHLYad5bHnplOgvtFobJaG3FEA +Px3wWmlv2hH22gQf+zGHkwVOd8Z+G9eSCl+wABRGUm4ef3n94DoqE1GqWJ02fHBT +hv3YRFiVH8A7AtBWyY3sdH5tgaO9uCwNiQ0gL64UyKS49F8jT5ChVTxidKyoQbWB +-----END CERTIFICATE----- +""" + +SSL_TEST_INTRODUCER_PUBLIC_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAsYqiR0+R4lwa9QsSAmDb8SzBDmsRFfpPfESLdc6463HwpBpU +F/GOJ6hdoJ/+7NMIFtpZDwI05xR/a9vZRc08erFahrk2peXnyYlKg8TGJlpLsIVV +3KknNKHMSrS+YUYpKflInzFumFEK9Fwwa7M0r1WUSokbXMBgV+wlCd6UeNB8R4Xc +xdytF56rcpimvw8+3oMKQJrPBB9ep3bzYLdDsu+Iiy6my0mCDKrUXvfVe5ApTEKQ +6c0F+O4kMsS9OO8aUtJwK04DnxNsAi/uJVmtttDvU2X+zKJ917V+0iW+9ZRJI4jb +EPvvUtL8zNAXFhnlfmOx9DKgZmyNLGC5bRxuHQIDAQABAoIBAAvvnBVbPh2Pv6g1 +xFIwnNjL/3ausAlgOLPMD+wtp7T8hgciVgD+FmaIJTNFTmgxj9updk9SAKiAckiY +ETVmJOjCv6lLDmd822ZrOn09X2z4qRoG/MzG+oHJVui22g3EH8RYpA8/zYWj/S6M +fBzhgWtAP6X7LcHAlTmUALF3K1gr309YpV+X1YiwyREU6mzc72ELXC6ZUWcn3jnr +AH4J3UEeWS4eQZs612WJC8TMs502jO5eoDS+qoev/lt/a0WCHrBz/DEwTE4/zIRN +FyN3FrYu+73ROsnUCxzMM76y6ff6N0Mg0d0z/PrC9QvjzDqJGQOSxMerWqTrwNvc +SmSVnMECgYEA5hAMxfHodOKUKfkxYfCcb1qx4Pjj7Uo/g34PJDuFWzJ002mb6Znj +xEwdWh7FDANwywojSSvXSryFyK54RR8yLjrUmtBzxiiRi8uUREseX6MxiBO/ZeQC +t+Gd/VJ9PpTVsrn/X4xmsozXBBKxzcqHKB7GwDPSZjzA4HFgAQkQqCkCgYEAxY6+ +4vyOPfypuJAuPZ1Uswu78M6Km4K4JlviJj0czMm2L+7TBDljurV8yNB/dVd1lYS7 +xnE2u3KlIVPaqNpTR78OLkzDYIZr3lkk0XI2/sA0f7iuHY20DfWqtM8asT+dg2SJ +E4NQM27zRHGOplsvD9cVqTbH+u5iA3ElT2gc5NUCgYEAqQQzjhzJjU2EUk3LdMuC +8d/sfH39XS/F94Fd+F1t/HDWGRcmPvkatvTAP5wJYWkJrXDWOYRm13Ymxyc+HnHr +uMDpvo7T70mQm+ZFF+Mj/ljzI6h2XZGkWZj8K8Y1Uwue733r2jNYo2YK9OgTDj/z +CYuKslugABI0FO/V+wzA2vkCgYBj/sC3+8WzsnPlq3T8UupQRhw24xRdamjzYYay +fDRbo63HzUaZ2MKV+s7ShlY9eqtVpv20kBF4B6t1lxASb4+/vQDchpZOATwQK2br +bLhRcdAg5cWbx+HfPv3MzxdfqCd+HiET819g6UPQ3PmrUnQbvG6GW+gVJxwNSfPs +oXIekQKBgGbtSfX6kZFV3T7DzbR/5WGw/48KoJQelQsyxIxxygTTbuGJ6UmTf8DD +VO5VhdMozGozRn91daoIT7usaqlY+tOcSAtwvj1EL2MoshcSk9JAzC6eAW8ZY6+d +GqmLP29tn8eIkavwWpCe0sinVGfXoqdMHgzDenUHeXShPqVGWGKT +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_PRIVATE_CA_CERT_AND_KEY_3: Tuple[bytes, bytes] = (SSL_TEST_PRIVATE_CA_CRT, SSL_TEST_PRIVATE_CA_KEY) + +SSL_TEST_NODE_CERTS_AND_KEYS_3: Dict[str, Dict[str, Dict[str, bytes]]] = { + "full_node": { + "private": {"crt": SSL_TEST_FULLNODE_PRIVATE_CRT, "key": SSL_TEST_FULLNODE_PRIVATE_KEY}, + "public": {"crt": SSL_TEST_FULLNODE_PUBLIC_CRT, "key": SSL_TEST_FULLNODE_PUBLIC_KEY}, + }, + "wallet": { + "private": {"crt": SSL_TEST_WALLET_PRIVATE_CRT, "key": SSL_TEST_WALLET_PRIVATE_KEY}, + "public": {"crt": SSL_TEST_WALLET_PUBLIC_CRT, "key": SSL_TEST_WALLET_PUBLIC_KEY}, + }, + "farmer": { + "private": {"crt": SSL_TEST_FARMER_PRIVATE_CRT, "key": SSL_TEST_FARMER_PRIVATE_KEY}, + "public": {"crt": SSL_TEST_FARMER_PUBLIC_CRT, "key": SSL_TEST_FARMER_PUBLIC_KEY}, + }, + "harvester": { + "private": {"crt": SSL_TEST_HARVESTER_PRIVATE_CRT, "key": SSL_TEST_HARVESTER_PRIVATE_KEY}, + }, + "timelord": { + "private": {"crt": SSL_TEST_TIMELORD_PRIVATE_CRT, "key": SSL_TEST_TIMELORD_PRIVATE_KEY}, + "public": {"crt": SSL_TEST_TIMELORD_PUBLIC_CRT, "key": SSL_TEST_TIMELORD_PUBLIC_KEY}, + }, + "crawler": { + "private": {"crt": SSL_TEST_CRAWLER_PRIVATE_CRT, "key": SSL_TEST_CRAWLER_PRIVATE_KEY}, + }, + "daemon": { + "private": {"crt": SSL_TEST_DAEMON_PRIVATE_CRT, "key": SSL_TEST_DAEMON_PRIVATE_KEY}, + }, + "introducer": { + "public": {"crt": SSL_TEST_INTRODUCER_PUBLIC_CRT, "key": SSL_TEST_INTRODUCER_PUBLIC_KEY}, + }, +} diff --git a/tests/util/ssl_certs_4.py b/tests/util/ssl_certs_4.py new file mode 100644 index 0000000000..ca3c576bd2 --- /dev/null +++ b/tests/util/ssl_certs_4.py @@ -0,0 +1,684 @@ +from typing import Dict, Tuple + +SSL_TEST_PRIVATE_CA_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDKTCCAhGgAwIBAgIUS+xy2kGNomsBGfU0DEELWiHoSa4wDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMB4XDTIyMDMyMzE3MjkyNFoXDTMyMDMy +MDE3MjkyNFowRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8G +A1UECwwYT3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEA9wgpBPIdclPot8ydp7C8EfKfZXve31sim/LBU9nViOTB +2vZGWcnwmb8bBg9gAaCCeSRHF0FqEmU0hUMDD7AY9npBpIzA4SUjUL3++/kKlZa7 +Yw6kWJoogcVXpCYvubeslpReXq7EhrrCwE83uqJ+gmz+pGkEaEoED42mw4xvNl+K +8B+nfYJ9aYlErX3JjQGtby+RWUw9aH3xBDDZ1Fss3+289OQ4+4KV6jPXXKZgniD4 +exnpss6LqdVhuRt6Wuhol7eoWl/kpcQfQ77fHr/8xTW1TsuFrHjsgJUXqGi73OuF +esOaijmYCLkgklocSND0LDeF9uzNjKEOXl86iHpOKwIDAQABoxMwETAPBgNVHRMB +Af8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQDeZ8UXHc6TqZGkvrFIY6U6ycHP +YSH42ihMkqJApBYWEpb8wFM3vAJIOZV0BBYguat8/7gApRGiy+xnq1TFDJiMLRPu +Q1yDWbYXM1fsObgyh83K8ZNQ/nFr0w5o+HcShkjia6pWaNsX5OErrJ57iJefaADU +xnLvxHXPDvwvs9f1mLZIZgzYtv3go9oQVOCgeIKOyV7cFUAAgIeyOidcoQEN6Gvy +DzlkZdmRRkvvIddDG0kcURmhMJzqg3Tn3hmG29wzSbsw6LK9kwr7S9BKNv/bgxDi +DOLVn9LP8qDeRA7zQtbneTtcEU6saUQT8Q9JLyvGUjk+Qgwdj24M79L9s0MR +-----END CERTIFICATE----- +""" + +SSL_TEST_PRIVATE_CA_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpgIBAAKCAQEA9wgpBPIdclPot8ydp7C8EfKfZXve31sim/LBU9nViOTB2vZG +Wcnwmb8bBg9gAaCCeSRHF0FqEmU0hUMDD7AY9npBpIzA4SUjUL3++/kKlZa7Yw6k +WJoogcVXpCYvubeslpReXq7EhrrCwE83uqJ+gmz+pGkEaEoED42mw4xvNl+K8B+n +fYJ9aYlErX3JjQGtby+RWUw9aH3xBDDZ1Fss3+289OQ4+4KV6jPXXKZgniD4exnp +ss6LqdVhuRt6Wuhol7eoWl/kpcQfQ77fHr/8xTW1TsuFrHjsgJUXqGi73OuFesOa +ijmYCLkgklocSND0LDeF9uzNjKEOXl86iHpOKwIDAQABAoIBAQCHx450T3fr/T7u +t6L4JuZYnxkJuNo5vmf5e6bTpen+wm3jInZsp9h9SVNbM1w7yLOuTkhc+fGJhuMl +VD38g3hVEcG+5jamCbmtiaD7cllk+2KoAcZHhQQ6v/N6IBsfY1uTsJ1mQX136HNf +LKufA+2xVqNoTujDQduViPBej3QZV7obRrcOuycF0SPbXQadbE0cEEKo2htfTgcH +R0LhPOFQQUvlV7fnTgUtCXZAnxRFvciLABUZ3SHwSswBhhWcbWmzaZQxzfCFOdpF +OvBk+xqlpSsa+pmgJ/MnL7O0b4y9JAdLlTf/w95w5gyJMOvn7B3LGeuwIZFHcxvd +CQMjlk3xAoGBAP19pcjZ5Kn2ChQXoeOx44mOd4ahAZXOgDgs1mR2tRPtdjH23Mqf +C3LaOtn9aBpW1A5UyJRHNOIlBQnqbvQcXHFbi1KJIs/L1yv638dUzmZyUZihunOV +hpLQCY5KFqej544BaLJSfBO+xK4mV0hxDiDky9WqzAP7kvmReRGCKqu9AoGBAPl6 +JUEOvhBkVHAS3FpVKbEkv9cIFLoY9wLI8/aprcEvSEgn3LmLJKcDauNKJBKXnukX +oXRkWYSU+CrOE4k5vDvos8O8KLJqDFZfrPNCuDz8hEdt52DI3Eu88oknfXbuSht+ +cJ04WjgyyIf5nDKvCgI7WvtuBLhGlmh9GRmvGcwHAoGBANc4xfhpH986GcaDZh0n +nPPetRbmPq1NncmUMBcuPoID3JWBbmbOcG78YHlS0P+D9xmP3JkgeAMFwWhw1fGG +3uoT+o+CBb9951vc7gCUvYV3zFWWAvM94ftmjKZ1uxRsch48jgLRS62MC/t8bCEC +dCdzeqkYEY3UHC6u16cI6GfVAoGBAJogvW1hF0l3Qrdu35YrcTOQ2biWtH94tvqQ +fjDRCZkFhimV/wbekQlh0iKUBo85/yJQyB3pdWi0xFFluaoY8lMs5Aq0b4wyembO +e0Ja4QpEk9CxdLZVwcxE8q6LqDbW5w/vYNGxJAP+U+e17ateeteAJiiaAu56Jahu +SRiWFmD3AoGBAPv5pzfb6L51/pey6kBL+Kry9gTEHN1hW9mfv4KyQbjBIDfBLSNj +GjrtGQCN3g0o/ElLP+IFXxhJ9k+KlFUZkQAFYMR3X9p1you8BL8eOCjJW+mk2H7P +rkUFuht8pmfgMrCAVcKneG+ZZfc+bvghcCmHVeNiioKfOw/7/fqDQ048 +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_FULLNODE_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUcVyMMiaYY4UmD0lc+D0TSzOgx6AwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyNFoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQCq6EP4SllvUyXjblM/2V88nxkpBwgC9ta7Ndd8pxIZR4Oy +lnNYiaes3gTVurf7HMAIZ0wHnlzRZghVvpZQ3eKGR1ETKYXaoRzlgwa1uZKGn8/a +DBU2bhioG31zYIOZ/QDf3ZcUR5JkcybdpY+Yj7YGowRkLT/GGN+5GgTA7tXJRWJQ +lpHNaIjFgjj5fKB+xXck6OhVHftl+rB2ZPrVgWaXPDBWjgpF1SJnxsbmOK9o4kB6 +bw6zm2wuByZrOYg8ckuIqbJhDjINKesfcyb9qSk77h+8ILj9b11OzZUfX7PhvgO1 ++W9se/RCYtfGgT4nSh9No7l2vA/IkwOnZOK7nBgDAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQAHcwPIii2n0DabvcPo4Kfz +iiHQfxOxlnTovNmI3VIWNYoe+ElYkuzKUlwbYEve0dEJwu6mWazIEo+Qexgv1Cs3 +Yn7djsmsC7q8pOvSmw+3t+6aOXGzeANcFUPJTgNIlxA0sucHoWwpROLsndBdqVWQ +LsV5IwgLJbcUt3tjaIsqfUXabqJMm/KleCd6uDzOuFlW7E1jdUyPomvbOKgc/jAt +/AxQimzkMt2uBRH/2IyOW1IS+035AxyyCfZgyhJIhf0l5oA6IiIvS47utLJ/DtWb +93+WPiBYIgNofNr2qGrDtK8Pm6BjjJtBlFvu9gNcHn0E2mC6TKNg2ppFNxXdX70Q +-----END CERTIFICATE----- +""" + +SSL_TEST_FULLNODE_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEAquhD+EpZb1Ml425TP9lfPJ8ZKQcIAvbWuzXXfKcSGUeDspZz +WImnrN4E1bq3+xzACGdMB55c0WYIVb6WUN3ihkdREymF2qEc5YMGtbmShp/P2gwV +Nm4YqBt9c2CDmf0A392XFEeSZHMm3aWPmI+2BqMEZC0/xhjfuRoEwO7VyUViUJaR +zWiIxYI4+XygfsV3JOjoVR37ZfqwdmT61YFmlzwwVo4KRdUiZ8bG5jivaOJAem8O +s5tsLgcmazmIPHJLiKmyYQ4yDSnrH3Mm/akpO+4fvCC4/W9dTs2VH1+z4b4Dtflv +bHv0QmLXxoE+J0ofTaO5drwPyJMDp2Tiu5wYAwIDAQABAoIBAGjkEAMsrmMSpuhE +Z7eCE19DTc/OTu5yzCstykjoyMTXDU7n43btVQlVYaZC6HOnm3wM2a67VL/3XRoy +1FJhO4up7WpTS6F4zCFYHyAc+n7BSnHKhKJZQ6y44m+TRnGVw5mhh/2cR4561dmm +qNC7Mr40Apfw5XkQ/w29mDlI29CgUZOCg9e/DNfNcHULXjaBvIT6Ecr3IOXl/d9B +zdtyAZohHCv5m3Psv7ciFjDKb1nY1+c6c8WUFUYgPQz6SUbm7mvtLiH1gVBuEjgw +xI6RwhcNqEVY11+NO8hVcHTvwffEIDMbn7W2L4nvJsU6PlHvsxZx5OHyJIPLmMi3 +IrnbKRECgYEA3jrZ+zMaP+eeuV2syjc3moYK+dbKzk+ewk6EBQsUTyvq6CPvIZXL +5MnckGjw3CECIKwZG0gKph2+Y6M9h4sfg2Wz7Kyfygk+TolMU21Aw8mRhkWRCs01 +9hiZbCrNypiQa4BmeFWo+uyjVDafSRJqcTIcVSHaoeyRn9uRIYIvOfUCgYEAxODe +//ZBx9lufRXMYR6NoEqok/fsK8uORr5+l+QdZimAkdSDmGtY4/o9/TBg6fm0C0kr +9o0owbi43FwEq3ZLyPIevCaKHClZO5MQm+PfRYDs+uZhrAWaPVW9Q0b6eiYe8Xwv +Vw9aR23DlTPXzV1kiuWwsLIq3+Oq9C7pt2qZdxcCgYAfMyIBa3ZG/IzDN4yXw1LS +JfmKhAZrGrCOVRmh36FVUDQlrU3YaEB8+X425BTUwumajq7jrqSYF9rwAC4WRokB +GJk/JCk24z9VJV+K4u7Rzg3ZTREE9DScPW3kysmjpPG5tggs4tHbkLeJjjWku6oo +BEIIDb21OBJl4ByrGKzqtQKBgE0Ph7nAdfb3kFu9kIXjI6Q+FMX2IKbzwfjGz148 +l5VJYV2zRN8ABYcWh/T2Xri2WFaiiWaz0eQhnZoDGoDSiM9aldUncJ+dP6Ql6DZc +dyQJVrjOPCTM/JZNXQtcWOY+zZXP+eelxrx2pjtcU3e6uoPza7l9w3Jm9p8lTa3R +N8h5AoGAUAtG7NJ3Q3CCUsz85OUaDGlQVPNrKi1BBG5KEZJla2n82qjnUdOYRWx1 +c9gr9O94Yukur3VWtrNKpxnjwJx+F3akW9rHwEEy5xtlAJbi1mR7/1thgObUS73P +uapcJeqezHfl4ir03YUHSAJebwefo54B5t5pOdWEFQLS2AkggSM= +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_FULLNODE_PUBLIC_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUIpT5MM70VeIvnygCEHRVsL6Aq80wDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyNFoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDsxtOxdud/1pyMnhIdMYyqWmH80gO0Afp/ojKApcqzV3aB +KBFfQWLp4hc+CwykpAItx3vuTNXn/dQFxzC2NXrmq1OlPiPUcxorzctxqDNdoXlj +WTtxjkC+kxvvA2d7hgl+Huz3JxTWWMt+fM8eLTAOdVpPea7unW5GfQ4TwhdEMsGQ +4AmUylw/vjJDUaiOHlKwwD2c4EakZNd35pCtRZfNjM3CF9BxdK2xysWp+xoOIY2C +G61UFfaXiVK+XkbZB1g0+nhNEsur03gFXkFEVmetXZvpfTvQ3J8a3f/sguzLqmYq +spKleR4utiP3llVrgnKPWpDiMvsx+xRbMlbSUMvHAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQAV6jnHn5x8uYtbM9jN3cqQ +FK0OrZPSDsk+QJt1I0U0+HF8j2jMZ1RTxRhUCnjCoytqbh/fT/Xk+8s0N614lvja +84fmW8dKq+asD2mWrPZeEgpipk+fzthUOrovNobAWtpdEqjKWEvQxMOICijEXFbv +95V4kZS7JN+s3jAf5nXOK9EhGVI9214UyGNZZU/nzFKlOLcZFhGBibUAT7oA9bKi +BLbCPI4/CIdUnwaK7y8xF9z9KL+A24ZZzhLNVC35gl0zESgVqa0DN9XQ+GP0qC1S +1Z6PF4qBDeta+3R28PtfPIiNpYJ6uHAOT/iDmIWBKTGC2Y6NVs2diNZSOlZXSzN6 +-----END CERTIFICATE----- +""" + +SSL_TEST_FULLNODE_PUBLIC_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEA7MbTsXbnf9acjJ4SHTGMqlph/NIDtAH6f6IygKXKs1d2gSgR +X0Fi6eIXPgsMpKQCLcd77kzV5/3UBccwtjV65qtTpT4j1HMaK83LcagzXaF5Y1k7 +cY5AvpMb7wNne4YJfh7s9ycU1ljLfnzPHi0wDnVaT3mu7p1uRn0OE8IXRDLBkOAJ +lMpcP74yQ1Gojh5SsMA9nOBGpGTXd+aQrUWXzYzNwhfQcXStscrFqfsaDiGNghut +VBX2l4lSvl5G2QdYNPp4TRLLq9N4BV5BRFZnrV2b6X070NyfGt3/7ILsy6pmKrKS +pXkeLrYj95ZVa4Jyj1qQ4jL7MfsUWzJW0lDLxwIDAQABAoIBAGOH7OMTpZrCf0pJ +BDpLYuMVXU1mhvH7Ru6yIuKbTsr2wDTov+y30rmYNcb55BWtb9EIoxr4J47+z0qi +geKGNqSSbnXu2ibrP5wcRSIA357DSwCtOOSyNJsnwb1GRBDTtlfS7i+yuPqllt0T +4AjCXAon4I+6CgP6H6n31ZwOobMjh+SOsgfcaCiSspyD1Dwnkxvz1tVRrLgv4RGa +gyzCEUN0zJaQTvTnlBhSOvZ7E+AgNa0gt2lYUKuSd3m8Hr/xtKKAyotFZZjkkI+A +GjK3eL7S2zL2yaYyJvQmGpwGwceti2oq5sytWXXREraFBxjusF1Yxw4n/pguvrAS ++5CDlFECgYEA+O7KoYx5g1JEOFCFpyfDVyR3s1SOVBe2pQIe7qcNbtrDFQu624Mv +YSvYNsvplSJsbFUCPIcqzEf+BIzgQQ17yDacczZnk5rN3VurU9xRaGjZTKeF73nE +bDhRXmIJlxCtkcXi/vzDUJdhAtzN1yTHhwgz7SvHHeqqZkKwPjEGo7kCgYEA83+v +vZfMOWJjHXGlKj2cAmHkLGrKal5l6HpMxOMqaoVbx/oDguQLP5uH8TQnckAJVyKA +ks0gJrJsu4lk5CCt2xgMQSLl+heGcN+usVmxiV7bBv3HC7E0wNp9/13NJWL5mrL6 +COEDIl/qjF9DI8ISam+L7KQYk+TPp4lxgyxxq38CgYEAk8pJuUHKPsIPyJNd1lDQ +M6NuAaUY3yo5AJxSuwOpAQCWQ590L7Eh5wH92wKTSjxmvKZ3rnHdYez4DcGJvnV/ +4O0zU1+gfMyynlI3VJGAL4nYQR9QcE4N5OZGwM9ZvDtloR8oVpTAbM+DBA0NlEa8 +wxmGoq+UBtn0ksPTGQlIVNkCgYA+XCUV2RpkV94qXECAYObjdU6KUY8lTqeqsieX +BNaIET9AJ7defiijUaGvFDxF9kBuIFftQLtLLcbLAJTmF7hus+nvhJCBTCUSIzcK +FH5zP+e4EqY3SFrKSSqbi9pOCNsD03JVc8rpssbOzFbVgY5V09tx71ScC61iqsB3 +Z5p04QKBgCDlV7wh15Q+C0KSR26EE+6Aj+CaH8uRSoDO707vf+ZS7oqw5Xivl32Y +QHFVDim4TF3UyYJvCRKmvSMNNsAKc9hFBU5b3TlBMwa5Cx8l+fOmYhe9eNsP8BNm +aOrHGu+nvZ/oke47p1HXEEqUfPw5hPdwo11jwa5lUtSJZhLQhhT/ +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_WALLET_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUBOIDJICHJA4JiPMdTj1KC19GQOgwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyNVoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDUjguITn4XjS5HDyHEP5Gmq+dgP1dxpYLMDWnJtHZatsYJ +0x/rnEmDTReeQgiCbISO1oyK/TZ/L1IfzoRTm///uNns8uBnku2VmUDaTUd5K6ws +WqxN3YU+h3P5de6otb0DGkayANr3bMy3KQqGm/XxQB2VvXuo4nzbB4Tk5jDO6vtk +lG4184IbY+08nrj41L3YNCOynSnRDi+1ipfc/hrIKuCA5Giuf56S02hHapjEw8+W +Tvokx1drAlcJkFBLDVuPd146L7klCAhENaIYxJmoqLme9ZNOta2jmSEpeIHbsw1x +HPJNi+6n/Kh7k8Lsp0fE+jgQfPDEaqOXsnLCZOcxAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQBXHURcU2ox80IFiBq8xEDO +cmHDZVOrQqpmOdygP+q/JRFoX9jF6X0nR17DBfDedgBz1ghax993nXwGJswvs1K+ +1DsTIKxO2HJefd/5iur6mxLFF8RXdku9as1tfNx7CZMm9WcML3XJu/u1/E+JRUFT ++QdoAX3+GnZGY6g+2MUSo11+3Ide9aaHvRUVDIXxqxDOZgLvy+EpIoQU4lkL7cuJ +CuFB0LYM9FMih1BX1uEu3wnCRhJq2nJuIObMEU8wQj8MmgPZTcJh5tyVR8OeDZ73 +CACnvjXydwYvFmcB/NCMLpolQxxgrpYKrz8dx1NN8mZRNb+HUrM2tiLsWKAdFEid +-----END CERTIFICATE----- +""" + +SSL_TEST_WALLET_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEA1I4LiE5+F40uRw8hxD+RpqvnYD9XcaWCzA1pybR2WrbGCdMf +65xJg00XnkIIgmyEjtaMiv02fy9SH86EU5v//7jZ7PLgZ5LtlZlA2k1HeSusLFqs +Td2FPodz+XXuqLW9AxpGsgDa92zMtykKhpv18UAdlb17qOJ82weE5OYwzur7ZJRu +NfOCG2PtPJ64+NS92DQjsp0p0Q4vtYqX3P4ayCrggORorn+ektNoR2qYxMPPlk76 +JMdXawJXCZBQSw1bj3deOi+5JQgIRDWiGMSZqKi5nvWTTrWto5khKXiB27MNcRzy +TYvup/yoe5PC7KdHxPo4EHzwxGqjl7JywmTnMQIDAQABAoIBAQDQJN1UOJEvnPgx +a7cER7/ouDQWw1BtIMgJ7CSo+ghgYtVhr5Z1khFG+8piFoXgukXA3oa4YKfqOjuw +m/pnKb+x+qGlcF2h73aq5W1lmQGhvcuXj59ljMS7a8d9BSiVm4qhLC0IiN/kJW3+ ++ritArL/8WpHRUuAIXJkxmM0B9rJ8/bPYhcK6cdgwV09KOKRL5FVrmVQIzNlM3F7 +EakCLVTaHeAlOHTt24XU5EuhV92ZtHorQOUvdx/wjWTGosOZxs92DS43gS/ZszUq +uH5mfbRTyTbde/BEKSDE27dgYDV2uJ9FuUeTJcJl2kjuKRUPrhZf+0FoCrhcAhzg +JIjVt3ABAoGBAPJ/AHWpEPlp5v4RxhVrwZGHbwac7kzzaaUqS3r4tgw8iAb7iEZF +VDyVrM4gXsfaKedUobxaVMUvH3ajlIHF6ncnND0I7u4jff6lc+V1HqZbOs4xaLwu +zlrfecfU6JOrQ9UnhYk18jpShzMsoBl2mdPFe8QZClvn6UMfXaOdot0BAoGBAOBk +NEchBh9Tms2826G2PZHclp9JVpCYWdxqW1/X3MoTt4T8gQUSGbeEx3ieY95oqAE4 +eE1RhEniIQ8sQtdgnZud/LD+9mrSCtaAdkDOSCulCXNt04B84odid3LHkd+qZ5/5 +rqctxAmECxLFaYHU6eIeAMhyoFx8gUcPLjIvRpoxAoGAPbMox8c7pWpXtr+I+fxP +5RpjmnglffjVIYwwZlqP328rYTNwyghr1Xpz3IKJ+ym8TbrP6B/Hv+AsjkAy0g4s +iSK1fO4f9QGc1kT8xx5UrRk7TiluL6ttH9wKnVjD0IbcHIkQxgeu2T4UXmX1WmU9 +4I833X5Nj3LjfAuoBLBgNwECgYEArzUOrMtYYHWDVkm0pJwLjyzSXyWAdf6/i59w +IXIHb7HdhfUzOKZddjIzHjdue2b0Z5+UL6sKxDXQ4mwI9Or3pV7Cw+EQv2+qDrrX +mtp2970xl/OVRao9psB3zCOP/zirGPp4KQlPHK8BhnKmYz3AMVKEAf+evxhoSPfN +dln7osECgYEAy/HevTnTfcCn6TZyYBz3rHfZ8mZBO1I6gyVytcNQNgmz2ZPI/Cxs +iDg78PSjypKSZ1PyYFc+5dIIw+02guglrTnIrrxUbGp7cy26VQfEwGLjaqFHZplc +PFS4W+Fz2xVGnkv2sQwh3tSihThxd3hQK9isI3iHBeZB3HDWpGQzRMg= +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_WALLET_PUBLIC_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUN7Hj/9zSlPgvmKSmTRU0Kd3ok3QwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyNVoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDgmG/ekJTb+4NZslwT7MXUZGuOOId95dTgXWrev88flfsE ++lEl1MvVKQLVi3F1I/mxZujYbCW4bRqmwEM/jwpLNxd6lzQjGLoePQWTURCBdnAY +RtslK1eetPhKRMJTTzaH21prkEEEwjqNb4he91O95VMApYSkEX1vOPd6LhxW2X5E +Z7rwZzgL+qwKtQy0VdnxYIcBnEXIKanNodC3vR6BRTU8vBvMM1wtxjKAAcs+fQVY +6eyBu3Z450Fo2Ge1+orDgLdN1qSFEDw/DU98V7Xo8CzEoBV0vRxja7VU3kRqIMKk +EyVwjD6QBfm6CadVC0+vj3B8sbFF4C+w/gkZUkodAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQB0UQbCG+es9N/hKKbzG6+P +nXbd/c8LB0iJIPZ6xyPWoZsyzPmItMt3KFnYko7EbZ083Uuvfy+IyHSPcxihxQl4 +qLGvjxHG+relpKexwnhYgRWuW7d8xI2WMjDT7Xs6q6npbCQjwpZXbKxe2Sr/WMu/ +HitB3RwZ/CCeQL5oh8rm7TRWi6boqJXG6Yx6jjPRrs+f+V7deXNxHs2eV3RUKdBp +Lc6IiNoTtdkZm9MS+xsucm0HJa/Mf0/Gbos5A9oqB++q8FR18Rg7cEt6oTyPjlBF +xq/9SRUCLAeaIVufV+Be/bx/tX117/MUQth3cqSqlMkPfvyIYmZFbJbr2wlyQ4wS +-----END CERTIFICATE----- +""" + +SSL_TEST_WALLET_PUBLIC_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA4Jhv3pCU2/uDWbJcE+zF1GRrjjiHfeXU4F1q3r/PH5X7BPpR +JdTL1SkC1YtxdSP5sWbo2GwluG0apsBDP48KSzcXepc0Ixi6Hj0Fk1EQgXZwGEbb +JStXnrT4SkTCU082h9taa5BBBMI6jW+IXvdTveVTAKWEpBF9bzj3ei4cVtl+RGe6 +8Gc4C/qsCrUMtFXZ8WCHAZxFyCmpzaHQt70egUU1PLwbzDNcLcYygAHLPn0FWOns +gbt2eOdBaNhntfqKw4C3TdakhRA8Pw1PfFe16PAsxKAVdL0cY2u1VN5EaiDCpBMl +cIw+kAX5ugmnVQtPr49wfLGxReAvsP4JGVJKHQIDAQABAoIBADWQZW3BMZ9dVrA3 +t3oRCAVlhbk/hiDihWiVHv3M5Qr1bA593IiXPZ2y0Dg5r29uiwhiMLoc4MohSy/l +vqQT6zKRCwpzsT2Fki3QA9pkhPk7U/SWQYGV2qnBI04jI+1WgPzZtbDdkIQgBnLg +3Lc5aUFqxebrkrzGZxH1liAPizay6ds8PsGGN7AAeGHdcyL4oGIlQux/jbiGbBzU +NBJmD3qvmbjyrc0J2wYyCJtlCyMYUW6Z428iRI8Qzv1wBzAmnEoKHlFnsIwvzPRU +SlG0CdvWyckXPy9MfWpjmMhQos7U5MZwECWl0aF9MPSkLSxuyfeVWw4/p9tOWS/f +ebyJVwkCgYEA9xU9GAgFzpTHE/1uFNqHSfQxqtEULo/FsxBcOsRJyVvO55+mQN+z +S0UtdiQJ7s4Vzz5UXrnhG3qgxtQvgt6grg2m7pPN5UekIDNsQoDMwMLA8Bt248vw +3TLbSe5Rn2H54F1MuxfoxG/sTMpzNAgNuc9TuPkRok6X+nsfbfiPQXsCgYEA6LNw +kuShVbWRu5aZd8t2hVSFOWN+lmI4MHhpDCFXdTyJ2kxU3k1vdPth0i9kFU3JktNI +Ptnf3R32Uf13lWa75e/0tHUlHaYs1gpdKqDU1T7OvU0xk0zzeogshc35cl1b7Lyw +Op+PJX3F+QjK3Y5gDEnKAUpi3Z4MFvi7sV7BE0cCgYEAuLa1/5svzCpJUdZqT0i3 +T0AxSUQY1F5DLASVDpHjn5b07Q/bGDCkNyc2P1Xd3xtODqrIJDDN6t8YBsxl4G5S +rQwjucPhbwDJ4BDRZD4p1AlEd7vwe4fhP1xft7tkZcS3K1ZUoKHVL9WEUDwhN8q1 +iC1Ip8X7ut0KnQUij/H8FrUCgYEApUF5uvgfE01E16GWD5sw6nMhwaXE6muKV/HL +OFAdWibKB3uZ8d2wP7WevLPnMbHyaxEdB3WXI+L5YTTOTg2Ndzg34kgnOa0fvknR +7EoXm/FkxM8jW+aUKvq2E7g5ZFykwbUmuhtCf2+YvsjduQY5c8Cbctsu5xAsqcuv +D8GpAFUCgYAWVdHC37arXcZiwLO/YYPE94PbIqd5LrMaDXcWNcwFSbB7kOnINt9G +stvnxoD999PrSJLRbnvWyQhcGhK8qXZtDyh5sw/VuUsufcz+xSwI1+K3NSBEJc09 +e9XstIYrR5rdizf1g6Ai45W+wAcs2ysUBfnY3fUv4+n8ZoRiLXCepA== +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_FARMER_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUH2fAuEi168jppWUawNNToTni7CQwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyNVoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDRJQfoJxErXVdwTU4sAQ+05EX8tC1REoYFJyB3hhB4LfOz +meCPe85X6FTYbcPdaL3NVevqEL2hzbqESD5Gf5Fvx9ctIdzwYv674P/tqPrIkTd+ +cLshBKaR6CeSjPt5cFbWhg1hnmWy9Ta7SsYqOXh2aBQJKTRIK80U9b+8iVs407E+ +NCMljerodAdePW5X13i0ca9ifwbTZkS2/c9nQEi7qldj18/MVax6qezY0aKqu/96 +8DSSTc6uUiNLKmRYP5xRJw06ggVooviX7snMzG6SgsbLK2tZJXeJj/EECOY4UrPc +FOkVmjxGBP3QD0oLoXnZpxvutS72ovUrcPxAMImxAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQBSOIrT/3mFkZmuoQ/7UcPR +TOssC9o0xAwR0iRdziNQBZne2zLCxk6p32di+T6GIJahqYFqVU2cfDyyw9YUCr3P +nbMjuwsSrvor4LwJ9jlWKRRyBm/adCttg6OQIO3rYk/rX7XE+fBY1wYhqK+KcSCb +iRLqHIPEo9On/kpaSOWKFeSrGLMkj8nQWMNNtbzTNcdhQlxEGXcxPsVb3PGs2b0p +n63n55HTUbiL0UsHQvxR8gr0YiSpmlgJLi5pipDbyMiVHyCxj5j5vEovXckRliVd +iEbH235NTXPtJ9aBVEDsHW7W1AhzK5gh0Ev0xOC9vP98qTYR+4Oq/3Mz9r2jP5/d +-----END CERTIFICATE----- +""" + +SSL_TEST_FARMER_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEA0SUH6CcRK11XcE1OLAEPtORF/LQtURKGBScgd4YQeC3zs5ng +j3vOV+hU2G3D3Wi9zVXr6hC9oc26hEg+Rn+Rb8fXLSHc8GL+u+D/7aj6yJE3fnC7 +IQSmkegnkoz7eXBW1oYNYZ5lsvU2u0rGKjl4dmgUCSk0SCvNFPW/vIlbONOxPjQj +JY3q6HQHXj1uV9d4tHGvYn8G02ZEtv3PZ0BIu6pXY9fPzFWseqns2NGiqrv/evA0 +kk3OrlIjSypkWD+cUScNOoIFaKL4l+7JzMxukoLGyytrWSV3iY/xBAjmOFKz3BTp +FZo8RgT90A9KC6F52acb7rUu9qL1K3D8QDCJsQIDAQABAoIBAQDBn1fXnDtv+yVV +KayCXqUs4dzNW/1MPirnIFcVcH9U0633izDzhTn99nB+Qfh/xVVagP48ny0AXBce +GkfVOorpgoh6FwyVXADa7S3i13r9LjvDChikM8sF73ibW3wA7HjoeAhxZJRgflYi +RNJ7CuO0MxzBcm0dl7dwfSb6I+vZCa5b6McimTnKhXSBwQy5m85ldAVKOZveU+aH +gLU1qSmW+2x9jErdzJadhfqrPDcy8UBla0uqamXfPBCeSdcSRHtlWvc9RxBcdtQF +jkzhCyGK4K2cBKEMa1rWCcr+kAd2uasEoSTfe4LMPgQGbS2e7sl9fufbKRDkZWrH +NuGr/aVlAoGBAOvjN8lAgOQJyI1PmKcZnbUXRFhyYvjZ9kWmsN73RpZ3yhWPL1MV +0qyVHD1VcqnRWW/Dw3Jw42cLw+LZNJMSNxPnl5e2MtxSnmYn0PcrkUcpOafxy6dO +MV6op8PeA6njtMMEFnnPBoVwM9km2OiSW2/L3+rndtS3eApRzkm7jjjfAoGBAOL6 +FolDf9EJS/njwHFGhMRfUvTC5C+YJh/vUjkY22rUw4v5GfxTlDVigbbqzerzMnA6 +XSU11S/I/n7HuqGbc5dyUGGyk8S7Iv7hvfDPLfy1EXlKvQElpcbXG2Ln1wZ9E124 +9+jRzzOUv0GcuxMXMGi+OIRsWyyzhNOZUlLYWT9vAoGBAMZhFO1//eXKBIwzQKJn +fKZrpuLrcCjwxZjWEzGwrACnRaDUBmzNkZvq2xEJ56DBm4HPFXQNVHG5B0ikev6k +9wUaY/cHF8cLBIPNQIRec5NxLDf9tdRCgmqlVFH5SQN7qO3JZk2Sul1Ge5RIg2s0 +iwl+YBZiCyHiGmYzXlXMElPpAoGBAJrLQglUzluqQnVmvLzEAhHGjNW+AE7xLbcD +yQiFikZ+Weog9XbfLSmHR72OvuZn+1MMiq+w2fZf1ihyYDaMxLVZUbZ/SkWV9pTr +MVWEhfFdL1CQBvw8R6Wm19eJE10qecWmOvQ9+lhMLm85y1+Gpg4ZBIRTPY7r0z9X +xgwX3i3jAoGASf/FiOO2qtKDxn61LLVedxDtdmxd8FHLP35i+4S2ZyeIe8l9K/Cf +lbXe42v2NEKSjYq+z0HKdtjgZLkL2ucF+rLbkBfg7G2hmWob0hfYCE8xcnNPWIKM +yoKW82uijH86yJEWHAFAv3IZhU1CQP0BkYteAxE8CExQU/CSuHsCDao= +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_FARMER_PUBLIC_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUFPTg1QrNlWLRFn/hC78RXi0IOD8wDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyNVoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDB7fCDqqnna6BfaJsv4xztP80jBCygHHhHdliSWbGX/tm0 +lK716u0lBRiI3FmzPk9MqKMuV2Vvjsqm7gwLzG3oMHKaUPJUOiVf5v5/rXauNiAA +m/sfRAROef+ZVoVmU6rqwnGvTf6POI/MPdEbCPGIXu3bWjPXPq/BKzJ0KCJh7ekR +DaFWCkfQEs3Zilr2ehrdObzwHOxJh408t2qGeCQDlQeDXZYa5cTHo0tNoSWdfJIi +1jNlEnvpo6ZV4fyKY1MiN42J/2swaxypdS3KxvPZzKWebgaloFaZoY3HziotiIva +EnJrUXNgQI1lW4/a7jooQ4c7A0t2XBidRS5Sohx7AgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQCAQP7xtLehAfWTp1k3E7IM +eMT0Qm2iBWQqB4RLxIJWgHyVHYeY7Lp7lS+BZFKHOkbVoc2J8cA3qGGDw3WrmQuF +uRxfL+bLC+HMSjEvPbXmnMWAqMKmVBzOvZf91VVKsFR0h4Gyt78EFteZVEHZI5bQ +jC2RLte2uCtht/Wum74z7jGzplx3fRV+zcig7Gka8IwTcHaRpfhhZa0wbbR3Kfe0 +uXcCgDF18rwr2uIDNPBmJfy9C3nyQugWzNV/j/FDmrqHD94tagfDx5wYPb/ZFVpM +TRg94mZSL6OkgITfba9MkOBcVGbkCO15NckC8rm0p3ngbEgu62eW9FlwsE8b1bVK +-----END CERTIFICATE----- +""" + +SSL_TEST_FARMER_PUBLIC_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEAwe3wg6qp52ugX2ibL+Mc7T/NIwQsoBx4R3ZYklmxl/7ZtJSu +9ertJQUYiNxZsz5PTKijLldlb47Kpu4MC8xt6DBymlDyVDolX+b+f612rjYgAJv7 +H0QETnn/mVaFZlOq6sJxr03+jziPzD3RGwjxiF7t21oz1z6vwSsydCgiYe3pEQ2h +VgpH0BLN2Ypa9noa3Tm88BzsSYeNPLdqhngkA5UHg12WGuXEx6NLTaElnXySItYz +ZRJ76aOmVeH8imNTIjeNif9rMGscqXUtysbz2cylnm4GpaBWmaGNx84qLYiL2hJy +a1FzYECNZVuP2u46KEOHOwNLdlwYnUUuUqIcewIDAQABAoIBAQCwX4qi9RBZXNUa +cLTTNKcWTzRuaFl9tObfd47Oa6zNJAcz6RXGqsbLKHtL3bvm/QB6I9VlTC8A6sj8 +UPu7r002IvnXx07ds5RSSG+mB0ks4CTy6OnXYbDY/rOr7bide/KyV+21FiYyc6q0 +gnQvNk8VS+Df4oXLeUO3V2Ynpmi+zl4B9dDT5nZ6bb26fYI8ei4HDPexPdQbJQ3k +mCimfkMbodEsrJfhM1V/NPwHxJvfXa8mTsEuJnn+efB7bsS3GjTtQ7nuIiliSqHm +SONfIUWYdgEo6chSnKA7MDWFsoPabV3zYrPU/aJqMeoCH2jNEu52NiOhTkv79Dg3 +AAqci1CBAoGBAPbdSxAWGaRv2KEa3Zry7snhhSVth3/wY+imVO7U7Z3dO23b+KNE +iEobXbuK6eLKvskvcHel04DfUbOhNws1qytDpG4rLklXZvX8eWpTECkt4BPfefVi +SeN8FCxpx2JSmQgiCzDuAGTg530OaHHTbymhEr+Sl8rQWBZYjo99A5lLAoGBAMkb +KLDai93wWYt96MYn4NPxBhUNbSW75wKSi3PHgHvnAM9qsInXo82BFmw6oUFCit6h +zRc+gAp2wsqIaka9/Hao0MSeCgR3xuuohZeOKmSmItnw70k75Qgrnu9wKyCEdpC4 +juDnkaf8G6lT7+Re9g48/MA0Qd6l6WVvXs5nTDuRAoGAaEDqe1+p8pzdcqQi5FYl +7BIWpcjMyYYe21irU7WOp/WPLIUSSvkdSZanDhXLUmDnE5W6PH1Ghg1Jtr+lvFEs ++Xd2kKQhxw1nSQkXyYRMtedO03W0TqH0rGJxLpR5hJd3U0z1RvOsLO4iNNkJ2NA/ +COiiP09MVXWJTd6WThiwlWMCgYEAlbwfA+71DP6T7YSF+GRgxe1DdhFVHy9UxVmP +c1krlRVeSRFK+JcSY0SmCVduEUUWWMVoCtKCS0g5qMsBNkLm4wK2zm5NTx5Pgc8s +CLfVYLNCZ7s4rvJliTvRTr3ZnpCCJycDWvmQPd88SUsx5nu+AMPv/Lvr/3bQ3LGb +iVroK8ECgYEAoSKTrvPcy+/ViHCr8ctBK7oIWiE07l0OeXNsH94hTp25OtBScGIy +alsJJrq3P8NjRJvxvbV0FXhMN2Mq08w3sZdCbZW3t7hu9mk1chxREcmmmfcJIqxx +x3zd2+szabHIFg5ozqybYbjmJfDZxNIG8h4HvHRdmBZocbRQHBM5VN0= +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_HARVESTER_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUC/PhYZPSyT/cH2+54Hfayu9ZXIQwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyNVoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQCog5fCeSavpTI1/3mA/Jv9XJF6ZGRzmNJq8JdRPUd/V6dQ +eU5cOE7QGXbqBV1gQUOXIf8Ke9wgwcMPGRLBbhMQcd9CqWK/rZZOuczRBoqyEvQP +YhkyPWmIbRsNTLg6KYxghdCD9Ps75YWBpxb7uGwKgYadixPGGTDlbGw4m4T+xoSX +kkXcoCiYf+AnWdT/xYloEG+ovy0oBfOfv3q3ps7ECZRX/hZ+4RCRgA1IYi4z7VwL +JepZz87PH6zv9D1CmtraQVZUD3UJRfMGVsimLlH09r+mbZm3Ndu9cO7fLLkLzLP6 +w9hhibZtnNAOyLDYrgOjl70bGjePzeodmqzPMY2zAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQB2/xNHBk4oXI5iOyhh4Kob +7ZVFfnjnOFFVhoWYAHSL4rJy6Zk12VwqsvUh4viwkSgmpKkZxyjQR7rKGTyopzHJ +aUEV7mhHc6lpM1biTZyXHz9PIJAgiHe1J+CTm5qVx9STi1b1cJ1FlTYK+7TT/noZ +Pscg1KOw5rmUbTcJ6UnBF1EtSSl+JzPZDxE0/NKBKJey/vRZXj8l4WLiN7sZTr9v +n3AnByDua5653q+AOTjoWP6/U/w1JWa4QNCzk05qBnFLczWGmU/oAXuvIRkTZ+wq +L/VQNnOjmBDeN+LAVAjUxDuGxVJiuCQisUiV5KZVl2kAayCgJccEI5N+OYKO2oI+ +-----END CERTIFICATE----- +""" + +SSL_TEST_HARVESTER_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAqIOXwnkmr6UyNf95gPyb/VyRemRkc5jSavCXUT1Hf1enUHlO +XDhO0Bl26gVdYEFDlyH/CnvcIMHDDxkSwW4TEHHfQqliv62WTrnM0QaKshL0D2IZ +Mj1piG0bDUy4OimMYIXQg/T7O+WFgacW+7hsCoGGnYsTxhkw5WxsOJuE/saEl5JF +3KAomH/gJ1nU/8WJaBBvqL8tKAXzn796t6bOxAmUV/4WfuEQkYANSGIuM+1cCyXq +Wc/Ozx+s7/Q9Qpra2kFWVA91CUXzBlbIpi5R9Pa/pm2ZtzXbvXDu3yy5C8yz+sPY +YYm2bZzQDsiw2K4Do5e9Gxo3j83qHZqszzGNswIDAQABAoIBAG0x0E4ZOUNJ9Y5d +/HrjtaTorfA0S49IcNkRC8x9u+29e9K+uFMzvYZFafPdBBPSVp0BT4WYmxyy0dXf +tnKXBE18rGJC5pU0Q5jB9wFfjtIzS+kH9THD77WSlZv5ocs2jxsguuw2+/FlGizY +fCEi8QehxPwjWe3c9v1DU6EezYBVT9ANny0k/tjIRWgl8XpCuErIOh5LbzdnVINx +smAPD5xbYA85HDSGxWL7ar/nV2cMyMPrXjq13cfMyJSgMgGQ7imMje3c4aUDNZdK +hhuNIAYqGqfGRvT7Sg18o9upN0pm8NX5gXDOifgqLgI0Pt07pomm3LdOlz1mJlqo +sWYiuYECgYEA1xuwXlNl29BiKKAxjpUPJrxwVMX2J1Ijrx76YfLWRkWRzCotYqKD +vvy3NyVUNJW2mDunAq1q/kjlf6c0M+bAQdF895hiYgQWmz40NwtlBG0NIuUvtUCa +EAj1RXi0mKvZ9da8p2eRL4GZW9CSgpK0d9Yq9NVJDxohL7OHuE/KXkECgYEAyIxi +k0BC4My6GX7zaPBt05mRWsaWhXpP4pN67sox9QLm19rP0eO2ivDrvc4d1ue9JyOe +W/mmmPI8wTIm2AgJvXKhUz8x1idwJ5I30NicOflBEhg9xgNlXFv6ja/QZE2PjyUz +l7UTE525Zwn2r2mtQSQoCljPYF2HhgfFkIbglvMCgYEAzCOP3gSBbvk0nl9giHK3 +XUiJxjnUX/6YtNHORnRBm5DcS4hfZ/LY2sBUU7ZOUlUeYxyBY44WMtoVSm7woKzF +GfFoCkUIYQKGPa/rt61NocSoKcyc2QNE8iC+O77QjO7SO3cdtDUaWJ5CXxryX45A +TFXokE91NSrUAcP78hNu9sECgYBWB/MZnA2Uhf6nhVBCCjHy/gPe3yYfKHMwjXfF +DDQWGSKSIqnYLklWnTdj+xHN6Se5rIv4hMY1AmWRs0P6lKgo/w25unhUmCKCtzT+ +gI20SPrjGkcVtMs8rbB0K6HIBYW6MIlLYUBHv/eS/jE22qyaLzqGBccgXb8PfjIA +Z/vchQKBgAv1/ufFNbrJqWWHsop8lz73D8jG0SEEFXsyOvsAT3E0MzfKK00J+o/q ++1Sw3QAXWmtn9/6QeRFk2J5ikSKCpz20oWsVWIoCHVZDb6/FkrLJn1HbFGIi2BD9 +eIb2MjCrudZLGJKlrL1aMSHJ1QZZNczDF/RtaUyD3e+15qLrXczQ +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_TIMELORD_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUKXI5XpFZ30y1ouQq11Ke6CJYc80wDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyNVoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC5cLVLbbFTsBDiYGEvK2t3V2I1o/OjEbX/xqAcfYasvNTo +E8q61KL3tjIB5kdKYp2Ywl0ibUSnM8M9Zm2uMz+Wrpc0YB1H6IEpoN796q36m6Xh +/O/lDpatgwZkRiBnKVAuvifGeVb868keNBKAZ2DNHdpQcRtbkG6jMKSNonmOh3Jx +nurvv01mvf7VR7iTc9o4kBIgO2lOnxB2dpFcPxdi/kIIGjrUgU7tzAh4SfQgKKVg +WwRDk4BrlLWLRGkPsIvvoUNkVuC0adqXOaX+8WRfalw1mNed3OpYQ+W0SjHWuw7S +CxrpcfvXMniy3CpEdBJmbtKyC8Somj41QxmRRZblAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQBVYAjTaWQpR8Ke7zD5ahJg +G/UDUUh9ZhUGCc4E0e2+qVjDgkJMqNjXx+OUUvj+iKo0A0UI/QJYf5n7kxs6C0GP +JLqt/OHbxdqRji3GQvftRAMjaIQ0KmRUIgN0XwbDUvFJ7QHBdV33AeWvDh1wWvtD +DYmMDausznQQBlYApt5LDq/Y+96rmMiaPGOga1Lz1GWON5v8RU3qPLyc8GgCeoaV +zoVLKiGDVtrhUzaOBTsZ464ZH74hIzjEb/QDqyoQYgk4o1RSdewNhnzmwWmS6hXD +E11IwGGiy0ix9OWyL5WyXvjHqjtJ219KIYQuLsEV/lOdHsybBcAQygjVqgMkz5CL +-----END CERTIFICATE----- +""" + +SSL_TEST_TIMELORD_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAuXC1S22xU7AQ4mBhLytrd1diNaPzoxG1/8agHH2GrLzU6BPK +utSi97YyAeZHSmKdmMJdIm1EpzPDPWZtrjM/lq6XNGAdR+iBKaDe/eqt+pul4fzv +5Q6WrYMGZEYgZylQLr4nxnlW/OvJHjQSgGdgzR3aUHEbW5BuozCkjaJ5jodycZ7q +779NZr3+1Ue4k3PaOJASIDtpTp8QdnaRXD8XYv5CCBo61IFO7cwIeEn0ICilYFsE +Q5OAa5S1i0RpD7CL76FDZFbgtGnalzml/vFkX2pcNZjXndzqWEPltEox1rsO0gsa +6XH71zJ4stwqRHQSZm7SsgvEqJo+NUMZkUWW5QIDAQABAoIBAQCTMXd2K9e5ieOd +DMuXWWuwCtiVo1Hcek5wfATTGIAx1KFapXsh2W6SGTiQcWzdCnH1szGiBgGchmXO +8uLUhzFONb8nf7M+RLthg6P9AK6gYbPGMbNpqa7Ig1wrc858lDplH+MKk34MvEuj +gcm9ylD3/14uw9jnUTnApve2xOSf0GDUdIAT0AkYfHmn0/NSev40uMi7q0KmH2Tf +3VCHjWTLKvEp5/z6a2vBw2pxQj4KpC9TobfZZCTBbnzt/VnW4zG3mZHcAYV+EZqU +/UZzmOHQC/0F4FkOzS8THlWb5rXUAv80NpOTzf/LNQXy6QhBpQN9a3atPvzvN4Eb +dt0vD+PxAoGBAOh12gPNpXolJJYIHGhhKqYzFIBh9pCJPlmQ3ok+lS4Frhfgzjzu +5m1daB8pUO0du4n+KLmQMb+cXpZTJ86KqRE2MXtuP71wt1RTxx+7KQCuuz/KfY8z +8A7NzGk9swXx8EqdfgYcm4gqrRjOYhvwWZ3R1m9b0x9A35QjBAZbLcVDAoGBAMw3 +8FguXSmIKUtU916S8kCZ8y+w+1Uh4tDYUMprbbvPrsmdiZI1pCRULcH0k7uw+r+n +UviUk0T3CZBTSP5W+0WZ57uSY+aeJzZeuyn1cNguDBiwVL9zmV2JkvFcIfXEWPkL +Ae5OBVfGUtucg6+Xp7UdXrYWg2XkMY79eqhVWNy3AoGBAKCfbjlai5DOwWz5xcdJ +/JJCkVP0XM6aRn7U3y+uEp5uRlExgNARsx62gA+oGMb+2GsNN06hF/7yKVlts/+/ +R/sgmyhSkbBwhfy6tshyJm7WTYRSglfE54cTJL9DZsQg3IxyLnZCpiV8d4bAdIIh +nYqzR5xCsqrRxKszVsCdmA7JAoGAbwaihm5+e8vpF2mUKzict/56thz0J26Kz5wr +IEGToR3iGv6pAnJjUNTrI52Ci/JGANhJRZgRENd1vZ9p+cz0QvzPfayy33hwPSD3 +hHJJ7V3reai0CnogkTfwSYQbenBLJuqTHCoSwYuzFG5dMaOzq8XR7hEDUuvi/ahV +fRsZerUCgYAXEJOAnffMvFJZrfflJ62HbPxQDuKtUqZ2aWFRh6/d6yLC+xCTv+AV +Ygl8U9GHqiafLb0jqzzHU+NzpCFsI9IG/6r5O3k+CoQkw2u1mN6diys8IIip5PRv +DsER2F0w6ZrwEkUpFxxIpQgTCXarTFugMbWkjhjcpgK/lDGWFsWW/w== +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_TIMELORD_PUBLIC_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIURVoAXVmDtr+4fUDOOVA0ZXW+RTEwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyNVoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDZsq3BSwg/a/I3AlY+Uj3d4S+W8jIhWHI8XHX5Ud7k+auJ +gfKvA/D6PrYI/TunHFzTGdVaGOd2y2Ylw7KUFZ9YIjtfQfNI0UnuIEyovcmLBiw2 +tCtQE7ItEgLkrEjgBX8DNWlQxGKZ8+HAeY5Ux3eRsLJJn3fBFAxOtC+cxF5hFFvt +EcGTMo1lYr/A/XKt5Klh8eoOLkE8JNbwuO7AQC5NQN1AP3ZP+3rOC6AU+xdECF33 +9H3gyfXeGk5ixLpV/d+Oz3VzRgmBCBt7+QLT/MSgm+xD3hO21MB2cBBIHJ6bzeTy +4nwvidsnSPPn6RoHg5vTR6HFmLvALirbiA0arr3/AgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQBl4c1dN+9iucNMtM0bLiAq +qeGRLnjGhizrhXuI0PtO5zrgmWgPnuJ/gZUwoPrGczO5g8ZO2zQhDuz8QWXLCNby +UL5C0aQrMafIqawKd3oumnHFOotY5eW4hf1rKyYfCGJ15xisWDIXuVSHzf6YlNlk +avHfchtw3I6xPIt6ui08qnRjuxVeoHbKKgM3DOx3vfvWiOyjXI0pZt2uYdMHdX8s +kOqJVoEF7XvSheDLXjhF7iWeGDmqjuBHv6eRfnA20MOXbE2l26Oa7M9z4xzVZBvU +GxtQwVXfxwmo54EuxVSS23gTD2q85JRRfPWuZnOs+NUr7e8P9MkejuC7iuvA2P7G +-----END CERTIFICATE----- +""" + +SSL_TEST_TIMELORD_PUBLIC_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEA2bKtwUsIP2vyNwJWPlI93eEvlvIyIVhyPFx1+VHe5PmriYHy +rwPw+j62CP07pxxc0xnVWhjndstmJcOylBWfWCI7X0HzSNFJ7iBMqL3JiwYsNrQr +UBOyLRIC5KxI4AV/AzVpUMRimfPhwHmOVMd3kbCySZ93wRQMTrQvnMReYRRb7RHB +kzKNZWK/wP1yreSpYfHqDi5BPCTW8LjuwEAuTUDdQD92T/t6zgugFPsXRAhd9/R9 +4Mn13hpOYsS6Vf3fjs91c0YJgQgbe/kC0/zEoJvsQ94TttTAdnAQSByem83k8uJ8 +L4nbJ0jz5+kaB4Ob00ehxZi7wC4q24gNGq69/wIDAQABAoIBABDpO2wvivV6SjeR +u+dddibdTlgYemJyv3UG7bcvb/QznOqyqIqF8NtPsc5i9ZZWsrNHZ3Z3RsvIoye9 +2wp734P2LMyKj/6RG4AfDDVzgMuG8DpTpqWy0f2ET6s54vNcGfDC3mqCxvIUqu3L +w428bQJpSoBDngbmqsoWXzh7XKWHzaeRNzhmEd58yNZH8Fb0OhPWESNA0U6t+oJx +eZ7mtSzIY21mF0Qo2JIRMC2BMwpK2MMHsvTKs4VcARBAA2X7K9ZAxAoASTZU3xCc +nOglUUOZzPa0mGses2E+b1pbI2M2YLhwov6kRm7MihtjXRgMHCVcOJwuNK6QR0HC +K29CP6ECgYEA8mZ1mvY5Xgt85fgQepVib23vfbdXHqRRKkkGoqky+o6Pa55bgSxS +wzI6dj3LJD/Qk/5I7gS0Ft8FCYeFQTDBf2a/wZ9+RH4k3NOR9WYVxEQtAnT9DeSq +DfZQqopSQ+29eosBS8uqfI+8C1C+k3aS4qJqpSpyaj58ZrOPCcZyA48CgYEA5elt +GE0oIzRaPmbH7aRSgSc+D/MtmMmlDQekA1v5vPKPCdrwCvNHh73sGpHGeYDuEZZI +wMMccVJ6rBQQ4Hsk2fmrHj3dbn2HNB++n14zxAX9iv7sVKGvrOvxTnhSidRXuQ92 +Ap3wHFAY2x4oPRRTBT+HJuz46wmqooOFGMd0ppECgYEA21meaNkRdqn8nvoIp3UQ ++3bHNsM24fKdxB8LExz7lcJ1xFQrx8t9JUgJoUAv2KCqtZFxG3pEIUI1g7cP/bsK +DqjDM4qJr59a6j3GIgP8BHwRIt0MtYrL3BCeVIURBolXYlHxnU4y+77x0meB3V16 +c/23dbjgioX6+tDXyme6er8CgYB1puMV+X3drg+0OSJ8QIeb4foHbXja4+1bYpqS +wYFmKHX8JBaMc/wZwZ3N5uU7DjhFtbMbOX0XnI57+nS8eyfbh8ECY8Qpo4EJsmj4 +4tr4p9wcQeGsWWUtxzuf3UDXmVser4PDSREzW+WsU51hzEHDwMOnrsKefD7elREK +Ih9WkQKBgDfRy6VKMVBnyvPW+mby5sS3aAS1Mq6CJXjWTWkLoolkhATd3YrrC2b+ +/IuSbjsgagN3u+Ih1uIKb3FDHjKv7o2o+bRot5415P4z+FQeKFrjU/pPF/0B80ug +PdlK3MF+/2UgKAwawIimV8HSgtSSx6VgDk8q0HUPVJHxdziyo4dR +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_CRAWLER_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUGfJCme460FNV8uIRcAb2+fNOKnowDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyNVoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC5pSuCco5DLrrC806I0t4XFEp/2HgHVve+xI3mIyl4A+mL +XXasrNMeVEo3MU1ADZBntZJcDl16PvHx01/sY5vo+0BwjzXIZyl96B5yH0ibxWeo +tZbkaU2FOg1/aR1sDL9guxQZ3JfrOA7AhFX+W5o36X9ySUsVcj9IFSuBd4WreAz+ +lo/DCcsdNq6PvfpwR3Lz9VURBsYmRseO7cHdcASzr/UbfaIYFaJxYQzUkC127qXt +6KEqaUKPwt6/pNSCx6PChTS9isqz7oTg8CH9Ku8M9lQz+w9J9T1/AmuFnKUhLAg6 +MVvl7bGDG657ndawiUYLsFnAtCQBxjnhdhngv0LPAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQCr3TlMTjaxIWlpeaHo0rcR +CmZNB01iJQKHhu6HEKJunILBf1eH8Gm/CLftytMtbxPfEUB/OG04CvDfCYAk+yVK +lVhlLXKU1MHNbjCEYYhL9Nai862dxvAMLI4PMbrhIl9qPYfQ2tZ/yRKKZIy0Jnsx +EQECv1dFXTDPFZOd8/ViNFmHNLR9cHAnEuTFKnM2NoTOYlRF+f01yTF3AAAgdNw5 +ViGPO3v4Xv5XeLVmpxOqG4ZXdCE4ZfSkqmR3MuDpe5GsYYOeEClLSZJxX4kNwd7e +EK8qZ/rAt2Yk+/O/FKGa5C59qj3dKiVVTN5UPfFD+cPYFFjCNjy+GP+Mw8sKit+r +-----END CERTIFICATE----- +""" + +SSL_TEST_CRAWLER_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAuaUrgnKOQy66wvNOiNLeFxRKf9h4B1b3vsSN5iMpeAPpi112 +rKzTHlRKNzFNQA2QZ7WSXA5dej7x8dNf7GOb6PtAcI81yGcpfegech9Im8VnqLWW +5GlNhToNf2kdbAy/YLsUGdyX6zgOwIRV/luaN+l/cklLFXI/SBUrgXeFq3gM/paP +wwnLHTauj736cEdy8/VVEQbGJkbHju3B3XAEs6/1G32iGBWicWEM1JAtdu6l7eih +KmlCj8Lev6TUgsejwoU0vYrKs+6E4PAh/SrvDPZUM/sPSfU9fwJrhZylISwIOjFb +5e2xgxuue53WsIlGC7BZwLQkAcY54XYZ4L9CzwIDAQABAoIBAQCbQCT1z4Vna7Hm +DQF1bRssI9z1s3sVcEZ5c/jTKD6qzmLGGOCBIXrg107Ff2aCFZXZFUCT2bOU4wUE +3mdO0jJ1kYDfYPRyZsuNLswfVkgrdNfugAXzeJjKvLTDA44GaVa2t1zlD9TAcj3s +A//CWqrK7WuWkPLIuaVwS7v5ZpITxT/fV3rEm/aNI0bKIQvg/QpXqX19q91WfFct +1zhzim0JRU6FmBqhpYG69Z2da9ZoNvj6ZENC0nNhaI243ubkvzGSz/vICREnGvlu +mTq70i77G6UK7Li2+7jTKtxSWhcwpUFjdnzxwNd7aDlvoTS1F0gbXQ4QlaRm9cv2 +0viZO7QZAoGBAPRepRdW6DRnYVbtd6788i/qKiTK+odtbQj9C8N5jBbLD/NWvTXL +syxSbxJUpIDRUgZOqLepNoetZZwDJOWnavMaLKsnxYGMUstH+cMrAeYbhyxlf+ol +oK00XzqQjW0kUL20usHQLr5GcWuAonsYIfLSucEZDI/bF+413hIlqDQzAoGBAMJ7 +CVo12fy36HcpKtWR55r9G7SYh71moSvt/LNlDwQaCrvt3ySKOid1y4Ufob5eQvDO +UBk6LFpuGH1pIBKQKz8okw++W2w7jqmcY0RdUTS2jKk9fwwIR4EtSpv8cTjE3S/1 +g9P9SjVVkAL/o/VVSEWTYLj/ho9Xhh3WDsI9h3r1AoGAMwcUaDRAlrjDrbg2lrbB +B9pY5IfyGpdx/j+A1leqNhQ/B2wkZHhduLKZ+PTtyOxsuV5xgrB174z4u8Q4TzBP +d+YOT8slRfD8VPB5qhRv+BHlfxLOzCEBVUmrXPpUXecIaSS1HsWPDTJ+eplI1HVs +mV0BZt4JLnzsmVRsQ9PTNNsCgYA8QgcJznm2Vf1PPpApEEYkvZvh/wi/5Ja3l8ue +ggd/C9qbk/55weJ264advslMxMQU/LfQuTeY5VftM69eURE1Rosaa67EAEgZwXz4 +Z7mLjaxTm9xLjB0rpy7g2fzyy/yEqZupCWf+0n4Gj9LrZvs3o4xqhbHZpBLIF9UG +1i2uKQKBgHEEncIbSz/BYXH3u2jh6CacXaoe5eh4S6ihEup1EZ/ajavYLtD/cfT4 +9QuJjBSD9me7I4Rdas5OtvRVcUbo8BLISU3Y9bMkTW8vf1wof7oIAlB6Q9jZFaXA +p05qDfXHJ4/DcMWQTkfC0PNVslc5lPHJ7jylPNhMq6oR9Wn3OH8/ +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_DAEMON_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUEfp1B/UPB0Hf5bcKFsJZ/Jg5ZUMwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyNVoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDAIc6vaGVenMWjN8uyIetlwtTXCVRK0aTwLj6HHXpcJCSF +bIhvsZRlZ7Fvu4VelVNzXH/kmZhpUXY59QQObspZ2z7TfVLgS0r4mAU8WqmCGi+F +7cLVX7Du2E06jGhsBgKd9l6Ybud0SlW2/y8IzdIq75bW9qD7viAkbXg6sSR1zqwg +2lFpoSKaf9TFvdbgtiCIeCbTQEwTZktYEEd3S+yY/HierG9RTcpXSJvC1Orcv/J8 +iH89U+C8QfNjULCChEOWhaw+qol2fKOK3394JsujORUn/9eHeJt1otc3JWnyR0DG +ok4y62xxl/y529npRJEkwXO7zoZXQVm+PoWZvYHDAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQCEugh4aiI6L9PbBZDEnc7o +tUU2boCKwOsI6igtPaBhZZcQhyTi/qlmPMKZm58TFS8s//oiKhD3q31+OhQIe/Ak +pvuwJwcJLe0r4iUzbtGJsn3aIpXP+GHqEDM+38tZhXMpxq5Kv8Zp8Nm7R7XidGHg +OOBXQ64UDTUAHYvs+n4ltYLgTsqCPPWsHxieABjC3YDBJAdGa/H4cRB/qU7vKNkN +uAyfhVLBzaAcyYtQBef9cuulTUaE+KA8mN1kJNbA/b3E2MCGYCqf4eNN6gRdmtxG +16aP/7qxvVlgWh1mYfUvIlszazjI8TI2N1y1JZOWpmO4RoyWhvqhWdPXKC/HyVub +-----END CERTIFICATE----- +""" + +SSL_TEST_DAEMON_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAwCHOr2hlXpzFozfLsiHrZcLU1wlUStGk8C4+hx16XCQkhWyI +b7GUZWexb7uFXpVTc1x/5JmYaVF2OfUEDm7KWds+031S4EtK+JgFPFqpghovhe3C +1V+w7thNOoxobAYCnfZemG7ndEpVtv8vCM3SKu+W1vag+74gJG14OrEkdc6sINpR +aaEimn/Uxb3W4LYgiHgm00BME2ZLWBBHd0vsmPx4nqxvUU3KV0ibwtTq3L/yfIh/ +PVPgvEHzY1CwgoRDloWsPqqJdnyjit9/eCbLozkVJ//Xh3ibdaLXNyVp8kdAxqJO +MutscZf8udvZ6USRJMFzu86GV0FZvj6Fmb2BwwIDAQABAoIBAQC9oCBHyvdRe9Us +FCN8ejHES5iZa2HAPk1Vp66a2CMt0ZYiAU5fPprBwqfDKQampSap0v9+9YERYQ8Y +gJQyUnJwYQ0O2r/zExy5YgC44pouB/4jZthGk50i/mSqhm2BQCVRFhmixMK3aa5T +YGRhghINwk3Td7LHA4zhpxFki/T6Nvp5R49zhWST2a00JIfKEUF7X/3ILVA1ShwT +Gl3lWZzSL3qWkluNMtHJVuA+9HRDsjbWID63lF4K5HHl0c+0yW2OTOgMH7zuxmLT +IhEdc5Vr5wCvgFOr1MwsXpO/OIT0KrorobSSn+x/HWMbvUoTVhfjiE7qxRsfqh5w +ZPru0OBBAoGBAPU+4ZSAJKKtBEjs5ej7LJbmGedQCBYka/u+FUWw4fp052bkT72M +4Y6cfQlxXs59i0E/JPPqytuXx9bRCNG7929yvCzcrZBNij5NLR/EYrRqtnDf7O49 +kCu8owgv6/zglt47kjyDuNv0JhX4D9iIcz/4TuFUG5zLn1SwWqUCOv9RAoGBAMiO +rNT2o4gJSg2wKn9oWuR6ysBQuq7Lj9kVZkilHVp2SwTtnLc3CjfFbmPivAhodRN8 +y/zlln539Bi3JyolYg0YDeU0oeI79HyeKUgflxY3rXB2tXhnK5W4l7Od/BZFc2Cw +hSYMzlcGte13DD/gr7XWohqEr5aQCXgM/3tZ+3LTAoGBAMmb6+4cegGRolghB9BD +zCAxAVJ7JGqvfmXxmaM1ClDPEfwv7K2yxypp0xCUNpAh/PyiYEp01lc3q30ZUtq4 +X20rMS7gK37Zf7A/2bynwUz3/QtFyoz/5ylNZekxHBtCtkPzTQCaeLm5OCYPS1eC +tNv90TrD3f9EFbOVVq8X6lBBAoGAGvwngRgWdM1bK3BSp4XxBOEIusuh8rbtCfZ5 +Jrkgs/VKrsUR2w0K0Oo9qi7twevcJN0bzVFO6IFXVKQAHwmcocpkxDxKs9gBU2ss +fsnRWGnxajpuvF6VXLXTo5VUP+LkXVQi9jWu5cK/Y84q1cVznvHcKdlEjuueeoq1 +LXG0BYUCgYBK4SYd4U/DGiSE45D/ikQa766J59cd4hOHAKTdoTh7ZWmn9Oh5ms8R +ggcxJQt8ZgGnOJFqjF2xN3tp8oluk8gTx932Myh90iYUPbxXGjB5mYJ0g0fDXK1X +i9wjKsZocYKO4ZzhtdXzbBqQcYMhoBicoEWY8NpzyA+0gVIx+bxKuA== +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_INTRODUCER_PUBLIC_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUQGJa9B0MRFmHuvjXjyCBbXypCBEwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyNVoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDGNB8T3gN1kLSJ4QhzMcoS7UPLvoWxvxVqYUSEap+4EI// +LDKVlFKOl5icf808nVxGwb2XD7Io5wkX1kppBiqudri+WwHn9ayyhdpSi6eUsi3G +suPObKUTzNH9LOli6DA++GBaYoQUVXoOKWz3DVk8QMSCXgej5+09owdwIMHl8ytV +G36/LpPjH8Chr4y2MAUtz2Dc/Evyq8XfBIeD835Azhr2RXs3c/AOXVWXPt9A2BW8 +sA7WvztNhYnqtL4EXpgG6H018aZTnCMEHEbil05fkfs+zRxgncqQ5BDSqARbkSDu +SeczaJtmW7E4yqRZTFZF2AnssyDuPQcl+qiYNNU1AgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQCFCSfOPoAbrIMBPLkiHGOv +a3OJmi/Kw9qfOp6iCVb4A0CE9ShzBZJqvSfZ/CnPeLsXy9zaRytrVHgkOXQyzbbv +uKiaBgwnLT1VFQlPorGBVJZisLl6uc+PIPK+9syqnOvaeilbI/UH1WrcESwrV2C1 +7CcV8ibj7a9WnWC0LvzNMDHFKqPyOUTmBZWHvS21fYHUXV/5abX19TmwOzJTOWuc +cms/M6RfeldLIgGhxGnqn1un2KLXJ9wGHqcTVkbp3Fvk3Sk/T2zxgmJCLLLzI7Ap +cvVw1It2vL4bmGfF/1CTjfawhEbmtvTl1NkY/e0c2AORZ1eCvz/ZQYuwZxCseP0u +-----END CERTIFICATE----- +""" + +SSL_TEST_INTRODUCER_PUBLIC_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAxjQfE94DdZC0ieEIczHKEu1Dy76Fsb8VamFEhGqfuBCP/ywy +lZRSjpeYnH/NPJ1cRsG9lw+yKOcJF9ZKaQYqrna4vlsB5/WssoXaUounlLItxrLj +zmylE8zR/SzpYugwPvhgWmKEFFV6Dils9w1ZPEDEgl4Ho+ftPaMHcCDB5fMrVRt+ +vy6T4x/Aoa+MtjAFLc9g3PxL8qvF3wSHg/N+QM4a9kV7N3PwDl1Vlz7fQNgVvLAO +1r87TYWJ6rS+BF6YBuh9NfGmU5wjBBxG4pdOX5H7Ps0cYJ3KkOQQ0qgEW5Eg7knn +M2ibZluxOMqkWUxWRdgJ7LMg7j0HJfqomDTVNQIDAQABAoIBAFKU4OX8OODBHBfe +pRCqDBH6vaakiTvX6+pZAJ1Td5zPec/N8H2WQRecXj/GmBLLVek9S+sm5QpZyNYf +uP0tTpdGbA8UCCVHnV78mkyOV5KC8sO5QWV+qwEm889S6SMGryNthWfjaDi4rJQ9 ++mKtMyMBsV7IItLODXEC/lRfsapG/PVnO8J1dCx+47BJNw4lA1XZQrwwg1TrrKTo ++t9N9R9GmUe+zqXKs0d4al/02JDDrPdReuKMGOAMnWvc14Ppyb8eYfC8lk6nluHt +gUccQlkXH963kPxHhmysC1Y470DcqUooiJADOh5GfD+W860GDeWqib5I5IOJ4HmK +xgTq64ECgYEA8egiv9nFuJNV+yN2FgkrKo2kqdsyMnlOsC1ppdfsUk/Clx6LB2WA +K+82boWmnzIkqhI96wlZ1Y8LXFS5fqMQeeO65VNwQyhk0KQnlJ/dTYT3FzSuZ61d +8CcD3p/nMrcXT3H9HOfYJooF1eATtcbCP+Sc3SS9JczYDcut59aA88UCgYEA0cAv +NHIVOUVL9EOyIQLSBsGTF9u23bPzCUaGUHc82acruRwJEcSzpfNaj8NbOzk0tR7r +ZawkbrlhxRqVC28rE4jvhPSAO9swq3Gr4IMjhGnJ2gc81zPV1NyRY0jR586z4xWk +kra01MYhEcJ5gya6D6t1y11glq4ht0zhrFcdwrECgYAn8/cJSKZnPa5NtCWkrg77 +EDnJ8/HudCqS3m08ftUBIzs4SkscBZ+NogyTZG+Ii3eSv0CKuRilNOLjdPrN95CZ +EQulJIq+DMXZz8LZwS2DyBonMwQ7C18gctEoy7AbqDGpZWIwi/ofI1yjXkbjFtiu +RMvDmnXC8HoejS1DxSG3IQKBgQDM+b/nw7kD77lrKqCv696tpYwGm7uX6xwNq3Lk +vbGkjd6HlmMyjwR0n12X8nR8asocWev2vwQXhGiMQw72TpxNCdvwFTQfynNEh+BM +ljsmUm9k9v+42roTu70ExowCuZhHycW7bntHF5wHjAJNbZIUcB28MDOM7Pyb8bD0 +R2oY8QKBgAJUUkmpgpNz4oNNv+mztAElg5LKEX6fNRqrKHF6H/rHmuI5zTrTsjPc +UwBCIG6KBlcmpAsTUpxJ03VrazZMcuyaw+sXXpT8PAcacSTHf5CYY/mEEA4lTcZt +iPfa9TABxtW6v3r2l5tO9Yz+Yb0v3nfGtaxDgp3U4+0/QzUwX2Jd +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_PRIVATE_CA_CERT_AND_KEY_4: Tuple[bytes, bytes] = (SSL_TEST_PRIVATE_CA_CRT, SSL_TEST_PRIVATE_CA_KEY) + +SSL_TEST_NODE_CERTS_AND_KEYS_4: Dict[str, Dict[str, Dict[str, bytes]]] = { + "full_node": { + "private": {"crt": SSL_TEST_FULLNODE_PRIVATE_CRT, "key": SSL_TEST_FULLNODE_PRIVATE_KEY}, + "public": {"crt": SSL_TEST_FULLNODE_PUBLIC_CRT, "key": SSL_TEST_FULLNODE_PUBLIC_KEY}, + }, + "wallet": { + "private": {"crt": SSL_TEST_WALLET_PRIVATE_CRT, "key": SSL_TEST_WALLET_PRIVATE_KEY}, + "public": {"crt": SSL_TEST_WALLET_PUBLIC_CRT, "key": SSL_TEST_WALLET_PUBLIC_KEY}, + }, + "farmer": { + "private": {"crt": SSL_TEST_FARMER_PRIVATE_CRT, "key": SSL_TEST_FARMER_PRIVATE_KEY}, + "public": {"crt": SSL_TEST_FARMER_PUBLIC_CRT, "key": SSL_TEST_FARMER_PUBLIC_KEY}, + }, + "harvester": { + "private": {"crt": SSL_TEST_HARVESTER_PRIVATE_CRT, "key": SSL_TEST_HARVESTER_PRIVATE_KEY}, + }, + "timelord": { + "private": {"crt": SSL_TEST_TIMELORD_PRIVATE_CRT, "key": SSL_TEST_TIMELORD_PRIVATE_KEY}, + "public": {"crt": SSL_TEST_TIMELORD_PUBLIC_CRT, "key": SSL_TEST_TIMELORD_PUBLIC_KEY}, + }, + "crawler": { + "private": {"crt": SSL_TEST_CRAWLER_PRIVATE_CRT, "key": SSL_TEST_CRAWLER_PRIVATE_KEY}, + }, + "daemon": { + "private": {"crt": SSL_TEST_DAEMON_PRIVATE_CRT, "key": SSL_TEST_DAEMON_PRIVATE_KEY}, + }, + "introducer": { + "public": {"crt": SSL_TEST_INTRODUCER_PUBLIC_CRT, "key": SSL_TEST_INTRODUCER_PUBLIC_KEY}, + }, +} diff --git a/tests/util/ssl_certs_5.py b/tests/util/ssl_certs_5.py new file mode 100644 index 0000000000..a0ddac66ce --- /dev/null +++ b/tests/util/ssl_certs_5.py @@ -0,0 +1,684 @@ +from typing import Dict, Tuple + +SSL_TEST_PRIVATE_CA_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDKTCCAhGgAwIBAgIUXU/nGxb+rZck2qIMztmDWKDZCBcwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMB4XDTIyMDMyMzE3MjkyNloXDTMyMDMy +MDE3MjkyNlowRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8G +A1UECwwYT3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAm8r7ngBPSkz0U2XxFwI0gT3xt/yqKTI0AZiSicyyMNo0 +oSHZHRVzIfzu/c+cI2SPFHA0n9ZaswiztWje38uzRjEqD30EmF1By54A6c5pDJgV +MVd6LXafbv7tWxSLdyLPJkoa8gcqAtR1tOFXRHRtKNa6g2thyU87/V/UXJ9+C4eQ +mmpq3goVzkA7ZRx0FbdXwijAGLcL5ZWStUPTaWjR+V3ApxUZYy8JV3tWybEm5FDK +JJOvdd0bJQgT5WTCYRKNYsXyjcRP2ypi/Ry2M1oQLBbqCIldrvvIyoUodbkV3Yc7 +AFhg4gUKc/O6zcIO/3PXKgFOAMLangjIBwWc9yyNXwIDAQABoxMwETAPBgNVHRMB +Af8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCILSP1KclF/iLlNb7w2bE1hZ5/ +IJcWsZJSec7vlZkF3AGxrUc2XzdT53gooZqpg5YIdMYqDZqCfPphvUbqGELbImfH +D7sWhD8jU0FsKc5ho6+Uwmj2I5H+xnSVSF8qEbSBk8nasAac+bXQ6cakqkG/cbO0 +9HBBHTd6V25KCeyvYN0kyuYMyT7GBfzOBmhyx5zf2L3oqoqVKAokbmC/9cvBXMUX ++1BWyowMjBVH5C5frOymcTF7b3ZlMuibFdl01lVa76QjVno/QMZ2bqnLaqDJA306 +f7vTyuGSYJSoXnEh0UJ4IR2ct0F+6JvuTCL4p/b97C4Au+Lq9jt+2sGV9CAs +-----END CERTIFICATE----- +""" + +SSL_TEST_PRIVATE_CA_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEAm8r7ngBPSkz0U2XxFwI0gT3xt/yqKTI0AZiSicyyMNo0oSHZ +HRVzIfzu/c+cI2SPFHA0n9ZaswiztWje38uzRjEqD30EmF1By54A6c5pDJgVMVd6 +LXafbv7tWxSLdyLPJkoa8gcqAtR1tOFXRHRtKNa6g2thyU87/V/UXJ9+C4eQmmpq +3goVzkA7ZRx0FbdXwijAGLcL5ZWStUPTaWjR+V3ApxUZYy8JV3tWybEm5FDKJJOv +dd0bJQgT5WTCYRKNYsXyjcRP2ypi/Ry2M1oQLBbqCIldrvvIyoUodbkV3Yc7AFhg +4gUKc/O6zcIO/3PXKgFOAMLangjIBwWc9yyNXwIDAQABAoIBAHLTHbbrhYU+yMl7 +FkGeF3K2ZCT2LbhlTx1qBX9ZBnCpMycb2njsKUqAsOkTDoKriCVJOhAgngLcxA9N +9w69hSmT7OszeqKOAYOAti2dO6HTqbMPRXaiuonFjM2Xi99IIaOX9Noz24vwabzi +ZT6IDTiPYzKff5gvNQjfi5ak2vLFVowAQH1Mf3dh86jvhD9PpLvYiUL2tb3w514c +LhUQtrk9YMhOMmCMKH8HxvU/8IsGhLNOwuOiQ2O6tXLfld+udt93n0JyshzRNcyl +I231KlThxK3BiXku2plE/qw7K3sW01amaVa7trfWxrOv7XQF8u4OOcLO7Wx1O1LY +gfbrAhkCgYEAzmZsCeTMTGJxNbkj/Zy5rU/+wyn5sFl6xfzXj64X0Ri6C8AKNBI7 +o1T4zSp8aUGHAg1SAW5OGWC5vVgACrIfIWoFpg5Rx9l1EkyZVczX0tbjLabQeA7j +4rHGrKLK38HFtf7lyHXoGVj55nvlxri9t9X02clBqz2WzJREiaYbFzUCgYEAwTs+ +th+yhJIwLIqqSeK6tPgK9Ofp4M3Qf8LD7yOZD8qmVdRlz8H2aJhbchyLGnaj0JJS +lH93sU81wZ4Lo3Uowb1uq+qdz/nuf2My6zFwG28+ww6KHnkss7XGvGQjLLBtLiol +j83Pi5lkKcsypf0psnKV8cKYpXooIod2MyU+YMMCgYBxWh6LcHQinw29i2gQqDnw +zLYFSNAv4XRjt3BLIDlERGgoe9cescS+9rONOYAJ7krO/bHDx2hs14oqSmH7fcdK ++ocPo12We/6nhhnP3SfKSumI8Mwco1DT9v49YUo5iJmkUdCwPtCw2wSjZ/fRIzRN ++dr2oGjIOpLO176sOeU24QKBgE2k3rgT2InIrC7ZsT9rKZbaLJzoK2Q3j1YnDtAi +v7hGt7u5Uwe+aqLwxZ3+ti52CbEfeqtM5O2MZI9eUFLoGu5uje/qoGsXhKwPUkCL +Zv6/HrsGNp20FzBHFIpSuoeUhOqN6PX1vzXa9xKMIdfs+DpKLNIuXWPwx/vH7sjy +aDQ9AoGAUad/5kDcK/FwSklNenqITWn9c/OFecb6Z6u+F7TPirleXPbhNQ0oXUW8 +pVVnLpzWWWpu9amxlS/4a4t7/lTEyYaT6rsjJr5ZBvDrIBwFc3zvXWYxbY9hnCRP +LQfRJRhurOJYEByEDjyiXRA9WPHcIhpKVGN8DGyjx/gvJjfTQR8= +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_FULLNODE_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUPIoys/kxRUAxhIW+huwsgqplVZ0wDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyNloYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQCpDfVovOj9fLjpheYdKVwV5V3hN/bUxqlYAW3s+zFU9Bpg ++SnI+5XuTW6SLpiPjx/5kZJsztqxI/Nr7BuTpHUOfbaCHkoJGBAcAkPdnOma8lH7 +bpZ8CpVjONeHqmTvsDP2dgCg8QW6nqVksEHMtkOFadTifIODxdWJtsB4KjzKlV1U +aiF0hUIJmbvX08bArrzrsX5EgM3pQV6vgo1wYWM/X9zRjAd0xJDbhVqOsQpK4AJS +zAAfqCwxNf04EHhRFD35Uam4NiBOzR3T8rB4XGcpMBYLPC6reLHtOmxneJ081NWh +ZgVDhxPg8/30Bs3OhNhT9ZlfBJZvPW8ReT/JzHXtAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQA4hi9UEfJtPMsTjpI08Pdp +AMNa1ybci7kDVaMfcvKvMDcOtoCEt5K1t3fGWrYojfgnJnSRJLTSZIa7IdBbyZG7 +e5ClNLzw6bCqiQ55mgyAFMFM0VUaYu39zRK5X6fA2qWXFYVbOGAbEgU8sFuOmBid +MjkEQKL561tiibAkVJucp0hLf1xzoH4dJZqFWyFiThH8RTUq4Gd4atH0pzk01Ts3 +VbQyinIqEU/gwLAawnOGtdMYdFPNtll0F+lP1+h5AZYtsTcfilm18D9Th4/rfQay +Ob1SSSdL7MXqy0pR9sF/BiXTeXauOK6Y5DooJ32y68yrNKL+TfbEzcPSfqiaK3Tm +-----END CERTIFICATE----- +""" + +SSL_TEST_FULLNODE_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEAqQ31aLzo/Xy46YXmHSlcFeVd4Tf21MapWAFt7PsxVPQaYPkp +yPuV7k1uki6Yj48f+ZGSbM7asSPza+wbk6R1Dn22gh5KCRgQHAJD3ZzpmvJR+26W +fAqVYzjXh6pk77Az9nYAoPEFup6lZLBBzLZDhWnU4nyDg8XVibbAeCo8ypVdVGoh +dIVCCZm719PGwK6867F+RIDN6UFer4KNcGFjP1/c0YwHdMSQ24VajrEKSuACUswA +H6gsMTX9OBB4URQ9+VGpuDYgTs0d0/KweFxnKTAWCzwuq3ix7TpsZ3idPNTVoWYF +Q4cT4PP99AbNzoTYU/WZXwSWbz1vEXk/ycx17QIDAQABAoIBACP1aCHjLNveT6a8 +aHoDdibiJtnlAYe4ygSCKVOjCpc7ZPEDjrPFb9rEdaR6bND8bJy1LiQey72qG/j0 +u9jnvk5axxtePfk5ORP8F1toKPhgWrfUigXQan40dQPSZq3lGOhvqSqSmdlcLWoB +Y72bdzlFjZavTXoV9pnYWZA1y8B7NFnaGfaBHfc1iNJ89cwLV2QhADaYb7tKIooZ +nlPyI4n/uF08+UmKzKEpwtDsxJxssa/J71YrQS274r13yEyYKGhsoVEhWrfD+d4t +BlBWHwFfXQLPVgRQ3du3pvMqAMAMNZEb0k20WeHcaAybRGaEIe6ltqOGH2m6j5uT +k7fYr7ECgYEA1fExK3+VrKKCVSkpRpky0bbLgwS+YJU89kPBurdpVBMxYh9XuGNx +xPYL6trKE5rfSXFP+sz8Vqi7WOEXCFzFx6ZHiBokaVdSWG1Avk16lB30Uu5y/r2W +BmfezbribDM9oQLYLlUd7tAxGU+/SIciREHpfelq+ejLmeWKHdWdVpMCgYEAyknC +2B8w4PwSoDMBB0xD9FM6q/7iaXChpa4n8yl/YLVEZlSrCyWFz0awPHQTOvszE0xf +UJ16HYDktMT3tyC9cDd5UHN89zi75edEMPLmPnLD6K7QOVaVR3X6PUqA0SM1spM3 +UTXWFxFhYTUTtudK6rMSseDCxGpY+r4hPmR+UX8CgYEAlNevyL6DyE5rdIolgEt3 +MrYFEosLVDCf8Akl0BxoeCi+M7Dwm4T8EvbHRcafzlHyRKtD5I4WhMfxR52aI6Q/ +qW4C2Cqv6GXrEUA5SeynekL4x3XDpX0K0jwTo3gArRxdJRbQhjOLlqlbb2uu/eue +KHTe2E27slCGzfQHSkhipWcCgYEAiUS0a2P/Dyz+lqcFs6YVFt7DmaNEkLhVeNBN +W7x1K3LWD3q09sNnodgeD2fVBNkhN59Drrit/QdSKzjdv+7/nf6G3AkCa+Cb4M6m +f3DUvNu0BVlbAw22DuAIBz9fWovCDIPJrdoShWTN5+DUl/Er7UfHD92tTQu9hakv +dd9LuJECgYEA1L3P0JKDoqkgSBEwsHbyScv2qo23xKZsTqdY09Cz0iG8wMkajRdb +QkWj15kmqYjhl/gpgmWfnB4xRmzIhKiI+k2AvVmiS9ttYgdqPwYJdauq4ON/H5hA +dXPyLob4mYRF76KcYeJeVyjRPXwtbojJQ/FFGZSKsuO2toathK+vBM4= +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_FULLNODE_PUBLIC_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUJ/ehUeJz6rFUOj2Sq6rL4SW0Wf0wDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyNloYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQCyjDKG7d7fU8ZdpnD0Ba5S3/F6FXpTvUBqxSRWOO9yI4tQ +hSqOJIP9x8u0aFhgmgMN8Rig3JZ6KfvCeQ1qO1xkcuZ1o3FoOOYkhZoj5OKjFQDk +6g+cOSrvUe4QtIaPxlfNhtV0peVQuKQGSOakEyC7Z5amZL7Ypwjbt6Wr/N5gZ2Be +2+UnoCOxYTVvUmOWl11Bre9eQZXYIM1D2oYht62HvGEMhoZD0NSoRsEiHPiJ5Hhi +ci+U/oO2XP9NrKK3LKr9A8NzWB6oHXqw7qidCQqGumY0zhE4MarACVzqJG6kCB4/ +cL1I3eSjDT6iEUWwn1OLFc/sdTaB50LNfEI0DeL/AgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQCfYRU1NbezmtNTU1hvOHLn +Dcw1qrUujyl6XSE4kNPooKreJLQwtlV5EV1h9APIk11jrieiEkxo9IYVRzadyrrf +3Dh4x2KFn+R/m+ybHWTICcBL2FvvHuvVx/ilFraM3e+Kv/s+pQRs3YvQuCYduBTq +SXz12aZO5ttTmG7LK2WcX5OgwC1kmSw9Km2DFb8zu/cNv/VQkRujsG0doVVrqxHa +4/CkSlTBNCBJO2Brhtbpx4F6kKfK6u26i9pW6HHgvctpC5PORTeGofPVM26Hpsap +6mHfYpFu1jIr1MhQcWZss369DEwsSy2nr5/3R4zIDWMlBXEKd8p3ey/wjUk6dD+p +-----END CERTIFICATE----- +""" + +SSL_TEST_FULLNODE_PUBLIC_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAsowyhu3e31PGXaZw9AWuUt/xehV6U71AasUkVjjvciOLUIUq +jiSD/cfLtGhYYJoDDfEYoNyWein7wnkNajtcZHLmdaNxaDjmJIWaI+TioxUA5OoP +nDkq71HuELSGj8ZXzYbVdKXlULikBkjmpBMgu2eWpmS+2KcI27elq/zeYGdgXtvl +J6AjsWE1b1JjlpddQa3vXkGV2CDNQ9qGIbeth7xhDIaGQ9DUqEbBIhz4ieR4YnIv +lP6Dtlz/Tayityyq/QPDc1geqB16sO6onQkKhrpmNM4RODGqwAlc6iRupAgeP3C9 +SN3kow0+ohFFsJ9TixXP7HU2gedCzXxCNA3i/wIDAQABAoIBAAxh3qsu2fMA+1PJ +VDIIJtPGhheiX65pBIujCmcUYb63qlS2N4JOE/1Imt7zEZX5eFbCLqQRSDpGqRgO +jxib70dkFIl6AUZqE8PapBrzJ6iJr1swxE5gRJL+SpVL/7z+014EiM8jJikX9QAe +lCgyz2VPxMnbWMTrqJicPtgTnFRxGR9KQncVKOyrfWNm6e8r10iMfhvx1HIUJGEI +V0AGsTpfjRc1ATDXvuKJ9iGQuAvhCOrfn75Q7kK1yxKgYoC8DXieIRRirIhoOSdG +nv1FWD7r9D2z7DWq7AVQgPLAuh3ulyE3y+gvDMZcEpYlHtr5h9qbvhSkB3UCfJav +KmU8AukCgYEA6bpcB7FZq9jRhCVcDOK2MiBUfs83IQ8z3/jiYTsrXfqrXDZcvrCG +JzMXbqB/BaE6bA6NQMLgwIiXkTLj4pyrtARlaU5XBUb3KQ2y+xkWvA2n1IVSJopE +dGClmIvDT3usUItcDzSr3uazfQSmjVHkpLW5gTtUK8dwJ34EaXZcnrUCgYEAw4/A +CKT9hqtO+JpvQDlT4NCXTfM/YVuQeIUc9xZQwp7guMEXkGKEbTsCVjGzCVleBR+J +ibg5jgcSjVd6OaXECXbsUufnpQGULbrnD89KmJUch5DyQwVklX5IbzCa3OGvuamN +Uo0ELPi9gxTJkpH2vFgAoHSEOdB942z/IuY5V2MCgYEAhXh/r4DulTz2wIDZJR6e +LtfZiKTqdX2KAR/Onvm8FSndi4YbxmVl5qK9gdYzU1Kz2xsgPNhMooYeD7PBARq4 +zs8n3k/3T7Mr14zUJaI5ImCl863CsPGKj+7VAdzmRtB4IXLDuoc4ksypuP3b4p3e +dNS1v3/S3EFC4bqL6HHICHUCgYB7w4oA7ooUpG4CH5qwxpcy/FAFYSCHeO9hlrzS +EylhQjNuOaW0FuVAS8wayLFKBWjfTSo6IoEqRYeUM/yCZ0o9wymk/mc3olwo5NQ+ +yS2oixXXJgBsMgmKIrWsyNH5YEtZ8NgjmmM+It2tC4bWX9ILOJaM9bCI9k31lJGT +gKhhiQKBgQCJOyZqyxQXD00jxxAzF8b8EPnculpWG0jvT40jYxoRzrx/+oI1KO2Q +6QFtyBjBibf+wDuXfNDjsahoX8EB3yQX+ofG4fCJ9WG3aNcgR8enPfejKoCzwRNf +o/6JFcAVoVo7l+lwcFJ4r8d1KXbP9Qt7doZSgmGrUSTvBTEWz+j3Ig== +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_WALLET_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUfnFEiDBphxztIz9efqOLOpYjA6YwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyNloYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDkLNTI9jghjYaXRMvt/3oFVDZ8FUraVUU718V8vW5NF4Or +I7HYi7EgS4BnRh9CfU8r+mkPxPTYJ7kgjKOcdNGw1ARCiIIl95gw6ymjcXZ7isLC +F+79kJNQSKq6lQvrPoKoQpfy8dgjRaGY7gH3DeX/Oi/QFd3N0C5ZGpyzE7+VmONg +gzoGk5MyLbBCcKcOsBQUqOR7p2bEYXDDP/xl7+u3R2rhWVsp/E9W0eJJmtiVwYrJ +y6sbzcWBxjCM3Rv4NZs9tTH19EHWDJM4whHgnEiB7eXz03+0tELhnwkrrm+a0qC2 +uVqzG9HZ2/hVY0VmPyPVprAihsAPLyJlnpArCs4ZAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQBUBe8jhAQgvnojPHIVbZTy +HyzRwfN8bx6sRGMzRWR1nFuSgeYz9ngzanf6adVCh7K7O8O1dZwdaPPZB9RKPKUH +0oPYPwhSyvmT6so2Xr/YB5Yx/KbrSK7dMlbxQ+9ct9saKkaioVfo7OvgOY3fFg9k +Qs0RwtRpE1TjaSJw7ScwlaUR7GYUrcIBuCKROcZJPTQaVSM537SOFQXqUn0M7Wfu +QM4545j1aULGnDzbP72fpk/icndS8ArmvAW3JpIe+HFk9IxBuzUh4HKHzO3Dny0l +rKOiVmeztN+a8mipfJRTveuZs/QykCugYkafg+nB9GOTjyBwZzTD6IfW1LO3UZLt +-----END CERTIFICATE----- +""" + +SSL_TEST_WALLET_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEA5CzUyPY4IY2Gl0TL7f96BVQ2fBVK2lVFO9fFfL1uTReDqyOx +2IuxIEuAZ0YfQn1PK/ppD8T02Ce5IIyjnHTRsNQEQoiCJfeYMOspo3F2e4rCwhfu +/ZCTUEiqupUL6z6CqEKX8vHYI0WhmO4B9w3l/zov0BXdzdAuWRqcsxO/lZjjYIM6 +BpOTMi2wQnCnDrAUFKjke6dmxGFwwz/8Ze/rt0dq4VlbKfxPVtHiSZrYlcGKycur +G83FgcYwjN0b+DWbPbUx9fRB1gyTOMIR4JxIge3l89N/tLRC4Z8JK65vmtKgtrla +sxvR2dv4VWNFZj8j1aawIobADy8iZZ6QKwrOGQIDAQABAoIBAAK9cxSyuDvW6j3Y +yqYiAkIcH8dfrhVvHrS4Q5va3n84gBFHDXSvQMJFhdY3plpzDMdXa3mQAOyzlWqJ +pdFUKcx4z1BJOV7hWUeFG2vmCekz4mDYTrtmyA4XwU0aSxlZF9KTciWtt828oVMn +0Ig594AYH8jc6lv1Wwkg467W1t8iABEthulRcdZq/xXVqT8q9uq2BYqsXaSN4oFG +Zg7LnCXFt/XfuIFs++mI7NZQuF5v2EnKWaDCWhpVMWvUiA+17r2mr+Qrbol+TdGX +WHZqRld9Fj1XzPLgxlqfn6AMLlgivTp3NrgLAkvNZ/aipq63KIfWys2p9DbavhBg +jJHYWl0CgYEA/fo2zXk7IAOvjKxenrDiqY4KWduD+Ww9EpStKuoauOcrbO27p1CY +nRDK4SRAUO+AI7OQY0TZHwLuv2/pyHZ8bvvJSHrecS8PUhV3mJhOVupl5JxaHtYv +EEf0+L+irdNTXUAvOCKi7KIB5mCaXGhdSw+raxj++Pt2QaAqOclKH3cCgYEA5f4D +h+0wY5zRkuOSKzpHC6Xd49plCDTW7jtKfx+PR9UIPIoAd0xhon20QsaDnl5MOf2g +ojvNAqdn8uUERr3nN3PgWcBEGd2wYq0ooGUD24yoTASDXgvTMNggYybStFbrymPa +vvF+9yuWfKLwKpSKlxEEfnbnxtBm7rg+W3VLgu8CgYB39fZqqQdXQMZrUINEu1Hk +OlYDSV8VsZ1LKHR+n6LNkUr+oW+QQM5E6ciZ/RBv6iABPPBHIx7WugDg5VBsQiLW +HRFercJhfZPj9oXNyqq9/OrxxzP9+rayHvrDf2isZ/OpSQbEof+Ie6EgGqLuYNEo +Ahe6d0z/d27M4oTvVHcxUwKBgF/Q1lm/iARH5cujQVb+/XAt1uZBKwwjL1Oqodua +I1ASwU6vU4hf6uEOK5YSK+1DbdBPCKft7/fmFFlN7d0m6nfgr5vUjMqV4BEMALvp +uZSy4b5htvTsSjy0HbIRD4EQIUV9GjmoVHPW1efw3ctvfNl4vn2NPfxHAEr9uQTT +NfVDAoGBALk5KL5Q6pAbxqaJw2e33I2Y7sVwKYcRynFdgi4oAcspQdt/22h2cBwO +l23240xCSSbf39fhrDJCZ3v2lWOGQMvdEq1i+9btj0FwhJPmcLGMOIIls0ycWYIw +/mrdq5dl5C17E1WfbzE1SMBsCeLFkaWa4l37KxN1o7Ck3Sl5W2tv +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_WALLET_PUBLIC_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUIYvyPYsDrigeLVIkFXsvpHrP/F4wDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyNloYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQCpwUvZ+07XGeclurl24s5mocAP/pmlUQU50unzsPRWarrt +4DIjFX4CUErlCnwGKff6sXkSNzJOCNQ4NQXIJ5imbEvx7d5V80z/5Phus2JsY4uf +IZ/LidOk4tSlUpLDuYURCziqy4fljEY4M58zfgCBHz2aBsLE6LJ7/WZSI6LcXcs6 +p9UkVY74uSfnFjVN7W7ivNutdv/vo2qsWPHojn35yYV2JEBje5LMtw+7SDJ8ljMc +kkVh+67msxiLlmxhZadA1eTf31kyceW3PcXA2rGqTMIcdb7REjOhA4kPgKV9R3lA +C0wqWEvufnkh2FuiOjI0mcYguRdvRJQooqMDr8KhAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQC3nE/WNyDiL0+UqIamE2ER +Xii4bQkuOfIFQKn13ciD3hxBI25sDS1T7ssAk/XvKxgMij7jx7vtRV2vJg905c53 +2+QxDkkCOO1wrYsvJfCNJ5yz2JkO0eXG1RLmIViixLoyipjEDwSwPM7SpK2LngsL +teV/CKkQAmdOIXB6e3KMv7DvBHboGmm/cv3JrKdLxcQd80HigqNR29nPAJhBx4T2 +VZneCNnrErYn+OsaM1TdlyIoTF15Aq5fJY5hfK3v5xLv7JP6X5XqXTVh8Bua/A9B +7pWnFtxNcMr2NbC5Jfmu2Zgc7xTcB1M0bRVSLO4ytMFnBvm451K3Awhz25CRF5zg +-----END CERTIFICATE----- +""" + +SSL_TEST_WALLET_PUBLIC_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEAqcFL2ftO1xnnJbq5duLOZqHAD/6ZpVEFOdLp87D0Vmq67eAy +IxV+AlBK5Qp8Bin3+rF5EjcyTgjUODUFyCeYpmxL8e3eVfNM/+T4brNibGOLnyGf +y4nTpOLUpVKSw7mFEQs4qsuH5YxGODOfM34AgR89mgbCxOiye/1mUiOi3F3LOqfV +JFWO+Lkn5xY1Te1u4rzbrXb/76NqrFjx6I59+cmFdiRAY3uSzLcPu0gyfJYzHJJF +Yfuu5rMYi5ZsYWWnQNXk399ZMnHltz3FwNqxqkzCHHW+0RIzoQOJD4ClfUd5QAtM +KlhL7n55IdhbojoyNJnGILkXb0SUKKKjA6/CoQIDAQABAoIBAGhbdWb3UJt5yBjw +to14lwyPCYSLrybrLPxERiDSuxLZIDuWZRweXU3M0I4HqQEdEd6i9dwV5K4GTXiU +WA6ZEQXWc8Wxxsot/TsfJv7e9nXNqIrWX+b/vwWRkMplfeYnCb/VlyugXdXnK0/n +pEpCfsriSruCxn/I0djZieqbD8bKPaCNkHUqcQsgibxC22qYF5U8ShGfuqc8X/Vs +df245Gcrh0QhCf/pTau4qPi+E473LtcM6bKjSR7EJGCCQCQXf63+TP6G8b/PI7oI +ZoCVEImrtEFI0rdC6u7F6KWCwc1PNhE549TkzkC7L+NpnP6EGroRcPzXgAzz/5iB ++Yju3AUCgYEA3SWRPsO3E4Tzvld5YvIFG9Fte6oIrkpwJJ2NfCVtoe0a7YOQJ5hj +N2qNGjMszhQF7ieG5IsBwvU/cAfTp1SNh8C86ScRwZsQ/IK4iKOVY84u+qCLxZG9 +4m1ZJi0Zwuo0i2Gs+T/wbF88SQAErVPdDf46hAQVu4mUs/019/RMTPcCgYEAxIJE +9aIhYa0p+RuIQw1kpCMsFr6zM6384aOV+zjvF/FcHvsFajcJWev+qG22OHAYRGjF +6RzJ7KRMel+dYMyrkdHwPA1DFxtXTnge7zg6P0xFVxysBw+GBIXJb6DGNqhkT1tP +KaQOOPOwQypJjzVXPknaSStiA6EwiULxltRK/ycCgYAdH9B0GqRmvrC3FaAX5tXD +Zx5rFeaUxZrlR5aVjfxVQfu04gm/HTOb3b19gNXawgpR5gS+3ou52ECliXJXbCxD +f5+heRK+k6R2DOUuoZSQE1xeh3xA5cPDKTF/dJsa72tCG/gCz2fjbdtrpcP3676G +FEAymLMgAquB1Mwhvpu52wKBgBc7X3O6yz+E/WVZ/+4Nc0yEa/30ZbNCapcyg9TD +kmC+RCnVe3pnL0/WOrEm51gcyIGt8Vfx811qvy/ohe6fw9jlfQVcfAYLUXMReHbH +qvs4xSnbVesvxqRaPMpZs5VaqyFGpkFCB/xrsvb91Nx9becLTCdCXcAYGmjf5Tfz +uToZAoGAMYalPv6XvJBf3CvlvEeBGiXDfaV4O+3t1kevtbSgrrV6pW5sy/WwUco8 +V7Q7wLdRDi+sghPqhxXqLnIyp8chU5LMOwEU3m2kw3pH9ApZKLmaUbcid5pS+4rd +G5puMkmYGwaZRBY2HGOXMA0kdYXiPw2y/jdH+Oz9DvWd2tVL8YI= +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_FARMER_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUSORAd4kBPC4fSPqHEQskE72Yt1kwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyNloYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDLIIgg1ILQGtE9Rkza0ieGUNn6wDssvm0fkcpIZXhrYbow +ClydjwDMQrLHF295ZgfkqDEmD5MUeJTxBNznDlZtkvBIRjPN+M7ZnlGJCUTc9jex +U0a/KxrK6ygsaWNzQ8eNaTNOAR/l6j/kuAUC4vKoYKGzLCW45LlKVB9xQDWinpov +nXpA6S5UUI6YxqeriHr2IiLtXSZmqb1lqftTGXenvdnHrJEmer4iYjXHAfMhq+5/ +yHCZmpy4IAX39zwAWA9FnYieGSE8KyEqZW4HfF1Fe3V9C6nsZ2gVL1k0sgAgJ8oW +3CtM8tljHCmyxxD9EHSjJAkSnY3OqU5P2+XMbNcJAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQAijxQXc6ndCfyUhP7DmFCr +OR3jfPd7Bvc5M306CepT4ZGxXrjgy5idkKS8PAdSTMFJ/h3ShkGatgnb/OoOqiMh +YV78dx0wr4/sdEauPHODkQXmtPj+u2Al9ZyYflTLeiMV7JOn8H4oEE+r0Ra3o89P +F9+GOd/jnF8BpO5GUDN0nN22tNid5kIepMNVG0L3iDMGSDMzcXbGE49a8FPc4CfK +24Fd6BZ2YsUM4NWQ97lfGKtCsnZkChwNVkSkVXP38Zvz5H+sHaMyWQ+hiNBlB7Up +OrNw0uq/jvNv5IGwx/JEuYuXXfPd5CvPesk43ycsBvbjyYFSOsdzU55jEcivPQNW +-----END CERTIFICATE----- +""" + +SSL_TEST_FARMER_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAyyCIINSC0BrRPUZM2tInhlDZ+sA7LL5tH5HKSGV4a2G6MApc +nY8AzEKyxxdveWYH5KgxJg+TFHiU8QTc5w5WbZLwSEYzzfjO2Z5RiQlE3PY3sVNG +vysayusoLGljc0PHjWkzTgEf5eo/5LgFAuLyqGChsywluOS5SlQfcUA1op6aL516 +QOkuVFCOmManq4h69iIi7V0mZqm9Zan7Uxl3p73Zx6yRJnq+ImI1xwHzIavuf8hw +mZqcuCAF9/c8AFgPRZ2InhkhPCshKmVuB3xdRXt1fQup7GdoFS9ZNLIAICfKFtwr +TPLZYxwpsscQ/RB0oyQJEp2NzqlOT9vlzGzXCQIDAQABAoIBAHEcRnFxpP5ZUJa8 +ZOOdDuFeeGOHU+xQhdeEiY3S40F4hANoYbZjAWC862yuAicpx89uUSAOoCpQEzA7 +Mv9/HmWZ4y972DEkEZtg66pRfQVGHjEiXEzrpdnFJPPGI9j1r1Nxd15Chg6zaKzm +Q/QdiF52oNRzCvZwdzWKro+T38oTZLaYF/GvHZ29ikO2v/txEhY0E6Ox8PjUEuaE +CH+SoCqAkrpyT5ue+Zq76M1mB5krnLQEfoyHWSKykeQ9svSSrlpa8sJvAufSG5xS +xgqh56i3pGsGrwP5QLC6j6sK1hnknvs7U07HFZ00WNON5bYQTqd11n0denPC1xHn +l/O4AxkCgYEA9i61oB6TbS2KK7RAKRXiF7uIKZgWBv4yv/ynsf7d65gkfG0XZyuP +UB2yCn5fn5dLvweHbK7NnzmfqqiwNQYM5JbPld/eqzVs8s3B1M2rWTLugfZZ8NeE +W4P/mYwdpSpdQiSgBwdlolAtIZcbQwfujEXTUK6ZjDaYsHsIuW5CdLcCgYEA0zpE +ePAZ6KAC89a6IDvErllaegPhY30jIuEf7JFBAan9o+4cmzp4WXsaLkbjeSjnI1Yu +czUorTraK7OCLp+tphSxbpoE8T5OtH8xB4gTFGmm4lz2UFv5ObNpA9+rrb6Jf0p6 +x9CyClTKF1vsDTtWQvEg+kDisE+tNdLtHYBM0j8CgYAw6XTinFCUR5EFP+njf9qM +9pCGGxZ9SzIQHQXAgq/a6D6PjikxMWFm/I9sMFGVZr0A9mD8wfpOoWdMw/lGf64+ +GIyj7XfTMmk0EJdrTXW24jyrC6QxCtDcUeyNuF4He9RNmPNGkjyqNB3TZ69d8Qx/ +SDxE8nvFdO9/WOKR3QtNHwKBgGQhO/JEh1Oh/qROhv7etlab3ur2SfLakDxpkbOY +C8PZLHZ4WrEvH3vzgi6rxgtaW2+B3BUa/wRXYLLUroKhiTSwnIe8lVky2yZvIPPc +CodjqgumW9EuOE+k/8QpVH3RU+a2jMuJ38xL81ztY1HGbhbfrW1UMuG3c3mPWn3g +owoLAoGBAOjm/N882BzVt1wK50hYf6ywdD8RA1UJg0T8XN4meoruG0nxHo0LJG+q +ot0B638GSG9ESBbAeYxQZ8zqgH5y1DS/O7xmLnHNck7Eu7DblJeQc496/yKW7Uci +cGosIckRRVM0Dekivt3fxdIvct9UonKUJsAxoZsf+fnmMj1QTMai +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_FARMER_PUBLIC_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUPNbZirLECcLXWjdq7AF5vdOX4UowDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyNloYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQCVE9/KTj19nPrT0DaIRmLQBhJCvvMsJnY8Fa8R0hfM+g41 +jHKzvriwD0yArxbdj+eKr00ZWM9PCG/TpnUkW33PSya+VQ4iADUTcD36F/5p0sfe +psu1+tUf7MdMGERrRnNwG/xTAo47whrJ7QoIYWjhtiOREjImBjWXRgatT4uLuNsj +wguPTFQklEH53mxunBago7qJLwJTFVJ+hrxMuHAwYHxhdNKA18oVKVcg1zE3JTwH +wcY/n8kvUXK6L8GJ3Cororn53ej4KBUbvrsAs6AXtpwUUQy/H0s1ZkuF7r1nmUH/ +zGvzrPTMnFvtRA3yyXxpjG2mJvx0svwqVAVV0HpDAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQCPL//viWfMURAJWiGJZSNH +uy1UWUkt/Ga5zIdr+22nHPEXTE6H4+TbDKomVa7xJebZ/Pr0zG4Y41wk/l65Qq4C +5FBNiGoLTO3T+6aSCF7iwUoWRW3leCL29TZrX3AG+R3CnYJnJtGpH+vmqb4lp10c +duCxdd/1Foe3V2Hc1QhFRwd3uG9wYJ1VL4ifjghT03Kp8UcPDYY3w4A3/QEjVMsl +A0pgj34t7oiT/K54bWtkWphbDu5jX8JP8+A01CXS9njXU1OXEnRKq/x2OhIFEAKS +eKywXcUoqfNpX0qmTKSahTslCZu3kUtOgyHQMOJIceot1AZ2hgzDmmEL3+DD2gZ9 +-----END CERTIFICATE----- +""" + +SSL_TEST_FARMER_PUBLIC_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAlRPfyk49fZz609A2iEZi0AYSQr7zLCZ2PBWvEdIXzPoONYxy +s764sA9MgK8W3Y/niq9NGVjPTwhv06Z1JFt9z0smvlUOIgA1E3A9+hf+adLH3qbL +tfrVH+zHTBhEa0ZzcBv8UwKOO8Iaye0KCGFo4bYjkRIyJgY1l0YGrU+Li7jbI8IL +j0xUJJRB+d5sbpwWoKO6iS8CUxVSfoa8TLhwMGB8YXTSgNfKFSlXINcxNyU8B8HG +P5/JL1Fyui/BidwqK6K5+d3o+CgVG767ALOgF7acFFEMvx9LNWZLhe69Z5lB/8xr +86z0zJxb7UQN8sl8aYxtpib8dLL8KlQFVdB6QwIDAQABAoIBABW+c1rXtKJYvkEc +0odn9MuwxwMTRPbAmWhEJWftA+my41WuKaDMBbYwVRFD+IrSjYwt64nx6TL24RC2 +68kkyyHsLTd/wnL1Isi2C2QqEcKvqtVv8LCXaHSinaMcuwYGnZnRiyk0aziOJEgl +mdwFET4yyddEFypyp2hsH1cyDgGP+O+8P4JKAVMSrtCCM/+5a0fj/Z2TUIEUDkzT +OCIY+GsKDwE88VPErSfzx6gZPWpPkQMI9evhGDKhwvUuBNgKal7oeSRbzxQ5Ihj4 +crACs07FTRrrEB3TG22cPk+gdMvM6nEbrXybIjLM8XzOpmw6M5RQdwYeO+O8+4en +YrH0KhECgYEAxniu226jcNCbl9D2UHEm31fIs6esyEz3IJKB1ZC2FAjQJdZ0Y2oy +KRAIxDBFHY96yL82vKXloT1b0LsBtsTFJLrqLGtiuoxLgUxNtU7s4r0aX0GjpStW +Dk0ncrInwxlh3uYcpM2Hj4qjNam0UrttDr1/177tOwaPdER11TkiRDsCgYEAwEn9 +HSb3XecbMD9Sap8ER7hIwxU5im/VopDzHqvpOb2a8TIQMV2rk48htZIkt0yVf7hv +X7Sx/FpaZOJPfa+ND6KeQKw1noajEeSHxLz13aOnFlUtSHzNTUcqk2oNSx+0lP4n +C3W5BJR0fsgtcFAd5lxEajwIxdmPnKm4T2j06ZkCgYEApE7k8+T0ikEpjtYAFTiX +5e7WyWTXNjwBm4Wu1w+mrY9eQvT4BhW00SnlGAaeMYrHK8qhliwBnysdCADJunXM +gEv98ig05Buhprl029UrZ8sGOjYtNGBcLhrRvbKgGHS7Ab2fmRBOWhd8ZsDH+HYS +I1HetM3ruCIGQUssAgn6xGECgYEAke2UsbMIt7LT52Gm4lObo/IvBh3tdSo6Lw1h +9Dzy2mcSV0lvEIfN1kYhhvJJ+vGb4znNDAzNpn3LbBRzzyaTHvKCtwH6DzyONN4C +S0Q8MuAnxcMOgpx0EdmYbhdlz0VYfloCt6e3qcogPrccBMhIaLJNGXJGFiBt5K7I +uTsl4sECgYAmsWXL22XeKAwv2JutLK5Hz/xn5BmzFDGBLvu0+FVml0aocYVVyQS2 +mzs2kRoJdLEDfcxibawQimTuCs53PkoKVNHB2JzFS8HNHdcFHaCb19ZO0NoSDbst +sSu4qj9TPFACKOKsfRpSIWoeHN/ps24ost1vE183ARVTsm8KTHgEJw== +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_HARVESTER_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUa0HzW3fH6O0kNO3yGndcTG3+kX0wDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyNloYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQCtlD5CM6r5C3//rZwWLmMHcIO3lDFfdSwrvONmMhwlkIDU +/FgLr20ZS6ny7DPSRVuU3jijL00Q6XZqpmmzsoN+RU6VITNuam/gB30E/WfF2yds +ifWtVpE9wM51V1SigEtAIviooNR/CrfXxaljw1wmReWjCAUP4MWJBBFGUymWpBlF +vEo+7VWZ5B4bfstRTZaFWRln/otMh8v3SOaJSmNafsDnulq1JXJz/i2hFfPjgfbo +rGp8bfCWpNmEzJSn+CY7aAyW9eKKR+unWzM7+PEnI2l+5rrq54BfxpMdfAFHlMK4 +NpIrJNmnjMLm1VQpm2/RFxI3LP+IDedCJmWpXbRpAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQBc3mZ5yN9pXLT/0Io6Ql2k +SxPSZc68538f/gjpnlXDxApiP0sk2RvAL3C3E3RCH1KeP0wjcRnOwE3J+BTaisGW +BbSQjQMnGm/zKtkwBaSIIjkKXSRCACEzneTMxPwEqCUgAWJMJ2/vzgmbZcQ7TxHQ +UZpOnDhjknCLmxxEk3cGk6+1SIAO9NQF4z4fL5grfQup6sBeyN+srl0WnUFWfBIi +d/pZHcUCKL+FmUrp6eCKGAFGQiM9TyJ62H4Cs/J0bR9e1asLOwSAunTB8+JnQa18 +ug0LdcWQLjcoIMaZk5XIn2wlmFIsTqVXS5i2Os7w8tb/XtdxL+2Qi+Hk0oBmGffx +-----END CERTIFICATE----- +""" + +SSL_TEST_HARVESTER_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEArZQ+QjOq+Qt//62cFi5jB3CDt5QxX3UsK7zjZjIcJZCA1PxY +C69tGUup8uwz0kVblN44oy9NEOl2aqZps7KDfkVOlSEzbmpv4Ad9BP1nxdsnbIn1 +rVaRPcDOdVdUooBLQCL4qKDUfwq318WpY8NcJkXlowgFD+DFiQQRRlMplqQZRbxK +Pu1VmeQeG37LUU2WhVkZZ/6LTIfL90jmiUpjWn7A57patSVyc/4toRXz44H26Kxq +fG3wlqTZhMyUp/gmO2gMlvXiikfrp1szO/jxJyNpfua66ueAX8aTHXwBR5TCuDaS +KyTZp4zC5tVUKZtv0RcSNyz/iA3nQiZlqV20aQIDAQABAoIBAAhgnjydt8O7TVsu +qtjbNkZWpNTIXzWnNxGJVURKaNdbSQx+fVVbCx3sa/BgfAPK+yeNLhiaINMPIXr2 +OyXEGNqQR8Gkz5Glq26ZjeweutJuyFFRuzy5b9sWIiDBrUEGhhs7VNr2oCrdfo/4 +Zzt8Y0cpmnKq4Wupwn7hZmAJhXlSr9deWrWUfzEbgzuqtMgIIVI9VWqW+wxCs82H +WxzD5crc6g9U4eo541wOx3eSn3Ni75Hotnkx1Vgs1Od/ivloYHAISDcbZB89C+c6 +FQtEiOphj0xU0V377e5RNNnjj6HXwdRti95YpQf21cGol2JRngR/w+o2AQuSO8E5 +TqiC2wECgYEA10jKJkWfGBcEd5s3SpP4j9mFrvVKAOeP1XDqwvs6uD52CkF9k2O9 ++Ja7O9QVxKI7Jt6fHISkrMY1srms/VGw/9R2lxBMHRgrsyZZUIjPSU09qwU5IORw +4Zv52zWqG6MQZu1dUsFRBsu5ibVbdzTic8G9v4V/U+fa2uz6cgLiTEkCgYEAzmhA +PL7acIhmtGhTxNPrnnoUB8sizfTP0E3xTytmTjbtr+lrNz5RvOIv9owp8hEWqMxG +ag9lBdERQnJhrW++ivjkprQZmyVzS9NR/XYXG0W/FSqYLZZX3xa/bmh5eRM0qcyu +AQVDfAvUs+7Wc0LTV6t931zIhTcz/jZ98wR85yECgYEAzKDGbKxedVJjj6B8ZKnT +aD/U3qEOD2ALClEDBAQyIzBTmJn5V6BF0MTNASgs7LNbUC3oxP2bXRIltlTghgQh +Hnp/okT+Y+U2nFlGKdNwW/dMN4OGcqpQVVGho2gV4aEUFRFnVCKl9rSsDaXRY7Rj +zq2Hw0SL62AFWXRI9Reiq+kCgYAFqnjw8fA/HI9tLlv2UDbsj79TA3F+I9U8i5cv +LCrPxNQ7evXVe2F1BOR6KRjRq0Rq98iLCsckJLwLjeY+g43AdNqZ9OGrD5kdoLxk +b8RsnDqFkzjAL5tT5WT12+pRt4Q/kP3Jy2Ix2oVJNyot2czBYFTBN+PNPFmyBb7p +V9sx4QKBgQDWEIRplbm9f0NnTBaZ68qMtEt7nXMqEv3vjalTeriB+X9GJKDKz4Ym +slr2WOPJSgmZApbz3B8EJmbKYys6gE1z0dN3Pl763YU5EhM6kezEX2C5HfL4iSFW +Obkbg7hMBYQk0faEyd6dReIZwVHD7WAf+zCvh9ZG6l4ic1wQs5kYfg== +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_TIMELORD_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUfogbG84aJo97wy3P0ZHAkXShqO0wDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyN1oYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQCxBstxYtPbm7eb1iRbL4SZCF0xIueUH/gZ5nfj3Tbo9DIn +QcHVbNkr5XxH5MBtQcT8bgF/tgBkj7uuFTymT2EpBrtTbdLCTsZ2eMQIABOQ4APZ +NKDiYb6g95JC7vdmuLfuB6VyvlMCZ/Ffyvow+PCgpT7ElNjMiLf7y6mcvzgNKSLN +JYqrJCf7vT0a4W+isck6/fD9J1RUhE0Xkts5wmpwJQGsRYme2hNy/PmCcEY9rqpi +YOxWWeyLbdZ4nI4OH652JwXKUTijqCZYc6+BoXfjwZGq05WK5NhBZVnlYMd5ZFab +DnXGR1WC9ysv1xkFqpSfPlwSZdZcJzBnXXwhJ4qrAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQCYInnIgvKBvmX65bVLmhNt +cEUickmBTKOEG4i1yovVcDPIPLGH+3p4Oxng+N9zJh6n4SyCeOou30tRuNEunHOC +PmixRUxM04iNm5lLLdS8dd+kErpX+EYT20amgbnN0HNDRi7+EANXTm2ld9HD7skb +M6lABrsQQdmepdNz6609G0HO/I9rdUy1GaXlwd2th21VyzKmmq28nIT7KidBoQNG +MhTjsnNrZekjW/k3sJA9nEhyERmdsApb/TlUV6A4ttQZOqPV3ClkumqQn04jLEhg +dBNTzK0UEqdVXrPRpJBa/gSkSsCWXjMhwY60pHDsDmnOQH0kLQ5KzPU7IF3x+l3M +-----END CERTIFICATE----- +""" + +SSL_TEST_TIMELORD_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEAsQbLcWLT25u3m9YkWy+EmQhdMSLnlB/4GeZ349026PQyJ0HB +1WzZK+V8R+TAbUHE/G4Bf7YAZI+7rhU8pk9hKQa7U23Swk7GdnjECAATkOAD2TSg +4mG+oPeSQu73Zri37gelcr5TAmfxX8r6MPjwoKU+xJTYzIi3+8upnL84DSkizSWK +qyQn+709GuFvorHJOv3w/SdUVIRNF5LbOcJqcCUBrEWJntoTcvz5gnBGPa6qYmDs +Vlnsi23WeJyODh+udicFylE4o6gmWHOvgaF348GRqtOViuTYQWVZ5WDHeWRWmw51 +xkdVgvcrL9cZBaqUnz5cEmXWXCcwZ118ISeKqwIDAQABAoIBAQCXksvK7+WaWYAi +rH5AnTUZmvHASrSiPaU+9/ibYCPN3pi6yDDhPuvMDBgXrqOcaP3zbXVXFkzLzc3S +xlhBxiHY8OygCJ62xKBlfA3NE9Os7kIdTlSawTpptNDFArtOdsb1xhJBZvjITJt9 +e9ww5lWSFyrhQtlGd6GgtMcrcQbbLHqP1bKKSwPIYI4V6OjxBRK2QPahgrudPdNp +C9C9GWCO5bVary0uKfbXvgHhUOrqC2ogtmnOY41KilofbxCRX7Mc7uLzR2SALKEz +FpTt/CThsWt4IeUUvxSOWtpUa+qIZ2U9zRZZUxIwXx9I84/K3unbk7REHG4RHspG +itgQTD/xAoGBAOCHw1v7K+xNRrDbdce5X6+jJFdVb4NNXkkWPzqD7PuGEdL6LUuG +lm75CAXx0YZtXATog93Fz1ZDBH96tLPzI3qxIEdoU2i+iPWFv9q+SMA7IHNqc8V1 +AL1XUFWnJlfTUGihvlHGEODLIZ0k9JpMPwDIdrxp/kaqJGkJ46Ue55BvAoGBAMnW +k7m7fI2aIfRaiuAUsDfaNAk73N/M3XmA85h+h+o3+hI8OYv7kCnK6ahD6vHygpD7 +eLJQgD3XPEpKswgP+uUt5p4cBAkt4gGR1sSVSEMrc7OJMF7CTYC+c9U/SRqG34V1 +eYvCorVpbFp7GbY3WbDJwJbtPnukaWlVVPvwTQ+FAoGBAMS7UBp1DnxDDXCDKkTw +kP2k9X+sNUQX80gYvRf5ZhjQ1SdF25A0gfUEMNp8kni1s439aSVVYCEWIYfNLS4L +GQg00LKgn4zEfd6a7YqtdbMxW3KlUIEvzpEYQyR5i6giWG8FYWvnHvzIH1DAg636 +pq15+EeIm6qxA6whZRxV4tHzAoGAJnp/4zK5Bg3SV1FDlICdL6irru74prnZpyZM +SlAk/SP6yqsslWE6FJ2YefmousNu3ND0K5ppOGDmH4uqIelZ/YMIqi/RHSbgJUh2 +VzfWdOe9wQZwcEA+okKstoTAHQyFZF4G8/wBJPCaNY2uUyyuLqPn0V4dQVkQt4IL +F5SyPDkCgYEApt5A/pc42+/bxjxw85ENMO26eJJ9YObUgZUgi+BwR7BdzpmTfxfm +Ubbpg0q5RA4hFofkdqQkPxx9A3Q40e8BNGto2NHKf//jhBCvbZs0uv4akAv7fERy +0SMTECjuLplUvSyzUQ/evpXDRkN5CuH7eo+GuIJPPulPCs5+FUo5TOg= +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_TIMELORD_PUBLIC_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUT43GvhVmx9CzguV2nwdektqBaZwwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyN1oYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDRiTszw1IkIr9n6KjMvgS/9I+p+La/NwfFPsIWkTE6cffr +LIi9H+yTMTM3tbNXM4JhvqdeN+c2mDAVjhoi+AAQH3gkpXitxD4ZjYzCCTtwd+q0 +gpCKLPOmKxYjqCcNkmEc70g/QOs95HyDdvLL1G1sgMnhldGuc0a1HX0Te9nE7KkW +40Etk6lhEKEa9o9rEjAL84Z6kizKELOtjgd5wM3FaAMB/UIhf+kDxB5vtAhsKewb +2Uy8wMpXJW79cqfLxgjDhd7LEZwSba2Z+XRDD+B+NuC58cv8H8y6b69Rwjmya50X +K1gW5/aZA2+mo9NlSAMdlOM5ntgd2Cbh0zg4jDPTAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQC//83StmG2IlGISJqGVwSj +B+Jl/eodYO1iYuWtCfobI/WZEz7Noqtuth9U2Pjc/VDImy+w/x6XNPTTa0MgUnqi +/GHG1qRIefWrWp00C7fFbrJW1llYv/AFZfgYZB92Vr2X7RupnQOY2a/XwT8dzstU +ZPTNK5wV47MmUp+u7p2Q24ywS+GuQTK7IZnhQjP7ttKKBgdBp9evHuT4B3yl7qUK +JWb3nAreUSESWkumSXlted0sDQQ7ahilzHPkemRgJZotbQID9sV7WqHYMCRtZENX +53jFAQFtxj7mjjacvwWs45XgEGsr37LjCBHUHujVEccfGXN9+LRrpS6pKiyJeMg1 +-----END CERTIFICATE----- +""" + +SSL_TEST_TIMELORD_PUBLIC_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEA0Yk7M8NSJCK/Z+iozL4Ev/SPqfi2vzcHxT7CFpExOnH36yyI +vR/skzEzN7WzVzOCYb6nXjfnNpgwFY4aIvgAEB94JKV4rcQ+GY2Mwgk7cHfqtIKQ +iizzpisWI6gnDZJhHO9IP0DrPeR8g3byy9RtbIDJ4ZXRrnNGtR19E3vZxOypFuNB +LZOpYRChGvaPaxIwC/OGepIsyhCzrY4HecDNxWgDAf1CIX/pA8Qeb7QIbCnsG9lM +vMDKVyVu/XKny8YIw4XeyxGcEm2tmfl0Qw/gfjbgufHL/B/Mum+vUcI5smudFytY +Fuf2mQNvpqPTZUgDHZTjOZ7YHdgm4dM4OIwz0wIDAQABAoIBAB+9ILmTgXK1zLZp +mIAC3GdTHRvK76uBI20uN2oBripDLyFxSnkTR9t33WE35aV0yPATV/i+kQhE/yuU +rcLUO/Y1PhaW9fOkQR/PwB14FofPsj6LdGdprbJi3mSiSOAWZx1h5VindbqXTIEB +WH+lermvvGSuM+ev0GsIv3RfEzpvtHYynKTQ92PDmrbJS7/x7IQGl20UUyA6T9lg +PidOesZrMJQuJvqCWfqp/bTYuwQPneawUsV4vNUxuLcd4ZVNPDJG3/Q/YtwpoKu0 +UDGH8DnMkqn7JVKvBonDhlARdtdJ6h7g2NmwPTSyKZmeNjwKy0Vl06bcY71PNRZB +8ET8PtECgYEA6dUyY/CkB5B46eD5Qpm2Kd0gsnCxaSvzvE1LC/2xIqeszKDjsjj6 +rS1zz8Fr5qsyYN/b4Liq61AR+kUEHcPfAgRggq8Jy8965xBFDuqTCdtW6jADQ7VG +TrwDZMg/byBqQUbE7dScCl549xItUKh3WgyjZVbv6CogaJyrkq1S5ysCgYEA5WZi +utnrUfSedb11LQPCFQnJ8gnvnOUsnigeRaMxArIXj2qmADmQfZjIoDOfHoKEbRR5 +/j2bHHuZTJ+2FWLI8cSCEAfuxTXCCj/SXU3BnzlawTheUQrvOddGWstUCh50VoHM +XPA8bT+9mfs75dXUNguuFHidfS0fr3tCCkzukfkCgYB378mj51dLJfhPBfz0A0Gj +YW+W9ySYbFndOMwIf3xu6RBB+TgxPvadAxZG9s/whdkWRVxTfIT2o6BE/UdqOQBW +2YXjIgLlTiuc/wRc7Ua0JJQFFNFn1kAUvG0FMY0P49F8X988mfPbga+MEv+5Ql/N +iXP508jEDW+IGOwMFOjT9wKBgHyePDApRe7FpndrroX/rqVjJfN4dlSTIsPgI2HN +H0jJmobsdrVUkCvKneJ5aI1YdbwUDZmRufulIUhA0teXTHYaPFWdGZbEd16+APdy +0CZBMA4bIxF/kSmoyq10G3lLxgNgi7ZJQ2pN4CAQHR/kI14gxjaUt2lS5A2eNegG +lutxAoGALG1JxRXI1G2QVqNXjveLI4BA9KKZlXymNPRYxHZwr9wkgr1OZUR6hzGf +GFzfciXBeiM5DgwCGzOsRmhEVWQY0AWtwNpkvdTo2+FG+wiehzSkMviiwi4wXDZs +ZPIOBDSJCDbdO4GS9MJR1HtSQ09uMVK2/DMEOUhmfY2fkd9+rcQ= +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_CRAWLER_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUaD0m6kjEe/kX8KV86Tm3JMOXw5gwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyN1oYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6kaAaFDrrIxHCuID22AfMrV7fVrB9F5h0uQP5KSawigxJ +BHqs9gIjPi7ur9nFGxGFjh+cyFF7kkWbLOJpABEu6J1DC6+MPe67rnQjq3IEds8d +c4ToidqfP1/Pgl4uOfV0MJpYF77Vpc/P2SHApjRIl7wCPxBS50BZkPaXbobb5e9r +3QSFpyLsvs0jeu1xp4w7DBdJsiHY/Qh3ekvUAH3A/tC/kQ97K9ZndgIQflW+OO89 +FwWS9pKLXkYbKejhbaQ5D6wP2xcvY4C093B8kpaeMA9DCW8tUATGGTYaN6MUhNt9 +d0LQZ0R58uolJW2o2Qv45TokYoHlsuGbDcc11ijDAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQCaugeA7XZuF/JeC6T/cDGq +c5Y5pEBuhvNHj6aESm2FvuRIgXS6djo1YZF0McTiLVOtnUqDBSl1h/VH1e4n8zj3 +MAVMPfXbAByexDGjbEIo0/aLmcUAAy3h/HQYmkX+Ge5Bm0MCszSbM/YqMPV30rSz +Gq/KfB8s8QQb7T2sS10VTlIBL54AjEgnyunR3vPjx0rqfnFRHdQoD7MdUwOEq3qE +6FFzpmp/fUaValfF9FS8w4vDq13LUY7OhphmW8mJHJ6e7GcUxFPLKs1oNpsMMPJz +wd4te+SB/dQ8CH1o3xvvFirUiPNz1wXRziJSO6AqjNXBMe86qnELwfXohI5oxUl9 +-----END CERTIFICATE----- +""" + +SSL_TEST_CRAWLER_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEAupGgGhQ66yMRwriA9tgHzK1e31awfReYdLkD+SkmsIoMSQR6 +rPYCIz4u7q/ZxRsRhY4fnMhRe5JFmyziaQARLuidQwuvjD3uu650I6tyBHbPHXOE +6Inanz9fz4JeLjn1dDCaWBe+1aXPz9khwKY0SJe8Aj8QUudAWZD2l26G2+Xva90E +haci7L7NI3rtcaeMOwwXSbIh2P0Id3pL1AB9wP7Qv5EPeyvWZ3YCEH5VvjjvPRcF +kvaSi15GGyno4W2kOQ+sD9sXL2OAtPdwfJKWnjAPQwlvLVAExhk2GjejFITbfXdC +0GdEefLqJSVtqNkL+OU6JGKB5bLhmw3HNdYowwIDAQABAoIBAQCWTQ07FUMl/Rmo +0jTrJ7yY0q7UpCUIkcK7ffXKe7F0lbIx/M7LmmC8fbMXjUmWNilWe9nR17t1HrC+ +w1kfF/O/45wV0Es7YwV546AiwFLZb9GJO3A+WhhrJIYOSUuQWBb65NDi2TZfLfaN +zrIXXo5OURcghCelcjFwNo3CD0PL0ECB2vfBJ27QYHlv3mBGCxKTLyCPb+Oyn1fT +bDGLiwHv5tPxx8zkcaNXDztjKDJYNMSS5hE3/69dyyIdkjA+PM8Qwghr5V14m2lJ +7RUIWntNzsbxRZ6t24rK1ytQVO2o9kOx+sEtNvu7hnvmkFSLhUhtXzEAabQXyXOn +ftCDVhqZAoGBANsha+ofkczMozKrALzEeugh5D57tDmGvcG2puIiiJiYCighovkr +cvQ0h5gr18lraEP3768rZlQ0814tA17yoXaHNeNY6IyE7EiLkTtKx4tRfi1FmgK1 +YTc0LWQhELN6lg1YqbuRgAn9wPxJY1MEFutuGXJCzcsGhCNCvqmRhl01AoGBANn1 +rabHjCBZRzWOeh8fNfAcbNdVLsrD/nmyCDxEN96q/ascb3fcyNx+USqKz1acoJNC +vGILzRa9gm/86KA5r7l41+bf0FYz0muTiqpzMNN9LCBG5ChosmsSB8v7i9Q4i7yu +pCcv5ATSSeAGUcvrenK5uWM7ht+fjfTdW1RsIsUXAoGAYSYVEMwEOLa0157GienV +z5pO9YCkayiYcgxHOlQzGOu2/QnElhE0Op4bS1SMq2ip5hBCu/dSu5xqFOOB7hNF +kCXrtypQlxPLKXJu5cmGY/ayKOIFoJPHUNEaGp0qKVf8tFgNj/G2wTc12uOyXDig +7Kl4MJb7Y7o01OkfXE//MM0CgYEAmJ87GNUUXzaE8ZCyHQba2ybcZDCG0n9Ju2eZ +8rGGOcqcVGxV9aXJlPRy24pVw31rx5JsnW9MDkdnhgmfz0p1rTdcX5OLrEEfcCrh +Z5e/segttPBPJaiifu0iPokHEfUCjH3x/mq/jUy/ZDqonlVm6dz5Xu449HAilDtI +j6Yk9sMCgYEAjE0g9OFzhHJtSwQtTy8S2GYJtFAvy8KneXsR/YAz/C0/CgvT+OsK +ACI948k1VXpUK/u2A+bmqxThN7OPDC9sLgThrdtAL+7UKH68fkqFYu0usiTif2z7 +/1VI9PPkm9ZKtHx6O97fdBjv7DHhGdYITB+pVXxI6VKXmS4+YgfonJo= +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_DAEMON_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUTYcm+E1jiGL7UEiopTFGmSwk3eQwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyN1oYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDD4xmVdRUqCRCDRebD9nds1h1mtyutoeHfruSn4PiEx30Q +YSzGRszSTvM+PwzL6jug6CVmlfWzLBC25unegeZhjlhoMkMkVavA1bZQ0sx2t2ll +wqFMhk0BvfQ0ftQ0BEgHpbll361gZGb7sLB0kuh1LhRE6uWpkg3WJT36DwzkCJ+R +YgAA63J11uLhMVk22bQ9UDIlmlL2Kd0M1sLrdPtF7h2wB77RirXpH9RxPilPWTwd +t63eHKetGMwmeCHP6VHWc3mtmnYCcEf851HXr/VYYdwn/Egbn5NWU9MkyG4U6Jw/ +7iVRvf8XIv6IGcwY+qB922OjrCxsHYCWUbfwiaFXAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQBFYpf2hnFIOfEEKFkNni9T +QK//s9W2Bf2hwn59TC6tvpN0pIenfqZ5A/Evc8PnjaO8UY+rWsxRL2YZoDEABnQb +3x0VfnZKQLKGju6JiVJWSn5F5Ilj2ntglHsAgQp4QBEMbIwfStW9AeaCwVoeD34B +/NFUoD33QM6E2yKuRetceeauBA+giBkSFaUA1jeSHfRGeWtuJmnNHvd9iA8cfrSg +gETkXKUyTYkS7Afi47oCMblmuy1pKOnQsirih8Vnic0Wn46bObLn8lt3k1d0+G0F +Nx37aAAP/ArHTyRh0ctfw99aTDgOm5v46NZNLPH9z7NPTtN0tz3r3C2nT4SUB+qq +-----END CERTIFICATE----- +""" + +SSL_TEST_DAEMON_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpgIBAAKCAQEAw+MZlXUVKgkQg0Xmw/Z3bNYdZrcrraHh367kp+D4hMd9EGEs +xkbM0k7zPj8My+o7oOglZpX1sywQtubp3oHmYY5YaDJDJFWrwNW2UNLMdrdpZcKh +TIZNAb30NH7UNARIB6W5Zd+tYGRm+7CwdJLodS4UROrlqZIN1iU9+g8M5AifkWIA +AOtyddbi4TFZNtm0PVAyJZpS9indDNbC63T7Re4dsAe+0Yq16R/UcT4pT1k8Hbet +3hynrRjMJnghz+lR1nN5rZp2AnBH/OdR16/1WGHcJ/xIG5+TVlPTJMhuFOicP+4l +Ub3/FyL+iBnMGPqgfdtjo6wsbB2AllG38ImhVwIDAQABAoIBAQCv0n98LwM4H7q6 +mVtwOSEoh2cMcwy5ZLwg0hJavQtT4trWgOJ3dcUSX9rk3CLYRP4Qh05Krf9DOyIl +iU4RcfcfSW0A2Vx6mIr5Itnp4cu0IxxvQisVTNaB4cX3+H7v0Yf1lUK7tfEgu/3T +m9xGRjZwN1PqKAzMD1RsCjF+6VNguOqHzsz+8aqppbAQPqGfVCwqjdfG0nn6h89M +KxpRBQXhsqLvrxVy452Danoz64vPEwRePXhF7ZOMStno9Gzc6ArjEhIFzkNvPp+M +OpwjOTeSzzFmkGP9bHPL9hbDWpFy/wVJYuJoHGdmtFZPdGyfTzOvWqxuBCnTkRAl +Na8oFz1BAoGBAOd9Pl09+zXzi0ILdnseLvGZ3aVeOr2fxf4v7/zHDCgpro/+9OPu +oYacMnnp+nbURrjCQBeE5lu5AKtq056JxLngXIAFrnVaEu/4BjuBTa/nauXJM+r6 +q5CLtNQSWsq46wpcto/btPvv5kl5AaGx/AtkmGqD6O7e0W6Xm2+r5AiLAoGBANig +0uCRtv4I/vTjl6A82aRRy7zWyXRYXei7ti2G5/EOs+MwYs3tJF6ncrVMyKjcNpof +DcnuO5UO8bL6Lcz5G/XPmMfnoicsuZxZk5X7NofRPEwG1JKvUA7wvHBJU630M+p9 +5xLI3fKIW1LB9zZT7wG64iJXx1CHFl5IoqCSDJflAoGBANH4m3nN/6/nMbh9V0HD +lgcVbqNR/mwDoX63krIxBgjkDe+U7iJVUHQd9/b3UXU5hNCPeb0bkis+eqoBouPZ +yPRk2uJQxPay9hxuV5Df70yP1zmIsCwCpV3eKu51m57n7mIeyIViXx5qcvLP7Lfz +DlBzNYDgF4eb2lG6+IVpX9STAoGBAMgpGZBss2PY1hNatABYGVWOSq1q3OvGtsbT +owpAC9IdnrN+Qt05kBBxsji5APOdvkn8BZaerKkXDNct+OHbDy26qtWTPq3p0nsX +/ZlobENkXs10xjffCx8y6zrpVgt2h/3UZY1i0klGGvPFy3GEbmPv1QCckMrkdxOZ +E8NAD6jNAoGBAJ9h+zA+zuJZZPddUltNeg1ZxvLbjg9rd/7YSGMVNmCWBpwv33HR +i881B4UXr3m/cEbA1PxBwHkSXGkfFvsmdqFN5UITd1oF3EAHVK0oUmewgl9clj8B +exwCTm7kDpCVHXsNu/ncODBQM8+r4Z3vjXAyw0DT94iaASYypEDpXVgw +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_INTRODUCER_PUBLIC_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUbtU04ozLF4XldtM40YPkF1DIMKEwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyN1oYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDnZYSeBOBGn94eiPAorxg9GdUoIGr4UUNxrtXTBmX8zZZp +LIu3m+2T+BO0ig6a4SZ7IxD4Ocbj2YP6sYl44F3fNXjvekvNzTE6LaeCvOh5myUj +3h/cCZTMCV9Ja4CMg+xOCBLu+CjyWSkp5Z8kdYz86o7gKNh1eJT50a8pARqyNdWw +Q/YoYTTpfG80GQp31Zb3hzX9fl6dT6+gYuV1xkiPrSuxX4oZZ7ZH+ktIwiFoXGOh +sQu1cLaLHP0iImF1QCHh56RwV7j/RcgqMx/hdzz80rShbUost85ngl+0ss3jYm1+ +Z5Ps8u8FRSdgN4H+HQL16q8OGrMZXdnRKUYEiCY3AgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQDG/ltB2n5vOIPi90d+GikR +nGu1SR7ALScsbF4w4uIH8UvtMTu4nctlLJWPNuor3s7ylnwv0eMwumtuHYuIBSm3 +9umrUIGlwMedCdMNKpvQF/WkXevEQj1azfGmltta+ZrQBxwhHg069y8Ykb84SM8D +5vEy0rJ+zmrvFYeKaxzAjA1sG4bjCiMMiwJ2rHXFjIFdQHMwwYcFQ1FeAPxEe/8T +PGYY561vOKVP6P86swKPOsQn+3MYR0Ehi8vdw5E4f3TcOkyxx5sPmiC/3pq0h4U4 +kmLI+Ng3D1A3NzSel2J0mp7RiPmUhu//WZOE3G38+27jGp9GPEM/zlc1gL2EHN9w +-----END CERTIFICATE----- +""" + +SSL_TEST_INTRODUCER_PUBLIC_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpgIBAAKCAQEA52WEngTgRp/eHojwKK8YPRnVKCBq+FFDca7V0wZl/M2WaSyL +t5vtk/gTtIoOmuEmeyMQ+DnG49mD+rGJeOBd3zV473pLzc0xOi2ngrzoeZslI94f +3AmUzAlfSWuAjIPsTggS7vgo8lkpKeWfJHWM/OqO4CjYdXiU+dGvKQEasjXVsEP2 +KGE06XxvNBkKd9WW94c1/X5enU+voGLldcZIj60rsV+KGWe2R/pLSMIhaFxjobEL +tXC2ixz9IiJhdUAh4eekcFe4/0XIKjMf4Xc8/NK0oW1KLLfOZ4JftLLN42JtfmeT +7PLvBUUnYDeB/h0C9eqvDhqzGV3Z0SlGBIgmNwIDAQABAoIBAQCPSwZ89HgORCHA +tvxBtWxFKiId3zVe4LPrSmGPdH7jtkxWhQdghGbzIsTRIE07DAJQbr6reNv5bVGV +hSukdwyqlOp3IjyfDVpWtL7u7xzncXPmaj9Ae45xa7xeMvxAB9Hl4IoZAgQZT612 +DIQoh8LvPDGODr08wZc/vOHDerOVdyNdVIu27pJziTHyhHBZMpJar31yBsG2J4j1 +FhKZrmZr+01fV/hGCQ1NkKy26gOA7OnOCqlco12iHX5PmWwAU1S6UJf6oSPxXAUS +4Za5T9pxvpFgYKlmp5665lhdRYNA+Kf3Z+dF6n956AOFZzBE1KuxTCl4ea1LPJqY +cmHGbeABAoGBAPy7PmMp/C+WbdK3JXactlV/XvMB5ldqbfh7q5CqwTG74q9Y70hJ +VFhfB/a/ZcMEb6vELgpnSzOMZFg6AA89PWBEip/2U1Yf6ugqjsU9xlKkXVnzoS/p +99QDtZ2vEw6Cm1dA0zIt615wz2A9/wDsBktya0/ijiBuxmc9CZcyUYoBAoGBAOpj +o0PlWbVTsKoj5N/rQH0VcIYwtIQqS4rbpsgAjhihA5oAS8ZKl484pAwf2adXdSdR +5vn+FP7y17oRt6ttQPITApKpZSIcxNuQlLNI95c49oU53tAvXZdddb0arjoqJtw1 +GkTlHj08whgxpTd4S80GGOn3GROekcJHVnjSA4A3AoGBAOSCiI4w0AxW/0WewwjT ++Sik2bzu4s33NSeO6jkLq1LEhtn0l6XMZ67ffdvkgqYpxK6R2u8dJimdrrz29EbT +IEOCtbScjA07HrJ8iEpe6IqggqdqWTtxWNsh33yLZ7ee78Wcn1innEDvzxE9/Otg +fPCKq+y287rvbgS6c4l5vbABAoGBAJ0EOHggaZM2SFACEa4Li7z/oszSTeuH5elU +sgqjjI1lN+NvtVNV3uf7+rGAmK8owHuhu0jXdDtCdU/Z1J/LZcmFAKE9R1mtyhaI +aYUdKXetmj+vf9sZD+p5mokfGX4vhK7aCAoFLte5HxFUGKjrNmRXZFM/zBW/kUeD +wKLZlazLAoGBAJXC3C/NiCxyxPuSAQ3/0CA3cN6rqul7Z+buPi5VRyXJTljB+4pp +4FUSFNtXSssU61cBvxXu2J7VBp3PkFOHrAzRZWIdq2loLE2t6Ma20Mj2quT/0M26 +fEK1BVt3jMFt2veQo0EZ7HMTvtSDeoKgkBnvcFvmXhjKOaqZYbSVEY7r +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_PRIVATE_CA_CERT_AND_KEY_5: Tuple[bytes, bytes] = (SSL_TEST_PRIVATE_CA_CRT, SSL_TEST_PRIVATE_CA_KEY) + +SSL_TEST_NODE_CERTS_AND_KEYS_5: Dict[str, Dict[str, Dict[str, bytes]]] = { + "full_node": { + "private": {"crt": SSL_TEST_FULLNODE_PRIVATE_CRT, "key": SSL_TEST_FULLNODE_PRIVATE_KEY}, + "public": {"crt": SSL_TEST_FULLNODE_PUBLIC_CRT, "key": SSL_TEST_FULLNODE_PUBLIC_KEY}, + }, + "wallet": { + "private": {"crt": SSL_TEST_WALLET_PRIVATE_CRT, "key": SSL_TEST_WALLET_PRIVATE_KEY}, + "public": {"crt": SSL_TEST_WALLET_PUBLIC_CRT, "key": SSL_TEST_WALLET_PUBLIC_KEY}, + }, + "farmer": { + "private": {"crt": SSL_TEST_FARMER_PRIVATE_CRT, "key": SSL_TEST_FARMER_PRIVATE_KEY}, + "public": {"crt": SSL_TEST_FARMER_PUBLIC_CRT, "key": SSL_TEST_FARMER_PUBLIC_KEY}, + }, + "harvester": { + "private": {"crt": SSL_TEST_HARVESTER_PRIVATE_CRT, "key": SSL_TEST_HARVESTER_PRIVATE_KEY}, + }, + "timelord": { + "private": {"crt": SSL_TEST_TIMELORD_PRIVATE_CRT, "key": SSL_TEST_TIMELORD_PRIVATE_KEY}, + "public": {"crt": SSL_TEST_TIMELORD_PUBLIC_CRT, "key": SSL_TEST_TIMELORD_PUBLIC_KEY}, + }, + "crawler": { + "private": {"crt": SSL_TEST_CRAWLER_PRIVATE_CRT, "key": SSL_TEST_CRAWLER_PRIVATE_KEY}, + }, + "daemon": { + "private": {"crt": SSL_TEST_DAEMON_PRIVATE_CRT, "key": SSL_TEST_DAEMON_PRIVATE_KEY}, + }, + "introducer": { + "public": {"crt": SSL_TEST_INTRODUCER_PUBLIC_CRT, "key": SSL_TEST_INTRODUCER_PUBLIC_KEY}, + }, +} diff --git a/tests/util/ssl_certs_6.py b/tests/util/ssl_certs_6.py new file mode 100644 index 0000000000..3cb5205c14 --- /dev/null +++ b/tests/util/ssl_certs_6.py @@ -0,0 +1,684 @@ +from typing import Dict, Tuple + +SSL_TEST_PRIVATE_CA_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDKTCCAhGgAwIBAgIUD5VUdvJQlRhGJg2WJ+/K8I2sYZcwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMB4XDTIyMDMyMzE3MjkyN1oXDTMyMDMy +MDE3MjkyN1owRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8G +A1UECwwYT3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEA47sS3nsWACyhnX2pvqdSMSfDWyeF1t+kmVvap2hk22yA +oAM56XCtHifhP8Zu8nI8uumP7Bnh8sW4yqE1Tl/Y5gkYD57r4ZH9o5lj1FvnZnoJ +lERpCpgeR9Lpw6xqfoPt+9a/KR6mQ93AwqH6tyqSicl+7TTNp8UAdAN/oFnymQ3T +VcBXV30YgiX3GIYNvcV0f+hglgA3BsprZLJRuaCv9fLT8PlhCqrFyJ67XflT98nE +0pyaGIAEcvPCPQstAkcc9nnhmARkoAq7/3dsOWRr31paoWAnrSzXJtb+NWomlNEQ +ZADbNd68TIV40H6bcN45ff1nOfC78NJkXIjwdnFmuwIDAQABoxMwETAPBgNVHRMB +Af8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAnl8bxBpQL41lIPB/o1Fe629IK +pFpJDjLC8xyUZrcoZigEYZ+O06Kbc8W52n3awRlLgSMjPUjwb3JExhPW1JcL2DAJ +ARoiu5XDCoTVAADeUAyf60YfARlu9y+hRDUSgYrUknuvJ07fTobJ4JbpMvP/mI9T +ILNZNJZVcaSD4ectURKYkveGtm5R9F3LIO0gscEFgWkhrPeLjiU6Hm1uuZgjRW8C +o57vHwW4yfmiWaXb3dwIjh8SBMgv/g9iDZskIkTCfRBEp8jM4ZlCAII0sNejSLkG +NjUDOtD3AYD46mLU9uOUkv/ecDn13usCaJSnQ7RfO7S/yGZQEcNw+DHHQXbS +-----END CERTIFICATE----- +""" + +SSL_TEST_PRIVATE_CA_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpgIBAAKCAQEA47sS3nsWACyhnX2pvqdSMSfDWyeF1t+kmVvap2hk22yAoAM5 +6XCtHifhP8Zu8nI8uumP7Bnh8sW4yqE1Tl/Y5gkYD57r4ZH9o5lj1FvnZnoJlERp +CpgeR9Lpw6xqfoPt+9a/KR6mQ93AwqH6tyqSicl+7TTNp8UAdAN/oFnymQ3TVcBX +V30YgiX3GIYNvcV0f+hglgA3BsprZLJRuaCv9fLT8PlhCqrFyJ67XflT98nE0pya +GIAEcvPCPQstAkcc9nnhmARkoAq7/3dsOWRr31paoWAnrSzXJtb+NWomlNEQZADb +Nd68TIV40H6bcN45ff1nOfC78NJkXIjwdnFmuwIDAQABAoIBAQDbXQOTDaumpVdU +loyhGxngQbY7ozmYPruWAlYANl4Yw06vVAw/4orP5ohiX2nV3tbDEWLSgigVLAKS +JXFsuoT7KT1lJqd/FJrnMUVpdNHU868whClOzDM26mLFWtsGXV0r3rMrD9wGuaAJ +m/Ae6kJXuaGrKtcDSY/jMM+KjbpTVJ0iWVS2yQtOQffgOc2l9SXi7EwxIccBGrbF +H+a+JOZIbLsPMXwCzo1i0PMeAkG/FneqkCG7BEc2RWeQl6nzkoxANydlLLwnJmzG +Xd+UPAJo2TTRlkXpK06Jb/+wsPSpEq3Sim9IQQMHp8kxtFSjgr2sDG28g0SRfV/K +3RMX8A3xAoGBAP8qXGX8QNl4IbGJl786lk5cCzVlEzmCSgPcKVv7V6hPWknRUInO +rB4UbI66hFAK3SGJrs6+gyj/1GB4mM88TSdGJaifZnt4dekA3NZdZbrMINoIcS64 +KFGpFyFlj81zxwXyEDitchwYrkMEQ8Y+wO20lepCPoEuMnhbJ+kH22hTAoGBAOR5 +viyu7m1DU9qv5ZWhFoS1+tDT3g3zHsKSrrKz5sE07tPz5t9FQztKfflmv9jCurDq +C+Dro00v+WnxUQSuDYXNk9JXU0Ly+Z/Tt7S3AEZQkarjya/jkDECsEQJuuHtOo/C +Lc/req4PeG3IHqoAIwJR2lLoSmA1/bFkBqzwvZr5AoGBAJ75Rm3n1oNm/B7/aYKj +vsd9QyJ2IZ8f1HtJLJ95HajoH4mEFlh1Yfivot7dx9eSnSjq/fUi7taZZTjhidr7 +Z9pDMu02uoPMjjGn7u7Da8EQspsEzXddFwmhfp65Bvnq2yGSKZcWQNTOb6ujOZKG +wG6Ypxo3QXf8T0d7C4d89K6vAoGBAKbwxaJEl3ZCsayixbAVKi0CAyg/BotOz3UA +VKHCjaMymCdKmbEeHMff4DgxeZBaiKrn+JH52zJ1EVr1tmsi+kKAObiBkhbjDr5X +pm1nIc4+5JDnK+FW9264Ni8gpOqbuiR8j5jSyKsSJr6gcLdqrintwQa/MEkoahwJ +qE8JAKGRAoGBALTTp3skePMl/wCpdzvOqNMvJzoDV9xX1ttPCKF0pNOKMmFdSRib +8JN6dpRuQ5CugLYqNQgMExxgpytduGVRsALp/hKNo7MYCmLRsRAcSIe6YpgvnVYw +y+ufj7QhG3hCPBMCAC2YHLTAAAkzdiookyhTmtfWtSZJuZlUYgLsMQ9g +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_FULLNODE_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUI/qIR41vNfZrImHDASkbd5CdhdkwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyN1oYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQClBLYsg7P6WBNexxAiF04sCZN6saN+dI0Q/KAN1Rp2jfTX +nApvuNImoc2fozCViausJmEWKtx7RHQheDJmx+0LSpQ0fgdJJSNK5UVRme/pgVyE +/FACdD+fBuiasX1LoaBUqk7mpfeyQpfwKW5D1q3HgDK5ROmiaMe5VnMD0BvW/QYc +1T3TDuBLXYZpAg7c+fdqmBKx4wnE1v9PqChdUd2AQF2INdQuz3QOHGAQ+cJsXqvy +cwep0LvlK9/j9dy08qKFvc40EZwsYqOh0HT6KzUupVh80qhZxOz3QSok6gNhGpnI +JHOFvJ+i2P48Wb05dCiqBqYkEnNQ252b1l7o+grjAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQBYYc7lM9pM40R/SUMzhI4C +D59d0VMwKjTqXRy2ifrcZYVxmc9CAldj+nk04piXC+YxUihsIRSOxppd2I72lbo7 +bCRPxj0rYK/iNBlkzFwvVCQ2e/chcKcFOEcXzEpKGzVpL2GyLv/NpxH87hLLJwSG +FPGsMm5MznnMDuCX1ALedLFKyvMoy8SSg/+z7TNiblJxEabxgEADpC/pbkLnJvlv +qQBTPZk9LD02ZXivI624ltlQt92tqIUFZBfQXKe6WDjz2IzeeaYSlhTBKvqzXXXg +aUXnGR1lA3Q7dBaCPSNkUimOm0qT6t81DLkvoSyQu3P0OvKFCmZNLxDbxEO5LBAK +-----END CERTIFICATE----- +""" + +SSL_TEST_FULLNODE_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEApQS2LIOz+lgTXscQIhdOLAmTerGjfnSNEPygDdUado3015wK +b7jSJqHNn6MwlYmrrCZhFirce0R0IXgyZsftC0qUNH4HSSUjSuVFUZnv6YFchPxQ +AnQ/nwbomrF9S6GgVKpO5qX3skKX8CluQ9atx4AyuUTpomjHuVZzA9Ab1v0GHNU9 +0w7gS12GaQIO3Pn3apgSseMJxNb/T6goXVHdgEBdiDXULs90DhxgEPnCbF6r8nMH +qdC75Svf4/XctPKihb3ONBGcLGKjodB0+is1LqVYfNKoWcTs90EqJOoDYRqZyCRz +hbyfotj+PFm9OXQoqgamJBJzUNudm9Ze6PoK4wIDAQABAoIBAGKIOa7CxUiKJqbE +/eEdQVQSM7ljMFhlh4XJEliwEikQAk5rod+r3++pVXoomu3vUk5sbDQsS5JfAWiq +uI2eeu/vDCd7ySXnwvcJhyZ+YD5xO6k8bxnIB+UQ3vrfWA086NslBg+6sfgCw25n +jqt7GDCzX5Y4i7iqD/eeovZ34OexH+J6dE0rtlO6hblbnrk8jgJJU/CsK+fPybky +U/Dpls6AMEI/s/6sC7Ajieq4HN8lJpnOS03LD7Xo5XQRzHDHzKfryFP6y/Ng0lGn +H9WD1kRWtvQ2JAct9V2VTgNUFcdVGICqn01uiob+3jI/LyfWylMqhoPOJv/K7i3B +pmi+FIECgYEA0WIeWEAREuLvs2sFFdxkUbfzJpEVrPiVy57csc7+q/5db6fFd4nR +Arcr8VoFQcVbEzMLXcJQzV8lXJUacPetjwNh+91NUdM6dFRotG+AYc9Gb0wd/YMg +5PCyqwWQfRXHj7OLB2iQ7jI2oZSi+MSNLBuNZiPoP5D1qSvyJlY43JMCgYEAycH/ +/dWP8/ukyxcZuwf+qeseZ7StCprTXY1+eEm6ov8okegvUfPWXUSFp3vu7nUf+jQb +j3KyemkUcDmxNXNKsWGyxpdUG/2kmg0Mktky+ndVhXIKJ/bkiBFfZagxnIO5MyBU +BoD9Kr55dCw4BwIDQoQ8h5SjBuKcQNe6Atx3WnECgYEAprJHFltrPG4QB/ecBNuB +ws2Ad6Pqbds65vGDIsx5VNUd7lbTj2fZTyAli/DvXn2RFKf+1JZvXhHx3NOYSXfm +ZYV77NkzRYG1eAf7lCtxOm2a1eDzv3E2Lw6yMBYuAmfkiTOX7D4DpJ+1fs6nMQbK +neMRn8/Wh0URT639Cyh5/KECgYEAl1DorXd+f348GhU5NwzH8qhkJWNcZJe57nAw +agbh811rEAMTemNmYo0BsJtCl5VAZmauROfA9A3bRk/+mBff7SlY65iTfGq/CMrA +o2JC2ZamjW76Lv78ZxCge52pl7kzLSUR387eETDJ5ldDrf3UdA65VvYjTwamKfuh +hoPTAAECgYBp0yhXkzMrGtsTfiiKSWAGe0HSakvz8H3bQDuQnUw67iEH6FbMhRtZ +Pu/QTafLpAMKrtbDMuls+2pxf2BN294naZyB+fI0zAmefXtTjx23hxGoFnh3FEVx +eMX8OdBvkvk/Ifbfa8PqD9/bTQTcez+RkCnzANn04+h/tUCzJExfhA== +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_FULLNODE_PUBLIC_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUBJH2JfwoCndkFqwVE6FeUMjDVx4wDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyOFoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQClPnyntGjxicj7xn5m1Ujkgid5yz+/d/g6kdRTJt0Faeiz +oqm+9o0YUsLeKWSjOhjgcKGPh542JPzYqTaV531R8gIYJEDs9hGR3dbjmeu5RzVd +Ycv3Ru9BInMudjH5GeelUos0nT3OUJlb75QcNB2Q3miP2SfPcHNtGHa72VXCP7mN +zmiadi6gEJyPz32eBAh64CPoV177/sJqqlrFERmo+LyUgNNiTpFqwbKYIW2dCozG +3V/8dz25xQVvOMbVG7GnmRHXr6M6wTOefqsciOiGpPyfsTGfx++W+poGHrT1xqCL +IQNUVJZ+jip0BkWheR//bwe3RqCR/fCpbsd8CwTFAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQAP3lZ7n12+Qq96lT5Q28/m +rldsTbJguDNPxOQYx8rvZO21Bf3YjJZmqAFM0H6wBgQf7d0CBru+3NxlwZs9RiLf +bpThwzl+oWWVw9dxyYmcBl6RXf9DvisbIxKvQloUWjPAGfRS64qyOqjjFwBc5dlc +r9AOzgsN1pM7f52o5Ks5frq0vfO20lVbkvFb9TfzcuzRh0xNROlrAVK2q3XEaEab +nBTNTYt5kq8KYU+s0jstlPFF9gGx+NOXKfZmdKtOfribuPJIQ5ADvxGDaWEmQHhF +PlgF7Y0kmP/vUknuY8rwMrGi+cncaafO+GIiaBXDGxa92SNWe2J7RtRWDC5NF1en +-----END CERTIFICATE----- +""" + +SSL_TEST_FULLNODE_PUBLIC_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEApT58p7Ro8YnI+8Z+ZtVI5IInecs/v3f4OpHUUybdBWnos6Kp +vvaNGFLC3ilkozoY4HChj4eeNiT82Kk2led9UfICGCRA7PYRkd3W45nruUc1XWHL +90bvQSJzLnYx+RnnpVKLNJ09zlCZW++UHDQdkN5oj9knz3BzbRh2u9lVwj+5jc5o +mnYuoBCcj899ngQIeuAj6Fde+/7CaqpaxREZqPi8lIDTYk6RasGymCFtnQqMxt1f +/Hc9ucUFbzjG1Ruxp5kR16+jOsEznn6rHIjohqT8n7Exn8fvlvqaBh609cagiyED +VFSWfo4qdAZFoXkf/28Ht0agkf3wqW7HfAsExQIDAQABAoIBAQCEiL3KdLTHJdAB +wI6ZQ/AW9x1aXl5e34ZE07oMh1s2gF+X1Jt5Ap7gJ2EMdv60vGA/g5bRW+DVZI03 +6WBSkzy8gPKVEl7Qr/wflmJIYqfiDu8KWuoRBt/Wyh6/4STruo9E1hO4u3VbCOI4 +DswoYtRj4T7UQUPg6Txq//gbapGSHefwrZ5hH9A/YB01ouVafnSxxh33JqodIjqe +1uL1LInxF+ghmH8hlifP2xmD6O0Y9Y7kq+6715gLmz+UToGvLwrEiJoN5JLfbCnI +lw5z+1LDzlBfS2jlyZTg7nUQrJtTnlcg5oQdaaM5nDo+R2Cl/kU7/2Rir0sKIefF +Y32lvkfxAoGBANlyjRYTLuvsi5yQo+yrMspDiWHrIkJZgl8Zp7DAWPz6BwsOqLFw +EuBBE+OtTYokLDKsprrWPLNKafXAQrRdV3WfQuEvM5WMUK3qMGb3UX1L6S7iMa3u +46DPbk+TYkljLH82mvTmg595g9UyTJIEodfWzkNT4R69TtgtHb5kzR+bAoGBAMKK +iughFvrb9dnEOFnFgWTxfFt+SRzZmJQDhu50dvjKmSB1uvxHfswdX0sJINVqylOB +x74bCQVERGOrEwfcp7lqGHEvxHXsoKxo0A2pYvIPz8pSvkMHFU8ZMjhpukb8eSeq +SmGOB4I3FvoXxl6XQVIfNzKaCtWIpRyyaz3+xiMfAoGASdPNuR/8P1fJsvec4F7j +2K6Dd35o3FQdooJIYAd+by3ItGVeuxfNINyXjyao++z6IJ5j4W2ZoFn0jd6gBzLl +3eabw27OOckxH0sy8dKolTzvx94+dcp0+IVU86mbpkUIt4xnohydtciBDSKNwsnV +1T12PH+/IDuwCE+RGLKKvl8CgYAn7mAMvZ4F59hS1p/qbUvd+GNaNFW1gkR7PS4Z +C/bPomZD72ZuGg7AvtashDclF0JoWZ8yOkJjvlt7ScYiOvyCZnCV6wQcYHGqceki +pL4WiYBROyKqh22sSrOwOKNvpqsHpUCXPZv08nHY68Bf8hQKUzX1QQEwS1f4x/aT +RxRMaQKBgHfwK+DSGjtojrwo10CKYQ94ZDwPnviuIPcZfNQ+X/KxRY+wCl2ft3iC +H23dOdNZ52NDlRVXafCCI7FFhy50/jojJ4MupVX3pTQ3oDiHkii0eHt4NwgAzqm4 +Um7BAuOB20ogIzQd5Hozd2eQTI0AFs4Zd3yBxTgG2B6BHPSwvxjd +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_WALLET_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUT34idpoOlGXOYcUny2DMZVL5T4owDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyOFoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDCzGdbpwHSb2Cr1yhXKPZ2aCWtHEksIl7ao2UCDO+ljCb0 +n6PxHAbgVHKJ0vy7mC6Y1VXdstr4FS1Ak22V+4ceo1UW6Tsls4I9RunAjkfAl9J6 +CzKCVr31L6GvWhIjgQBkxswmYK9AFx3WbOQfz7kN46usBX3YgAWiUwBseOS8KBuh +EWfguDqxL8yyPHf6v5kWy2QyfwUBITuLQE6AanbLrkoT5bRrE+06X7+PeKidHzXx +b72fSvuJ7ERbNPiHmmVoila6kb3PegcKnKsm7d6Blg9MwCeOcvTXRrXsCFHlJnlZ +YWczAKAvtd/OJeTEC4de4UTuuyuDm2+00FUjVKITAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQAgc1DcbsLsxrKHZEoIENxp +2pB5LM2Kq284Pll7Ix5x7OH8JRenLLZCGMLK+AeW25UchHZ8iagHYR6tQrc+7CLI +piE6YKchJu340c3RONXcxDZUKqXBxalUyVcb3z8I/syiqsvDrE94hnGfp4X9Yg/M +7EIdv+I4y41qTxMD4HvVTcXVU5gapEC2mpOQ7mfN/rnIU1Gv6kpwG1FrnUyH+aP/ +2lpVSke8eSY59W4hThqZNf5cSGw/t95CBHigePoTqoD5MfmGhhrwGrjr9JHXVMpX +IUNgsbuPb6N5J7a63Ilgr+26X2ZC2zco7Ff5zKz1xKPMvLQ4tGBjm4rwQ1r7F4jH +-----END CERTIFICATE----- +""" + +SSL_TEST_WALLET_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAwsxnW6cB0m9gq9coVyj2dmglrRxJLCJe2qNlAgzvpYwm9J+j +8RwG4FRyidL8u5gumNVV3bLa+BUtQJNtlfuHHqNVFuk7JbOCPUbpwI5HwJfSegsy +gla99S+hr1oSI4EAZMbMJmCvQBcd1mzkH8+5DeOrrAV92IAFolMAbHjkvCgboRFn +4Lg6sS/Msjx3+r+ZFstkMn8FASE7i0BOgGp2y65KE+W0axPtOl+/j3ionR818W+9 +n0r7iexEWzT4h5plaIpWupG9z3oHCpyrJu3egZYPTMAnjnL010a17AhR5SZ5WWFn +MwCgL7XfziXkxAuHXuFE7rsrg5tvtNBVI1SiEwIDAQABAoIBAQCnQns85xlZZujK +o+OvcyysXqB7E16A1sI7WTDRoenja4PHZ4uM61O8KsZuMQtwyCq6b/NaeMgrW4OP +fwcJUP+j/vqAwaJXrNqXYtwyyfgyFipTQGoOIAzbChr6RYxtj8aWwVtpWHshvLeR +9c2qwuFSW7p76fs0ejhcOIiUmvlL1GTF8fWvZ8PibxcMEHbNaclx58rpWdBKOZpI +WXQ593AOGwufWX8EJFSdv+zjJs+JIIrVVOqLUMhww3B9SKRkYvMGABTRFY53U6Ru +ixR5jBRCrSdot5S7YIktZ+BoyZYDl4LNzcEsWv8KDqD35RbjRUXH6pPRD5xaTucZ +nKCGCGUBAoGBAOUyXq7KRqkrDlXpgvbkfI99ESS9rHCBa88SLjIKIdGszE1AIUVy +xHjXH/eYWQQ1u9ghqEgU0uyPcDbGwR2DiKnV6M9Y1RqOxgMVe7b02SjeIzqp+6zw +ZeqJsaaUPaRQFOG0gKSjpxA3FrQZO2HRnnUIZT7jmXXsCSMxcsYmuIVpAoGBANmU +Og7mag5iTgpsP38O+vHkCi9dXOif+20xI04Wuyt26EapPC3oNW3TwsDkCTX7ljpo +yI0yRQQgNUvPu/trsBaqDhTOXTaFCvH3+EA9SbXKKoFD7XiQ2iPJ5s/wv9aAsu/p +zpE8UI619RWx1NNp9qzPPYRaT5QQWbw0vG4ASBAbAoGAG/XQHSyqABszjYGGK45m +L68HN184OSVgvIswPYSE6apV5hqrtGgy1bcQvEjGmz/e4ZgBioGX1aoN+3C1wF76 +fhWNaDYjETFXsKqfRAuMrnKjA5YXENrm4/zWQkcVWgU29u3pP6yDRfQifegSGXXU +CdzzVP+5Cey4lKWEpe21VvkCgYBQscq+j/Ixl3/+GZuLEhE7+SlV27iDhiIHozvG +0GNmgVkwK7/n/sEiFHGcfHZ2EPLsgsQuqcAzAYcCsO61FoFeRn+mc8raV4lxqFfn +61MVGv+cpYbDOmXM9CqoYE+lzGGQ3RQBhW8THqThAO0/44LbIJleJuhwr4e4Z46i +9XPElQKBgQDZDFu6mSo2MdYpEQucOgJAaLrwyUPCD9Ja/Gd+Mdb+2AC1kovp6v6u +xg+COGdQaLddU1yWbxB39lKC42yi7AKDb24gCBRmyj5lsgaipnlQkGtNNK10MWg2 +ff90qGZpBO6tE4L/GMNsEcvQxxFGkbrTnU08Cp9mz8zJr47rlRoRig== +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_WALLET_PUBLIC_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUUFx52dcZRD27Ek1S8a4FJOg5WTwwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyOFoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQCvCRPBz1Wjq7GEdOtWDZUp0BTB4pTIuXP2F7bdAwPTJ7Pd +T6mjIPxM85E5sJL0pHvF49BZSFPm3OcrVv/4CHSZ9OV9aDGeioHZj5DdFZJDFv21 +0E02uZSDZBJ6b22zbA0dqq/wWm/s6J6dbypcW4895QeH/OqMU//A4dFPeDJzBf0b +1BVjt/1QsFoEymb2nPRd0Pi05ROhuEaM4QuNSmncaFucLnDnn2UE3OB/O5K8zfyG +hsXxJx3RwS+0SLAIbzde9GxQUbU3SS0CFHN9J+UbeOX+fIBOvPrQsWZwRdOveTFS +tcqiEe0InWYXIIsfBxfdI0JNrsSrKlwMAhITg7yfAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQAuBrB0tzL1s5Eaxv04bVeY +s2bktuk6zFw87kN9mJBEAQSkVAzx/5DfL/XT4uFhls3VyLOU2yMu7Vhxm2ZuMVXk +QdnhZ43T87lBnDBbZHd1NkrCY8UBqePB6cgA4JpmR1R8ypZmT6/V+POjqKGGwxJu +sxjF0f5VB78yJlPEoAnzYiqZUitZ1Lptq8K4ICORtN2yWG+dsq8Cv/dIvMOvEMpy +O6ozbk1qY0EaRuZAl7S/xghUq3QQOFZLQIkNGSJ5Q5xN1lqPJiDBinAjSb/r/zYn +edxjLvMjHDSLEfzyD9g1nmNq9z/8QsiYdc0mVMkkuvhXGDdCMOFmnZ0Zc3nPdvQ7 +-----END CERTIFICATE----- +""" + +SSL_TEST_WALLET_PUBLIC_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEArwkTwc9Vo6uxhHTrVg2VKdAUweKUyLlz9he23QMD0yez3U+p +oyD8TPORObCS9KR7xePQWUhT5tznK1b/+Ah0mfTlfWgxnoqB2Y+Q3RWSQxb9tdBN +NrmUg2QSem9ts2wNHaqv8Fpv7OienW8qXFuPPeUHh/zqjFP/wOHRT3gycwX9G9QV +Y7f9ULBaBMpm9pz0XdD4tOUTobhGjOELjUpp3GhbnC5w559lBNzgfzuSvM38hobF +8Scd0cEvtEiwCG83XvRsUFG1N0ktAhRzfSflG3jl/nyATrz60LFmcEXTr3kxUrXK +ohHtCJ1mFyCLHwcX3SNCTa7EqypcDAISE4O8nwIDAQABAoIBABWYkx14jWJyTqa/ +HkIxztOn3sfFQwI5D3uvlVpTgudMoL6Pk6iS6047RxHNHXSdzr+tygkaCXAUlVkd +lNtvf6N3OdFtR6H+CONk+USt4qvwbEFAgCZeY1qKwFTm5qwaisu8QZTwM5sRYHCg +RKO8kEHcvj8jD3Vc79NGiWK6u87BHAUp84GLLgyuju1aNaZ8n0NM+P6wEWxlduFU +l/yNoSJkQXAs8okIIA1yR1BGoCcgzXJnGY+WGglQpmSxWigay7mgg6odLoWGf2jh +eL7AsB389cgGm7xfxDj9cfh3lSnZJCbSDFcD2nl3DlgktrDq2JpndI3IL46hBp4i +rJnVPQECgYEA5EVznienuuGegGAod0Faaj9W+eEngZmikB0JaykRJpR9D9NsXXxM +P5iMAhbTl/HWh1ISXD5M8DOBdNYHHJS1sbxflWrHxR4yHqPboZw3sFUOEp6yyZ1K +5eGfXPEWm4s0w9hytC5YoLp+8DP8wqBdEtYLL/CNKRhukzwYmkYEtkECgYEAxEwm +0u/eYHOcBnnbJTDZwQTzjySAlyVPa2DaLlEtPfYhP93Uy74P7hh4e4yABwVxhO7p +rnES/NFDOMSOe2hsd8E4amknI76C2/xNaRP92we6jU/Rsw2HFbuqapFvPzApY+rm +mtGu/kEG2TKCOqvTUar2azmV8jtFZrGavR8Oet8CgYBQ8Yuw7jDc5Lo2nWJb/1GX +UUR/MOa4Xwk0/wbi99n8CzVZkkff0n6bInWrG/sF6xx+OY0HJpRTrH/gNTCqYtUW +5EwkiIu0CyQMl1//K4zXuyFVWu7c7Sis4VeINnkkyLT6KVtrJvAIdnkipdygCwtV +7Y5j/nGfu+khznKO6fsrwQKBgDcdbpUxVk3ciAVld3t0wN8qJbyeMiC+EBOFKR1y +G3LXRbSp81KVdeGTK1j9NQFDrQD3F9Or2fn0Q5yPy7WotzPUo6N1DNFDb3iW2aFU +RKWYAPAmZimQ9cnLXGj5lrO2MRjl3oO/thObbHHVda1Fi1rV1sR6cbiGndDcsybA +ro8fAoGBAMreL4+KxIzdIBQ36bN70pxqUYREoeT+d3AUFhfFyYaH0U0PFXOf/XtO +kC7k75CYwsLiarYne531tuo6AvY39aDePK6D0uHF4BqI/PZ/rsIKOVAkUhWSNDU2 +b4NkEZRl1ejdxk/PjGR8oH+9S1X4Y1+kzJKpqt/k96Uct2eSxiQM +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_FARMER_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUR15D8Dk0zvppH7mRgS1FK1xRwf8wDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyOFoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC+v0wEABCQFqugGlVovy1kKU9YYWmPmK431Z2Gm8CECi6Q +GujhMJ4WYp9g/NhGcP7U6uQnuI1Ab0paDkPW4mMhqpfrrFE+dy0q+G/vlJZnD32U +BvAPHHd6z8QBJ3bM9t1mMZMPwi7iCadwQMDHaz+DOLC9EJO1FhsATAw8FLri8lJz +Acvs7LUwbRqoDn+7gR5lFg+kxSkEr/E0rVQZW27n+5nDE7lwU15O4czbczN+z1jA +ELSn/wJOFNyVsrDANALQ7ibHafWzk7T5wWDUyMsOSOd+E3uYz+myOJej9XpfwL2q +ANPkt8sa9XmJwiG2O/O45Lt/6nsjJzQbVuOW6jcHAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQAqb3wJxEyRg3Z4UFzufrmK +WeWqEOCndJj5l3ppvf3yVW2VMoiqVssnfhtQ6LXJUZrl2qrkAYE0LFlWLpr9DQPG +i0Atr3dFH6+6f41pMe4GX2uusR/MdmRoU1mF2TpjxgkS8B5Q2aB23h/q6SR4n4bR +SWO7i3ARFljj9iAMVTOqrpyWbb+wuGWav709BqAXM7ZUYga6ifKaxL7ahr7K7HTY +yXbmisTBUY4yT7RYfvau1GyT93fU7K8cdtXBDHUBpVOWUJFQBHPKVKRivO7DkDTR +sPcphGcNjvGSNqjwGmN4Hzp+WC5/uJahRlhL7Y3+v3pfIeGUnOSatau6UuJpXNl1 +-----END CERTIFICATE----- +""" + +SSL_TEST_FARMER_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEAvr9MBAAQkBaroBpVaL8tZClPWGFpj5iuN9WdhpvAhAoukBro +4TCeFmKfYPzYRnD+1OrkJ7iNQG9KWg5D1uJjIaqX66xRPnctKvhv75SWZw99lAbw +Dxx3es/EASd2zPbdZjGTD8Iu4gmncEDAx2s/gziwvRCTtRYbAEwMPBS64vJScwHL +7Oy1MG0aqA5/u4EeZRYPpMUpBK/xNK1UGVtu5/uZwxO5cFNeTuHM23Mzfs9YwBC0 +p/8CThTclbKwwDQC0O4mx2n1s5O0+cFg1MjLDkjnfhN7mM/psjiXo/V6X8C9qgDT +5LfLGvV5icIhtjvzuOS7f+p7Iyc0G1bjluo3BwIDAQABAoIBAQCK62N/XlSxu/EO +z174xJNYaUWiRn/M1xO7ElaBnJmfEJNM3GxS5UedYgJVbpBM7SqLAu9bhmtJTERI +Ri9eJs6vzECMoZkh90XsD7fmMr8/G+cHke3v83mI9hv4AzfgmsIwFVbXmULv2Lwb +Yu2DzzYYaYc+iv4oWosbskcO0sIxWax7UffFAM6fw1SYboL4ubxQrCYJKMvSCPE7 +tDtuvndO1tr3EFrAo84E5KuPFRR1ncaI07FPC2H7tK8qMf8N/ks9CNxA7jmnPS5L +yaIoNtwk4i1rFTVzZY4hPQD5cN/b947XEMiWSZtcKF8W9La2vbjcJk2U6dTQUre2 +4ej1dx1BAoGBAOKrQ8jFjB/eeQ7OnrKsyh+Fk52F0qEOWdnh/OmZ0BVPrt1R4Rtc +hEbYk4Q614AlHApiSP/SnQ0vtBx/C0If46ATRmh76hsmqeH0dK2FHNgih2IYsXdM +T+AiZDzhTrNdSiZu6ZiegeQeNUhx2dbJfLIaEbP0l/A9xPmrrjxaZCRxAoGBANdu +EqG/VTxxnqLNEsIWfPT4SVTXAfOHOMyxFvMJe8Nrqe7yAuIfybw/JNJHE8J7grvB +0aZLYwDTo6kmQW7cviNIkcc7TJCUczJjqlu0XxEIcu70J+1cel2Ekh/2l6qyUG4y +WaputvX2pgWcFiyBhIG0SGfjPn7Izzmk/th6Cu73AoGAWDkYtPhOxcitjZnWIu0l +7obrIZCInq8bQba33aREXUcaZIIN/7xOr9Rz9i+A2RuYgmImz4uGHS/IBp9cHmyT +CCb4bIpuYAr4bD3de/wncehekUvTJv/IxxAbu6ZmH2HcDoF04jYvkD5BtuS5SOQ7 +aIbFBSnaSWOBWzv7IPp9p8ECgYEAmu/BWq8fAE+/BdtzqD9AM3b2Vpwj/R+9jAm5 +NaYWat/d4coQpMyz7D2Fn+4amf72cU7eFzmUxJ1x0U+AM9lyrjGdFqrhUAJUL2Na +vIWm8bsf3hefN6kRIH0eEvro7Y09J2Py9Q6Xa6KumM4/bFbiE96zTHQ1GD4YO58c +4lgz0NUCgYEA3vVVE9JMVlN/KXW0rrw5WHCX3PpYhs3ohvXinur1vHSNdYi+thHp +QoyG/jA2t1jVQlrsbe245QNXzoh+2mZKtzEukY2B7ivoszSF0k5P8CK52efof6Ss +nejt8xMdtQlTxcFx2EOnsvPjn3nmMMuye4bUsZPprPqNrDtzkzJVccQ= +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_FARMER_PUBLIC_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUbNfOeBL5Eg+Tt37NytSIPVDVDKowDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyOFoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDdwdMrIMRVxTYSO0s1krlXy/sAk/BYSKWEUIe6Htzc2GGn +gAVNdvOiVsXc+T213Euw7yvBb0pfRUmS5f1O+uWZespgDTsZUy0SJYOuHhGFmI9I +UelOX6Oy8fRDWVz8lovFKRcr2ytywXTAb1mTGad7VHwPW3DlnE/xeAfmLPjENQxy +qiUjxqgqK1U+mdhxIxMg5hScsFjWdZDvngKzH0bojgicnKwWAymG7eJDd31TFQ3d +Cs0SNPzXmNAOKCRkiAMgaln3hG3FXASQbl09JvEdYPpxcJXUePxBIXh6D8KhkAGS +LoFq4uXSw4cm1fMO/TGHtZgVOFS9+EprA8L2KSjpAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQC3ZKaUzSnUlaeNCdUvyRL4 +RYVbzr5RuUPL085/JEtSpXUF7cZPMbpvpw/EWIUp+EPVG8h4/89F4L67MmHwCxgU +VwL2N87lk0b+TpOkLO93mO8gIGy7jJuIvDGqhWS13ocKI0Mm5Gl7n3zPS7pbqj2Z +F82nU6532WK16UBiYBYa4k+ZG4puYXpJc33/M8eiUQK5eY3sUL//OTJVz6WO8vCd +QVUn3+FwKZSJIaMaosKgb1SdHSqeti9RDNdQ44k6bfklZoz/NLOXi3bGUOt7RUp+ +PEWLB7UnsI5qUY8aUU6g7PE3qt96dTy/9c+NTcpEnHj20wykofuPkaZOgDNgx51X +-----END CERTIFICATE----- +""" + +SSL_TEST_FARMER_PUBLIC_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEA3cHTKyDEVcU2EjtLNZK5V8v7AJPwWEilhFCHuh7c3Nhhp4AF +TXbzolbF3Pk9tdxLsO8rwW9KX0VJkuX9TvrlmXrKYA07GVMtEiWDrh4RhZiPSFHp +Tl+jsvH0Q1lc/JaLxSkXK9srcsF0wG9Zkxmne1R8D1tw5ZxP8XgH5iz4xDUMcqol +I8aoKitVPpnYcSMTIOYUnLBY1nWQ754Csx9G6I4InJysFgMphu3iQ3d9UxUN3QrN +EjT815jQDigkZIgDIGpZ94RtxVwEkG5dPSbxHWD6cXCV1Hj8QSF4eg/CoZABki6B +auLl0sOHJtXzDv0xh7WYFThUvfhKawPC9iko6QIDAQABAoIBAFMzntRGpgN8S85J +Wu2N0GaFjPZpizrEfv2G7XXCkKF3uiQLX3HyGHUnU3OWPDYYonmPMv6Pj/rw1yr7 +ia/xaOXN8VJahHr6/yUY2DAi7fYPCGtc+ElEjvnb2AbQ55eJsIVX5m64+7NBrFlr +LdOIQ5N9XlKwv0oW/NOfcm9FHk0W23qsFG6+lsPnGuCCvzJrzz2OxFsGhRD66e0L +3Zv4xMjxIKV2nHyI8Ca/rWgQnYJ465TWMbz8qfIcH7FKK2T7/poajaOBqiVQ0FvQ +JxU5LPoCDfqN1IQxt354KhOEy33a8vOlt6NkbN+0BUdB6Mw5JPTg1I6EVMKwZMlr +lN98wbUCgYEA7u4p8+WM16VoUWmwu+4C/GNziQdg7sDFD5sALARgaAle8ql+/pU2 +v4PbgY0H7AQ4YdLQkMG9k/JyitL1uIcdt9I3NErWahFZsxu6uMa6loqERW1/1JZa ++yJbDQk0s3P4XxJ16XEB9RHVpjM4K+70I2Hj6wBZ/KCABPJ9+lMkGGsCgYEA7ZmT +2Pf7RPZZUBDx/BcRXvgFQp0UBzcUCW+gEfcmuXUFsfxpEML3p6jkYTG5exmiu74V +JSMfJQbxgjx/8jV6qjEWrOI19ONmrLwAn6YSi4kTSFOzy/nunbO90yZS1EPWHTgt +1KwIpVV3YQwx8unAj3w+ioNKW2pNdKqgruD9qPsCgYEAoRnrJa2oupqn7QUDiqOg +VcdE1qcn/7Pw62XKxuMokd2HrL0GiOfZY2an8gFCzyvFTIhV4tUPW5tFCj/WONa5 +/gD7AgJX8mrCfZb73qz4kJrTNvDvGUtMCzsOA4sqgrl2RbxvzrhI5pJg6VBt1omn +CdhuUj0Jb+JUj4Fl2gyHMQMCgYBbKzHS8BxnMsvEcCwaGdPdh/ekvtcfiZ/TmxRl +sFsYkHGWAQ9jkhwrJiAztzu/o2+Q8Hf2nwplT8u9uG8zxheCVIGp5sbjZ5pPL3hh +yfyVtAxFFXEJFKbdtklhSvQ/ZKQ05AiZ8UUEA85h26cS2WS86eSpi4UtnJWJ7aro +T4alnwKBgGQfkEQvkthUo1xwkYQEgbJzk5aunQ3aZ0467L/kkEJZ2SknAXKLURin +uErwhm3wgKHMCy3p5SLU7uv1BihG6nNvLuskrD6mAkUPBMJmXCX1NEIBLwcMM4YH +H7IipX9XJOjCnauv9AsChOkz9pgG4/0BaaxkQ/Cm/zKm+wUXIfUx +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_HARVESTER_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUZGh0kY4W3yL0nzJVIYYmCTQM0LwwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyOFoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDVy8kOTXSTWhLK3BILK95b5/tY1dq7ARqrv4tVDWcXuyGV +vPPNj2BibF3Iv+4Gr/6XeZEWmH2ybbEKrAws9aBIw7ETQhTNjoBlEvkoKvISBkkR +KaQ3lUQ0Km0BONsdSwxkgcgzn61TeSOlWgpOuW8EOXZNSEUJTxp82GbbdVH1TAXH +28oxUvrV/hPltxuQJ+3tcqN78VD2cGPwp4+RNYwklG04Jcj97wjv6v41jVrQ8IR2 +k5GYuI8f9V6y1zw45A4XasZDb1/UmKk5cROSI/nJgOqZLmAhjK6eQMx1XqPYm2B/ +e5J7V2nrOVhsasddwNH8fx+QhBz8cZwd7uK17oWdAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQCpby2yro0LmC4xuhhuqs8q +pn4r6E5i5QTDHa5uVZ/GtNgYDP7x5MsSaWcVFHsq5TONiQY8rFg3iTMfoQTqvVqg ++4Eyopx/b7a8SryImxJXNVCNnY2GZ9DQIojYxDqiqsqDpIlgeR7FRCrjdy0W+5h3 +Icbugg7sDeLYnerD9RAQciuClMC8jgAUc8LWXvI715kxTbrr2//8wu0YpfBLHln7 +zL3zdyKcaAnqvbBx1FHgj4YI6ozfdpqYX88Uj4aeirCzHzT3QQGoAHXoDLFdg2yX +s44rft3s9/+MKiFdcvaxVkh5UIajc2q2ZZJ/mqdRtW/paO9cv+aNSdgPoRcn9hzb +-----END CERTIFICATE----- +""" + +SSL_TEST_HARVESTER_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA1cvJDk10k1oSytwSCyveW+f7WNXauwEaq7+LVQ1nF7shlbzz +zY9gYmxdyL/uBq/+l3mRFph9sm2xCqwMLPWgSMOxE0IUzY6AZRL5KCryEgZJESmk +N5VENCptATjbHUsMZIHIM5+tU3kjpVoKTrlvBDl2TUhFCU8afNhm23VR9UwFx9vK +MVL61f4T5bcbkCft7XKje/FQ9nBj8KePkTWMJJRtOCXI/e8I7+r+NY1a0PCEdpOR +mLiPH/Vestc8OOQOF2rGQ29f1JipOXETkiP5yYDqmS5gIYyunkDMdV6j2Jtgf3uS +e1dp6zlYbGrHXcDR/H8fkIQc/HGcHe7ite6FnQIDAQABAoIBAGzlaJotX5RyS6Ii +J9qi1JaReZfNDaU0scYLQUfoFLukqD2hybjJL7nSIo7PG8kyOYYj+H++2j9Y2dVq +vqTj02lcq8P4Y6ozzDgvStNn1HbT1sG0KR3anKvJdE4sDIdGI6DJ7hRFX75ltH9T +dm6UyvQm5JgGmIteTEqM2w8rGbzLtsg6SakuNoyGSL17wlc6GmYiO1N383KZaaqR +yfKz0yQDRIzHiGv9bQP53uPNZv0YL0+LJQg8lNGyq8+grwslT89zMw81pnCcWEjJ +Bm3g+97tyIzxBW3CBh3KCfAtggrYNZ0BAvC+Hh0+mExQSEJOK5Xh06r/OnUYLcKK +JTeK3CECgYEA7W/aWfOXwLz18qt4AqYSBWV8/MzAj2UGPvbHbyM/y5FOpBNHWRge +vwrCgLXWAFLYnSrbLs+7CcLdlURGo5aAT0Xfxefa2MKUK9HVBLGjzQAhL+g1Z7KU +RibPgxcxf9rEE0bfS59AamD9y3psRm6yzqfatYvvAQeMy8aKx30hGHUCgYEA5oLG +eNuHxRICGZNbV/4Hgj1dn9Sc+28wVU50Km0aT82rTddH2K7xX3EqN3+bS0npdOwB +2c47MeRJWwa0/QII+5MOPNcbhz6pHy6WhPkfbphjBfURtTlInJ4QBbe5Zdm7uGTs +zVSXyQ5vA2bhkGHlLR5pTf8hbQ/UipAglRXQ04kCgYAbMZ5egwm0Z2/71Suvkfmq +aI9CHOlJAxcOCxGYZv8df4z0OckIKT0MQF06hJj3/IUWqxvjZqNTYOAkAmfcwJX9 +flE8x2tHPDHgOu4c1YOfLQ6gAAZt1AQrbLKDnxpqPFIMqydT7+9ev7ERpvnTr0YH +aS4hcN90zLqRdDHc2zX5KQKBgQCU9aeqTDtlp6iBvI8Hwto5WMyaz7uOZCD4z5UU +IaMiNQdhayA7r3m9spSUfrrtIVtjOmxLwxDPwfWBhEkLQvhpEnPd7ygT8vM5elK8 +pXyhbIp5PBBwaw84XpB+EWcWoWjE1TuNyP+5ZsFokmBrfEesK33jcF66asNvs4nK +relf+QKBgQDREMabtiYvEmJhG+oVnqcWCpQnYetgrUYeXKj0sOeRvC15XRSt0Jh5 +TjxpY3OV37lvXDi9QCst2akbKxahzP4CDX1//RQsT2fgzLK5yc6xmPm5hdLb0EtR +K3WDy96qj7+5xWNpqSGollLAFxXmdZ4NOrnU3mMHxsLDYe0+9diGQQ== +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_TIMELORD_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUBingUaQUNXQpmRUh3SWSFMUaSqkwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyOFoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDTqgBgTsNxYUYJrT8MLFe8Myww/wTuLUhZWTkCqGzQ7grt +BPV1d5BTN2gthV1sltE3pjVowQrakbhnYyKQtxkuuaL2j+99cd1ZAC7BopxnDgnw +wNp7lkwsuV9de5GcykCz5wLzkfj5webvaOWsYptahtFkAv2Q2EgeXp8ZK7xoiW9p +uTZ/74+7i+FqY4M3DcM7/RATcQTtKW8qvqF3oFUXlFxZb7j0UMjqPGfzjP0ccze2 +zKxes1lgcic8TzCHWztOC4sYpSEfK/djDv2vSVjBBsGOWK+hi8rDCmoOKJonO9Fc +iw431LSHlvVyhg73Xp3HmBz+92IY1/EtJDrMGooHAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQCpHVgrVBHGBx+s+CllkVJS +re1AACf94K1PUrnCe3nSPIjsjlauMO1vJEg39XnOdxz1GIj0ZxPVoanRWjJWRC6E +TGivunOZzfREEFrMmvxO/azlgLn2VjhPxXxgyvyhjVE1ZUTabuNCMQtvwvon79Ko +TX0Na8Rkkdx23TPR33YIkQXeGnFHY3Cikc8UiXPus7LMMP89PmVh7ACi4t5v+DRu +CImEvP+jr18Sjhul9aA+CtL5PFPzn8bWlROCAgGI7GZPMhJvugCusHHWSzG8UblK +hWV8Aa5CTndzTOya2regyeZyy/ftXEmjqKjKSH5kfL83MI5MWr7AJMJ2oeEoC1W0 +-----END CERTIFICATE----- +""" + +SSL_TEST_TIMELORD_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA06oAYE7DcWFGCa0/DCxXvDMsMP8E7i1IWVk5Aqhs0O4K7QT1 +dXeQUzdoLYVdbJbRN6Y1aMEK2pG4Z2MikLcZLrmi9o/vfXHdWQAuwaKcZw4J8MDa +e5ZMLLlfXXuRnMpAs+cC85H4+cHm72jlrGKbWobRZAL9kNhIHl6fGSu8aIlvabk2 +f++Pu4vhamODNw3DO/0QE3EE7SlvKr6hd6BVF5RcWW+49FDI6jxn84z9HHM3tsys +XrNZYHInPE8wh1s7TguLGKUhHyv3Yw79r0lYwQbBjlivoYvKwwpqDiiaJzvRXIsO +N9S0h5b1coYO916dx5gc/vdiGNfxLSQ6zBqKBwIDAQABAoIBAER9H74J/meziAwd +iOcReholnMkF27yN3nk6y522je9U9ygWkK4/z+19YjJIkyBN9MjC+Uk6HZ73w+mA +RHD7LiTWYIrTrDS1IWBpFLgHPACEpGbIoGmZCnD2UotXLpjDQQh1WZkixKNcQLN7 +B8Yt6gLy2NI5vX6e3UcmauikJETWjMm2CBa4O5s0sKl/ZtzCUrzy4osyDdaOwpHW +2vPTHNgTVkETlI9UZehqC6iXOsOGzZR2lpcY9KGoS9rXAnc31tfRCfolyHvKHm/I +YCEFLzLypHp48hI5qgikkBhJFC9GnvOWJtvz9XQlkUahBIGx+xRSvNXHZS/OVPqG +dYZJp2ECgYEA+AttR6dXwChtGNjEwOI/F2X3RzBKMxS7tLaqEGD1SYTM3y/Fz7FY +aqiE5052Q5CXJj7juVB1YMfPXhq6ae6wCFqjZC9mzc6DhDs9NZ8Vx4sCsIZQI6uO +DAR9P4FyXW8mMAijN8oRQb4dkyk9NgWJ+1lA83cYAXWn6hGDHvT8cH8CgYEA2nPf +Hi8AOu0aDYWrBRyobttWvvy8t8+JT7qvRcyLgUL05mblKkt7QzrJuv5WvRYdMhiQ +Fh3eaXZpmBrb0O1jAeTlzOlkJtKYJlq0l6My9gLVEJuDN2TjZpcqSYQswUQWImx+ +wc71MUI03rLQnsXbuTgpzjxSp2nZ5XDRCMHnonkCgYBUz1NmFImkYi4rOLLNYI5B +6dNKu/Ai1wv3Fh2/y+cSZB3IkgUIppKcpVIL5H/7SgzkPsyOKDx6AtecTXc/kSUP +Ni53qt1zsRC2vaqIEwTXXWhmAwaTq6y93ysT86au27oq4kksYiLUX7StBISxW+N5 +1WKn3CiRFzF6jtJOW2WU8QKBgQCPew2wAITxLywud34VlHYYod3/AXdeb2Srxl06 +xhdW5kh+UFTyi7NBPAql1EnaVf0FG1b//8xGjqzaZ8G7H0ApTVOWXDEYwreGcYsu +EdX1+XRCPTJZHt2xU1ZGBRd0NSkooQQ8fZdULD0XjHEz55bit73VpI9RQFgKuCfD +zcA7WQKBgQCTBD1+CnwFHqrgp4tSjz+4kgclI89Hf+K0wSzi9hL5I4uvaJRvfVVD +mNs+eID0NbRALpNc9M+P6+EBdYFsSMdcOEeV672DFEukdy7e2ldbiQ221yTU3mSs +SHfBOBR7KJ6cmreUG9Cj9QLdsBuF2FEPfrzpP/YX/d7z/OdmStbX8w== +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_TIMELORD_PUBLIC_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUcWOy/+2e2VlxzEedhpSZS3UdmKUwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyOFoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDHS48UM5B+l3SpuKg1ZncimLWwOSyHyCASgN1dTFhFMW7/ +WN1hGGrB/2lw8CAdEBb1y+i2+PHo/HQq+2tn6GmT3744GnwS3vZOqvhN0LBA4Eg8 +DtE6utFBb4TZKcU2GQqGOHS3BdewXcVdoMfzM4IslqmHaQOXiqVwMrCGjiVKzF2l +SFzZdIsUBFiwSv02ZvWKhb0IbTsm7YK4NTGYKZxP4fsTHHZeBICjL2GEKlkXx47Z +JwthnpxB1AgeIdD+6tp8oCGPZxzd4lJxxTV385WH9zFg7jSp6poAOETra8ZnnceT +YgfHVvY5PEiKB+uZzMiPf9VIoVE3KwhW7JLWktnZAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQDGEr3k2P9Z4lOIwghhuVRf +T0YYzq39Vd/cDpQ/v1Ohs5kMdAEP/sDt5JWamtNLkbUDhbdgrE4Z5uKd2zTmL8Nb +aiT4vJ8E9hYYEheatE0qNJl0v3qxhz2mDGDfuYxGPPnssuxr/6cGWA2u1FasInYo +obLx7tBB3HNgKAtqSJZSwAMAhebJataR3REtkmBkn8s9zaTczwGsavH4AFit9ipB +oXkddyfvr5Ogpo1BEydLIOCv1c94zh9yI4gn9/Gz1uEgQZq6xg+A1VV4p3Oy0LWf +4OjEohsV2dX8KMVbVJwht4HiTv58M+iL9kxvcYe2Ao/z6CnvObxiFgD0eVZjNsVq +-----END CERTIFICATE----- +""" + +SSL_TEST_TIMELORD_PUBLIC_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEAx0uPFDOQfpd0qbioNWZ3Ipi1sDksh8ggEoDdXUxYRTFu/1jd +YRhqwf9pcPAgHRAW9cvotvjx6Px0KvtrZ+hpk9++OBp8Et72Tqr4TdCwQOBIPA7R +OrrRQW+E2SnFNhkKhjh0twXXsF3FXaDH8zOCLJaph2kDl4qlcDKwho4lSsxdpUhc +2XSLFARYsEr9Nmb1ioW9CG07Ju2CuDUxmCmcT+H7Exx2XgSAoy9hhCpZF8eO2ScL +YZ6cQdQIHiHQ/urafKAhj2cc3eJSccU1d/OVh/cxYO40qeqaADhE62vGZ53Hk2IH +x1b2OTxIigfrmczIj3/VSKFRNysIVuyS1pLZ2QIDAQABAoIBAHfJS4tp3tyn7gAh +NEE8gDj0LqhoBQLr35Mfj24HeDrGlp+16wH0Kh7GhLrUKYkuZY6BbDOl98kBDFXV +Xl5LDEJMRkn0aUTybHsmOi6TU4z7AY/PnCS/qwy4mdHpUFbOwEuiXUywn06rXfiD +rgrYl9JzEByKmxUXyY5heUa242VL1YxVgKhtU41cTxo8TaaZ9mhQdjnMY09piuKe +Nb1pK5TzjIl/ci9VXp/JWtOcES+EGNLlboQydZAM6RXC9/GQKcdA39bibq/nLg1b +u2ha4NQPkxYUI3Qlzjz0X+uPvIr6vUHsvzUo5e6GFhVM3tm26iGtojogrP83/c6u +p12TDgECgYEA++fbGx/5q1Qhf5bbEZykseTmbOk+Qm969IEYpcDS2ENGVntc/zpf +xbwonZJB3gk1P9YWfOF0wR3IueG13D4cifRbSCfW8gkT9DzeNJO2QXsOFM96lb7r ++oUXIYqecno5T0V0Rhs4miIoj+M5owJiJcQHEbolKblFEWoKLb7AAxkCgYEAyojM +SM1mO8bT8WU4AQ3kGq0Bhy3fpQtAmkoOKWkcYsWwzOLMQDl9RM11r3k3ha92zzQn +8z5Dq+CMreO/7k2AO+iPQUxbVxSWcDfeBgFzUgRDrhGfVfInn1BFeyqTu8achZV9 +FVwg/b+qhNbnoOOL9qjsw6LYyG6w2uDEbzeJJMECgYASEb6QwolpNb61ZT/Pkpnp +vM6ej1iM8Wwzb7Mx6JP3OVQpTe4MzMYj6+xJ6TzaTXTJYHT6fj2ewKEuXDdsVfQ8 +HRATK/BqKiaJRXh28wWGyunmqj9T0H8i2Dshh8z3zzafLg86HCfCPqMENztiKwCZ +Tudm6SBTTtvadO3H/D/PuQKBgHM4yB9S2yp+vuzCDM5svKyAaDIjYuxeLm6YWt4s +Mj3vAdpN3K1dB2sxCBa/+1pOrGTM4z162rzZjq8Oto44ARAUCgu4CO7Ng5hr8B+y +i4zJaEeLNv6KOQhlfmHHoyxcnYdRuEuCkjJJ7BSOvk/FpEa7a5cQ+gttDag33wj2 +q0sBAoGAchejiA7NRNoudW5Nj5AZz5Lao2mY5VABIQEe3fbZKmNN8whsDul0bpEi +AboLaJVCj71HEwBKEPGcqgK9eAWRJqgmkZXQm1nXjmJeFo4PF98L98TBsM7JxnBr +IDrNl1cpFWosD7XWnabJnVLZ3ZfRbXHE1egjnTjtJ9fQhlI9Du8= +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_CRAWLER_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUDNXuwE8yqviMvf47HApsgcMIG6kwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyOFoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC4r+RhnufHjAar0Rj+PEnVQFi2DtJGOVh4u96xaEbiY2EJ +3Z+jZG+pV2ivKfKZJiVCWsMa/XZ9GoDckAM/7/BACMozRYdBXGXJQ8luOaBLh6oy +w+nCMQ7zs6J3meJKm8AXiEpq6y7AGJ2P0EcG5qY7jiKqkNckFvJayuJ7mt9DGxS8 +OCNu0ja4waEtcVsMerM11zl4hQAxpm/+zRbTeRdHe6jY7Oxg3/V5e7W9kj6klzAt +LEFq3GNqztXlxEvnNCf2ItJ4RZ6P6dzho7hKQjIICkmzBrApcEZAj2Rhr47q2Prx +Ztw9E3iBTc3qpRkadbhQAtXUHDxTX/wUUzXgkBfXAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQDH2bDcb+NYjee2vV48E2Bc +16MvrBDfgQLA9Nv6oczcE2yfD1qOQTnoLs40QtKhDq2PMivTLSS+x6pstg0R63bH +7cCbWtGOYRDsjbjqTHwAFczQCgxZA3uKUeTaOv5M1jhQ4oP7Oz/oQv4yH7Fv9T0j +QOyCHe+CnLDP5VY0+3UWDSudCDIBWD/BxvsCBva+dstPfz3heIDciGiCRqrSXCh8 +ROiBKUh1TaASOtcIKYIJfrLFs5zpHT0zZSppKQcxPeKimCR5q4ZC+CuPXMJzvzrX +xPlO7OvgQ6dJE1/nOnXdXvl085ycWrrefNb7IvJ2Oc2/yB0957jbm0+13tuikXgG +-----END CERTIFICATE----- +""" + +SSL_TEST_CRAWLER_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAuK/kYZ7nx4wGq9EY/jxJ1UBYtg7SRjlYeLvesWhG4mNhCd2f +o2RvqVdorynymSYlQlrDGv12fRqA3JADP+/wQAjKM0WHQVxlyUPJbjmgS4eqMsPp +wjEO87Oid5niSpvAF4hKausuwBidj9BHBuamO44iqpDXJBbyWsrie5rfQxsUvDgj +btI2uMGhLXFbDHqzNdc5eIUAMaZv/s0W03kXR3uo2OzsYN/1eXu1vZI+pJcwLSxB +atxjas7V5cRL5zQn9iLSeEWej+nc4aO4SkIyCApJswawKXBGQI9kYa+O6tj68Wbc +PRN4gU3N6qUZGnW4UALV1Bw8U1/8FFM14JAX1wIDAQABAoIBAQC1MsVETe6jpitp +aXY3AZmC42XmATam9V5q3hAISQG63bv4PPuCCGlRYNPxf5toTLejmX7wvRsCdP1W +6Oh3U4aInNcdZKrmIqwuwhYf0eQGFq2Srwpqn01HJshQxabygkr+C5bPvbyZdc0o +qzT0fVk89x/l7sNVwjm3gHSixvkjUQKBxDwVDVLbNJLdeN6LIkep2PJoZCi8R441 +ySR1GkMlJjpCCkrv35/syAQpevbdM+7wBnuZkgfnzE7ECNKPvSMtTcgSf7Gs+943 +ydMau+e7sL+uDME2EIq0cveNceMQaHn6mYr2PVULsD6Sp42YlJWWZCgO053jPQxd ++qKREFZBAoGBAPGt0E5nN+FCsRXgYI3dAD9HOqjp2NjVF+qUtnHIw/rRnfsxPhSg +dQxjDMrBc0bYk5vim7q3Kd5W59ElSLFBjeUIbE+41dlJot99D25eD54ipWZqWJ89 +410y9O8/BOlmAalrlWmFUPvrIo/afVt4KbfZShvtCYkVHU5Uu7+LKmYhAoGBAMOh +iAGl6eP5KJBLJMe1ANNt7imVxOCzsEDryP2SPUk2tBpapxRCoYtHv0NFORKXUSX3 +g86eJL2EzFIvTHta4ksWs5xb6RdTET+CZlcA2FZik0kb50URt5R24HhwNuvSP9ET +E31E9n2V+gX5OtaqHJUqRpf2FY9Y9LyF9PebWc73AoGAHoP24F9yE9RK7ds19dOo +21SQGJHmWoKVkX4Th0x1Sm87RmNSVmJoRRcgn11Lw+9GvBEh3rKP684HWUYe5prD +Yt7sZiiNf/EnSpbM4v+ncy0mu0bER98VnUf421iWsy25Gf5GkFtP/W8UHxvUZj9G +7TrXe60zXga3e5OBXU8iHGECgYANnibrhnMbjXKHaNOsmyrtjM9xUZ2czqVMP52E +GTPu7sHmu7y5qlG4ckwcEKuCYcoiTHJ+ZX/FOYNHjUdTpuXtuCzUi4lUOFIRC7C4 +CbUFfmMmSaz1n+AZk5TYjWclT0Nl+F/47l4CK/h1hf3Uh47py0GSvmyNx/FxVhnR +Sp0bzQKBgHPyCjMEW/f17QG+NOTth87uBn0qxQ/3N5u3TK8j697GYz6GrZk8FsxY +2dO/O5Bp87LxlrDmI17SpbhP4OIwT53eQoMESa1MrUuOSl5TNQDLfP/ZRS2A5FZR +azPRUP1FibFtIF9+Oil/V6rWU+oOnvSSYt+P0Npy+WXnyDdRi+qm +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_DAEMON_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUaVjP5toSZjz+kCPgpM9eyglT71IwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyOVoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDKT+/vp2gbgVymuRMyDDgpefM0auPvmIFcNGIS7MiCIc+N +qpYCfjaCdZc5gCo0pgS4Z1rqbl88puYH47Awav+b6YXz5jvU66ZssVlRHXdrnD1r +kXTdRGQxEMBy/iUfEdQgOgsk779QoEpAWAyxyHp2r3LSdphnRpHua+04cMdpWiRN +Jv90l/qHL5DEubwd9GIrnOa4BmfCfpyn3waJITN49ngSNumyQiCOoMKIcCRDdt1K +yxTw00cLLUVhhaaOlMGZ2Xvmlpl1UhIpXS6BPnztV7lbAQzgfAKFL7f+ae3hAsrq +jTKKU4BpzwNLsggE0/UaPqrvDP22rcQ0GBtYLUTbAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQACY+ZfFoP7D93ZJmwjFm36 +AYwDLDCWbrwk1+MuLGVa3ppnbhb1ZnMpG+SUUoGUZ6BB0/Hq/945Y1igMPsElSRX +qrwq+Rtbr3f3ZqZe/JIVSlpFpPYYdZkXFJYrMkLSGJP8DkJVpmlskbXGqtaqcIQR +CurKKhkBsYsY3Z/YTEf82EHwXifukX2OlCmNWIEJe87/Dx/01GC9jD6iaHgJA76a +RIBwzf9YZqpgBEgOoTH5Pvz88tRf63njMdupgJVsxC03AqVBLFacDQ6aRjYgLedS +8gJnwq0CY6nfO63UkPH1wHBLd8UFSw75FVIUxyeh9JNjiaPj/vlr7sOVseqTaKZK +-----END CERTIFICATE----- +""" + +SSL_TEST_DAEMON_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAyk/v76doG4FcprkTMgw4KXnzNGrj75iBXDRiEuzIgiHPjaqW +An42gnWXOYAqNKYEuGda6m5fPKbmB+OwMGr/m+mF8+Y71OumbLFZUR13a5w9a5F0 +3URkMRDAcv4lHxHUIDoLJO+/UKBKQFgMsch6dq9y0naYZ0aR7mvtOHDHaVokTSb/ +dJf6hy+QxLm8HfRiK5zmuAZnwn6cp98GiSEzePZ4EjbpskIgjqDCiHAkQ3bdSssU +8NNHCy1FYYWmjpTBmdl75paZdVISKV0ugT587Ve5WwEM4HwChS+3/mnt4QLK6o0y +ilOAac8DS7IIBNP1Gj6q7wz9tq3ENBgbWC1E2wIDAQABAoIBABWBz/kDK+8Ynnfe +3uqIIARQwYkF//s9lCrwKqjmYR5sZ7sgslfLgRH3XD8xn8r/BytvWVvopdk1yOh3 +zQgop8m0VpgqFpw4/PU7GUqlPkfDUUg5K1pGZfxNUpgm6l1WMN3ILd0cW5M/pwUW +FytjK5moZyV2lBcOin71HD/OxXQuf0wKp4xKswag0DzUAB0AVLHmaIIMf9Sp0hXc +NqsdL5hnxHaMJ78lA9a14dVQ3Kx2Hovo3EFShqcEOqQH/Ekqj1QNlivn5TiarkhS +FFcIwuJisFg3RKZiSETEL3LHYr/tx9Q8g44GzgQb3lwBznG/0WjtatEqXUNqJ/nz +s5fp2+kCgYEA/7yAkYMKyIEYO6c+31NYrONkOFvD1EkQe9boSb+CUZbjGNHw1NDK +ChUYTbKOSV9PLV2SQKghQ4KVN+ZReVeEfdGptax03tWfrz6woRMzLTyo9hxlZLU5 +8xsNBt58f9XqjPsPU25FWSY2Q5C8AEykwNRiCBgsuW1wOmv+5IP39I8CgYEAyoVV +pJ8fy36CX+T+oYWyGMc1B0QCIWBPRZwA+EPgHWNBrNgd30JfndC9BJwq519eEaqW +x313/rM43B+mXgsMkndszIdwpt+i2Poqvv6FO6iwIdQsSe6FiUIRMYxwxccrzIp3 +0PrTLThIl3Z2gnaDFh1pj6yKHxvO/vTUHTtoSPUCgYEAvb4tokkZChUGVtRLCMW9 +KGF6rXogfPRM/6U/KeCmn0SVcIfr6OqUzRBDvPo7KeNGSsF/Tuuv6ngLoLMJRj+R +9QxHn5y6Bc94MD0SLiChuvGj5x7AeA0iVuZ+LteKhgrAgSORhnRtjayVXGIZqxsy +rkOmDJ1rKZUyTJZuQzxLD68CgYBzpMWt1kuCmP/7oDiipUR4j7BBMN2Cj4tUtWt8 +WM3uGhKTj2knZrBQ3rRAoKiDLFr7/YxR59yQbWjnkY8fnnGUZWuUMzbpo0RLYDbu +j0onMgE5n/2WTgSkxzwoLgjrdvsUtnEKvV+/L6eMDdJIV0Ita6guqZjJgMinn8hL +1POMzQKBgQD5HFgGlb0YEpEu9aS2cQiBGW5s5Ww64Sjpqui7PRm8J25V7mGIcpAk +N2LxBYnCSt5vOcpx7MiWqsR50ExROkS97383VD7tb+gSLc3NiGHnL2Q0A4DXbNc9 +VB9enMPAbSaXQ8dSj3l+GkC45xm5mRcespWoD1Q8N+FHENlkXYRj4Q== +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_INTRODUCER_PUBLIC_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUOwoUduReWasvp/QDg0CoLyhjMnAwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyOVoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6ghTGOkfeWwqPLfK1hMgIbY5HaowuUHRXkCyxCF0E994w +CVGnU+dCSJIy+xAqRDvmiQc4DyG4SSskTSCq1tv2xCDmdCb8BFjFVoKwtTpDjIkF +mZBRAWJWnuDxE1zUH1kwR9p/d44Ln+SJQV9/tHdLrn1exmAl7TZ3fMHFKyyXsded +qJ7K/9mlNAHs4Mz2hMZ6h93363bShVRP0clOzdJ0g0/OpXgRkRDSntDwATlBpsYU +p0mWrpyAdPIvADHBWlFZik2Ts/DLpdzPaHG0jUmQ3OFAOUNWBGvGTbkPeWsv3grk +4+m+MYbmoCg30l0ReeWy66J6OdjJMAiKuxoLfuRBAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQCYEncQIRyINhibeDZaPwhF +exLV0IfnbLFMpICG36F/sK7b9RFAg1x3SrPk6SXe7odKfmEvjKivptKXnUJ1mojA +cufGQiMY9k+xiLzL/x9nTKMuT6hcGAwdpSZl9T1xQOalI67PVl9OH02Qdab1h1bR +Un5OISmD4D0vtFH4CYXjG//r/SpfbC7d5h7v9/h8rRhZPN/uGgezHE1s6IJdeRas +zRhieSXDW0aW3Y7agkgwdfrPbz4wpEYUpWHDM0dyRMpqww/aXgw32L7Iv2wYJroW +R8FESaGFlY+7aBORNlOqULtg6SEzCy+Bb2Z90iUA1A8UuuGQpIPvZPKfv68Hr/mI +-----END CERTIFICATE----- +""" + +SSL_TEST_INTRODUCER_PUBLIC_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpgIBAAKCAQEAuoIUxjpH3lsKjy3ytYTICG2OR2qMLlB0V5AssQhdBPfeMAlR +p1PnQkiSMvsQKkQ75okHOA8huEkrJE0gqtbb9sQg5nQm/ARYxVaCsLU6Q4yJBZmQ +UQFiVp7g8RNc1B9ZMEfaf3eOC5/kiUFff7R3S659XsZgJe02d3zBxSssl7HXnaie +yv/ZpTQB7ODM9oTGeofd9+t20oVUT9HJTs3SdINPzqV4EZEQ0p7Q8AE5QabGFKdJ +lq6cgHTyLwAxwVpRWYpNk7Pwy6Xcz2hxtI1JkNzhQDlDVgRrxk25D3lrL94K5OPp +vjGG5qAoN9JdEXnlsuuiejnYyTAIirsaC37kQQIDAQABAoIBAQCHRA6jEePLzYWk +ADQWGB4nlqVpAEp40JsAYq03HBSypL59YlTZIY4I0a9O0C2SKfizo1AcBUV0bYSf +iFyX6sqPdwFRgo4/mztyq+KPHHEMSqGZ8Rzs0y8qGYKU9XEO20mJLaO3bNMVdTp/ +nW0QpqcauYttsDxNZXRqRo4WXNCzluf5HEargy2A3/44MGc34vmwvbUYPk+2DpFL +glsVXrRyiB17pwUMw17/h40t0sSTsm2GlubfGzz6PWTtJ7tqSXLMeFDn3zLOd89N +GGWyi/d682xzXmBJ1KA+rEKFCoC3S+enIJEMedJU2LQ9TtyPVy//8ocPksijlcah +Rg/bInIdAoGBAN/dH/3bVaLg0C0lrEdHVa38QnjbBce6nUkzjPqTE5H6AlUDReEM +kKBWbWXT03MYrsoR5+SP6YAmzrdFnVQIVgeEOCtTn1MTP0O8vgSaS+koA1K3E12V +Hnn/Ca2Auqhmq9Lu+PMgTlrfHmHlvfljHTeM8XCsk1Z1RnfCTB0VAP47AoGBANVI +J/v0Y6LhFAsGSDuM6Bxrz64rFOXDpwGMyIi9Joxe7Lhlx957So/vLMb7UyJhnN/U +0Fo/xNtuP6X0YtuOtfW/hfM4F7Q4IX9RWWEf3o4M9ePgmy221RNBghiCW3o409y9 +C9q9Ic0LWjFccRJYviitnU2I+vRTMv29mUGmIFOzAoGBAMVumJNjiGAw04itrAXl +FNxwGRPLXoqqu6Lekxw+8EiS7NGbJFr5oOe3sZ3XtqnQf/740cJTZcS+9RrPi5Sc +EXtpkbwscNxsoiQUZqVai05jGqMtkSe8pvdDBX7+hCCXBDzww6BwwooEMyB15Rj3 +38GpTRppKTxcC7z9H/GaH5kXAoGBALyT8haKPVaUoD4nLdLJgakvgg9DNFT7Kzzp +l52fcOgIPlHEXHZQmNqu5O6C5TyvBh+6cQZ6/7nsvwYjEQ2EH0rMLsmgPQUx5BxI +dzizDvqWZws3Wr2OvNMrxrWY/P0SJfE0jbi4JZzAftzKGYfZQzmAWGdnyEwjDCDi +dRFgq5CVAoGBAKaxSX+aKLw+rGS2c+gJj3WpmAjiyrpd/T/rWr/Vb7WODIENTZNx +cV6qrEx/K3KLNWWt/RSGF1WcwMogfIQeFSCuYUFC1OTaFIIzHXHoJ5kfNDuc58dY +5KBvJhlub9s4tAwlsEFHtHiKoOwpqDQqrMVk5T74cZnSY/01aMJzya8w +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_PRIVATE_CA_CERT_AND_KEY_6: Tuple[bytes, bytes] = (SSL_TEST_PRIVATE_CA_CRT, SSL_TEST_PRIVATE_CA_KEY) + +SSL_TEST_NODE_CERTS_AND_KEYS_6: Dict[str, Dict[str, Dict[str, bytes]]] = { + "full_node": { + "private": {"crt": SSL_TEST_FULLNODE_PRIVATE_CRT, "key": SSL_TEST_FULLNODE_PRIVATE_KEY}, + "public": {"crt": SSL_TEST_FULLNODE_PUBLIC_CRT, "key": SSL_TEST_FULLNODE_PUBLIC_KEY}, + }, + "wallet": { + "private": {"crt": SSL_TEST_WALLET_PRIVATE_CRT, "key": SSL_TEST_WALLET_PRIVATE_KEY}, + "public": {"crt": SSL_TEST_WALLET_PUBLIC_CRT, "key": SSL_TEST_WALLET_PUBLIC_KEY}, + }, + "farmer": { + "private": {"crt": SSL_TEST_FARMER_PRIVATE_CRT, "key": SSL_TEST_FARMER_PRIVATE_KEY}, + "public": {"crt": SSL_TEST_FARMER_PUBLIC_CRT, "key": SSL_TEST_FARMER_PUBLIC_KEY}, + }, + "harvester": { + "private": {"crt": SSL_TEST_HARVESTER_PRIVATE_CRT, "key": SSL_TEST_HARVESTER_PRIVATE_KEY}, + }, + "timelord": { + "private": {"crt": SSL_TEST_TIMELORD_PRIVATE_CRT, "key": SSL_TEST_TIMELORD_PRIVATE_KEY}, + "public": {"crt": SSL_TEST_TIMELORD_PUBLIC_CRT, "key": SSL_TEST_TIMELORD_PUBLIC_KEY}, + }, + "crawler": { + "private": {"crt": SSL_TEST_CRAWLER_PRIVATE_CRT, "key": SSL_TEST_CRAWLER_PRIVATE_KEY}, + }, + "daemon": { + "private": {"crt": SSL_TEST_DAEMON_PRIVATE_CRT, "key": SSL_TEST_DAEMON_PRIVATE_KEY}, + }, + "introducer": { + "public": {"crt": SSL_TEST_INTRODUCER_PUBLIC_CRT, "key": SSL_TEST_INTRODUCER_PUBLIC_KEY}, + }, +} diff --git a/tests/util/ssl_certs_7.py b/tests/util/ssl_certs_7.py new file mode 100644 index 0000000000..d7f79f2763 --- /dev/null +++ b/tests/util/ssl_certs_7.py @@ -0,0 +1,684 @@ +from typing import Dict, Tuple + +SSL_TEST_PRIVATE_CA_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDKTCCAhGgAwIBAgIUHoeobLQu3yMmraIDXDF+F6M4j9IwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMB4XDTIyMDMyMzE3MjkyOVoXDTMyMDMy +MDE3MjkyOVowRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8G +A1UECwwYT3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAskK29xVfnH/4tpM+loZOOZX3d0u/NARRkgnPeoTs14M0 +dKP+dZ+FRuuqKmJQHuO8+MFfeTFIiI671rWobtdGCXVD+TZ3g4btdtGdvPjIBXJs +RFhYkP/fIjzq0MoJ9O6qlhXh3skispfHRY2ysVHpT4d63tixhycDsMn82Jh92OGm +BaO8UpjIk1twEnfxsKm5MtPbvNJGVzAkwYXWVFdV7GdEYCKsVm94Sd85TpDg0xFq +q5YWOg5mpFbGAExBjFerHSuVBuNsBap0mjL3aIb6MXvQeYp+lKrzeUfkUH06e/Pr +AY+TQPO9ktcUHHZ8+HrXhOODdeDlbC8mWzR9I59AfQIDAQABoxMwETAPBgNVHRMB +Af8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBQ/s/lX6Tbdg1g1FIShK+BH+5q +msfNkAQG+mXYGbn6SYQQspYFZdZp4kXLdSKSjok5eWoMnfYN+hy29A5HgeJfdbM4 +4Nmt5OUvWT0EOTD1VtdVnsH8tac5Q1XevE0ZK9DXYBSEXqO8sVSt6VWmNT98lmEZ +AVWtawc0zt/31QAZEa5Jjghq/HRbIi6KUX1t3Hx/yVa9Uxiz1dBVE8A+QBwVKOzv +egKu6T94xBCcOeOh0NgluRdFiTr9cXAYNQAUM+WdmyAvFZ4qwuUKam7C7zX+td6M +r80F1SD8qbQgxYS1bwqx6K06xbFRLXpWbyHXG18v6ia+sifWblg6JQnYhxZg +-----END CERTIFICATE----- +""" + +SSL_TEST_PRIVATE_CA_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEAskK29xVfnH/4tpM+loZOOZX3d0u/NARRkgnPeoTs14M0dKP+ +dZ+FRuuqKmJQHuO8+MFfeTFIiI671rWobtdGCXVD+TZ3g4btdtGdvPjIBXJsRFhY +kP/fIjzq0MoJ9O6qlhXh3skispfHRY2ysVHpT4d63tixhycDsMn82Jh92OGmBaO8 +UpjIk1twEnfxsKm5MtPbvNJGVzAkwYXWVFdV7GdEYCKsVm94Sd85TpDg0xFqq5YW +Og5mpFbGAExBjFerHSuVBuNsBap0mjL3aIb6MXvQeYp+lKrzeUfkUH06e/PrAY+T +QPO9ktcUHHZ8+HrXhOODdeDlbC8mWzR9I59AfQIDAQABAoIBAFm7l5qdWbnP+YT+ +bf0bsnjuctnMeX1Xxy/6XETScN6zn04v10GigVaH/urC/o3uGgwmW0cIdfi30Ppu +C1FwcEMGkqb6sgK1gwfS0NJ1cUq8pJ9q0Xp8MvhrLdDYQ1bWZWyTq1WYbiz0lkz+ +3TrBfu6XxlQzRHpCO2tc4jit2nu3k92I8EHo8sRPcFssgEH7JdFpGOm/G6ATWGpU +mSJZTxBOzR5iprR8Hl2RXIBDGXqVKXApLJ3OlchSOodeFt2h7ffiNJmuGZ/cnxs0 +05eXzIg0zJ5CffoQdO5s63SPRg+x8O+L+hN0k6Kh5CmFpAcn1jzZatvGO47ndBUx +kSyrH0ECgYEA2a1n+84y6A35LOeUvTE0m3c+DXoI7jl6zUSffXJ5PVH7lKro2hq8 +P5TDG2NV9qFv4KFJVy8hvy6Ie0+HTNP+QSUB2LvJSp4GhlQNP4/J6oY4NGfocfbK ++rc8/jEVQaoySq1ODLchEaxMjwgKOVcUqh6tCQjiTZ3dqpZuwUGALoUCgYEA0aTR +UYcynBWPyt5OT98EkVX4Nu+NqONAyKlDYJqU2NHP4xHFxVPPwYR1C4vZJEmC1z3C +Rad+svwBhCXsh54hTBhZkF+BV8ll4/BqiuHiaqF95VRz8B4wjv+0QKN1fCQO4RT5 +dEqbAkJYPq+vYCJew3iPWODLkaK/B8yc1hQ3l5kCgYAkYhGBSwPDOaKuWL7JqJHM +cm/SvNUFTGI0MQYfZ6TQFQXh4XcuDU3tqqW5zC6wHGeguhSSF/SiCdsSEUbiFoTm +ypK2cRzB9gvNI/ta5mOvaWO3jq6Rbdibc0kki3usEBB73t+uzGUgmRXqykM7Nkzj +6mCto+h/ZKWKP76fWp1cKQKBgH2KEiKdMExRiRr1xrWDmkuhzJKxHwZsl6XR3lwi +FVJFShTy1piU2MtMk36Hj09wid50yDpH09JAoHPO9fY8VjooNrICzwSPwOkfVd22 +6IvsCuTijs7SdUecjgdLGxZszVAx7DOcXXib3BYlxIJv8olhT43sh1q9t2FnQN/d +mXC5AoGAN5klrbJVgUE8kRik5GvpcoasyDktJQ8KKDD2u/TDkRaCJf6H0ZP145aM +k0Mg5DMG5M8+Eb6l+iEOX1lrrJ3EPtcQraUiFAPXF8slboUs7k5HZ6rVckHqMvBC +ZTAxfIdR90eFK6q0PTRYH2ZfxKKpPDORQvzt59reHexvOVTuozk= +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_FULLNODE_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUFNReIWFnacmYlEf+oXKER30rJfAwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkyOVoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDdivRLL/onTCvG9JKzYXCxW6hrwYRgmiyG4ISrIWlainW3 +ZCduM13t4qlWp2lVYCIez8K3NYb+m9Jk4tYJujzU9FhusvAy2D7SeGJGkAvDuYMK +LCRM0m3/Q0fls0RMHyNd7Csg26LNyGukdvEyKmonqA8q5MZENtsRx1tQtHORLlio +kEXjyd67J1wm5m4rOk+DqdrIzSAuomj+M/D1lRh0icjiSE0Wm9PXJllzSp/JyLqN +AMIDIjkG5CZc7cD2yM7OZQ+haCxIbAmxzyWVhLeuGiTP2qZ2ZRML2HXGVkQfbE+c +vFkPKVoY6pOI0USzM6ipqmYO9Y6357SIeSWhNNG1AgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQBGWHpJNp8iDR5uy14qFYwY +1wwIvQUem0IYADuTXIP3Y+kSKyZpuZeYWFlKzrfTf6wTlmZchcqpidUfkqPS8sFL +4LLRlDFTCWhIiBSs25gLLwRiMTErStedojGS9+smMVpp+/LguAp+kR0zyov7+Qe/ +05DW/fgtZFZIuDa9DX2aLcr2LHLpQU2+nKFM5E4dOEEwaf2rDkpqITME00bZRipF +yytQq6MIG+W2dl48b32B+VhU3UtjeJ4bYDY2BUvAoI69XN/RWO2JVZqEcuAKXjIY +m/+snrJJ8RNATWZ0XgFUQ3UL2j98qHwY5XtGNvLfkot6EC48t0jmuPICg/mTxCPV +-----END CERTIFICATE----- +""" + +SSL_TEST_FULLNODE_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA3Yr0Sy/6J0wrxvSSs2FwsVuoa8GEYJoshuCEqyFpWop1t2Qn +bjNd7eKpVqdpVWAiHs/CtzWG/pvSZOLWCbo81PRYbrLwMtg+0nhiRpALw7mDCiwk +TNJt/0NH5bNETB8jXewrINuizchrpHbxMipqJ6gPKuTGRDbbEcdbULRzkS5YqJBF +48neuydcJuZuKzpPg6nayM0gLqJo/jPw9ZUYdInI4khNFpvT1yZZc0qfyci6jQDC +AyI5BuQmXO3A9sjOzmUPoWgsSGwJsc8llYS3rhokz9qmdmUTC9h1xlZEH2xPnLxZ +DylaGOqTiNFEszOoqapmDvWOt+e0iHkloTTRtQIDAQABAoIBACHjhJUPxLtIKpYn +iV1JNXzb4XqCQqaoTtFe/MxUsxH3hiREfMedseuWtYKc3z8BEpcV/toZpQnDej6W +eFlKlM2ahwB//MA6VfnKEnZqyHHrKcFfmTnrIopel1vqvTLLvJQ8cSh4kIHb+6NP +0ntzA4QHcDKGhlGe9onUrgI9aEQ3wrHZvChyyAV8P/sxY2IseOf5PkJ/fBqttGPZ +9aRdpzvMCyfbhygHAVklucefuQehpc2duv6BUwCd1HgAIwZ42gaTQ8h8Yh2SxDiV +9DKkkQEJoG8ZXYGHfKpXo7u+RgTtpMPmRnls5uIt34qECRJGmXr1pC9iBx1oRIi6 +Qdno4q0CgYEA/lcKRnpjrnWfGYgLZpIPEr4pV328BZ1I7FjzaCcfDEU70gxFpCXa +ViHP8TEWG3+yH+WPodHMfLQ3UzLzSBu/o/XYfU0Nk4A7QrGt4heDRmPGGY+WEKs/ +LoiXlLrF4rOKw3feuR2wagg6NpP5uDraVJFCDG5O0/SIyWSc5ZW7DEMCgYEA3v0d +jfm0n6dNpJDgvCz50qhI6ijUT/Wvnl1VVXHpGSVJjDMSffLsGe9G9bHJCz0s3E0B +NfGJlixmkpzmtNmb4qt4ahdEY/ltYUFlWTvY84JjvJTFrjV0if3LLlVWeHm0aEcB +rBsp0Z+/qpoY6AJhWmN0jX2pS8WbsjHO9OM8xqcCgYEA603rm7ivcEAxqZVLtuF6 +QITeCquwwCD7zm2dA8bt2pRS+8mOxIagsP8nOqWHJnnFee0QLU3EObshVD/XA+do +LXDNkV8wKD6ClPl9PaczNHQqWouU8mb8VTjZxCfn3AzvXFgSHoFxLSffc48DgYYx +Z/vbd1S2aTHbOzdyUJVuL7ECgYAUApC5YdQEk6XTA7E3Ea4lajaI1LsgpcJpqqRy +s3Mgb4knDJo3NSpctW0ftSF+YbH53ush5RfcowVdWLkXN4PWll6K3qWjdwmKtayb +klRIncXHcW4/0Moxa9XkxYGp8/ntdZm/0PwytGwlqghcIYKM8unNnJ4pj4UGO5P/ +w7h7dwKBgQDYqai2lM4mtud8Xn77maR1olSScon+S9eG6GGyRQPVom4NyvfaQxvb +qFQZnwoQuh5ugsbyCA0qkm2RhBIqNWo4j8rM7AHb27qkB9F5tHA6S+DYG9kEvgmn +HFxiZCY+Lu6wRP5Ssnz444i2Tr6kUnIcj4XRyOQjcwKqhMYNod5XGg== +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_FULLNODE_PUBLIC_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUfZLZhnra/z8yyJivw/7O2simIzowDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkzMFoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDAkSC0hl+/EeP4XUtJDAWCBRosaU7munJ8XX4fZDcmXzsg +p2zdv9UZp2zkfXTYP5zFAnjG9QEiiURMZ4rIKdr/cJXY/93H6dwfrjZTS1gCSlpc +gkuq/cdbOeU6xCX8X/dotSQupbYr6ccPVf22iON/FotilEpP2yOFZi0d54uKnBoq +x6GP22b9/Ij+tQNacPZavQjZD2i7ChtLigtMDmrrFMOrsQjSCQPpGKsXmyNqTo+/ +BKAKEs+WghuoVh6G5BeC2EY/PoUohUxBUWlAXThA73yrq/nGQRWfPeNZ2r0d1z9m +AlUakb4a54M8tDO+OOqw985KyhPYRGxOgPDFy4cdAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQAQRNledZvjT6+Rtb29W8pN +11WfUj5+QW7DX7/AFd59PXQkPbTf9EPiNtbriPaeOQ/B+jJ10/hGGGUhft4IEzpX +ffQ09CPNAFMiyvvnOQdykH9lvDMcoVYi4EjzFsCa7uVbKSZApeO07hCWRtlEeDrx +QU//I1F/BcGQGh9Evh4LiZZUzRxqlGE11jSBNIpSNkVE0DO90lBwEujvb1OC4YUh +x8Ef3hzI8EkR4VHG8SwX+VlasHAvM06ouKAQeMMNTWxeShaTI+mZkVUgkWJvTxf6 +LwmU1B8s9M9hNUailBda/7ztvcZHWxghBhsWICZIngUvt8M5/rrgph+e0rI2QMiP +-----END CERTIFICATE----- +""" + +SSL_TEST_FULLNODE_PUBLIC_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEAwJEgtIZfvxHj+F1LSQwFggUaLGlO5rpyfF1+H2Q3Jl87IKds +3b/VGads5H102D+cxQJ4xvUBIolETGeKyCna/3CV2P/dx+ncH642U0tYAkpaXIJL +qv3HWznlOsQl/F/3aLUkLqW2K+nHD1X9tojjfxaLYpRKT9sjhWYtHeeLipwaKseh +j9tm/fyI/rUDWnD2Wr0I2Q9ouwobS4oLTA5q6xTDq7EI0gkD6RirF5sjak6PvwSg +ChLPloIbqFYehuQXgthGPz6FKIVMQVFpQF04QO98q6v5xkEVnz3jWdq9Hdc/ZgJV +GpG+GueDPLQzvjjqsPfOSsoT2ERsToDwxcuHHQIDAQABAoIBADweEsPJH6MbBrzH +A3Xultmclis/RS6rDorc9T7/nmgQWvk6y7X+6Zx0tH4w3IWWdm7a8rHKU2xgxj3E +JYOP7ZrJnz57wtVioSIS1UrzvqoYZFV1KAJd8Br+3B2YlvNPUoIR6xXVDiZveYHE +Ks0Nt1g5xZIlEX4Uv+Ypm/Q2EU5YGnxs238K8kwkPtNTLyAQ7v40YAyZ8uehUu+T +vaMKi4GwX/+TaXWW8dek2fsktWGf10drMckvv0fyo3CdYlSMs0PFZkIHqMQuQv9/ +E+XI8viMovrnhU53jLbs4Tt+f3kDtWVUrd+kqWw5MXzT2K5z6OGQtjK2enACwilj +kbv/ntECgYEA8hUfsihlCFKZdJHZW6mldFY5Ld8YEsAqTter4r9iid8+R6yrSr2k +ZcdAyNFcDBGWkX51nupteU/LFHojlRymxVD2AVGanknYrJ4DNvvc08bCgVZOx7vz +u9KQb8E1xsi9T7uzoGfDqOapQSqPrFvxIPkqKWpOeqY5Jq4UZD7onmcCgYEAy6NA +oqFjbz8/6ImpOaR7cQMFgPnw749qmiRoIMHSL0ULkKq/XF8pN3/mxzKxmLGXGYm/ +yXbpcpuS5oIE2vhwxg1XAgUjpEG7stWtv0tlzpy230/TzwTJO2OOEaVcND+9nawV +T0ufX7c9CRcH4csgG4eJR749rG7jdLiGoqdms9sCgYEAng8YwNQLE2IK+8d2qZic +hNb/QmoVZ7i8Zvn+KnBXQDnYiie9N3GW8zUjoXrApMifDKQK3BWoILrul5IfxW4N +nWt9E+NaFtuUczBAXRgZWNS/jn7xtQuM2idjUvRNzlqm8HZXk/XsFE12WSwW3qyx +RZwp4Ryd3QrG6fBjNAi3DSUCgYEAoTvHR30lL8YSodmtZXh4TIip6O7895DERPui +fp04ADlY6Nho34hxKAJbBUl8GHw0OQI6GhfOyvGnJF+53G5tTELvqyfKipmJNhW9 +lgLqvuaSXMnl2LnfYuh2aj5VfQEi7x57WOd1buG0r+fOU9byuxlbdrSIPGkoKxiX +cV2+EZUCgYEA3rMsb5/F1nCsuhPS1DNlurMwSmodFaYasg2+cg3hQPtHe4LO86U8 +doW1c97sdKLLkH09E7ZmZafXTj4uKwQlLa35UmaRvPM+mWdPLr0Nkkm1dEAi298g +zD1u3pg1jQE1Ta4kuE65u8lwu0JKvje8pvHBRRcXuLvr2oyJ1VWVfvA= +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_WALLET_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUZmWsnGgQgJO07P9Mrqx1hHBfQbkwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkzMFoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDjcVLjFq2N6GKxvke2xGntOo62h4ze0fNrdj/OifXvpzxf +qnPkhBcb7+6GL/gO9IT6hnTCDSjNQG/Coi1grjoPT9T+DkamwioBcFdIOYwEqPCd +Fk5ZnqwAWWg94+dkb/jlRcFlShNcgDriH/MrgfQ03A4VfqzcNT8GzZ4zwFqAyhiV +KQ56q0qrnIrHQDERII3QMH72EGCVX+32IIkz2CJvo56yngwF+tDzYJYHMJnNTCG8 +iVD71v6qBM52G/6bKFRJhyZkKkVqPwptIXInDPY5ETgfZYgD67ffQ5+W1kXlCmmH +PuK8w48Fw7LjRDzLTYRFyDSIT1H5sdRvHLIl9BEnAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQBvOTJdNGUD5Zc976Q5SJre +15KN8PaOsLePPISn7e/2DwMGuq7GXnGa4JCb35XTGjX+Wxgnv/0/8asMimay6gwE +YZBcRwakm3l3//4W1ELc6SREoFcUTV49rnccq/N3u7ZrDubf1U9uKvFEpwp9TM8a +nq7tVOe3j+Msyvq4/q/l0nnHX/uuWYrZrC+Cm6tjytmOr6JzAhURFoVx3QnwaD8z +qm+cisSE3/lLuyTzgNUiQkdIC6bCg5KVOrTXFo3T72F7+oeM7h+OiDO71y79x9UH +r6YE8Ab1nYz6Cw1fwy3/QzxtazuTrJ5gBotF0oqCoayEtiOMZr+aQuM/qRs0EeTy +-----END CERTIFICATE----- +""" + +SSL_TEST_WALLET_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA43FS4xatjehisb5HtsRp7TqOtoeM3tHza3Y/zon176c8X6pz +5IQXG+/uhi/4DvSE+oZ0wg0ozUBvwqItYK46D0/U/g5GpsIqAXBXSDmMBKjwnRZO +WZ6sAFloPePnZG/45UXBZUoTXIA64h/zK4H0NNwOFX6s3DU/Bs2eM8BagMoYlSkO +eqtKq5yKx0AxESCN0DB+9hBglV/t9iCJM9gib6Oesp4MBfrQ82CWBzCZzUwhvIlQ ++9b+qgTOdhv+myhUSYcmZCpFaj8KbSFyJwz2ORE4H2WIA+u330OfltZF5Qpphz7i +vMOPBcOy40Q8y02ERcg0iE9R+bHUbxyyJfQRJwIDAQABAoIBAHyCXDLPBmGqNuVA +2nd2XNqudNP9rqOIYe6RRGrn4Ye5kHZ6lIkjupbjqTsyZWSifW28T4yvsYdzX/s3 +1wmXN1eMh3gxDoJZxq8U9eMnBbzDUz1bqbasA1MJnuRKsDCuj53LqwytGZ5I4HNL +tE48DRkm4lroBu9iAsfRpmqEQcdAUtXGLvGGkX+V9j2exREyVXrxALC5N+4i4w7E +f5aidhH79IGuMbfp88QS7NbjrpEwd1uyP3J7KCiyXwWIJnJyF8pcd7ZUsP95msE9 +STeoKBaV+cIE03jvTT4fpuQ2Cn2WYSxkgVdWM+XdxGouIQvboOBNvPdWfdQCLSHa +acRhzGkCgYEA/nd/BXmm9pkGKHm9XDHy97pYm1PSOihsgjZq148hY33gdA/ibUtK +X7nSlmGAUzVTU01nfPmjkHp0YyoDn+NejAyPhBUqPoxfC7p2In1MiibOlMDxOpPl +199+gvadHk59g5Ap02iCu1lnlR9DhFY+42XcBSLba8MdplOL4lhnx9UCgYEA5NAk +45Dt0NXnaKKLbMW5EOZA1zLUcomO8AH1dEF+l3e5UOm9g+YnYtUVALKM1nBc0EJ3 +fu8fmKhDqieLxb42o7j8yQqeKUXZW3XeDGPdLhR8coxICZv8f2j59Qgx6gwQ0ipy +IUan/0rDUm7dinu+07Va4hqnvpuPbUco3VclDwsCgYEAvwScyVNkzkBYqxGX4Blu +th+gXBkz+oxVx/lpgp7jBXh8gSNbaYfXMLyhJFnUpqGlBydXxCzxZ4dEzxu+1Mst +MhxLr27j40gkIP27qHA+gIZZFLkxXDOhmccfhNfzYcix14zkmNofKNwYMYzidfj4 +BGN2IjTkWaSCIVUd8K9EWHECgYB6wKu5pivfaJIgEWvJK/4P8ecBTFSrKd8UJYjg +GK7oZaN2pB823sdsfzIoUKG7/UXduHrRD0odJNBAPbz/lf9MMFb1KAwXylBEf+Rj +M0Qaj4UAEwAmn5eDZvcKHJ5imJyBk6Hs9jH0hNBqre2OeLq0a0vZl0E8wcndb1qd +/D12ZwKBgQCDKNhzVlKwtG5hF9rG0FLxUtOduOEH9OI4N0BaptoJncGw/LEqZI9R +ZWim7eYzst6zGvsm6hiCZXR9pt1IUNVC0YxaP38YoolFKYxwcraPIfhteXx5CF2D +EfVRIx4ZL8Ec0nKeG7sfzl1AM30kOT1sZ74ZnoS6iYNXGbkXIeecUA== +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_WALLET_PUBLIC_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUJg7OmxTb+nSse9yCvMecvDQ995gwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkzMFoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQCoMxRs8WLspmYqmfcq6MqZI2h1bNRqXkdXdDpRTNkdfusp +8Xm5/Oncd2ewVbOIWNtaw0c5Uq6futXmo3cMAf4fTCpQUxEeWcMw1KWK5vudfXFY +w0VNxS9fAR4ByRbNGDcW7HXu0silleuD8onSKxBEyUpNHksqmuWLJ+Av9zvRfl4V +P5WUVr84dpaotLXYx4PxoPINRloIKIrzsEAVwrmV8OxsbsxdlvokUYy6kezTRNqN +7izl2CCi5PvklOHYr9Bf5NgfAE4VMMTcVrQKebTkGAdlJipJ3N7gf75Yi/mMTXnW +SjMSRjJWGub0iowNUEXLXLaSQurQRJ5iCoMCZr4tAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQAw9TzzcnbQvjEC4zF4nPr4 +w6cNUog8tfiUx3Oh2Hf4+//Urhu+9rO2ylV90apT2kR5qUT0yod3s/9WGMe56P1b +3qES6PTN2LipOT0js9SmmhHmcy+tiQxeKk37SWjFMHMmfpaZHLZROxIAsHUlisYo +Pb45Lm9zd/yofyh0xTHC36KaU7R3mVzE0cKtFKHZIiwpd5BUp638lY6tngQzOOe/ +hhxRyJ4XoafugAgW9nykm+zMG9LxhHpoMFIZuZQZED4RKG7gKA8l0VqKm9Cg9DTm +xqhRHtHY9hS47dsHL9Ggv8XsBy4nnkemVhB33DPK9kYRmz+J4Y8gjoqlL7ZL8bnr +-----END CERTIFICATE----- +""" + +SSL_TEST_WALLET_PUBLIC_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAqDMUbPFi7KZmKpn3KujKmSNodWzUal5HV3Q6UUzZHX7rKfF5 +ufzp3HdnsFWziFjbWsNHOVKun7rV5qN3DAH+H0wqUFMRHlnDMNSliub7nX1xWMNF +TcUvXwEeAckWzRg3Fux17tLIpZXrg/KJ0isQRMlKTR5LKprliyfgL/c70X5eFT+V +lFa/OHaWqLS12MeD8aDyDUZaCCiK87BAFcK5lfDsbG7MXZb6JFGMupHs00Taje4s +5dggouT75JTh2K/QX+TYHwBOFTDE3Fa0Cnm05BgHZSYqSdze4H++WIv5jE151koz +EkYyVhrm9IqMDVBFy1y2kkLq0ESeYgqDAma+LQIDAQABAoIBACodB/szARrRmvkF +rc4vlTJ8nBXylsi/LEuoTUW34RCyi3zn+htoSMGrn+mVu6ri3KFADaA7pH9Xz2C9 +Avydrxv0/Q85jSq1PNsIEx7RMKTBGNUppzuOqIq4A+RcjfnyGzEBKZIPcq+K9voF +ix51K9CdOZ5PfHCBcgHCjS5VT8Pm4QtUnH7Ak+unT8QZ2DaK1PY9lnsburr2o7ax +kk7DLSsb60pb7XBDLrv0c5i4/XIhSP/GBUJ0GLTEutWG9iXwa5Nzlxoz4UGjnljP +80KQB1TGiZnFYiolrKaj+rmcuXeApYuiAwFI8B58DYyol3KJXmUCzilw38ycArd0 +nIkhyJ0CgYEA0TXHfUKZnF9X7Vig3hCCfHZFJy8g3L8RklIjZVn9VUGFZhCIPiMN +zgSI5fK8sx1oLKz4vYvT4+4QoS3kb13pWGRoG8ooF76R/0soXckKG/0Nl2fq6YHR +9Bygxvn9XxxGHToIJfxfcmzfE8h+wmpdd4t1vuWzIzrAqyoBDf2nxIcCgYEAzdFD +Bb+J9CZviAtsOAEiouZby/rtZ9ayLUulRTDZuKpVnVHRnzckA6cLEqECC4dr5WsH +bDFasktvx5chl5SuE3NFR8cznMyFN5rpWOpYdl1QwwOQ15sBJ2LuT+mafXpu1/7x +RhZyw5oaDDrpaqOLTvQbxlrXjpXYlNsIeXALyKsCgYB1uTtuIuHpekUyC6NKEiQ7 +ARpcuEpXrTSoD4xXZdIF/X6hNkBUJsmH2klmi7bfW3bZXOQDVQGAyt+UswxOFpxN +3wIuUQ1KfzQMYjBuxcfog/b38cPgberE4K8gCGAo+vIBVDxtk5vp+ZV1vmaF4/CA +antxVjP9aPwt1M8PHmMfVQKBgQCNrFYuRsJ3RV3Qj8xWYLGu4FKf/oIc0DSl6URC +dHXqH5X/TKq2pgYsXXfJwvrdZMJokVvypaaAxFyVTvrYlIee6+HsnrpwXHf25rNp +eSabk3BcTMAPKauJqRfR+kNVzEkwdVUvoZQuAI2djY/Oz/S8zFuyFiX7CDqlfIBA +11fFMQKBgEBlJNb5pEhu9tdULlOEroG0XeCcAKDfS0WULrbk1VCeRNOOXYdoiG2v +YImM6jUSIrHmZaMu7aaLYKDbC3xwd4ZyRRq4KjBYKHM6o4h+bZbxl3Eagjb0UQnr +vIsFw4+VWa5DOrdVtpoKBANUY0MSAfUPlBDBMGUuQ/q3X8GgxZ5B +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_FARMER_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUBK/eOJ8iPyAfvjMt3GSSInfW8+owDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkzMFoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6Z/5RC7RCEceZktvq4CJeAaGlKGJFpF3z/THIWoVjJ03N +KpDMprhq8N2HM1pM5I0HPDze0hDCRGpGh3wby3FmVAxb1vJyDTT/DLw5KYDBQaCY +TXwschPu3MYfSJIUXlJVWRC7di3xV6si3L1ALdfmK2des/YWCYP0qIjc1E8j/OVc +wD2PdyHR+p129SsO6WB8KIH/ocTw5YJisQBebUo4m495FhKLcKPiczUpRL4CmZUa +dFkrTWz1Vcr33f6fFybYaWI3lxHHYxOSB3MilDd8Au55tLhkpwpkaqPKWDP6b7au +WFuc3q8DegbYRLyq7qEudsG/u4afrHfI+vovHLVBAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQB/MflzZFEWhLZ/ZcHfmVkO +nTs74yALWjdld24er665E/tbRUScuGwpGJDhxoLE3JrsM8wIyqw/dOLqGscNprl2 +u5MBRMwzbQncE1kZ9YNyT/1oC84Fee3IFni47hBUJK3o1zOuRlU9cMTj3dttBEG2 +hByAv/ZP56H/dQN1/LIGoOHNSRhdzuY33rFYg6ZjV5mnFh4BHQ8jElA6lTiz2uBL +98RePraQx1ONCXyrjBV5o0G1Ra1UmRo/DBvkQu03eZXIyqSrZJKX1xM8345p9SjI +Ztpr9N0YFHRkMrj8SCiqYeRX0LdUW/D5e/gBf5j+dJzFiB6NHgyD6mKORQgxmIPY +-----END CERTIFICATE----- +""" + +SSL_TEST_FARMER_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEAumf+UQu0QhHHmZLb6uAiXgGhpShiRaRd8/0xyFqFYydNzSqQ +zKa4avDdhzNaTOSNBzw83tIQwkRqRod8G8txZlQMW9bycg00/wy8OSmAwUGgmE18 +LHIT7tzGH0iSFF5SVVkQu3Yt8VerIty9QC3X5itnXrP2FgmD9KiI3NRPI/zlXMA9 +j3ch0fqddvUrDulgfCiB/6HE8OWCYrEAXm1KOJuPeRYSi3Cj4nM1KUS+ApmVGnRZ +K01s9VXK993+nxcm2GliN5cRx2MTkgdzIpQ3fALuebS4ZKcKZGqjylgz+m+2rlhb +nN6vA3oG2ES8qu6hLnbBv7uGn6x3yPr6Lxy1QQIDAQABAoIBAGV238aLwWXJOcWN +W+mgcPSMnMlCjyNrUbzSkDuHkl2jckUAK2tKQM3tKBhEyp1aNq2+iz+aRocIKHUV +oGecuLBDhaqj+Lo+GB/QddADmFMZfuoIG1QyEEmPoMQ8g09U/Cn63hG8RUu+Nag3 +UUhS69ccvxqciJH8Qfh1mHHjmuRyAMMsYlbiq2qJxcwPQQO8S+ieywfz5KtYKkLD +2Gwzvmit29r1APhp2jFaTIsrMkzY5nYc5+gp6K8+XZ3Bm2au50P/YnzBuXFDB6Tc +gDSPfaho5HawsHHyIop15fajn8dvJzzMTux4kdxXcsJcpasTyc1bW8v1VrcGgHcc +7yhogLUCgYEA6A6Nk8gfcrN7oTW47ECy+TfwiP47lCm3Mi+XrW6TdKL6fQ0mhfvv +WsvuHfmDH6b+yN+TZXQI49VTxJoIUbvNdKr+3i9rp+2vahib4+zEkos28ODei5fO +FJcZrjsM204kVpVz6j0HQRHE8SjAfUYO1jHLI4h0FyEFedF22nMlwSMCgYEAzaOl +HxZwiI1eUto2SdmT2TZZWE75uTn3ihk0wfJar//LG1uAxrqHN0g4KVMqgQN+IFJd +NZ2FPtIQ2E0P42lID2fGtpwDnMCAn/drpvhxDU5i2gNEZQ7LIpeZOLKC6NDQqb92 +8ReuKdPQ3QmMJ9uWn9A4IPkS7c1WvkIrEkTgYEsCgYEA0gEhlOTduOK+9kR05rEi +hrFeJ8vTxSD/XhZ98IEKRtqbT4IQI968XPICuvOr+4AYQVc7v+uDhBPxrBEtiDIq +G/QHlLFbfux1+9DrexgxSOFdxh3qqG+oGzAnGGruFqWf8w9riEbUgsl+7jPQB07Y +bHVBfhWl4ayLlRO/uK/OMfsCgYEAvYLbkIvQh7eovrhFIcf3Xk2dByo5L/+A5m8W +VMqx0tLsbjjks8CBDmxq/YKcgCsk2EqvhdK2Uk+roHtcchq7gx8DXZToK1So9UNC +na0GGtordXlfVbbNdAK7/SleRYrzUgyWY9eL9RY0vQ+ob68J4Bw3LgP88tSy5UH7 +iamaEoMCgYEAmuf1w3Sa8cunGBrzljwhr/5CjG3zDI1+fdFUePivoU5NocsKrLPp +KpkaBa2jcLXxf23NQBNNDWBqfsi9w28/5kl/gURT7ohOcf4YR+Ypnywpb8HI5mb4 +XxOG7la3Y9Mhaw/iC/JWbDgb2JORQmfEGhTn89ggy7yu52brz6t/MNQ= +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_FARMER_PUBLIC_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUDuk4yYHfeEkTr0RtsKoTAPWmWRYwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkzMFoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDjKy/CjxjtUi82UKxLzsR39LAoE9BUZwLlkvPrugeudoLq +EHlKTolTuvlFJAi1e5PKjJiHdKW2vSrpt9yBj56qw2xt7eJOQKxIE1kdeCdLoK1M +WaVWVekONJSlSqcHkW3NuBVtbAKJO+KIdTMMolYJlheQKBZp3JsSjLakDUQEoGyb +GT/+/xo3OZciBk1acmOBh9mJ///p8LO/oFZXZCXSau3+9K9vzcwS5J3HkDjkNVxb +AJny8gEe6ux0rXzkZLfG8WA7F0SVu+493kDHB4TO6o7UxAWatGVcyG+M3ujJ9iEg +0oeyoCghgpBSX02gM0alwW2cWNrkgisf0tyuJBRdAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQAqtpdHxteYdjGDUaNuVzRN +1qmnmD8m+scvNpqYU5wQ4xawZVFyx6k9dl40BYeYvTcvSpBmNoy9fTpuTYVeeOae +glreJiKnulsbMRHwxDjCKvhoCge8ZTsX/0Atfkb+AHNMEN/QXS857ovSy8JoV71Y +S3ZGa01vG6AdHfpin+xHuDBh/B7bCHPBEwNc943PgAeQ09X0ZP/EFb31h2sK/eoR +jytU7Aw/NwCnSaA689xoTmtJp2p7INSTXJNO/rJeRKPxKNF3Jcg9Ngtci7CxkXzi +4+Hs2aSkIAYj05UcYdiLs4TNR2ZrPKA4/ZSZUCCDQAogOEUg+SOMGPkevqpojYvf +-----END CERTIFICATE----- +""" + +SSL_TEST_FARMER_PUBLIC_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA4ysvwo8Y7VIvNlCsS87Ed/SwKBPQVGcC5ZLz67oHrnaC6hB5 +Sk6JU7r5RSQItXuTyoyYh3Sltr0q6bfcgY+eqsNsbe3iTkCsSBNZHXgnS6CtTFml +VlXpDjSUpUqnB5FtzbgVbWwCiTviiHUzDKJWCZYXkCgWadybEoy2pA1EBKBsmxk/ +/v8aNzmXIgZNWnJjgYfZif//6fCzv6BWV2Ql0mrt/vSvb83MEuSdx5A45DVcWwCZ +8vIBHursdK185GS3xvFgOxdElbvuPd5AxweEzuqO1MQFmrRlXMhvjN7oyfYhINKH +sqAoIYKQUl9NoDNGpcFtnFja5IIrH9LcriQUXQIDAQABAoIBAQCXviRUAQQ0mp5A +2NiOdtqUClWVH88cYgb0VRosTwKMjktakJCEizt+O7oAblaG67pIJWxJpyh+jZPZ +tOBNhyMEjC+kqq9teBPcvVfcsIMHKJg6FPO1XQOlYogcdWZnTsSbEyj1A54aD299 +mVP1T4bLNoAc4jo+kobfeDEUGmxh7Yj3LICr+D9yPzqKsNJAzbWILhtYzR/hNqb2 +JGBdDXu0usls/oSjNUYTAmtATQjVs5TbL7Ver+bdfDYaScBR8GqfavCTOrjGUaU/ +26yPpPKpycxL4biULej6SwmQm8AXaftb68+TaZ767DpxY5/3goqBfjKlu20WQyj/ +pTfxaasdAoGBAPdhtDkFddD12+tsm4F17RHAp7ODZ5w0Wd7/DuyRPbpq74fXCYuA +5VSj1SPE4t5tAqUn9Vo7zgxBoZIdeHWBAIdunQw4bst11PD0uckzE5oMDxj+lT6B +7XFZXXJgcRtYI8c2na9/ISf9I4WtE8Y422xPZl/U/FV1+k2sKuOLm6r3AoGBAOsV +NiDuMqR1/IopAkdZIeMMiunaLCdwkfJ12TQzG4hGDxE5Nfog90cEoJO4F6d9IZcG +qtmlLiJjLYILX5vvthoQ2STVxLxSWVcWdbhYth8PTBm6waAfJH/00lmZtI0bHxlu +eK6jr3QK7Rm8PFKP3xbnKr6BkTeL5aOfs139EXJLAoGBAL0MMnD9BjspF+ZCulfl +6cSOSNo7iltp+mAa5KnOmLC0ddaGc6njV94l0YUjOgimn8Xc0nghieX95d5GnT6W +1fOpiWTEX48mvhNhwfTLDqjDnGoKa704B19+3pXAs88kvTrJNxndelYX8iR+zsTF +wJF14BNOLYOVxDHFZ4U6tDyjAoGAWGfjsUKi3OJaFIMTjk1gxwgCfatEi5hz6mCT +TGQj6H2gUPPY7rXTCGwfDy5eBuix5x/kxHCwBtKRXKR2Uig1rVvErWuOztuRKYUS +xD7oTonsLojjJBpSGaSyLmv1UFNwwJmg3NxFsTgirljxvoLIfM52bqo/OEpuE7iN +Nb1kAD0CgYBb60T8GmoWRS4rS20J8KMs2Cmk0XmJHHNlSweYwO1fNFXXUwYG+bWj +ZNdOc5eLtNBi8at5vbK+c5fq+IRfgYZbdbFMqZwq366kUc5+BnCphdKOb4M9M60t +PtpalMa4s+J0SM3snolKUz45Lnz2KXVu3vy+rXScdo5+RJCNsD/xxg== +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_HARVESTER_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUF+41lzP8r7pBiPCZFG7cMvOPcnowDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkzMFoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC2wkXkBcUaOlajfjIsrbJPbKnSspyB9PbJ2nT/Nga/za94 +79C2tTntMhbh40hT6E00HHxmwDOpzEEH+C+vkmhR3zkTFmP9uV2jSyylwBwWnTru +9io58MA/G25FMYH7a/3lKYspeh/mSKWqhV2xN07Mov9JbNAUVT13oHvUMlmhxaoX +pTKehNH6u3dm8ovYlZyimVRbu8d88Ke5atjV613Ci1zV63b/Vt5YmWR3bAw6h10W +UMSrh5pDEXuKplS9dTYOwfkVLhIinFSbyw66k9X1qNZIF2M10rvW8FsZxwtHbdAI +ArD4kB7FrsoezBW2+Drap4aeHD1cMOYZPh9XnW05AgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQAs7LdVyhNjP4DiXaKCy9De +7skX66TzJiwBBQ+fXjvAcOZCmn6lrje5ZA1pEE2e26huygXcADPntZJWgaV8uQ0M +SXml0t5eSbDFlxOOOVTk7bRyt3+Wj3kz4N0P9ehLKtemKd7A0kYrgcFhylQrEHFq +Ijo8uEhv77AzhJfNHDbqw+qax3rvOG2b1H+7yyn6u6kdiOVbGUd1ChIh1zTFFYrT +WJbF+67bEFy/AEUYFdK53x6M94NWoBKqkIrgvbjf6G+++6IiL+PpaR0j3Dnu86ea +anXRdbkhy36143Kk8GUy/Vx0e0L+aAbLDwobngzvMYactqDo7pqcDaORLSLKiQT5 +-----END CERTIFICATE----- +""" + +SSL_TEST_HARVESTER_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEAtsJF5AXFGjpWo34yLK2yT2yp0rKcgfT2ydp0/zYGv82veO/Q +trU57TIW4eNIU+hNNBx8ZsAzqcxBB/gvr5JoUd85ExZj/bldo0sspcAcFp067vYq +OfDAPxtuRTGB+2v95SmLKXof5kilqoVdsTdOzKL/SWzQFFU9d6B71DJZocWqF6Uy +noTR+rt3ZvKL2JWcoplUW7vHfPCnuWrY1etdwotc1et2/1beWJlkd2wMOoddFlDE +q4eaQxF7iqZUvXU2DsH5FS4SIpxUm8sOupPV9ajWSBdjNdK71vBbGccLR23QCAKw ++JAexa7KHswVtvg62qeGnhw9XDDmGT4fV51tOQIDAQABAoIBAGS74kAT+hdBzp1h +IpDD0MO8dkJ/Voq/FgQemFxPUBsKaUy0iosaiuo1sK0jVKuDIIK3rM4J5LATuEiH +QOl6PmvaKSBfOBASyw0Fk39sy06frWsnXhD/pUdjfD1BU47ccF6OrnjXKpwIsN+z +kPfsL0/WC/ZRtsNuVGoKmBZXBlaGqXqJyuK4ZUpY/qkhgmc16BZyUpYbe2dAjaEo +PoVri1pWGCnrOxOiBakwDAh4NQ340WKROIZi1/Z6q+oTEDBiPh17TVt6IBvL4IOl +fAXHocnksr4GatfiGEPnLkIeIo6OLNQ+bln11Qhpemmyr12eRbdpjBGcV/Pupp8q +fqrrWYECgYEA3e6LmnMqGHNg3HMUj3nUY1K5aRtTo2O/SsCH7hUXf43EXG6cSgo0 +W87cs3e5FgXmxId62CQsZF9jLYtvjN23TQMbqQnbSeUJH+gElRLowyD3x2jD9u2Q ++bG3QlJIFGjxvfVd24+Zj9OvWRNdk/pzbqHq/zFCwdTNB5P3E+qWCukCgYEA0tBQ +Ozw4HowUMJdwSLDgJFNAkeAsX6MnXUk9EIr+vP2fusKxKLpHBP/Ojk/X1MaBQyE3 +4q5EkL253iHOJ6+IoKQANgtBlADpScg08rfzBdY53bvZBN48wQTDCsfRtMdj7g3j +ALVLd2+zmx5KCYMab2nyLGSTgnU43KwXdRE9PdECgYAZptPeA0evUc61TFvpBYTm +Ag7KNk1hikr3Ae/0Nd3kcWdr46EO8cUBg5SA7eqnwADfYGVzjCLRazEUd5RqLMpe +DWjqDeiZzu5SEMhOzsO2oh3hn5te9DCYm9D5ynboXQTsFutFUIDIXghbfGCJlR44 +gGCgJHp52vXj1VdupuO22QKBgBqI3+Bk1wd5SD1JgneT09Keq/zwg4VSKu1B/66q +YB/3qHhAcz4WHERT0nL1N8xvY+vILZmZp8W0K8X66VDzdjYKDoC+7/UqHDMOQSPf +5XXxnfz73PgQ5QLCj642sn2Xr0tSciUvrJ0O8UNwD4+c8eHeKv5NdoewK4UTICy7 +C8NRAoGALmB7np+s+wCZCpA+cTkgZpzbqnwfRnqCrBx7Yj+ZVAa5CDZWqztwmSkY +u8Y5q/qsPB5Fbno7rVAWuyk/smrDLVi0w6trv6RaOS4dhhKGSOhsAK2jXka6OztX +y7mCud9RuNytEuuLjWQFt5syjyrmVtI55TxHrF9Q9ylQAdvL9DU= +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_TIMELORD_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUaTJzz6JzsH2ZddKgtyDaLvK0+fgwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkzMFoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQCcusqOeHXjSZtVYgT32PKxIjsW/TPBlv/ovjQpFIkBZTCC +Rp+O0BNUJ13Kv9MVyyprKlR3EMldjIxolACVS+UIieuIERjufyMQVBuqJg+qr80l +rbBwcKmzB496Lopi4DpX3W3kqaXd1c65RNCAhiQ50ZfEvFwLIhRzxC/ZofRW/iFX +0B2x+LE7TZ8uEXhtzVPc9GYVnEk/I2hN426pX59WmF/+xQ+HKguzCCBQ/7V6TiS8 +1dLw4z5aIKedBgvlX8ibDkCUp6jOOfUTh12Xx6nHd3TX9qhL5h9zDfWbdoBdr3PU +tYEgNXrYVq75HTlHoSRCuG4SccoVCwNzdKyjJ4mDAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQAKaLVA7Ogf7S4gIwv/3K88 +PGJxIhTcgMSyCVdKnPLWRUEofdZVMZEDcVI+l+4iB8sJ0XOs7fZp+bAnaQfgXzE2 +wyWAODuytYlYZYc42xlT0PhqNnRKLUKf6uLCtNZFgpmiVmqgvAkzk/SJXTPw2F7q +hFA8K70Z6Wh08rZCP3hXLk5A8h6ejcNBHAoOg7B8Z9AMPlHW474xoGUrLjl01H4S +6C2/7D/URCQFBTrLt4sIvtxe+cAtggB4DVpJk7eoxk7JL4CsRu8flqGLn1wFraqr +jIb+X70mOXY7cO1R0n0uJLgHTU1dDkMlV3xOVfqhE+pe7caknwI0Nfzvlar491Ct +-----END CERTIFICATE----- +""" + +SSL_TEST_TIMELORD_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEAnLrKjnh140mbVWIE99jysSI7Fv0zwZb/6L40KRSJAWUwgkaf +jtATVCddyr/TFcsqaypUdxDJXYyMaJQAlUvlCInriBEY7n8jEFQbqiYPqq/NJa2w +cHCpswePei6KYuA6V91t5Kml3dXOuUTQgIYkOdGXxLxcCyIUc8Qv2aH0Vv4hV9Ad +sfixO02fLhF4bc1T3PRmFZxJPyNoTeNuqV+fVphf/sUPhyoLswggUP+1ek4kvNXS +8OM+WiCnnQYL5V/Imw5AlKeozjn1E4ddl8epx3d01/aoS+Yfcw31m3aAXa9z1LWB +IDV62Fau+R05R6EkQrhuEnHKFQsDc3SsoyeJgwIDAQABAoIBACKhf3plkZ7sN79x +Din5rP6I0sesoRAInnk99eaR3AgL5OEUW9NBlNPGcwoGwsyQ/Ml7K/i3I9dg4/GD +qnFSuMPfPcTuCjVAsG2+N/KrwFB10f2eWFsv+b9OT1yvBfL9GscpbUvWVIkk4i27 +z9pmSYDhGAjnmer3188QrYYILCZAXnYmTQrqvHAOJEpxf7/4z2rcSVbVdez/58He +xjloGfKSWfITpPLhpcM0Fh4cpx9fUJHgK0rV6CcL369XXHiJZ/OtEY6n57jqfEZd +SQMUCAbxyZnb5Trl73ucBdcAkELjyURstlEBXuMQ65/USAZd1ndObjt25hYRBVTy +SBf6VnECgYEAyVvg3xBZduR8ioxnflQoyQmrgWBN3BNVNIypmMicF1fsaHVAXXB2 +gk7RjSKLNCzEZGkqcIOfw7nmC/aRdb6K6xOxeA2jC76ZP65dRqczOzDR7sDtW7CH +3zrMGMtvvjxzhtA7JhWtmDBmVzC8M3JeXiaVKuAjtEfKqwdB34RXfBkCgYEAx0KU +1ZCsIHY0BScRg/udckakILTVI76uGkQ/lEnEcbnTt2SB1NE7ityEVhTlcqWoKLbL +6N7X6BLENAifVgi+wj/n/v/OURCmQZZIWSgJNpV7q2XEURnRgcLqznUU95A8S1hq +QVeCABmzzNFX9NUsxG2MXkybqmgPBAtmEVYjZfsCgYACh1PYmUT2WEI0HzVBgd8N +P0DXHBV+OQPt6AJNN9+171W5rhdD1SC33DOHeTKUUieZNzTgOtbrx07bQZpsBxuJ +fjLRViKBCEC2awMi2wCqsp9AR03zw9DA/eUIPq3Fjs7Il57WiJkoexsd5y/F2Z7T +wdpHso7gObKS2UF7hBbxKQKBgEFRPw6e5P2jIbxKqUA1e9AY/fZGsNONzu6HTrwi +TkXlX1RvmuuTRsxnKu443Vnumaf2+/KzEd1eQXi5FtoR9c4hOsBpRE1ogsdfJwoq +yJJe//IYYvke2IGLzoKs+JmKa2lba0FOGSxFQJ40RXvZYVpmeqvyuthqUfnGbsfi +D6p/AoGAVQyoyJ3bgy2xWInoq49Dc99uo4bLmn4blaENuIUrEDV1p2JTd41jRLGx +pcv80SfZZtMa5YclBoezEhv8mrtBtnxNnNJ1UkDPmGagG88+avl/8FiBNtB+rZru +9Kh/jDmFddfY831nOdwgCMEZB/x9qCmyRTtzE35sKNZoAY2AVfs= +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_TIMELORD_PUBLIC_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUaXeigR1NhYcViVNvWOSNgb1hguMwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkzMFoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDlm9CbdDwaD7gUkwY+Y2by3np+QtBFoJtk4hcbdAQ4Vd27 +7sJGve+iYg4vCCg3fdpxKZrM7p8VlRlQOMu2+Nkel726yhvs9hALWx0UVppk4iKV +rj/dzd/Oiwaf/Tk3DwMnfiv4RyUU1YnVusUnche1KKHfwHGCzLAnlu286wQXruug +Xl6onBQiF3rDqkLVrHcqMiasCJHLS2S9xktDiKwNCphATHFuZtzUIZeJK+yNiF+M +JKXN1xQFq8k9kb2q8y8qAgf1dY3wW9Xj4iP1Qo9Bzx1CxJTLpezIk3QTcCWKUkE+ +2/4Nly+M5GoJDv59gzjvPmyWPTr6TZ3lrls/Z/rjAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQBQBbv4tGvdNY+P2A62GfhR +cyNDjXUKk+YHY64hGeiXp61l8e2Hf58lV9lgBoMpniXUvMk9Nx0g+d1Gsoc9VWHs +LP1MhVaf0zodeK45jJxuzCC+eDHSNmvhkUJEVD8LDgmHTJlddpwYBwKocyr4m3XX +2QMcgiKcYaqIt5MLFwCWuarQ6bXKT88qRVTxKTA4FoqXXqJKCbAsEMql1h+dvXeV +yTwPK3vuRrZxyiIYlILG/tgNS6P+qUwLCnYjoPX2Ml3djMkUhRBdsTWR8wWTYkb0 +qmqKNsNL7+OHzUI+Z8WBoja8MHVZohl0iDAvFO7Y67ovldeYS8mlb0Tv3nVRUhiM +-----END CERTIFICATE----- +""" + +SSL_TEST_TIMELORD_PUBLIC_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEA5ZvQm3Q8Gg+4FJMGPmNm8t56fkLQRaCbZOIXG3QEOFXdu+7C +Rr3vomIOLwgoN33acSmazO6fFZUZUDjLtvjZHpe9usob7PYQC1sdFFaaZOIila4/ +3c3fzosGn/05Nw8DJ34r+EclFNWJ1brFJ3IXtSih38BxgsywJ5btvOsEF67roF5e +qJwUIhd6w6pC1ax3KjImrAiRy0tkvcZLQ4isDQqYQExxbmbc1CGXiSvsjYhfjCSl +zdcUBavJPZG9qvMvKgIH9XWN8FvV4+Ij9UKPQc8dQsSUy6XsyJN0E3AlilJBPtv+ +DZcvjORqCQ7+fYM47z5slj06+k2d5a5bP2f64wIDAQABAoIBAQDd6juzk6LnGVwz +3mnBcLc2ctp3H8JGGVU3KuFkcjwF6s+U7M0uLDLogdbtk/eyslum1aw890AgTuuZ +Qlt564eFbuk8GEznOGcHYrd3ScCNUpZUjoZBrNHrwSjVBpv+3+6Pg/2hR7nKKhy+ +ynX0iuvo9m2FYW0UGxsCGHiMB6T78QoxeHczwLq2c8isG9cW4xsXvFOls/5du6a2 ++wHP0qMAk6BRJ2XNlEw5bHXcV9yTdLK+HhSyNDtzUGTQuj0BPAHKl31M72JsHpYn +ofiIem0+P1XWj/pvPAofNp545vmjfhlVTkkjEjwXZbSujBQRhZ5JRshR9T3nlB5a ++WKBHVJhAoGBAPVvqmMPbW2oOIg4drBwgTIXIgBvMtUvIMI2fDqyMm+aQXfKowty +17Q470D2RHZ4CKm4KtGxP7zoPnsJ39XHXTrr2gono3t+mghwkYuroFNXOs0y1P3U +Y2BH++6rGpLv8yxMPaJo+1mVjXSIzeJSlGgKGaoy/+9qbcpf3NcUv1BxAoGBAO99 +wPlQYHgrp9C0KDjh8OWXiI9HdCTBZ+qE7AuiM2HGoF4WSe+BvpeBWQTzPcEPB/sK +nHW8GQ6u1TPpJamuvdg/hnLOmx7sPwsD98FkocMmbeaf/vnlSwXNZEdbypRNeggy +5utbfYf2520dmn73dMGEZSXfgj7ldJgouptBHmqTAoGAGcT0rdvz0FymOt86zwGw +/vJg1ozWWH3PQbT4zCzjkMYwc4RqJAyVy01jCX4R6CJoPnGgxU2H9Kypyr9Zqhd5 +mXMj/Ib26kN7psEy9ug5OCbjfKIGrPP8zyIfuIpsitr4vEDxA7lkEp7aME8g1s92 +14mf8jfSmW+iQWpZRJfgEnECgYBIdu6LAY0PD3aJqdl5zLPNZJqHcAFula7RwUKD +CqMtdKJVlbztYX6/7P14h/kpj1jE1yMcZLvYO4J7YJJq01rSMfaGiolZQ/aXaK3w +sHhZyij63XKTPpQCv3EWPmn/kanZDT3d/SLwnv7Lf2ed/1Yur9bDLOwGB/vNhpVg +IMYJTQKBgHp287GYTmfEIYQt8TwpFdIiehOc51bV62iD5ittj8oh98s+1+TxVvED +rpkuO0w2IV/CCMPagmh+5zHVeEjr87w2qTEzukw/uhsyqDDlwgStxv5mqGTHPBDQ +EDnFBXhZeOJsVFQFZ89HQ8hR4EyvkDRIW7X5oX54VxizlNpfpb4H +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_CRAWLER_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUdCBu6ITWB8mIr3CFYUGSoidgl9IwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkzMFoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6CqdPjfQSDqwE+0QwTkW3Gq2z+SdyOkCbA1f65tpk9dzN +yLx2xtHRV433IUFRxY4slpeO/ff/yWI11e8aubv1TJt1Df2XJWsrTSpasHiB0cQu +sBIUPCw0KkvNsZ93UVRArKyiNIut3tFTvM54hzUsSpMnH3gUiF2osJP/qFi9Fm4w +nHhhvjnm98YZ73r9qmS7x1pRLkduOLauQrZeMGtfqPbrDn+zrXISJz/WlVs1RFtj +S//fsuWYX1mecsowyj2uPgCiWxd4uYcnYEmv8o1+3yMucR6dWQCQxxLFaN4vgksz +vxQRQ+GzLYBG4rGXaJhuTd7zNX4MAvFC7dZF4Ey/AgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQCWFqbiMrpwtfPP9S5YKnFw +kv6aDeUeq6GYfoBdKYnVpfaXQgPXzc8eiNXptAPuMIVoSn811Hg+p9SsEjKBjPlZ +jdbbl44S2owhrJ7N4H5qTSoryBvuTwlh+aQDsDh+x5uO7PQzb2F3yU2cM2MvtU+2 +4pYr0Pucs2A0XzqWp+cZLhWHcTOm391Ab+Vr+Q/ZguvOxbmsBCs+qwSlPaktd9Yw +AqNKFau9hAnb++jd3k08EN8GBVlQBP/njdEoWEGjHD2SnTo2z1sv5jF+t9E28Swm +QbkNYNrgryTYJzPDZMMrK6DkkEFnH0djbKjwAdkooHr0pa9COcuYMhsqNMZ8irgY +-----END CERTIFICATE----- +""" + +SSL_TEST_CRAWLER_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAugqnT430Eg6sBPtEME5Ftxqts/kncjpAmwNX+ubaZPXczci8 +dsbR0VeN9yFBUcWOLJaXjv33/8liNdXvGrm79UybdQ39lyVrK00qWrB4gdHELrAS +FDwsNCpLzbGfd1FUQKysojSLrd7RU7zOeIc1LEqTJx94FIhdqLCT/6hYvRZuMJx4 +Yb455vfGGe96/apku8daUS5Hbji2rkK2XjBrX6j26w5/s61yEic/1pVbNURbY0v/ +37LlmF9ZnnLKMMo9rj4AolsXeLmHJ2BJr/KNft8jLnEenVkAkMcSxWjeL4JLM78U +EUPhsy2ARuKxl2iYbk3e8zV+DALxQu3WReBMvwIDAQABAoIBAFXwie1EA9U7ldcP +QyaVYbr9xfP3SnOH2URCPSgX8BbnREKDUhwEJ/RuX5QjdosRmWWbgxN42lD8dDOu +Sa+s0Ni1tLJT7iseC+2Kzd/q2SAPCHMQvqk+SqUmTLIONT3nAeaGXZDoeQWugkAO +XcprmvKE2IkgDlZdz/YW66cT2zotEggMAubtRTRZy5k9UwhZkHCB98dbCrLKDS2T +TECySx4OnhTbvVheIjXLZSHAI4KDyOfnkb4yYiiOYNnXaGMMqXJ6ITc4L055W+Sg +aqPXxifgK04cuceyciQH74HxWypFQMJX1HyOJ9qz5dF8FsJO8vw+USEcsMQvkaSi ++/iT02ECgYEA7cLr2c2vtAzEz/KqFH1ll5LALSmFlDfIr/s7ljDEmrgMMuJc8gQ5 +2UPiZhd5DMUBD1yncAd+O8QjoC/GBecsoAfeRYwowCO1VFZ+EdbL4X5NwdL4HwLe +KNiR3EzfWpEZPO8FAKHJdyoZhogV2aj8Wd1JgcW8xrIQHZIImeRg3scCgYEAyFAT +h+h2zWk76JTAvSDLWSRXBDdYuMc3dINu0Nv3pY86Kpxjq8nFdsdsP4gIoHleG5M6 +3RWljKFxALckNzgRoRt18GqX9k0c3svXWY1UhVgI+TFTwjm5JgkzIvAzWqB0BeZ8 +scxNyAkn/sYBa+SQw4l66Cq7uS/4OS3sC90LCkkCgYEAtsm0KK5I9lMavAQDXd1J +zU21EQNq/pgkYab0GHNFsuzr8/KzIhy9nJrj4zkIhxitx/GjiC06jxgri2svAjrH +xABIkY8/hPfu3/fe1DgeZi2D+g8HUlASG7Tj7knrLOWAUagwYFwBVuu21AarRbr0 +xuGpMWujxd3/JbyvgCBjmOECgYA4LNS9WYDvrCJj4EuI/ohocFuC0C6uaxfvMejC +4904bclHJ+J/y67314dQ7cpVjpPIsephE/AAV0oEhFfAsJWpE7VofcwuA4QkKxAy +igL4/i5OC/pMTrnQo+XWV3xfXv4KpY+0oPHzNjYkKc0+P7QlUgnI0CsjDQPUrT80 +OIIfGQKBgGSf00zTS9KDIHKtWkZi4qdMmUDiIoxlZ27eZelfF7XMNxm+eP5gtGPZ +Hq0JKSswlMQZE+KWakyaVh6OnGRdGLM2yuU4tYjU5ZgJ/O5BuZykCFLb4OPq7Uos +Wx8tJU4lx2r0q+TFzVwMv92K/p0sIGvHVfTn9/xNwtZAI561vEcu +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_DAEMON_PRIVATE_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUJWB6PMvY6/sycKKe2rKlyk2Jhx0wDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkzMFoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQDpNyGq9RLF09KE+uiFLgNAWUXiUWRDWS86+S+knZMa40Pi +iDdpxcRxNgxUVioleNfKIuXQp1eKCwCuAv8js9hRqOIkEfZHtiNaai4iJWYKD8v6 +/Mh1iTQ8evvsxR9Edlr2vpf86uWcIZ6NfD2R0QuDNi/rEQimilQr9O0zgpVcZ/rX +lu/ApUkBZP7nRXSgFDwyxub9eGO/XXYCFiaznFEewdEwMxJ7mekMejT+47QZj1PJ +JLII1sgGUMOnwauUqub4L3ibcFtWVI948ckq/vaYsX/MVYZ+Vr8sDpcuAZC+2FuZ +Wj8cjoFXGG2uHbXilw/+9uHiIpH9jE7sQLz7RUOjAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQCCivAYNk17t6dwt0l3GmiO +eEQp2nXF7hkt3Nws4+GefOrcCzyTAoinwGzoSJpuv6YdIp8txyylWeEVVrvJRXyg +3m648yIgnp3U5fSD6a2V7GnCSOjCoT1dlcIMFPuOk/XKN/0acfAEsJGscS0y/mVQ +MiJjjNv3K+ZzY8nDu+UxdC+cqLaY3KFF9QarWNjyiDjRi+7NrJN6mdGtZITSND1w +3RXLCSaaB5VTHqkSTGNrSMr8Y5CGgXyPq9sQMLS2Hfb8K/Y57xlnuJJEkHo09pUF +mz79hUFHqgjrtxAd4UoBUujTpwBN1on/KFrYa7fGwmisb1V35Qjjogs8AGD8tnh7 +-----END CERTIFICATE----- +""" + +SSL_TEST_DAEMON_PRIVATE_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEA6TchqvUSxdPShProhS4DQFlF4lFkQ1kvOvkvpJ2TGuND4og3 +acXEcTYMVFYqJXjXyiLl0KdXigsArgL/I7PYUajiJBH2R7YjWmouIiVmCg/L+vzI +dYk0PHr77MUfRHZa9r6X/OrlnCGejXw9kdELgzYv6xEIpopUK/TtM4KVXGf615bv +wKVJAWT+50V0oBQ8Msbm/Xhjv112AhYms5xRHsHRMDMSe5npDHo0/uO0GY9TySSy +CNbIBlDDp8GrlKrm+C94m3BbVlSPePHJKv72mLF/zFWGfla/LA6XLgGQvthbmVo/ +HI6BVxhtrh214pcP/vbh4iKR/YxO7EC8+0VDowIDAQABAoIBAAPMBP1OjiawYy4N +E7oPXLgwe+XKY3KBQjaYlgD9G8cFSjam9xf+w0sAkUTSPk9r3z+IP+ucvd0efr1W +iSbgp7X0pPHnZPYX7g1ryyJ9L2McjLqiYPUg7bvKWM2rC+5Gawa3ZawVevWGypkN +G8eC+sgBGtid52EmwWYRz8bV6m6drs+JJ0wY6TBMggL5z7aOBgVmMhJosdTxBlg2 +mUMYVGXFkwhoOtTvQP4C4jTJ7cgLAqXvfnKiT1LAWrt8uQLeplyHCvabAP2yyM45 +YpkTMwtlidK5dJ4qL1TFRCaHrQzRcgg41GDB/BR6MOLo4QNyh1RcKxISCM/5pheE +Hry6x1ECgYEA+ZoZ5eAuAwku/073VtL+nmiL5yslEynJVf3WoW7BZbwjBdE1cyPL +kiFT47Pw+RYB1Z5OWhPKzzeWrH11I2FP1IwuahPbCrM04Z4VvjYrXj6GsX4CXLyT +9zyyGq4WQh1eW+MwZk9zrTgL2H70Wkybl6cdmDssXKV3Sy5s1rc1g9kCgYEA7zGA +MpqZCL0FsvFcG1Bi+VcDtBmjocQokeyCWHn5/dXKgfVcVeLxJW4ts/sFTtB/prpH +QZ0Na/Tzy93kw8y/yPZYCCLSl7n4c0+oQv0IWZa6d96xXxx/9n27wWg1TghJFxBo +kDPyFIzeq3kdYUQJrd+G493hH4Iyv82cp+viodsCgYEAuObsinsg+sTB2QYBeoNB +dc3S3gP7KhAJgzdQ2TP39sqBU1zg8JOyyWUBBSyWtZ8U6s+kEVyaIBl49/zUWspK +3hSeiZx95pZM9Vorl0X/qIg/NZs4WsSkBEIlWlheSsoAzacmgpQXCFn9hHq/v2kC +1jxJUy16toMpNTuGCyWbcjkCgYByAdENzZwlixrdSKdTKYSTPcM5I4NXxkxkCSuz +iif6sdz9BnrFQQ8ZfSNxhrLn9v7w9BakknvkOfO99vxjywKagbhB4H8p7G0cYRpd +G4fQU8R6//zgzY+8Z/+G1umZUN+ti5ebK/c1jlNPvcGgK7LFWiZME+SKhR81RoZl +j0wNQwKBgQD5QzQkxZmprgcoMfpg9KQKnAnEjRT09v0JygBCSkc9lyjU16xL32hS +miOy+/MGYilWacKiqkky+AvjnjHRtE9lSmvxaLLkuObFuMwPyELDOsQkkKEofztG +HI0r3T+jYkXCDt33mW9uE84DlJf0n5QQbpEJNsfumB6ODTh/rLl0MA== +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_INTRODUCER_PUBLIC_CRT = b"""-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUIOpxHZYryCoSWIfdQ8uCSoeS3KkwDQYJKoZIhvcNAQEL +BQAwRDENMAsGA1UECgwEQ2hpYTEQMA4GA1UEAwwHQ2hpYSBDQTEhMB8GA1UECwwY +T3JnYW5pYyBGYXJtaW5nIERpdmlzaW9uMCAXDTIyMDMyMjEwMjkzMFoYDzIxMDAw +ODAyMDAwMDAwWjBBMQ0wCwYDVQQDDARDaGlhMQ0wCwYDVQQKDARDaGlhMSEwHwYD +VQQLDBhPcmdhbmljIEZhcm1pbmcgRGl2aXNpb24wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC/LMgHvqhwBTGYi8fLSDC5BAMvpZlHojkCtD2tAe8x4xES +ziFbEN0h3majAaFEbKWf38QwZb8+MTqtqC3hBXLlmQMOHJ98B+pcJiquWmDFadWm +mRv/aSsDcN8Nuil07mTYVl4KjqJ3BIuBgBF6VHU5EtALFPwM/xnFONPB5BC4Gm6X +/Bb9QQ4lBZVbXvuaHoiY/qXZeM/M0J4jGjgW3CvFKx6Cg3QrSPTZQRo7YoFOJzCe +WEU1NjaY32vstiK7qTFJCZ+Vfk3NNU0QealoqUdd7SeTNgPwEpYlTLalyKJHGPAU +yeq2LHmUX9F81MZIdk3Y2ugwonIjdAgo2d1Bft1nAgMBAAGjFzAVMBMGA1UdEQQM +MAqCCGNoaWEubmV0MA0GCSqGSIb3DQEBCwUAA4IBAQC1ACGsaR3WXsh2iMZEtbFU +JDbmDgviv1WCft7Lt0lpTWCNq24PXn5EOFU2UPBcsLCjoMfgvjj+b4dVcGt7mX91 +dtMIwEORe9stfr1Y1Frql9nMgk8PyRYDt4oUUUwwZ/MjqU3ZiP4znsiZuEGTAdKb +BqhVubSZdYOIrYV5Chbta7/OXxXpOv458CWLKqvfoDVsWldhQDWOkeh6nz8dkPO3 +Jt0IRUPqS7TV2fUcbHLpO3z1xUxL83xN3wgoBafSSbvVcLAN1+//+1JqLPxznSjV +rYf9ERqDwJpIGysbRvIyu+ahf0zJwBwob/O6+1vuryLQ2SdMFIlk57U6JOkePfEy +-----END CERTIFICATE----- +""" + +SSL_TEST_INTRODUCER_PUBLIC_KEY = b"""-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAvyzIB76ocAUxmIvHy0gwuQQDL6WZR6I5ArQ9rQHvMeMREs4h +WxDdId5mowGhRGyln9/EMGW/PjE6ragt4QVy5ZkDDhyffAfqXCYqrlpgxWnVppkb +/2krA3DfDbopdO5k2FZeCo6idwSLgYARelR1ORLQCxT8DP8ZxTjTweQQuBpul/wW +/UEOJQWVW177mh6ImP6l2XjPzNCeIxo4FtwrxSsegoN0K0j02UEaO2KBTicwnlhF +NTY2mN9r7LYiu6kxSQmflX5NzTVNEHmpaKlHXe0nkzYD8BKWJUy2pciiRxjwFMnq +tix5lF/RfNTGSHZN2NroMKJyI3QIKNndQX7dZwIDAQABAoIBAQCoMQPDHJAgDdG2 +fbPHOrny7H7JGo4iIay6nkxsu3jvkO/idYuPDOUf+QSfgL2a72M/pqR6V+nLE5Cm +W4IRqLOPH/E6JyCBBI3BiKqgPk9JH3WiXq3tJV98ZX84GoKCp4H9eu69pwN0ZoE9 +66h00X1YOx7hwRKHdJ/9jaNvv/CdpsyNHsqK86HyI80WbdN/y0ib2CpWvDD0hMqz +x2svsUE7FPSpqqMVyXR9OH1gZ7xPDf9fO4/wFlK6BaGcbcq9/nLG5gsWMGGrH7i2 +yPGn5K80yzNW4b23SHVVcwKQY2+Q6bOu4t68Vvft+m1kMe8IkyEGyNNcksRjb9FO +L3RBSVTxAoGBAPMJ6dqGMBPeqkfk6QgAPTwVtJQerPO3O3hdTha8VTRY5k70xQOI +hC6fusAnuy//ZtqYS/U2rScEa3rpJk3UjVZ/fRzkSUK898MwHNiDNsFZrspDS/Yl +wYk0vRMgz7+cG/VfG2N8DV8BngxIBNa0X3C8A3vT/MsHVxYlsbGuZZVjAoGBAMle +zBzczZe1W2vkrvhTsIK6kovsMXBU9bz6VKMusZ8lWATrXkjaDYSCla0OT9IATfOX +w43KmG2t3Z+TXcm3CU9UpAZRkpFErd7hxGGApAP0TWOHG3NK3KiI137G4RHRoxE1 +eHpImN1MJFl0SgMMyOrVIvbfvb1jgcYcH7t4imktAoGBAO82LbeJZh7Yha+XronS +enL+RiuX+dEz41P4OlkEa7THX4ANSTDOGJQvYUeqk4KNlrXHOtQTSeBiaEuk2a+3 +apndh859H2KRzieO3oV4uNccJ38rN8QBq3kZsJP4MqK8y4P6ZWHJAvwlAmPCKwkM +pfe3BpLFt0Y6ZkwFM93X8mJTAoGAfjklyJG/bXEItUDLTG1pHwjEA2EyPC+FOcfQ +ddk3DYLjAXJnz1KfVohkOe3WqtP2CNMAiUiM83MgkH5XM7G/7DIp/qvzK4vZUPRD +nLp+FNx2BgUSd9pdJmdgbN9NBVZa2NajhkMrTswDnO7/1ZmV911SZV0qGiTdm8jV +OzX7zKECgYA7XzxqMEiTeyWnKbewk+QomhddzPpQ8JKTBVTSCY+LVsBaRNSLqloX +0jSpEfr1Zd8WocUYdheV+DEPC0XbUtdZhC33QYviEbnZ+DKZ+h5fxNVPf8MRBY13 +xDGazUAN3pGUwMzKB9MhLCAQl/iiJUEid1nxIzgvV3uQkeqjxJkffQ== +-----END RSA PRIVATE KEY----- +""" + +SSL_TEST_PRIVATE_CA_CERT_AND_KEY_7: Tuple[bytes, bytes] = (SSL_TEST_PRIVATE_CA_CRT, SSL_TEST_PRIVATE_CA_KEY) + +SSL_TEST_NODE_CERTS_AND_KEYS_7: Dict[str, Dict[str, Dict[str, bytes]]] = { + "full_node": { + "private": {"crt": SSL_TEST_FULLNODE_PRIVATE_CRT, "key": SSL_TEST_FULLNODE_PRIVATE_KEY}, + "public": {"crt": SSL_TEST_FULLNODE_PUBLIC_CRT, "key": SSL_TEST_FULLNODE_PUBLIC_KEY}, + }, + "wallet": { + "private": {"crt": SSL_TEST_WALLET_PRIVATE_CRT, "key": SSL_TEST_WALLET_PRIVATE_KEY}, + "public": {"crt": SSL_TEST_WALLET_PUBLIC_CRT, "key": SSL_TEST_WALLET_PUBLIC_KEY}, + }, + "farmer": { + "private": {"crt": SSL_TEST_FARMER_PRIVATE_CRT, "key": SSL_TEST_FARMER_PRIVATE_KEY}, + "public": {"crt": SSL_TEST_FARMER_PUBLIC_CRT, "key": SSL_TEST_FARMER_PUBLIC_KEY}, + }, + "harvester": { + "private": {"crt": SSL_TEST_HARVESTER_PRIVATE_CRT, "key": SSL_TEST_HARVESTER_PRIVATE_KEY}, + }, + "timelord": { + "private": {"crt": SSL_TEST_TIMELORD_PRIVATE_CRT, "key": SSL_TEST_TIMELORD_PRIVATE_KEY}, + "public": {"crt": SSL_TEST_TIMELORD_PUBLIC_CRT, "key": SSL_TEST_TIMELORD_PUBLIC_KEY}, + }, + "crawler": { + "private": {"crt": SSL_TEST_CRAWLER_PRIVATE_CRT, "key": SSL_TEST_CRAWLER_PRIVATE_KEY}, + }, + "daemon": { + "private": {"crt": SSL_TEST_DAEMON_PRIVATE_CRT, "key": SSL_TEST_DAEMON_PRIVATE_KEY}, + }, + "introducer": { + "public": {"crt": SSL_TEST_INTRODUCER_PUBLIC_CRT, "key": SSL_TEST_INTRODUCER_PUBLIC_KEY}, + }, +} diff --git a/tests/wallet/cat_wallet/config.py b/tests/wallet/cat_wallet/config.py index a805fb7b88..eb21fe13cd 100644 --- a/tests/wallet/cat_wallet/config.py +++ b/tests/wallet/cat_wallet/config.py @@ -1 +1,2 @@ +# flake8: noqa: E501 job_timeout = 50 diff --git a/tests/wallet/cat_wallet/test_cat_lifecycle.py b/tests/wallet/cat_wallet/test_cat_lifecycle.py index b4bdf889b1..c56a6d95ab 100644 --- a/tests/wallet/cat_wallet/test_cat_lifecycle.py +++ b/tests/wallet/cat_wallet/test_cat_lifecycle.py @@ -1,49 +1,39 @@ -import pytest -import pytest_asyncio - from typing import List, Tuple, Optional, Dict + +import pytest from blspy import PrivateKey, AugSchemeMPL, G2Element from clvm.casts import int_to_bytes from chia.clvm.spend_sim import SpendSim, SimClient -from chia.types.blockchain_format.program import Program from chia.types.blockchain_format.coin import Coin +from chia.types.blockchain_format.program import Program from chia.types.blockchain_format.sized_bytes import bytes32 -from chia.types.spend_bundle import SpendBundle from chia.types.coin_spend import CoinSpend from chia.types.mempool_inclusion_status import MempoolInclusionStatus +from chia.types.spend_bundle import SpendBundle from chia.util.errors import Err from chia.util.ints import uint64 -from chia.wallet.lineage_proof import LineageProof from chia.wallet.cat_wallet.cat_utils import ( CAT_MOD, SpendableCAT, construct_cat_puzzle, unsigned_spend_bundle_for_spendable_cats, ) +from chia.wallet.lineage_proof import LineageProof from chia.wallet.puzzles.tails import ( GenesisById, GenesisByPuzhash, EverythingWithSig, DelegatedLimitations, ) - -from tests.clvm.test_puzzles import secret_exponent_for_index from tests.clvm.benchmark_costs import cost_of_spend_bundle +from tests.clvm.test_puzzles import secret_exponent_for_index acs = Program.to(1) acs_ph = acs.get_tree_hash() NO_LINEAGE_PROOF = LineageProof() -@pytest_asyncio.fixture(scope="function") -async def setup_sim(): - sim = await SpendSim.create() - sim_client = SimClient(sim) - await sim.farm_block() - return sim, sim_client - - async def do_spend( sim: SpendSim, sim_client: SimClient, diff --git a/tests/wallet/cat_wallet/test_cat_wallet.py b/tests/wallet/cat_wallet/test_cat_wallet.py index 808a76c529..a8c57100a8 100644 --- a/tests/wallet/cat_wallet/test_cat_wallet.py +++ b/tests/wallet/cat_wallet/test_cat_wallet.py @@ -2,7 +2,6 @@ import asyncio from typing import List import pytest -import pytest_asyncio from chia.consensus.block_rewards import calculate_base_farmer_reward, calculate_pool_reward from chia.full_node.mempool_manager import MempoolManager @@ -11,15 +10,14 @@ from chia.types.blockchain_format.coin import Coin from chia.types.blockchain_format.sized_bytes import bytes32 from chia.types.peer_info import PeerInfo from chia.util.ints import uint16, uint32, uint64 -from chia.wallet.cat_wallet.cat_utils import construct_cat_puzzle -from chia.wallet.cat_wallet.cat_wallet import CATWallet from chia.wallet.cat_wallet.cat_constants import DEFAULT_CATS from chia.wallet.cat_wallet.cat_info import LegacyCATInfo +from chia.wallet.cat_wallet.cat_utils import construct_cat_puzzle +from chia.wallet.cat_wallet.cat_wallet import CATWallet from chia.wallet.puzzles.cat_loader import CAT_MOD from chia.wallet.transaction_record import TransactionRecord from chia.wallet.wallet_info import WalletInfo from tests.pools.test_pool_rpc import wallet_is_synced -from tests.setup_nodes import setup_simulators_and_wallets from tests.time_out_assert import time_out_assert @@ -30,24 +28,6 @@ async def tx_in_pool(mempool: MempoolManager, tx_id: bytes32): return True -@pytest_asyncio.fixture(scope="function") -async def wallet_node_sim_and_wallet(): - async for _ in setup_simulators_and_wallets(1, 1, {}): - yield _ - - -@pytest_asyncio.fixture(scope="function") -async def two_wallet_nodes(): - async for _ in setup_simulators_and_wallets(1, 2, {}): - yield _ - - -@pytest_asyncio.fixture(scope="function") -async def three_wallet_nodes(): - async for _ in setup_simulators_and_wallets(1, 3, {}): - yield _ - - class TestCATWallet: @pytest.mark.parametrize( "trusted", diff --git a/tests/wallet/cat_wallet/test_offer_lifecycle.py b/tests/wallet/cat_wallet/test_offer_lifecycle.py index 7f1e9272e3..a2777376e8 100644 --- a/tests/wallet/cat_wallet/test_offer_lifecycle.py +++ b/tests/wallet/cat_wallet/test_offer_lifecycle.py @@ -1,17 +1,15 @@ -import pytest -import pytest_asyncio - from typing import Dict, Optional, List + +import pytest from blspy import G2Element -from chia.clvm.spend_sim import SpendSim, SimClient -from chia.types.blockchain_format.coin import Coin -from chia.types.blockchain_format.sized_bytes import bytes32 -from chia.types.blockchain_format.program import Program from chia.types.announcement import Announcement -from chia.types.spend_bundle import SpendBundle +from chia.types.blockchain_format.coin import Coin +from chia.types.blockchain_format.program import Program +from chia.types.blockchain_format.sized_bytes import bytes32 from chia.types.coin_spend import CoinSpend from chia.types.mempool_inclusion_status import MempoolInclusionStatus +from chia.types.spend_bundle import SpendBundle from chia.util.ints import uint64 from chia.wallet.cat_wallet.cat_utils import ( CAT_MOD, @@ -21,7 +19,6 @@ from chia.wallet.cat_wallet.cat_utils import ( ) from chia.wallet.payment import Payment from chia.wallet.trading.offer import Offer, NotarizedPayment - from tests.clvm.benchmark_costs import cost_of_spend_bundle acs = Program.to(1) @@ -41,14 +38,6 @@ def str_to_cat_hash(tail_str: str) -> bytes32: return construct_cat_puzzle(CAT_MOD, str_to_tail_hash(tail_str), acs).get_tree_hash() -@pytest_asyncio.fixture(scope="function") -async def setup_sim(): - sim = await SpendSim.create() - sim_client = SimClient(sim) - await sim.farm_block() - return sim, sim_client - - # This method takes a dictionary of strings mapping to amounts and generates the appropriate CAT/XCH coins async def generate_coins( sim, diff --git a/tests/wallet/cat_wallet/test_trades.py b/tests/wallet/cat_wallet/test_trades.py index f2366362a8..2ac4701bb2 100644 --- a/tests/wallet/cat_wallet/test_trades.py +++ b/tests/wallet/cat_wallet/test_trades.py @@ -3,19 +3,15 @@ from secrets import token_bytes from typing import List import pytest -import pytest_asyncio from chia.full_node.mempool_manager import MempoolManager from chia.simulator.simulator_protocol import FarmNewBlockProtocol -from chia.types.peer_info import PeerInfo -from chia.util.ints import uint16, uint64 +from chia.util.ints import uint64 from chia.wallet.cat_wallet.cat_wallet import CATWallet from chia.wallet.trading.offer import Offer from chia.wallet.trading.trade_status import TradeStatus from chia.wallet.transaction_record import TransactionRecord from chia.wallet.util.transaction_type import TransactionType -from tests.pools.test_pool_rpc import wallet_is_synced -from tests.setup_nodes import setup_simulators_and_wallets from tests.time_out_assert import time_out_assert @@ -26,58 +22,9 @@ async def tx_in_pool(mempool: MempoolManager, tx_id): return True -@pytest_asyncio.fixture(scope="function") -async def two_wallet_nodes(): - async for _ in setup_simulators_and_wallets(1, 2, {}): - yield _ - - buffer_blocks = 4 -@pytest_asyncio.fixture(scope="function") -async def wallets_prefarm(two_wallet_nodes, self_hostname, trusted): - """ - Sets up the node with 10 blocks, and returns a payer and payee wallet. - """ - farm_blocks = 10 - buffer = 4 - full_nodes, wallets = two_wallet_nodes - full_node_api = full_nodes[0] - full_node_server = full_node_api.server - wallet_node_0, wallet_server_0 = wallets[0] - wallet_node_1, wallet_server_1 = wallets[1] - wallet_0 = wallet_node_0.wallet_state_manager.main_wallet - wallet_1 = wallet_node_1.wallet_state_manager.main_wallet - - ph0 = await wallet_0.get_new_puzzlehash() - ph1 = await wallet_1.get_new_puzzlehash() - - if trusted: - wallet_node_0.config["trusted_peers"] = {full_node_server.node_id.hex(): full_node_server.node_id.hex()} - wallet_node_1.config["trusted_peers"] = {full_node_server.node_id.hex(): full_node_server.node_id.hex()} - else: - wallet_node_0.config["trusted_peers"] = {} - wallet_node_1.config["trusted_peers"] = {} - - await wallet_server_0.start_client(PeerInfo(self_hostname, uint16(full_node_server._port)), None) - await wallet_server_1.start_client(PeerInfo(self_hostname, uint16(full_node_server._port)), None) - - for i in range(0, farm_blocks): - await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph0)) - - for i in range(0, farm_blocks): - await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(ph1)) - - for i in range(0, buffer): - await full_node_api.farm_new_transaction_block(FarmNewBlockProtocol(token_bytes())) - - await time_out_assert(10, wallet_is_synced, True, wallet_node_0, full_node_api) - await time_out_assert(10, wallet_is_synced, True, wallet_node_1, full_node_api) - - return wallet_node_0, wallet_node_1, full_node_api - - @pytest.mark.parametrize( "trusted", [True, False], @@ -200,14 +147,12 @@ class TestCATTrades: await time_out_assert(15, get_trade_and_status, TradeStatus.CONFIRMED, trade_manager_maker, trade_make) await time_out_assert(15, get_trade_and_status, TradeStatus.CONFIRMED, trade_manager_taker, trade_take) - maker_txs = await wallet_node_maker.wallet_state_manager.tx_store.get_transactions_by_trade_id( - trade_make.trade_id - ) - taker_txs = await wallet_node_taker.wallet_state_manager.tx_store.get_transactions_by_trade_id( - trade_take.trade_id - ) - assert len(maker_txs) == 1 # The other side will show up as a regular incoming transaction - assert len(taker_txs) == 3 # One for each: the outgoing CAT, the incoming chia, and the outgoing chia fee + async def assert_trade_tx_number(wallet_node, trade_id, number): + txs = await wallet_node.wallet_state_manager.tx_store.get_transactions_by_trade_id(trade_id) + return len(txs) == number + + await time_out_assert(15, assert_trade_tx_number, True, wallet_node_maker, trade_make.trade_id, 1) + await time_out_assert(15, assert_trade_tx_number, True, wallet_node_taker, trade_take.trade_id, 3) # cat_for_chia success, trade_make, error = await trade_manager_maker.create_offer_for_ids(cat_for_chia) @@ -247,15 +192,8 @@ class TestCATTrades: await time_out_assert(15, cat_wallet_taker.get_unconfirmed_balance, TAKER_CAT_BALANCE) await time_out_assert(15, get_trade_and_status, TradeStatus.CONFIRMED, trade_manager_maker, trade_make) await time_out_assert(15, get_trade_and_status, TradeStatus.CONFIRMED, trade_manager_taker, trade_take) - - maker_txs = await wallet_node_maker.wallet_state_manager.tx_store.get_transactions_by_trade_id( - trade_make.trade_id - ) - taker_txs = await wallet_node_taker.wallet_state_manager.tx_store.get_transactions_by_trade_id( - trade_take.trade_id - ) - assert len(maker_txs) == 1 # The other side will show up as a regular incoming transaction - assert len(taker_txs) == 2 # One for each: the outgoing chia, the incoming CAT + await time_out_assert(15, assert_trade_tx_number, True, wallet_node_maker, trade_make.trade_id, 1) + await time_out_assert(15, assert_trade_tx_number, True, wallet_node_taker, trade_take.trade_id, 2) # cat_for_cat success, trade_make, error = await trade_manager_maker.create_offer_for_ids(cat_for_cat) diff --git a/tests/wallet/config.py b/tests/wallet/config.py index 7f9e1e1a76..e90fb48eaa 100644 --- a/tests/wallet/config.py +++ b/tests/wallet/config.py @@ -1 +1,3 @@ +# flake8: noqa: E501 +job_timeout = 40 parallel = True diff --git a/tests/wallet/did_wallet/test_did.py b/tests/wallet/did_wallet/test_did.py index 11b9bdd800..221a194583 100644 --- a/tests/wallet/did_wallet/test_did.py +++ b/tests/wallet/did_wallet/test_did.py @@ -1,43 +1,18 @@ import pytest -import pytest_asyncio -from chia.simulator.simulator_protocol import FarmNewBlockProtocol -from chia.types.peer_info import PeerInfo -from chia.util.ints import uint16, uint32, uint64 -from tests.setup_nodes import setup_simulators_and_wallets -from chia.wallet.did_wallet.did_wallet import DIDWallet -from chia.types.blockchain_format.program import Program from blspy import AugSchemeMPL -from chia.types.spend_bundle import SpendBundle + from chia.consensus.block_rewards import calculate_pool_reward, calculate_base_farmer_reward +from chia.simulator.simulator_protocol import FarmNewBlockProtocol +from chia.types.blockchain_format.program import Program +from chia.types.peer_info import PeerInfo +from chia.types.spend_bundle import SpendBundle +from chia.util.ints import uint16, uint32, uint64 +from chia.wallet.did_wallet.did_wallet import DIDWallet from tests.time_out_assert import time_out_assert, time_out_assert_not_none pytestmark = pytest.mark.skip("TODO: Fix tests") -@pytest_asyncio.fixture(scope="function") -async def two_wallet_nodes(): - async for _ in setup_simulators_and_wallets(1, 2, {}): - yield _ - - -@pytest_asyncio.fixture(scope="function") -async def three_wallet_nodes(): - async for _ in setup_simulators_and_wallets(1, 3, {}): - yield _ - - -@pytest_asyncio.fixture(scope="function") -async def two_wallet_nodes_five_freeze(): - async for _ in setup_simulators_and_wallets(1, 2, {}): - yield _ - - -@pytest_asyncio.fixture(scope="function") -async def three_sim_two_wallets(): - async for _ in setup_simulators_and_wallets(3, 2, {}): - yield _ - - class TestDIDWallet: @pytest.mark.asyncio async def test_creation_from_backup_file(self, self_hostname, three_wallet_nodes): diff --git a/tests/wallet/did_wallet/test_did_rpc.py b/tests/wallet/did_wallet/test_did_rpc.py index f393c3164a..75f8cc1b4a 100644 --- a/tests/wallet/did_wallet/test_did_rpc.py +++ b/tests/wallet/did_wallet/test_did_rpc.py @@ -1,6 +1,6 @@ import logging + import pytest -import pytest_asyncio from chia.rpc.rpc_server import start_rpc_server from chia.rpc.wallet_rpc_api import WalletRpcApi @@ -8,24 +8,16 @@ from chia.rpc.wallet_rpc_client import WalletRpcClient from chia.simulator.simulator_protocol import FarmNewBlockProtocol from chia.types.peer_info import PeerInfo from chia.util.ints import uint16, uint64 -from chia.wallet.util.wallet_types import WalletType -from tests.setup_nodes import setup_simulators_and_wallets -from tests.time_out_assert import time_out_assert from chia.wallet.did_wallet.did_wallet import DIDWallet +from chia.wallet.util.wallet_types import WalletType +from tests.time_out_assert import time_out_assert from tests.util.socket import find_available_listen_port - log = logging.getLogger(__name__) pytestmark = pytest.mark.skip("TODO: Fix tests") -@pytest_asyncio.fixture(scope="function") -async def three_wallet_nodes(): - async for _ in setup_simulators_and_wallets(1, 3, {}): - yield _ - - class TestDIDWallet: @pytest.mark.asyncio async def test_create_did(self, bt, three_wallet_nodes, self_hostname): diff --git a/tests/wallet/rl_wallet/test_rl_rpc.py b/tests/wallet/rl_wallet/test_rl_rpc.py index e387646e79..78a6f58da7 100644 --- a/tests/wallet/rl_wallet/test_rl_rpc.py +++ b/tests/wallet/rl_wallet/test_rl_rpc.py @@ -1,7 +1,6 @@ import asyncio import pytest -import pytest_asyncio from chia.rpc.wallet_rpc_api import WalletRpcApi from chia.simulator.simulator_protocol import FarmNewBlockProtocol @@ -13,7 +12,6 @@ from chia.util.bech32m import encode_puzzle_hash from chia.util.ints import uint16 from chia.wallet.transaction_record import TransactionRecord from chia.wallet.util.wallet_types import WalletType -from tests.setup_nodes import setup_simulators_and_wallets from tests.time_out_assert import time_out_assert from tests.wallet.sync.test_wallet_sync import wallet_height_at_least @@ -46,12 +44,6 @@ async def check_balance(api, wallet_id): return balance -@pytest_asyncio.fixture(scope="function") -async def three_wallet_nodes(): - async for _ in setup_simulators_and_wallets(1, 3, {}): - yield _ - - class TestRLWallet: @pytest.mark.asyncio @pytest.mark.skip diff --git a/tests/wallet/rl_wallet/test_rl_wallet.py b/tests/wallet/rl_wallet/test_rl_wallet.py index cee43b28fc..ebf0ddd595 100644 --- a/tests/wallet/rl_wallet/test_rl_wallet.py +++ b/tests/wallet/rl_wallet/test_rl_wallet.py @@ -1,20 +1,12 @@ import pytest -import pytest_asyncio from chia.simulator.simulator_protocol import FarmNewBlockProtocol from chia.types.peer_info import PeerInfo from chia.util.ints import uint16, uint64 from chia.wallet.rl_wallet.rl_wallet import RLWallet -from tests.setup_nodes import setup_simulators_and_wallets from tests.time_out_assert import time_out_assert -@pytest_asyncio.fixture(scope="function") -async def two_wallet_nodes(): - async for _ in setup_simulators_and_wallets(1, 2, {}): - yield _ - - class TestCATWallet: @pytest.mark.asyncio @pytest.mark.skip diff --git a/tests/wallet/rpc/test_wallet_rpc.py b/tests/wallet/rpc/test_wallet_rpc.py index bcfbb80ece..f92570b31a 100644 --- a/tests/wallet/rpc/test_wallet_rpc.py +++ b/tests/wallet/rpc/test_wallet_rpc.py @@ -1,19 +1,13 @@ import asyncio +import logging +from operator import attrgetter from typing import Dict, Optional +import pytest from blspy import G2Element -from chia.types.coin_record import CoinRecord -from chia.types.coin_spend import CoinSpend -from chia.types.spend_bundle import SpendBundle -from chia.util.config import get_config_lock, load_config, save_config -from operator import attrgetter -import logging - -import pytest -import pytest_asyncio - from chia.consensus.block_rewards import calculate_base_farmer_reward, calculate_pool_reward +from chia.consensus.coinbase import create_puzzlehash_for_pk from chia.rpc.full_node_rpc_api import FullNodeRpcApi from chia.rpc.full_node_rpc_client import FullNodeRpcClient from chia.rpc.rpc_server import start_rpc_server @@ -22,33 +16,29 @@ from chia.rpc.wallet_rpc_client import WalletRpcClient from chia.simulator.simulator_protocol import FarmNewBlockProtocol from chia.types.announcement import Announcement from chia.types.blockchain_format.program import Program +from chia.types.coin_record import CoinRecord +from chia.types.coin_spend import CoinSpend from chia.types.peer_info import PeerInfo +from chia.types.spend_bundle import SpendBundle from chia.util.bech32m import decode_puzzle_hash, encode_puzzle_hash -from chia.consensus.coinbase import create_puzzlehash_for_pk +from chia.util.config import lock_and_load_config, save_config from chia.util.hash import std_hash -from chia.wallet.derive_keys import master_sk_to_wallet_sk from chia.util.ints import uint16, uint32, uint64 from chia.wallet.cat_wallet.cat_constants import DEFAULT_CATS from chia.wallet.cat_wallet.cat_wallet import CATWallet +from chia.wallet.derive_keys import master_sk_to_wallet_sk from chia.wallet.trading.trade_status import TradeStatus from chia.wallet.transaction_record import TransactionRecord from chia.wallet.transaction_sorting import SortKey from chia.wallet.util.compute_memos import compute_memos from chia.wallet.util.wallet_types import WalletType from tests.pools.test_pool_rpc import wallet_is_synced -from tests.setup_nodes import setup_simulators_and_wallets from tests.time_out_assert import time_out_assert from tests.util.socket import find_available_listen_port log = logging.getLogger(__name__) -@pytest_asyncio.fixture(scope="function") -async def two_wallet_nodes(): - async for _ in setup_simulators_and_wallets(1, 2, {}): - yield _ - - async def assert_wallet_types(client: WalletRpcClient, expected: Dict[WalletType, int]) -> None: for wallet_type in WalletType: wallets = await client.get_wallets(wallet_type) @@ -626,8 +616,7 @@ class TestWalletRpc: # set farmer to first private key sk = await wallet_node.get_key_for_fingerprint(pks[0]) test_ph = create_puzzlehash_for_pk(master_sk_to_wallet_sk(sk, uint32(0)).get_g1()) - with get_config_lock(wallet_node.root_path, "config.yaml"): - test_config = load_config(wallet_node.root_path, "config.yaml", acquire_lock=False) + with lock_and_load_config(wallet_node.root_path, "config.yaml") as test_config: test_config["farmer"]["xch_target_address"] = encode_puzzle_hash(test_ph, "txch") # set pool to second private key sk = await wallet_node.get_key_for_fingerprint(pks[1]) diff --git a/tests/wallet/simple_sync/test_simple_sync_protocol.py b/tests/wallet/simple_sync/test_simple_sync_protocol.py index 2e45359f57..bcbd59c5b7 100644 --- a/tests/wallet/simple_sync/test_simple_sync_protocol.py +++ b/tests/wallet/simple_sync/test_simple_sync_protocol.py @@ -3,15 +3,14 @@ import asyncio from typing import List, Optional import pytest -import pytest_asyncio from clvm.casts import int_to_bytes from colorlog import getLogger from chia.consensus.block_rewards import calculate_pool_reward, calculate_base_farmer_reward -from chia.protocols import wallet_protocol, full_node_protocol +from chia.protocols import wallet_protocol from chia.protocols.full_node_protocol import RespondTransaction from chia.protocols.protocol_message_types import ProtocolMessageTypes -from chia.protocols.wallet_protocol import RespondToCoinUpdates, CoinStateUpdate, RespondToPhUpdates, CoinState +from chia.protocols.wallet_protocol import RespondToCoinUpdates, CoinStateUpdate, RespondToPhUpdates from chia.server.outbound_message import NodeType from chia.simulator.simulator_protocol import FarmNewBlockProtocol, ReorgProtocol from chia.types.blockchain_format.coin import Coin @@ -25,7 +24,6 @@ from chia.wallet.wallet import Wallet from chia.wallet.wallet_state_manager import WalletStateManager from tests.connection_utils import add_dummy_connection from tests.pools.test_pool_rpc import wallet_is_synced -from tests.setup_nodes import setup_simulators_and_wallets from tests.time_out_assert import time_out_assert from tests.wallet.cat_wallet.test_cat_wallet import tx_in_pool from tests.wallet_tools import WalletTool @@ -41,18 +39,6 @@ def wallet_height_at_least(wallet_node, h): log = getLogger(__name__) -@pytest_asyncio.fixture(scope="function") -async def wallet_node_simulator(): - async for _ in setup_simulators_and_wallets(1, 1, {}): - yield _ - - -@pytest_asyncio.fixture(scope="function") -async def wallet_two_node_simulator(): - async for _ in setup_simulators_and_wallets(2, 1, {}): - yield _ - - async def get_all_messages_in_queue(queue): all_messages = [] await asyncio.sleep(2) diff --git a/tests/wallet/sync/test_wallet_sync.py b/tests/wallet/sync/test_wallet_sync.py index e904a1a8d1..c98f78354c 100644 --- a/tests/wallet/sync/test_wallet_sync.py +++ b/tests/wallet/sync/test_wallet_sync.py @@ -2,7 +2,6 @@ import asyncio import pytest -import pytest_asyncio from colorlog import getLogger from chia.consensus.block_rewards import calculate_base_farmer_reward, calculate_pool_reward @@ -13,7 +12,7 @@ from chia.util.ints import uint16, uint32 from chia.wallet.wallet_state_manager import WalletStateManager from tests.connection_utils import disconnect_all_and_reconnect from tests.pools.test_pool_rpc import wallet_is_synced -from tests.setup_nodes import setup_node_and_wallet, setup_simulators_and_wallets, test_constants +from tests.setup_nodes import test_constants from tests.time_out_assert import time_out_assert @@ -27,24 +26,6 @@ def wallet_height_at_least(wallet_node, h): log = getLogger(__name__) -@pytest_asyncio.fixture(scope="function") -async def wallet_node(self_hostname): - async for _ in setup_node_and_wallet(test_constants, self_hostname): - yield _ - - -@pytest_asyncio.fixture(scope="function") -async def wallet_node_simulator(): - async for _ in setup_simulators_and_wallets(1, 1, {}): - yield _ - - -@pytest_asyncio.fixture(scope="function") -async def wallet_node_starting_height(self_hostname): - async for _ in setup_node_and_wallet(test_constants, self_hostname, starting_height=100): - yield _ - - class TestWalletSync: @pytest.mark.parametrize( "trusted", diff --git a/tests/wallet/test_wallet.py b/tests/wallet/test_wallet.py index bd75233fcb..02467334ac 100644 --- a/tests/wallet/test_wallet.py +++ b/tests/wallet/test_wallet.py @@ -1,7 +1,8 @@ import asyncio -import pytest -import pytest_asyncio import time + +import pytest + from chia.consensus.block_rewards import calculate_base_farmer_reward, calculate_pool_reward from chia.protocols.full_node_protocol import RespondBlock from chia.server.server import ChiaServer @@ -11,52 +12,15 @@ from chia.types.blockchain_format.sized_bytes import bytes32 from chia.types.peer_info import PeerInfo from chia.util.ints import uint16, uint32, uint64 from chia.wallet.derive_keys import master_sk_to_wallet_sk -from chia.wallet.util.transaction_type import TransactionType -from chia.wallet.util.compute_memos import compute_memos from chia.wallet.transaction_record import TransactionRecord +from chia.wallet.util.compute_memos import compute_memos +from chia.wallet.util.transaction_type import TransactionType from chia.wallet.wallet_node import WalletNode from chia.wallet.wallet_state_manager import WalletStateManager -from tests.setup_nodes import setup_simulators_and_wallets from tests.time_out_assert import time_out_assert, time_out_assert_not_none from tests.wallet.cat_wallet.test_cat_wallet import tx_in_pool -@pytest_asyncio.fixture(scope="function") -async def wallet_node(): - async for _ in setup_simulators_and_wallets(1, 1, {}): - yield _ - - -@pytest_asyncio.fixture(scope="function") -async def wallet_node_sim_and_wallet(): - async for _ in setup_simulators_and_wallets(1, 1, {}): - yield _ - - -@pytest_asyncio.fixture(scope="function") -async def wallet_node_100_pk(): - async for _ in setup_simulators_and_wallets(1, 1, {}, initial_num_public_keys=100): - yield _ - - -@pytest_asyncio.fixture(scope="function") -async def two_wallet_nodes(): - async for _ in setup_simulators_and_wallets(1, 2, {}): - yield _ - - -@pytest_asyncio.fixture(scope="function") -async def two_wallet_nodes_five_freeze(): - async for _ in setup_simulators_and_wallets(1, 2, {}): - yield _ - - -@pytest_asyncio.fixture(scope="function") -async def three_sim_two_wallets(): - async for _ in setup_simulators_and_wallets(3, 2, {}): - yield _ - - class TestWalletSimulator: @pytest.mark.parametrize( "trusted", diff --git a/tests/wallet/test_wallet_blockchain.py b/tests/wallet/test_wallet_blockchain.py index f2dd424f09..e5a84f5984 100644 --- a/tests/wallet/test_wallet_blockchain.py +++ b/tests/wallet/test_wallet_blockchain.py @@ -3,7 +3,6 @@ from pathlib import Path import aiosqlite import pytest -import pytest_asyncio from chia.consensus.blockchain import ReceiveBlockResult from chia.protocols import full_node_protocol @@ -13,13 +12,7 @@ from chia.util.db_wrapper import DBWrapper from chia.util.generator_tools import get_block_header from chia.wallet.key_val_store import KeyValStore from chia.wallet.wallet_blockchain import WalletBlockchain -from tests.setup_nodes import test_constants, setup_node_and_wallet - - -@pytest_asyncio.fixture(scope="function") -async def wallet_node(self_hostname): - async for _ in setup_node_and_wallet(test_constants, self_hostname): - yield _ +from tests.setup_nodes import test_constants class TestWalletBlockchain: @@ -50,7 +43,7 @@ class TestWalletBlockchain: weight_proof_short: WeightProof = full_node_protocol.RespondProofOfWeight.from_bytes(res_2.data).wp weight_proof_long: WeightProof = full_node_protocol.RespondProofOfWeight.from_bytes(res_3.data).wp - db_filename = Path("wallet_store_test.db") + db_filename = Path("wallet_blockchain_store_test.db") if db_filename.exists(): db_filename.unlink() diff --git a/tests/wallet/test_wallet_interested_store.py b/tests/wallet/test_wallet_interested_store.py index 11b4b8bb0b..112ed558d4 100644 --- a/tests/wallet/test_wallet_interested_store.py +++ b/tests/wallet/test_wallet_interested_store.py @@ -13,7 +13,7 @@ from chia.wallet.wallet_interested_store import WalletInterestedStore class TestWalletInterestedStore: @pytest.mark.asyncio async def test_store(self): - db_filename = Path("wallet_store_test.db") + db_filename = Path("wallet_interested_store_test.db") if db_filename.exists(): db_filename.unlink() diff --git a/tests/wallet/test_wallet_key_val_store.py b/tests/wallet/test_wallet_key_val_store.py index 9ae34e0e93..4f688e0eda 100644 --- a/tests/wallet/test_wallet_key_val_store.py +++ b/tests/wallet/test_wallet_key_val_store.py @@ -11,7 +11,7 @@ from chia.wallet.key_val_store import KeyValStore class TestWalletKeyValStore: @pytest.mark.asyncio async def test_store(self, bt): - db_filename = Path("wallet_store_test.db") + db_filename = Path("wallet_kv_store_test.db") if db_filename.exists(): db_filename.unlink() diff --git a/tests/weight_proof/test_weight_proof.py b/tests/weight_proof/test_weight_proof.py index 8bc04a001a..e7e7b86e6c 100644 --- a/tests/weight_proof/test_weight_proof.py +++ b/tests/weight_proof/test_weight_proof.py @@ -72,12 +72,12 @@ def get_prev_ses_block(sub_blocks, last_hash) -> Tuple[BlockRecord, int]: async def load_blocks_dont_validate( blocks, ) -> Tuple[ - Dict[bytes32, HeaderBlock], Dict[uint32, bytes32], Dict[bytes32, BlockRecord], Dict[bytes32, SubEpochSummary] + Dict[bytes32, HeaderBlock], Dict[uint32, bytes32], Dict[bytes32, BlockRecord], Dict[uint32, SubEpochSummary] ]: header_cache: Dict[bytes32, HeaderBlock] = {} height_to_hash: Dict[uint32, bytes32] = {} sub_blocks: Dict[bytes32, BlockRecord] = {} - sub_epoch_summaries: Dict[bytes32, SubEpochSummary] = {} + sub_epoch_summaries: Dict[uint32, SubEpochSummary] = {} prev_block = None difficulty = test_constants.DIFFICULTY_STARTING block: FullBlock diff --git a/tools/test_full_sync.py b/tools/test_full_sync.py index 3b8716aa21..afd3197d96 100755 --- a/tools/test_full_sync.py +++ b/tools/test_full_sync.py @@ -46,7 +46,7 @@ def enable_profiler(profile: bool, counter: int) -> Iterator[None]: pr.dump_stats(f"slow-batch-{counter:05d}.profile") -async def run_sync_test(file: Path, db_version, profile: bool) -> None: +async def run_sync_test(file: Path, db_version, profile: bool, single_thread: bool) -> None: logger = logging.getLogger() logger.setLevel(logging.WARNING) @@ -69,6 +69,9 @@ async def run_sync_test(file: Path, db_version, profile: bool) -> None: overrides = config["network_overrides"]["constants"][config["selected_network"]] constants = DEFAULT_CONSTANTS.replace_str_to_bytes(**overrides) + if single_thread: + config["full_node"]["single_threaded"] = True + config["full_node"]["db_sync"] = "off" full_node = FullNode( config["full_node"], root_path=root_path, @@ -88,13 +91,13 @@ async def run_sync_test(file: Path, db_version, profile: bool) -> None: start_time = time.monotonic() async for r in rows: - block = FullBlock.from_bytes(zstd.decompress(r[2])) - - block_batch.append(block) - if len(block_batch) < 32: - continue - with enable_profiler(profile, counter): + block = FullBlock.from_bytes(zstd.decompress(r[2])) + + block_batch.append(block) + if len(block_batch) < 32: + continue + success, advanced_peak, fork_height, coin_changes = await full_node.receive_block_batch( block_batch, None, None # type: ignore[arg-type] ) @@ -121,8 +124,15 @@ def main() -> None: @click.argument("file", type=click.Path(), required=True) @click.option("--db-version", type=int, required=False, default=2, help="the version of the specified db file") @click.option("--profile", is_flag=True, required=False, default=False, help="dump CPU profiles for slow batches") -def run(file: Path, db_version: int, profile: bool) -> None: - asyncio.run(run_sync_test(Path(file), db_version, profile)) +@click.option( + "--single-thread", + is_flag=True, + required=False, + default=False, + help="run node in a single process, to include validation in profiles", +) +def run(file: Path, db_version: int, profile: bool, single_thread: bool) -> None: + asyncio.run(run_sync_test(Path(file), db_version, profile, single_thread)) @main.command("analyze", short_help="generate call stacks for all profiles dumped to current directory")