mirror of https://github.com/hyperledger/besu
# Conflicts: # ethereum/eth/src/main/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerTaskExecutor.java # ethereum/eth/src/test/java/org/hyperledger/besu/ethereum/eth/manager/peertask/PeerTaskExecutorTest.javapull/7638/head
commit
fae39a8db7
@ -0,0 +1,109 @@ |
|||||||
|
name: Docker Promote |
||||||
|
|
||||||
|
run-name: "Docker Promote ${{ github.event.release.name }}" |
||||||
|
|
||||||
|
on: |
||||||
|
release: |
||||||
|
types: [released] |
||||||
|
|
||||||
|
env: |
||||||
|
registry: docker.io |
||||||
|
GRADLE_OPTS: "-Dorg.gradle.parallel=true -Dorg.gradle.caching=true" |
||||||
|
|
||||||
|
jobs: |
||||||
|
validate: |
||||||
|
runs-on: ubuntu-22.04 |
||||||
|
env: |
||||||
|
RELEASE_VERSION: "${{ github.event.release.name }}" |
||||||
|
steps: |
||||||
|
- name: Pre-process Release Name |
||||||
|
id: pre_process_release_version |
||||||
|
run: | |
||||||
|
# strip all whitespace |
||||||
|
RELEASE_VERSION="${RELEASE_VERSION//[[:space:]]/}" |
||||||
|
if [[ ! "$RELEASE_VERSION" =~ ^[0-9]+\.[0-9]+(\.[0-9]+)?(-.*)?$ ]]; then |
||||||
|
echo "Release name does not conform to a valid besu release format YY.M.v[-suffix], e.g. 24.8.0-RC1." |
||||||
|
exit 1 |
||||||
|
fi |
||||||
|
echo "release_version=$RELEASE_VERSION" >> $GITHUB_OUTPUT # Set as output using the new syntax |
||||||
|
outputs: |
||||||
|
release_version: ${{ steps.pre_process_release_version.outputs.release_version }} |
||||||
|
|
||||||
|
docker-promote: |
||||||
|
needs: [validate] |
||||||
|
env: |
||||||
|
RELEASE_VERSION: ${{ needs.validate.outputs.release_version }} |
||||||
|
runs-on: ubuntu-22.04 |
||||||
|
steps: |
||||||
|
- name: Checkout |
||||||
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 |
||||||
|
|
||||||
|
- name: Setup Java |
||||||
|
uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 |
||||||
|
with: |
||||||
|
distribution: temurin |
||||||
|
java-version: 21 |
||||||
|
cache: gradle |
||||||
|
|
||||||
|
- name: Login to ${{ env.registry }} |
||||||
|
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d |
||||||
|
with: |
||||||
|
registry: ${{ env.registry }} |
||||||
|
username: ${{ secrets.DOCKER_USER_RW }} |
||||||
|
password: ${{ secrets.DOCKER_PASSWORD_RW }} |
||||||
|
|
||||||
|
- name: Setup Gradle |
||||||
|
uses: gradle/actions/setup-gradle@9e899d11ad247ec76be7a60bc1cf9d3abbb9e7f1 |
||||||
|
with: |
||||||
|
cache-disabled: true |
||||||
|
|
||||||
|
- name: Docker upload |
||||||
|
run: ./gradlew "-Prelease.releaseVersion=${{ env.RELEASE_VERSION }}" "-PdockerOrgName=${{ env.registry }}/${{ secrets.DOCKER_ORG }}" dockerUploadRelease |
||||||
|
|
||||||
|
- name: Docker manifest |
||||||
|
run: ./gradlew "-Prelease.releaseVersion=${{ env.RELEASE_VERSION }}" "-PdockerOrgName=${{ env.registry }}/${{ secrets.DOCKER_ORG }}" manifestDockerRelease |
||||||
|
|
||||||
|
docker-verify: |
||||||
|
needs: [validate,docker-promote] |
||||||
|
env: |
||||||
|
CONTAINER_NAME: besu-check |
||||||
|
RELEASE_VERSION: ${{ needs.validate.outputs.release_version }} |
||||||
|
runs-on: ${{ matrix.combination.runner }} |
||||||
|
timeout-minutes: 4 |
||||||
|
strategy: |
||||||
|
matrix: |
||||||
|
combination: |
||||||
|
- tag: latest-amd64 |
||||||
|
platform: 'linux/amd64' |
||||||
|
runner: ubuntu-22.04 |
||||||
|
- tag: latest |
||||||
|
platform: '' |
||||||
|
runner: ubuntu-22.04 |
||||||
|
- tag: latest-arm64 |
||||||
|
platform: '' |
||||||
|
runner: besu-arm64 |
||||||
|
- tag: latest |
||||||
|
platform: '' |
||||||
|
runner: besu-arm64 |
||||||
|
|
||||||
|
steps: |
||||||
|
- name: Checkout |
||||||
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 |
||||||
|
with: |
||||||
|
sparse-checkout: '.github/workflows/BesuContainerVerify.sh' |
||||||
|
|
||||||
|
- name: Start container |
||||||
|
run: | |
||||||
|
PLATFORM_OPT="" |
||||||
|
[[ x${{ matrix.combination.platform }} != 'x' ]] && PLATFORM_OPT="--platform ${{ matrix.combination.platform }}" |
||||||
|
docker run -d $PLATFORM_OPT --name ${{ env.CONTAINER_NAME }} ${{ secrets.DOCKER_ORG }}/besu:${{ matrix.combination.tag }} |
||||||
|
|
||||||
|
- name: Verify besu container |
||||||
|
run: bash .github/workflows/BesuContainerVerify.sh |
||||||
|
env: |
||||||
|
TAG: ${{ matrix.combination.tag }} |
||||||
|
VERSION: ${{ env.RELEASE_VERSION }} |
||||||
|
CHECK_LATEST: true |
||||||
|
|
||||||
|
- name: Stop container |
||||||
|
run: docker stop ${{ env.CONTAINER_NAME }} |
@ -0,0 +1,398 @@ |
|||||||
|
name: Draft Release |
||||||
|
|
||||||
|
run-name: "Draft Release ${{ inputs.tag }}" |
||||||
|
|
||||||
|
on: |
||||||
|
workflow_dispatch: |
||||||
|
inputs: |
||||||
|
tag: |
||||||
|
required: true |
||||||
|
|
||||||
|
env: |
||||||
|
registry: docker.io |
||||||
|
GRADLE_OPTS: "-Dorg.gradle.parallel=true -Dorg.gradle.caching=true" |
||||||
|
|
||||||
|
jobs: |
||||||
|
validate: |
||||||
|
runs-on: ubuntu-22.04 |
||||||
|
env: |
||||||
|
RELEASE_VERSION: "${{ inputs.tag }}" |
||||||
|
steps: |
||||||
|
- name: Check default branch |
||||||
|
run: | |
||||||
|
echo "Current Branch: ${{ github.ref_name }}" |
||||||
|
echo "Default Branch: ${{ github.event.repository.default_branch }}" |
||||||
|
if [[ ${{ github.ref_name }} != ${{ github.event.repository.default_branch }} ]] |
||||||
|
then |
||||||
|
echo "This workflow can only be run on default branch. This is not an issue for hot fixes as code is checked out from the tag" |
||||||
|
exit 1 |
||||||
|
fi |
||||||
|
|
||||||
|
- name: Pre-process Release Name |
||||||
|
id: validate_release_version |
||||||
|
run: | |
||||||
|
# strip all whitespace |
||||||
|
RELEASE_VERSION="${RELEASE_VERSION//[[:space:]]/}" |
||||||
|
if [[ ! "$RELEASE_VERSION" =~ ^[0-9]+\.[0-9]+(\.[0-9]+)?(-.*)?$ ]]; then |
||||||
|
echo "Release name does not conform to a valid besu release format YY.M.v[-suffix], e.g. 24.8.0-RC1." |
||||||
|
exit 1 |
||||||
|
fi |
||||||
|
echo "release_version=$RELEASE_VERSION" >> $GITHUB_OUTPUT # Set as output using the new syntax |
||||||
|
|
||||||
|
# Perform a tag checkout to ensure tag is available |
||||||
|
- name: Verify tag Exist |
||||||
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 |
||||||
|
with: |
||||||
|
ref: ${{ steps.validate_release_version.outputs.release_version }} |
||||||
|
fetch-depth: 1 |
||||||
|
|
||||||
|
outputs: |
||||||
|
release_version: ${{ steps.validate_release_version.outputs.release_version }} |
||||||
|
|
||||||
|
build: |
||||||
|
runs-on: ubuntu-22.04 |
||||||
|
needs: validate |
||||||
|
env: |
||||||
|
RELEASE_VERSION: ${{ needs.validate.outputs.release_version }} # Use the output from the pre_process_release job |
||||||
|
outputs: |
||||||
|
tarSha: ${{steps.hashes.outputs.tarSha}} |
||||||
|
zipSha: ${{steps.hashes.outputs.zipSha}} |
||||||
|
steps: |
||||||
|
- name: Checkout tag |
||||||
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 |
||||||
|
with: |
||||||
|
ref: ${{ env.RELEASE_VERSION }} |
||||||
|
|
||||||
|
- name: Set up Java |
||||||
|
uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 |
||||||
|
with: |
||||||
|
distribution: temurin |
||||||
|
java-version: 21 |
||||||
|
|
||||||
|
- name: Setup gradle |
||||||
|
uses: gradle/actions/setup-gradle@9e899d11ad247ec76be7a60bc1cf9d3abbb9e7f1 |
||||||
|
with: |
||||||
|
cache-disabled: true |
||||||
|
|
||||||
|
- name: Assemble release |
||||||
|
run: |
||||||
|
./gradlew -Prelease.releaseVersion=${{env.RELEASE_VERSION}} -Pversion=${{env.RELEASE_VERSION}} assemble |
||||||
|
|
||||||
|
- name: Hashes |
||||||
|
id: hashes |
||||||
|
run: | |
||||||
|
cd build/distributions |
||||||
|
echo "zipSha=$(shasum -a 256 besu*.zip)" |
||||||
|
echo "tarSha=$(shasum -a 256 besu*.tar.gz)" |
||||||
|
echo "zipSha=$(shasum -a 256 besu*.zip)" >> $GITHUB_OUTPUT |
||||||
|
echo "tarSha=$(shasum -a 256 besu*.tar.gz)" >> $GITHUB_OUTPUT |
||||||
|
shasum -a 256 besu-${{env.RELEASE_VERSION}}.tar.gz > besu-${{env.RELEASE_VERSION}}.tar.gz.sha256 |
||||||
|
shasum -a 256 besu-${{env.RELEASE_VERSION}}.zip > besu-${{env.RELEASE_VERSION}}.zip.sha256 |
||||||
|
|
||||||
|
- name: Upload tarball |
||||||
|
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 |
||||||
|
with: |
||||||
|
path: 'build/distributions/besu-${{ env.RELEASE_VERSION }}.tar.gz' |
||||||
|
name: besu-${{ env.RELEASE_VERSION }}.tar.gz |
||||||
|
compression-level: 0 |
||||||
|
|
||||||
|
- name: upload zipfile |
||||||
|
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 |
||||||
|
with: |
||||||
|
path: 'build/distributions/besu-${{ env.RELEASE_VERSION }}.zip' |
||||||
|
name: besu-${{ env.RELEASE_VERSION }}.zip |
||||||
|
compression-level: 0 |
||||||
|
|
||||||
|
- name: upload checksum zip |
||||||
|
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 |
||||||
|
with: |
||||||
|
path: 'build/distributions/besu-${{ env.RELEASE_VERSION }}.zip.sha256' |
||||||
|
name: besu-${{ env.RELEASE_VERSION }}.zip.sha256 |
||||||
|
compression-level: 0 |
||||||
|
|
||||||
|
- name: upload checksum tar.gz |
||||||
|
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 |
||||||
|
with: |
||||||
|
path: 'build/distributions/besu-${{ env.RELEASE_VERSION }}.tar.gz.sha256' |
||||||
|
name: besu-${{ env.RELEASE_VERSION }}.tar.gz.sha256 |
||||||
|
compression-level: 0 |
||||||
|
|
||||||
|
test-windows: |
||||||
|
runs-on: windows-2022 |
||||||
|
needs: ["build"] |
||||||
|
timeout-minutes: 5 |
||||||
|
steps: |
||||||
|
- name: Set up Java |
||||||
|
uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 |
||||||
|
with: |
||||||
|
distribution: temurin |
||||||
|
java-version: 21 |
||||||
|
|
||||||
|
- name: Download zip |
||||||
|
uses: actions/download-artifact@eaceaf801fd36c7dee90939fad912460b18a1ffe |
||||||
|
with: |
||||||
|
pattern: besu-*.zip |
||||||
|
merge-multiple: true |
||||||
|
|
||||||
|
- name: Test |
||||||
|
run: | |
||||||
|
unzip besu-*.zip -d besu-tmp |
||||||
|
cd besu-tmp |
||||||
|
mv besu-* ../besu |
||||||
|
cd .. |
||||||
|
besu\bin\besu.bat --help |
||||||
|
besu\bin\besu.bat --version |
||||||
|
|
||||||
|
test-linux: |
||||||
|
runs-on: ubuntu-22.04 |
||||||
|
needs: ["build"] |
||||||
|
timeout-minutes: 5 |
||||||
|
steps: |
||||||
|
- name: Set up Java |
||||||
|
uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 |
||||||
|
with: |
||||||
|
distribution: temurin |
||||||
|
java-version: 21 |
||||||
|
|
||||||
|
- name: Download tar.gz |
||||||
|
uses: actions/download-artifact@eaceaf801fd36c7dee90939fad912460b18a1ffe |
||||||
|
with: |
||||||
|
pattern: besu-*.tar.gz |
||||||
|
merge-multiple: true |
||||||
|
|
||||||
|
- name: Test |
||||||
|
run: | |
||||||
|
tar zxvf besu-*.tar.gz |
||||||
|
rm -f besu-*.tar.gz |
||||||
|
mv besu-* besu-test |
||||||
|
besu-test/bin/besu --help |
||||||
|
besu-test/bin/besu --version |
||||||
|
|
||||||
|
docker-lint: |
||||||
|
runs-on: ubuntu-22.04 |
||||||
|
needs: [test-linux, test-windows] |
||||||
|
env: |
||||||
|
RELEASE_VERSION: ${{ needs.validate.outputs.release_version }} # Use the output from the pre_process_release job |
||||||
|
steps: |
||||||
|
- name: Checkout Repo |
||||||
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 |
||||||
|
with: |
||||||
|
ref: ${{ env.RELEASE_VERSION }} |
||||||
|
|
||||||
|
- name: hadoLint |
||||||
|
run: docker run --rm -i hadolint/hadolint < docker/Dockerfile |
||||||
|
|
||||||
|
docker-publish: |
||||||
|
needs: [validate, docker-lint] |
||||||
|
env: |
||||||
|
RELEASE_VERSION: ${{ needs.validate.outputs.release_version }} # Use the output from the pre_process_release job |
||||||
|
strategy: |
||||||
|
fail-fast: false |
||||||
|
matrix: |
||||||
|
platform: |
||||||
|
- ubuntu-22.04 |
||||||
|
- besu-arm64 |
||||||
|
runs-on: ${{ matrix.platform }} |
||||||
|
steps: |
||||||
|
- name: Prepare |
||||||
|
id: prep |
||||||
|
run: | |
||||||
|
platform=${{ matrix.platform }} |
||||||
|
if [ "$platform" = 'ubuntu-22.04' ]; then |
||||||
|
echo "PLATFORM_PAIR=linux-amd64" >> $GITHUB_OUTPUT |
||||||
|
echo "ARCH=amd64" >> $GITHUB_OUTPUT |
||||||
|
else |
||||||
|
echo "PLATFORM_PAIR=linux-arm64" >> $GITHUB_OUTPUT |
||||||
|
echo "ARCH=arm64" >> $GITHUB_OUTPUT |
||||||
|
fi |
||||||
|
|
||||||
|
- name: Checkout Repo |
||||||
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 |
||||||
|
with: |
||||||
|
ref: ${{ env.RELEASE_VERSION }} |
||||||
|
|
||||||
|
- name: short sha |
||||||
|
id: shortSha |
||||||
|
run: echo "sha=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT |
||||||
|
|
||||||
|
- name: Set up Java |
||||||
|
uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 |
||||||
|
with: |
||||||
|
distribution: temurin |
||||||
|
java-version: 21 |
||||||
|
|
||||||
|
- name: setup gradle |
||||||
|
uses: gradle/actions/setup-gradle@9e899d11ad247ec76be7a60bc1cf9d3abbb9e7f1 |
||||||
|
with: |
||||||
|
cache-disabled: true |
||||||
|
|
||||||
|
- name: install goss |
||||||
|
run: | |
||||||
|
mkdir -p docker/reports |
||||||
|
curl -L https://github.com/aelsabbahy/goss/releases/download/v0.4.4/goss-${{ steps.prep.outputs.PLATFORM_PAIR }} -o ./docker/tests/goss-${{ steps.prep.outputs.PLATFORM_PAIR }} |
||||||
|
|
||||||
|
- name: login to ${{ env.registry }} |
||||||
|
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d |
||||||
|
with: |
||||||
|
registry: ${{ env.registry }} |
||||||
|
username: ${{ secrets.DOCKER_USER_RW }} |
||||||
|
password: ${{ secrets.DOCKER_PASSWORD_RW }} |
||||||
|
|
||||||
|
- name: build and test docker |
||||||
|
uses: gradle/actions/setup-gradle@9e899d11ad247ec76be7a60bc1cf9d3abbb9e7f1 |
||||||
|
env: |
||||||
|
architecture: ${{ steps.prep.outputs.ARCH }} |
||||||
|
with: |
||||||
|
cache-disabled: true |
||||||
|
arguments: testDocker -PdockerOrgName=${{ env.registry }}/${{ secrets.DOCKER_ORG }} -Pversion=${{env.RELEASE_VERSION}} -Prelease.releaseVersion=${{ env.RELEASE_VERSION }} |
||||||
|
|
||||||
|
- name: publish |
||||||
|
env: |
||||||
|
architecture: ${{ steps.prep.outputs.ARCH }} |
||||||
|
run: ./gradlew --no-daemon dockerUpload -PdockerOrgName=${{ env.registry }}/${{ secrets.DOCKER_ORG }} -Pversion=${{env.RELEASE_VERSION}} -Prelease.releaseVersion=${{ env.RELEASE_VERSION }} |
||||||
|
|
||||||
|
docker-manifest: |
||||||
|
needs: [validate, docker-publish] |
||||||
|
runs-on: ubuntu-22.04 |
||||||
|
env: |
||||||
|
RELEASE_VERSION: ${{ needs.validate.outputs.release_version }} |
||||||
|
steps: |
||||||
|
- name: Checkout Repo |
||||||
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 |
||||||
|
with: |
||||||
|
ref: ${{ env.RELEASE_VERSION }} |
||||||
|
|
||||||
|
- name: Set up Java |
||||||
|
uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 |
||||||
|
with: |
||||||
|
distribution: temurin |
||||||
|
java-version: 21 |
||||||
|
|
||||||
|
- name: setup gradle |
||||||
|
uses: gradle/actions/setup-gradle@9e899d11ad247ec76be7a60bc1cf9d3abbb9e7f1 |
||||||
|
with: |
||||||
|
cache-disabled: true |
||||||
|
|
||||||
|
- name: login to ${{ env.registry }} |
||||||
|
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d |
||||||
|
with: |
||||||
|
registry: ${{ env.registry }} |
||||||
|
username: ${{ secrets.DOCKER_USER_RW }} |
||||||
|
password: ${{ secrets.DOCKER_PASSWORD_RW }} |
||||||
|
|
||||||
|
- name: multi-arch docker |
||||||
|
run: ./gradlew manifestDocker -PdockerOrgName=${{ env.registry }}/${{ secrets.DOCKER_ORG }} -Pversion=${{env.RELEASE_VERSION}} -Prelease.releaseVersion=${{ env.RELEASE_VERSION }} |
||||||
|
|
||||||
|
docker-verify: |
||||||
|
needs: [validate,docker-manifest] |
||||||
|
env: |
||||||
|
CONTAINER_NAME: besu-check |
||||||
|
RELEASE_VERSION: ${{ needs.validate.outputs.release_version }} |
||||||
|
runs-on: ${{ matrix.combination.runner }} |
||||||
|
timeout-minutes: 4 |
||||||
|
strategy: |
||||||
|
matrix: |
||||||
|
combination: |
||||||
|
- tag: ${{ needs.validate.outputs.release_version }} |
||||||
|
platform: '' |
||||||
|
runner: ubuntu-22.04 |
||||||
|
- tag: ${{ needs.validate.outputs.release_version }}-amd64 |
||||||
|
platform: 'linux/amd64' |
||||||
|
runner: ubuntu-22.04 |
||||||
|
- tag: ${{ needs.validate.outputs.release_version }}-arm64 |
||||||
|
platform: '' |
||||||
|
runner: besu-arm64 |
||||||
|
steps: |
||||||
|
- name: Checkout |
||||||
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 |
||||||
|
with: |
||||||
|
sparse-checkout: '.github/workflows/BesuContainerVerify.sh' |
||||||
|
|
||||||
|
- name: Start container |
||||||
|
run: | |
||||||
|
PLATFORM_OPT="" |
||||||
|
[[ x${{ matrix.combination.platform }} != 'x' ]] && PLATFORM_OPT="--platform ${{ matrix.combination.platform }}" |
||||||
|
docker run -d $PLATFORM_OPT --name ${{ env.CONTAINER_NAME }} ${{ secrets.DOCKER_ORG }}/besu:${{ matrix.combination.tag }} |
||||||
|
|
||||||
|
- name: Verify besu container |
||||||
|
run: bash .github/workflows/BesuContainerVerify.sh |
||||||
|
env: |
||||||
|
TAG: ${{ matrix.combination.tag }} |
||||||
|
VERSION: ${{ env.RELEASE_VERSION }} |
||||||
|
CHECK_LATEST: false |
||||||
|
|
||||||
|
- name: Stop container |
||||||
|
run: docker stop ${{ env.CONTAINER_NAME }} |
||||||
|
|
||||||
|
release-draft: |
||||||
|
runs-on: ubuntu-22.04 |
||||||
|
needs: [validate, test-linux, test-windows] |
||||||
|
permissions: |
||||||
|
contents: write |
||||||
|
env: |
||||||
|
RELEASE_VERSION: ${{ needs.validate.outputs.release_version }} |
||||||
|
steps: |
||||||
|
- name: Checkout Repo |
||||||
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 |
||||||
|
with: |
||||||
|
ref: ${{ env.RELEASE_VERSION }} |
||||||
|
|
||||||
|
- name: Download Besu artifacts |
||||||
|
uses: actions/download-artifact@eaceaf801fd36c7dee90939fad912460b18a1ffe |
||||||
|
with: |
||||||
|
pattern: besu-${{env.RELEASE_VERSION}}* |
||||||
|
merge-multiple: true |
||||||
|
|
||||||
|
- name: Draft release notes |
||||||
|
run: | |
||||||
|
echo "## ${{env.RELEASE_VERSION}}" > draft-release-notes.md |
||||||
|
echo "## Upcoming Breaking Changes" >> draft-release-notes.md |
||||||
|
echo "## Breaking Changes" >> draft-release-notes.md |
||||||
|
echo "## Additions and Improvements" >> draft-release-notes.md |
||||||
|
echo "## Bug fixes" >> draft-release-notes.md |
||||||
|
echo "`$(cat besu-${{env.RELEASE_VERSION}}.zip.sha256)`" >> draft-release-notes.md |
||||||
|
echo "`$(cat besu-${{env.RELEASE_VERSION}}.tar.gz.sha256)`" >> draft-release-notes.md |
||||||
|
cat besu-${{env.RELEASE_VERSION}}.zip.sha256 >> draft-release-notes.md |
||||||
|
cat besu-${{env.RELEASE_VERSION}}.tar.gz.sha256 >> draft-release-notes.md |
||||||
|
|
||||||
|
- name: Draft release |
||||||
|
run: | |
||||||
|
gh release create \ |
||||||
|
--draft \ |
||||||
|
--title=${{env.RELEASE_VERSION}} \ |
||||||
|
--notes-file draft-release-notes.md \ |
||||||
|
--verify-tag ${{env.RELEASE_VERSION}} \ |
||||||
|
besu-${{env.RELEASE_VERSION}}.tar.gz \ |
||||||
|
besu-${{env.RELEASE_VERSION}}.zip \ |
||||||
|
besu-${{env.RELEASE_VERSION}}.zip.sha256 \ |
||||||
|
besu-${{env.RELEASE_VERSION}}.tar.gz.sha256 |
||||||
|
env: |
||||||
|
GH_TOKEN: ${{ github.token }} |
||||||
|
|
||||||
|
artifactory: |
||||||
|
runs-on: ubuntu-22.04 |
||||||
|
needs: [validate, test-linux, test-windows] |
||||||
|
env: |
||||||
|
RELEASE_VERSION: ${{ needs.validate.outputs.release_version }} |
||||||
|
steps: |
||||||
|
- name: checkout |
||||||
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 |
||||||
|
with: |
||||||
|
ref: ${{ env.RELEASE_VERSION }} |
||||||
|
|
||||||
|
- name: Set up Java |
||||||
|
uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 |
||||||
|
with: |
||||||
|
distribution: temurin |
||||||
|
java-version: 21 |
||||||
|
|
||||||
|
- name: setup gradle |
||||||
|
uses: gradle/actions/setup-gradle@9e899d11ad247ec76be7a60bc1cf9d3abbb9e7f1 |
||||||
|
with: |
||||||
|
cache-disabled: true |
||||||
|
|
||||||
|
- name: Artifactory Publish |
||||||
|
env: |
||||||
|
ARTIFACTORY_USER: ${{ secrets.BESU_ARTIFACTORY_USER }} |
||||||
|
ARTIFACTORY_KEY: ${{ secrets.BESU_ARTIFACTORY_TOKEN }} |
||||||
|
run: ./gradlew -Prelease.releaseVersion=${{ env.RELEASE_VERSION }} -Pversion=${{env.RELEASE_VERSION}} artifactoryPublish |
@ -1,316 +0,0 @@ |
|||||||
name: release |
|
||||||
|
|
||||||
on: |
|
||||||
release: |
|
||||||
types: [released] |
|
||||||
|
|
||||||
env: |
|
||||||
registry: docker.io |
|
||||||
GRADLE_OPTS: "-Dorg.gradle.parallel=true -Dorg.gradle.caching=true" |
|
||||||
|
|
||||||
jobs: |
|
||||||
preprocess_release: |
|
||||||
runs-on: ubuntu-22.04 |
|
||||||
steps: |
|
||||||
- name: Pre-process Release Name |
|
||||||
id: pre_process_release_name |
|
||||||
env: |
|
||||||
RELEASE_NAME: "${{ github.event.release.name }}" |
|
||||||
run: | |
|
||||||
# strip all whitespace |
|
||||||
RELEASE_NAME="${RELEASE_NAME//[[:space:]]/}" |
|
||||||
if [[ ! "$RELEASE_NAME" =~ ^[0-9]+\.[0-9]+(\.[0-9]+)?(-.*)?$ ]]; then |
|
||||||
echo "Release name does not conform to a valid besu release format YY.M.v[-suffix], e.g. 24.8.0-RC1." |
|
||||||
exit 1 |
|
||||||
fi |
|
||||||
echo "release_name=$RELEASE_NAME" >> $GITHUB_OUTPUT # Set as output using the new syntax |
|
||||||
outputs: |
|
||||||
release_name: ${{ steps.pre_process_release_name.outputs.release_name }} |
|
||||||
|
|
||||||
artifacts: |
|
||||||
runs-on: ubuntu-22.04 |
|
||||||
needs: preprocess_release |
|
||||||
env: |
|
||||||
RELEASE_NAME: ${{ needs.preprocess_release.outputs.release_name }} # Use the output from the pre_process_release job |
|
||||||
permissions: |
|
||||||
contents: write |
|
||||||
outputs: |
|
||||||
tarSha: ${{steps.hashes.outputs.tarSha}} |
|
||||||
zipSha: ${{steps.hashes.outputs.zipSha}} |
|
||||||
steps: |
|
||||||
- name: checkout |
|
||||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 |
|
||||||
- name: Set up Java |
|
||||||
uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 |
|
||||||
with: |
|
||||||
distribution: temurin |
|
||||||
java-version: 21 |
|
||||||
- name: setup gradle |
|
||||||
uses: gradle/actions/setup-gradle@9e899d11ad247ec76be7a60bc1cf9d3abbb9e7f1 |
|
||||||
with: |
|
||||||
cache-disabled: true |
|
||||||
- name: assemble release |
|
||||||
run: |
|
||||||
./gradlew -Prelease.releaseVersion=${{env.RELEASE_NAME}} -Pversion=${{env.RELEASE_NAME}} assemble |
|
||||||
- name: hashes |
|
||||||
id: hashes |
|
||||||
run: | |
|
||||||
cd build/distributions |
|
||||||
echo "zipSha=$(shasum -a 256 besu*.zip)" |
|
||||||
echo "tarSha=$(shasum -a 256 besu*.tar.gz)" |
|
||||||
echo "zipSha=$(shasum -a 256 besu*.zip)" >> $GITHUB_OUTPUT |
|
||||||
echo "tarSha=$(shasum -a 256 besu*.tar.gz)" >> $GITHUB_OUTPUT |
|
||||||
- name: upload tarball |
|
||||||
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 |
|
||||||
with: |
|
||||||
path: 'build/distributions/besu*.tar.gz' |
|
||||||
name: besu-${{ env.RELEASE_NAME }}.tar.gz |
|
||||||
compression-level: 0 |
|
||||||
- name: upload zipfile |
|
||||||
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 |
|
||||||
with: |
|
||||||
path: 'build/distributions/besu*.zip' |
|
||||||
name: besu-${{ env.RELEASE_NAME }}.zip |
|
||||||
compression-level: 0 |
|
||||||
|
|
||||||
testWindows: |
|
||||||
runs-on: windows-2022 |
|
||||||
needs: artifacts |
|
||||||
timeout-minutes: 10 |
|
||||||
steps: |
|
||||||
- name: Set up Java |
|
||||||
uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 |
|
||||||
with: |
|
||||||
distribution: temurin |
|
||||||
java-version: 21 |
|
||||||
- name: Download zip |
|
||||||
uses: actions/download-artifact@eaceaf801fd36c7dee90939fad912460b18a1ffe |
|
||||||
with: |
|
||||||
pattern: besu-*.zip |
|
||||||
merge-multiple: true |
|
||||||
- name: test Besu |
|
||||||
run: | |
|
||||||
dir |
|
||||||
unzip besu-*.zip -d besu-tmp |
|
||||||
cd besu-tmp |
|
||||||
mv besu-* ../besu |
|
||||||
cd .. |
|
||||||
besu\bin\besu.bat --help |
|
||||||
besu\bin\besu.bat --version |
|
||||||
|
|
||||||
publish: |
|
||||||
runs-on: ubuntu-22.04 |
|
||||||
needs: [preprocess_release, testWindows, artifacts] |
|
||||||
env: |
|
||||||
RELEASE_NAME: ${{ needs.preprocess_release.outputs.release_name }} # Use the output from the pre_process_release job |
|
||||||
permissions: |
|
||||||
contents: write |
|
||||||
steps: |
|
||||||
- name: Download archives |
|
||||||
uses: actions/download-artifact@eaceaf801fd36c7dee90939fad912460b18a1ffe |
|
||||||
with: |
|
||||||
pattern: besu-* |
|
||||||
merge-multiple: true |
|
||||||
path: 'build/distributions' |
|
||||||
- name: Upload Release assets |
|
||||||
uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 |
|
||||||
with: |
|
||||||
append_body: true |
|
||||||
files: | |
|
||||||
build/distributions/besu*.tar.gz |
|
||||||
build/distributions/besu*.zip |
|
||||||
body: | |
|
||||||
${{needs.artifacts.outputs.tarSha}} |
|
||||||
${{needs.artifacts.outputs.zipSha}} |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
artifactoryPublish: |
|
||||||
runs-on: ubuntu-22.04 |
|
||||||
needs: [preprocess_release, artifacts] |
|
||||||
env: |
|
||||||
RELEASE_NAME: ${{ needs.preprocess_release.outputs.release_name }} # Use the output from the pre_process_release job |
|
||||||
steps: |
|
||||||
- name: checkout |
|
||||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 |
|
||||||
- name: Set up Java |
|
||||||
uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 |
|
||||||
with: |
|
||||||
distribution: temurin |
|
||||||
java-version: 21 |
|
||||||
- name: setup gradle |
|
||||||
uses: gradle/actions/setup-gradle@9e899d11ad247ec76be7a60bc1cf9d3abbb9e7f1 |
|
||||||
with: |
|
||||||
cache-disabled: true |
|
||||||
- name: Artifactory Publish |
|
||||||
env: |
|
||||||
ARTIFACTORY_USER: ${{ secrets.BESU_ARTIFACTORY_USER }} |
|
||||||
ARTIFACTORY_KEY: ${{ secrets.BESU_ARTIFACTORY_TOKEN }} |
|
||||||
run: ./gradlew -Prelease.releaseVersion=${{ env.RELEASE_NAME }} -Pversion=${{env.RELEASE_NAME}} artifactoryPublish |
|
||||||
|
|
||||||
hadolint: |
|
||||||
runs-on: ubuntu-22.04 |
|
||||||
steps: |
|
||||||
- name: Checkout Repo |
|
||||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 |
|
||||||
- name: Set up Java |
|
||||||
uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 |
|
||||||
with: |
|
||||||
distribution: temurin |
|
||||||
java-version: 21 |
|
||||||
- name: setup gradle |
|
||||||
uses: gradle/actions/setup-gradle@9e899d11ad247ec76be7a60bc1cf9d3abbb9e7f1 |
|
||||||
with: |
|
||||||
cache-disabled: true |
|
||||||
- name: hadoLint |
|
||||||
run: docker run --rm -i hadolint/hadolint < docker/Dockerfile |
|
||||||
|
|
||||||
buildDocker: |
|
||||||
needs: [preprocess_release, hadolint] |
|
||||||
env: |
|
||||||
RELEASE_NAME: ${{ needs.preprocess_release.outputs.release_name }} # Use the output from the pre_process_release job |
|
||||||
permissions: |
|
||||||
contents: read |
|
||||||
packages: write |
|
||||||
|
|
||||||
strategy: |
|
||||||
fail-fast: false |
|
||||||
matrix: |
|
||||||
platform: |
|
||||||
- ubuntu-22.04 |
|
||||||
- besu-arm64 |
|
||||||
runs-on: ${{ matrix.platform }} |
|
||||||
steps: |
|
||||||
- name: Prepare |
|
||||||
id: prep |
|
||||||
run: | |
|
||||||
platform=${{ matrix.platform }} |
|
||||||
if [ "$platform" = 'ubuntu-22.04' ]; then |
|
||||||
echo "PLATFORM_PAIR=linux-amd64" >> $GITHUB_OUTPUT |
|
||||||
echo "ARCH=amd64" >> $GITHUB_OUTPUT |
|
||||||
else |
|
||||||
echo "PLATFORM_PAIR=linux-arm64" >> $GITHUB_OUTPUT |
|
||||||
echo "ARCH=arm64" >> $GITHUB_OUTPUT |
|
||||||
fi |
|
||||||
- name: Checkout Repo |
|
||||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 |
|
||||||
- name: short sha |
|
||||||
id: shortSha |
|
||||||
run: echo "sha=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT |
|
||||||
- name: Set up Java |
|
||||||
uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 |
|
||||||
with: |
|
||||||
distribution: temurin |
|
||||||
java-version: 21 |
|
||||||
- name: setup gradle |
|
||||||
uses: gradle/actions/setup-gradle@9e899d11ad247ec76be7a60bc1cf9d3abbb9e7f1 |
|
||||||
with: |
|
||||||
cache-disabled: true |
|
||||||
- name: install goss |
|
||||||
run: | |
|
||||||
mkdir -p docker/reports |
|
||||||
curl -L https://github.com/aelsabbahy/goss/releases/download/v0.4.4/goss-${{ steps.prep.outputs.PLATFORM_PAIR }} -o ./docker/tests/goss-${{ steps.prep.outputs.PLATFORM_PAIR }} |
|
||||||
- name: login to ${{ env.registry }} |
|
||||||
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d |
|
||||||
with: |
|
||||||
registry: ${{ env.registry }} |
|
||||||
username: ${{ secrets.DOCKER_USER_RW }} |
|
||||||
password: ${{ secrets.DOCKER_PASSWORD_RW }} |
|
||||||
- name: build and test docker |
|
||||||
uses: gradle/actions/setup-gradle@9e899d11ad247ec76be7a60bc1cf9d3abbb9e7f1 |
|
||||||
env: |
|
||||||
architecture: ${{ steps.prep.outputs.ARCH }} |
|
||||||
with: |
|
||||||
cache-disabled: true |
|
||||||
arguments: testDocker -PdockerOrgName=${{ env.registry }}/${{ secrets.DOCKER_ORG }} -Pversion=${{env.RELEASE_NAME}} -Prelease.releaseVersion=${{ env.RELEASE_NAME }} |
|
||||||
- name: publish |
|
||||||
env: |
|
||||||
architecture: ${{ steps.prep.outputs.ARCH }} |
|
||||||
run: ./gradlew --no-daemon dockerUpload -PdockerOrgName=${{ env.registry }}/${{ secrets.DOCKER_ORG }} -Pversion=${{env.RELEASE_NAME}} -Prelease.releaseVersion=${{ env.RELEASE_NAME }} |
|
||||||
|
|
||||||
multiArch: |
|
||||||
needs: [preprocess_release, buildDocker] |
|
||||||
env: |
|
||||||
RELEASE_NAME: ${{ needs.preprocess_release.outputs.release_name }} # Use the output from the pre_process_release job |
|
||||||
runs-on: ubuntu-22.04 |
|
||||||
permissions: |
|
||||||
contents: read |
|
||||||
packages: write |
|
||||||
steps: |
|
||||||
- name: Checkout Repo |
|
||||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 |
|
||||||
- name: Set up Java |
|
||||||
uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 |
|
||||||
with: |
|
||||||
distribution: temurin |
|
||||||
java-version: 21 |
|
||||||
- name: setup gradle |
|
||||||
uses: gradle/actions/setup-gradle@9e899d11ad247ec76be7a60bc1cf9d3abbb9e7f1 |
|
||||||
with: |
|
||||||
cache-disabled: true |
|
||||||
- name: login to ${{ env.registry }} |
|
||||||
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d |
|
||||||
with: |
|
||||||
registry: ${{ env.registry }} |
|
||||||
username: ${{ secrets.DOCKER_USER_RW }} |
|
||||||
password: ${{ secrets.DOCKER_PASSWORD_RW }} |
|
||||||
- name: multi-arch docker |
|
||||||
run: ./gradlew manifestDocker -PdockerOrgName=${{ env.registry }}/${{ secrets.DOCKER_ORG }} -Pversion=${{env.RELEASE_NAME}} -Prelease.releaseVersion=${{ env.RELEASE_NAME }} |
|
||||||
|
|
||||||
amendNotes: |
|
||||||
needs: [preprocess_release, multiArch] |
|
||||||
env: |
|
||||||
RELEASE_NAME: ${{ needs.preprocess_release.outputs.release_name }} # Use the output from the pre_process_release job |
|
||||||
runs-on: ubuntu-22.04 |
|
||||||
permissions: |
|
||||||
contents: write |
|
||||||
steps: |
|
||||||
- name: add pull command to release notes |
|
||||||
uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 |
|
||||||
with: |
|
||||||
append_body: true |
|
||||||
body: | |
|
||||||
`docker pull ${{env.registry}}/${{secrets.DOCKER_ORG}}/besu:${{env.RELEASE_NAME}}` |
|
||||||
|
|
||||||
dockerPromoteX64: |
|
||||||
needs: [preprocess_release, multiArch] |
|
||||||
env: |
|
||||||
RELEASE_NAME: ${{ needs.preprocess_release.outputs.release_name }} # Use the output from the pre_process_release job |
|
||||||
runs-on: ubuntu-22.04 |
|
||||||
steps: |
|
||||||
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 |
|
||||||
- uses: actions/setup-java@387ac29b308b003ca37ba93a6cab5eb57c8f5f93 |
|
||||||
with: |
|
||||||
distribution: temurin |
|
||||||
java-version: 21 |
|
||||||
cache: gradle |
|
||||||
- name: login to ${{ env.registry }} |
|
||||||
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d |
|
||||||
with: |
|
||||||
registry: ${{ env.registry }} |
|
||||||
username: ${{ secrets.DOCKER_USER_RW }} |
|
||||||
password: ${{ secrets.DOCKER_PASSWORD_RW }} |
|
||||||
- name: Setup Gradle |
|
||||||
uses: gradle/actions/setup-gradle@9e899d11ad247ec76be7a60bc1cf9d3abbb9e7f1 |
|
||||||
with: |
|
||||||
cache-disabled: true |
|
||||||
- name: Docker upload |
|
||||||
run: ./gradlew "-Prelease.releaseVersion=${{ env.RELEASE_NAME }}" "-PdockerOrgName=${{ env.registry }}/${{ secrets.DOCKER_ORG }}" dockerUploadRelease |
|
||||||
- name: Docker manifest |
|
||||||
run: ./gradlew "-Prelease.releaseVersion=${{ env.RELEASE_NAME }}" "-PdockerOrgName=${{ env.registry }}/${{ secrets.DOCKER_ORG }}" manifestDockerRelease |
|
||||||
|
|
||||||
verifyContainer: |
|
||||||
needs: [preprocess_release, dockerPromoteX64] |
|
||||||
env: |
|
||||||
RELEASE_NAME: ${{ needs.preprocess_release.outputs.release_name }} # Use the output from the pre_process_release job |
|
||||||
runs-on: ubuntu-22.04 |
|
||||||
permissions: |
|
||||||
contents: read |
|
||||||
actions: write |
|
||||||
steps: |
|
||||||
- name: Checkout |
|
||||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 |
|
||||||
- name: Trigger container verify |
|
||||||
run: echo '{"version":"${{ env.RELEASE_NAME }}","verify-latest-version":"true"}' | gh workflow run container-verify.yml --json |
|
||||||
env: |
|
||||||
GH_TOKEN: ${{ github.token }} |
|
@ -0,0 +1,36 @@ |
|||||||
|
/* |
||||||
|
* Copyright contributors to Hyperledger Besu. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||||
|
* the License. You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||||
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||||
|
* specific language governing permissions and limitations under the License. |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
package org.hyperledger.besu.cli.options.stable; |
||||||
|
|
||||||
|
import org.hyperledger.besu.cli.custom.JsonRPCAllowlistHostsProperty; |
||||||
|
|
||||||
|
import java.nio.file.Path; |
||||||
|
|
||||||
|
/** |
||||||
|
* Command line options for configuring Engine RPC on the node. |
||||||
|
* |
||||||
|
* @param overrideEngineRpcEnabled enable the engine api, even in the absence of merge-specific |
||||||
|
* configurations. |
||||||
|
* @param engineRpcPort Port to provide consensus client APIS on |
||||||
|
* @param engineJwtKeyFile Path to file containing shared secret key for JWT signature verification |
||||||
|
* @param isEngineAuthDisabled Disable authentication for Engine APIs |
||||||
|
* @param engineHostsAllowlist List of hosts to allowlist for Engine APIs |
||||||
|
*/ |
||||||
|
public record EngineRPCConfiguration( |
||||||
|
Boolean overrideEngineRpcEnabled, |
||||||
|
Integer engineRpcPort, |
||||||
|
Path engineJwtKeyFile, |
||||||
|
Boolean isEngineAuthDisabled, |
||||||
|
JsonRPCAllowlistHostsProperty engineHostsAllowlist) {} |
@ -0,0 +1,81 @@ |
|||||||
|
/* |
||||||
|
* Copyright contributors to Hyperledger Besu. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||||
|
* the License. You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||||
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||||
|
* specific language governing permissions and limitations under the License. |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
package org.hyperledger.besu.cli.options.stable; |
||||||
|
|
||||||
|
import static org.hyperledger.besu.ethereum.api.jsonrpc.JsonRpcConfiguration.DEFAULT_ENGINE_JSON_RPC_PORT; |
||||||
|
|
||||||
|
import org.hyperledger.besu.cli.DefaultCommandValues; |
||||||
|
import org.hyperledger.besu.cli.custom.JsonRPCAllowlistHostsProperty; |
||||||
|
import org.hyperledger.besu.cli.options.CLIOptions; |
||||||
|
import org.hyperledger.besu.cli.util.CommandLineUtils; |
||||||
|
|
||||||
|
import java.nio.file.Path; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import picocli.CommandLine; |
||||||
|
|
||||||
|
/** Command line options for configuring Engine RPC on the node. */ |
||||||
|
public class EngineRPCOptions implements CLIOptions<EngineRPCConfiguration> { |
||||||
|
|
||||||
|
/** Default constructor */ |
||||||
|
public EngineRPCOptions() {} |
||||||
|
|
||||||
|
@CommandLine.Option( |
||||||
|
names = {"--engine-rpc-enabled"}, |
||||||
|
description = "enable the engine api, even in the absence of merge-specific configurations.") |
||||||
|
private final Boolean overrideEngineRpcEnabled = false; |
||||||
|
|
||||||
|
@CommandLine.Option( |
||||||
|
names = {"--engine-rpc-port", "--engine-rpc-http-port"}, |
||||||
|
paramLabel = DefaultCommandValues.MANDATORY_PORT_FORMAT_HELP, |
||||||
|
description = "Port to provide consensus client APIS on (default: ${DEFAULT-VALUE})", |
||||||
|
arity = "1") |
||||||
|
private final Integer engineRpcPort = DEFAULT_ENGINE_JSON_RPC_PORT; |
||||||
|
|
||||||
|
@CommandLine.Option( |
||||||
|
names = {"--engine-jwt-secret"}, |
||||||
|
paramLabel = DefaultCommandValues.MANDATORY_FILE_FORMAT_HELP, |
||||||
|
description = "Path to file containing shared secret key for JWT signature verification") |
||||||
|
private final Path engineJwtKeyFile = null; |
||||||
|
|
||||||
|
@CommandLine.Option( |
||||||
|
names = {"--engine-jwt-disabled"}, |
||||||
|
description = "Disable authentication for Engine APIs (default: ${DEFAULT-VALUE})") |
||||||
|
private final Boolean isEngineAuthDisabled = false; |
||||||
|
|
||||||
|
@CommandLine.Option( |
||||||
|
names = {"--engine-host-allowlist"}, |
||||||
|
paramLabel = "<hostname>[,<hostname>...]... or * or all", |
||||||
|
description = |
||||||
|
"Comma separated list of hostnames to allow for ENGINE API access (applies to both HTTP and websockets), or * to accept any host (default: ${DEFAULT-VALUE})", |
||||||
|
defaultValue = "localhost,127.0.0.1") |
||||||
|
private final JsonRPCAllowlistHostsProperty engineHostsAllowlist = |
||||||
|
new JsonRPCAllowlistHostsProperty(); |
||||||
|
|
||||||
|
@Override |
||||||
|
public EngineRPCConfiguration toDomainObject() { |
||||||
|
return new EngineRPCConfiguration( |
||||||
|
overrideEngineRpcEnabled, |
||||||
|
engineRpcPort, |
||||||
|
engineJwtKeyFile, |
||||||
|
isEngineAuthDisabled, |
||||||
|
engineHostsAllowlist); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public List<String> getCLIOptions() { |
||||||
|
return CommandLineUtils.getCLIOptions(this, new EngineRPCOptions()); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,238 @@ |
|||||||
|
/* |
||||||
|
* Copyright contributors to Hyperledger Besu. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||||
|
* the License. You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||||
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||||
|
* specific language governing permissions and limitations under the License. |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
package org.hyperledger.besu.cli.options.stable; |
||||||
|
|
||||||
|
import org.hyperledger.besu.cli.DefaultCommandValues; |
||||||
|
import org.hyperledger.besu.cli.converter.PercentageConverter; |
||||||
|
import org.hyperledger.besu.cli.converter.SubnetInfoConverter; |
||||||
|
import org.hyperledger.besu.cli.options.CLIOptions; |
||||||
|
import org.hyperledger.besu.cli.util.CommandLineUtils; |
||||||
|
import org.hyperledger.besu.ethereum.p2p.discovery.P2PDiscoveryConfiguration; |
||||||
|
import org.hyperledger.besu.ethereum.p2p.peers.EnodeURLImpl; |
||||||
|
import org.hyperledger.besu.util.NetworkUtility; |
||||||
|
import org.hyperledger.besu.util.number.Fraction; |
||||||
|
import org.hyperledger.besu.util.number.Percentage; |
||||||
|
|
||||||
|
import java.net.InetAddress; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.Collection; |
||||||
|
import java.util.List; |
||||||
|
import java.util.Optional; |
||||||
|
import java.util.stream.Collectors; |
||||||
|
|
||||||
|
import org.apache.commons.net.util.SubnetUtils; |
||||||
|
import org.apache.tuweni.bytes.Bytes; |
||||||
|
import picocli.CommandLine; |
||||||
|
|
||||||
|
/** Command line options for configuring P2P discovery on the node. */ |
||||||
|
public class P2PDiscoveryOptions implements CLIOptions<P2PDiscoveryConfiguration> { |
||||||
|
|
||||||
|
/** Default constructor */ |
||||||
|
public P2PDiscoveryOptions() {} |
||||||
|
|
||||||
|
// Public IP stored to prevent having to research it each time we need it.
|
||||||
|
private InetAddress autoDiscoveredDefaultIP = null; |
||||||
|
|
||||||
|
/** Completely disables P2P within Besu. */ |
||||||
|
@CommandLine.Option( |
||||||
|
names = {"--p2p-enabled"}, |
||||||
|
description = "Enable P2P functionality (default: ${DEFAULT-VALUE})", |
||||||
|
arity = "1") |
||||||
|
public final Boolean p2pEnabled = true; |
||||||
|
|
||||||
|
/** |
||||||
|
* Boolean option to indicate if peers should NOT be discovered, default to false indicates that |
||||||
|
* the peers should be discovered by default. |
||||||
|
*/ |
||||||
|
//
|
||||||
|
// This negative option is required because of the nature of the option that is
|
||||||
|
// true when
|
||||||
|
// added on the command line. You can't do --option=false, so false is set as
|
||||||
|
// default
|
||||||
|
// and you have not to set the option at all if you want it false.
|
||||||
|
// This seems to be the only way it works with Picocli.
|
||||||
|
// Also many other software use the same negative option scheme for false
|
||||||
|
// defaults
|
||||||
|
// meaning that it's probably the right way to handle disabling options.
|
||||||
|
@CommandLine.Option( |
||||||
|
names = {"--discovery-enabled"}, |
||||||
|
description = "Enable P2P discovery (default: ${DEFAULT-VALUE})", |
||||||
|
arity = "1") |
||||||
|
public final Boolean peerDiscoveryEnabled = true; |
||||||
|
|
||||||
|
/** |
||||||
|
* A list of bootstrap nodes can be passed and a hardcoded list will be used otherwise by the |
||||||
|
* Runner. |
||||||
|
*/ |
||||||
|
// NOTE: we have no control over default value here.
|
||||||
|
@CommandLine.Option( |
||||||
|
names = {"--bootnodes"}, |
||||||
|
paramLabel = "<enode://id@host:port>", |
||||||
|
description = |
||||||
|
"Comma separated enode URLs for P2P discovery bootstrap. " |
||||||
|
+ "Default is a predefined list.", |
||||||
|
split = ",", |
||||||
|
arity = "0..*") |
||||||
|
public final List<String> bootNodes = null; |
||||||
|
|
||||||
|
/** The IP the node advertises to peers for P2P communication. */ |
||||||
|
@SuppressWarnings({"FieldCanBeFinal", "FieldMayBeFinal"}) // PicoCLI requires non-final Strings.
|
||||||
|
@CommandLine.Option( |
||||||
|
names = {"--p2p-host"}, |
||||||
|
paramLabel = DefaultCommandValues.MANDATORY_HOST_FORMAT_HELP, |
||||||
|
description = "IP address this node advertises to its peers (default: ${DEFAULT-VALUE})", |
||||||
|
arity = "1") |
||||||
|
public String p2pHost = autoDiscoverDefaultIP().getHostAddress(); |
||||||
|
|
||||||
|
/** The network interface address on which this node listens for P2P communication. */ |
||||||
|
@SuppressWarnings({"FieldCanBeFinal", "FieldMayBeFinal"}) // PicoCLI requires non-final Strings.
|
||||||
|
@CommandLine.Option( |
||||||
|
names = {"--p2p-interface"}, |
||||||
|
paramLabel = DefaultCommandValues.MANDATORY_HOST_FORMAT_HELP, |
||||||
|
description = |
||||||
|
"The network interface address on which this node listens for P2P communication (default: ${DEFAULT-VALUE})", |
||||||
|
arity = "1") |
||||||
|
public String p2pInterface = NetworkUtility.INADDR_ANY; |
||||||
|
|
||||||
|
/** The port on which this node listens for P2P communication. */ |
||||||
|
@CommandLine.Option( |
||||||
|
names = {"--p2p-port"}, |
||||||
|
paramLabel = DefaultCommandValues.MANDATORY_PORT_FORMAT_HELP, |
||||||
|
description = "Port on which to listen for P2P communication (default: ${DEFAULT-VALUE})", |
||||||
|
arity = "1") |
||||||
|
public final Integer p2pPort = EnodeURLImpl.DEFAULT_LISTENING_PORT; |
||||||
|
|
||||||
|
/** The maximum number of peers this node can connect to. */ |
||||||
|
@CommandLine.Option( |
||||||
|
names = {"--max-peers", "--p2p-peer-upper-bound"}, |
||||||
|
paramLabel = DefaultCommandValues.MANDATORY_INTEGER_FORMAT_HELP, |
||||||
|
description = "Maximum P2P connections that can be established (default: ${DEFAULT-VALUE})") |
||||||
|
public final Integer maxPeers = DefaultCommandValues.DEFAULT_MAX_PEERS; |
||||||
|
|
||||||
|
/** Boolean option to limit the number of P2P connections initiated remotely. */ |
||||||
|
@CommandLine.Option( |
||||||
|
names = {"--remote-connections-limit-enabled"}, |
||||||
|
description = |
||||||
|
"Whether to limit the number of P2P connections initiated remotely. (default: ${DEFAULT-VALUE})") |
||||||
|
public final Boolean isLimitRemoteWireConnectionsEnabled = true; |
||||||
|
|
||||||
|
/** The maximum percentage of P2P connections that can be initiated remotely. */ |
||||||
|
@CommandLine.Option( |
||||||
|
names = {"--remote-connections-max-percentage"}, |
||||||
|
paramLabel = DefaultCommandValues.MANDATORY_DOUBLE_FORMAT_HELP, |
||||||
|
description = |
||||||
|
"The maximum percentage of P2P connections that can be initiated remotely. Must be between 0 and 100 inclusive. (default: ${DEFAULT-VALUE})", |
||||||
|
arity = "1", |
||||||
|
converter = PercentageConverter.class) |
||||||
|
public final Percentage maxRemoteConnectionsPercentage = |
||||||
|
Fraction.fromFloat(DefaultCommandValues.DEFAULT_FRACTION_REMOTE_WIRE_CONNECTIONS_ALLOWED) |
||||||
|
.toPercentage(); |
||||||
|
|
||||||
|
/** The URL to use for DNS discovery. */ |
||||||
|
@SuppressWarnings({"FieldCanBeFinal", "FieldMayBeFinal"}) // PicoCLI requires non-final Strings.
|
||||||
|
@CommandLine.Option( |
||||||
|
names = {"--discovery-dns-url"}, |
||||||
|
description = "Specifies the URL to use for DNS discovery") |
||||||
|
public String discoveryDnsUrl = null; |
||||||
|
|
||||||
|
/** Boolean option to allow for incoming connections to be prioritized randomly. */ |
||||||
|
@CommandLine.Option( |
||||||
|
names = {"--random-peer-priority-enabled"}, |
||||||
|
description = |
||||||
|
"Allow for incoming connections to be prioritized randomly. This will prevent (typically small, stable) networks from forming impenetrable peer cliques. (default: ${DEFAULT-VALUE})") |
||||||
|
public final Boolean randomPeerPriority = Boolean.FALSE; |
||||||
|
|
||||||
|
/** A list of node IDs to ban from the P2P network. */ |
||||||
|
@CommandLine.Option( |
||||||
|
names = {"--banned-node-ids", "--banned-node-id"}, |
||||||
|
paramLabel = DefaultCommandValues.MANDATORY_NODE_ID_FORMAT_HELP, |
||||||
|
description = "A list of node IDs to ban from the P2P network.", |
||||||
|
split = ",", |
||||||
|
arity = "1..*") |
||||||
|
void setBannedNodeIds(final List<String> values) { |
||||||
|
try { |
||||||
|
bannedNodeIds = |
||||||
|
values.stream() |
||||||
|
.filter(value -> !value.isEmpty()) |
||||||
|
.map(EnodeURLImpl::parseNodeId) |
||||||
|
.collect(Collectors.toList()); |
||||||
|
} catch (final IllegalArgumentException e) { |
||||||
|
throw new CommandLine.ParameterException( |
||||||
|
new CommandLine(this), "Invalid ids supplied to '--banned-node-ids'. " + e.getMessage()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// Boolean option to set that in a PoA network the bootnodes should always be queried during
|
||||||
|
// peer table refresh. If this flag is disabled bootnodes are only sent FINDN requests on first
|
||||||
|
// startup, meaning that an offline bootnode or network outage at the client can prevent it
|
||||||
|
// discovering any peers without a restart.
|
||||||
|
@CommandLine.Option( |
||||||
|
names = {"--poa-discovery-retry-bootnodes"}, |
||||||
|
description = |
||||||
|
"Always use of bootnodes for discovery in PoA networks. Disabling this reverts " |
||||||
|
+ " to the same behaviour as non-PoA networks, where neighbours are only discovered from bootnodes on first startup." |
||||||
|
+ "(default: ${DEFAULT-VALUE})", |
||||||
|
arity = "1") |
||||||
|
private final Boolean poaDiscoveryRetryBootnodes = true; |
||||||
|
|
||||||
|
private Collection<Bytes> bannedNodeIds = new ArrayList<>(); |
||||||
|
|
||||||
|
/** |
||||||
|
* Auto-discovers the default IP of the client. |
||||||
|
* |
||||||
|
* @return machine loopback address |
||||||
|
*/ |
||||||
|
// Loopback IP is used by default as this is how smokeTests require it to be
|
||||||
|
// and it's probably a good security behaviour to default only on the localhost.
|
||||||
|
public InetAddress autoDiscoverDefaultIP() { |
||||||
|
autoDiscoveredDefaultIP = |
||||||
|
Optional.ofNullable(autoDiscoveredDefaultIP).orElseGet(InetAddress::getLoopbackAddress); |
||||||
|
|
||||||
|
return autoDiscoveredDefaultIP; |
||||||
|
} |
||||||
|
|
||||||
|
@CommandLine.Option( |
||||||
|
names = {"--net-restrict"}, |
||||||
|
arity = "1..*", |
||||||
|
split = ",", |
||||||
|
converter = SubnetInfoConverter.class, |
||||||
|
description = |
||||||
|
"Comma-separated list of allowed IP subnets (e.g., '192.168.1.0/24,10.0.0.0/8').") |
||||||
|
private List<SubnetUtils.SubnetInfo> allowedSubnets; |
||||||
|
|
||||||
|
@Override |
||||||
|
public P2PDiscoveryConfiguration toDomainObject() { |
||||||
|
return new P2PDiscoveryConfiguration( |
||||||
|
p2pEnabled, |
||||||
|
peerDiscoveryEnabled, |
||||||
|
p2pHost, |
||||||
|
p2pInterface, |
||||||
|
p2pPort, |
||||||
|
maxPeers, |
||||||
|
isLimitRemoteWireConnectionsEnabled, |
||||||
|
maxRemoteConnectionsPercentage, |
||||||
|
randomPeerPriority, |
||||||
|
bannedNodeIds, |
||||||
|
allowedSubnets, |
||||||
|
poaDiscoveryRetryBootnodes, |
||||||
|
bootNodes, |
||||||
|
discoveryDnsUrl); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public List<String> getCLIOptions() { |
||||||
|
return CommandLineUtils.getCLIOptions(this, new P2PDiscoveryOptions()); |
||||||
|
} |
||||||
|
} |
@ -1,102 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright contributors to Hyperledger Besu. |
|
||||||
* |
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
|
||||||
* the License. You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
|
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
|
||||||
* specific language governing permissions and limitations under the License. |
|
||||||
* |
|
||||||
* SPDX-License-Identifier: Apache-2.0 |
|
||||||
*/ |
|
||||||
package org.hyperledger.besu.ethereum.eth.manager.peertask; |
|
||||||
|
|
||||||
import org.hyperledger.besu.ethereum.eth.manager.EthPeer; |
|
||||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; |
|
||||||
import org.hyperledger.besu.ethereum.p2p.peers.PeerId; |
|
||||||
import org.hyperledger.besu.ethereum.p2p.rlpx.wire.SubProtocol; |
|
||||||
|
|
||||||
import java.util.Collection; |
|
||||||
import java.util.Comparator; |
|
||||||
import java.util.Map; |
|
||||||
import java.util.Optional; |
|
||||||
import java.util.concurrent.ConcurrentHashMap; |
|
||||||
import java.util.function.Predicate; |
|
||||||
import java.util.function.Supplier; |
|
||||||
|
|
||||||
import org.slf4j.Logger; |
|
||||||
import org.slf4j.LoggerFactory; |
|
||||||
|
|
||||||
/** |
|
||||||
* This is a simple PeerSelector implementation that can be used the default implementation in most |
|
||||||
* situations |
|
||||||
*/ |
|
||||||
public class DefaultPeerSelector implements PeerSelector { |
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(DefaultPeerSelector.class); |
|
||||||
|
|
||||||
private final Supplier<ProtocolSpec> protocolSpecSupplier; |
|
||||||
private final Map<PeerId, EthPeer> ethPeersByPeerId = new ConcurrentHashMap<>(); |
|
||||||
|
|
||||||
public DefaultPeerSelector(final Supplier<ProtocolSpec> protocolSpecSupplier) { |
|
||||||
this.protocolSpecSupplier = protocolSpecSupplier; |
|
||||||
} |
|
||||||
|
|
||||||
/** |
|
||||||
* Gets the highest reputation peer matching the supplied filter |
|
||||||
* |
|
||||||
* @param filter a filter to match prospective peers with |
|
||||||
* @return the highest reputation peer matching the supplies filter |
|
||||||
* @throws NoAvailablePeerException If there are no suitable peers |
|
||||||
*/ |
|
||||||
private EthPeer getPeer(final Predicate<EthPeer> filter) throws NoAvailablePeerException { |
|
||||||
LOG.trace("Finding peer from pool of {} peers", ethPeersByPeerId.size()); |
|
||||||
return ethPeersByPeerId.values().stream() |
|
||||||
.filter(filter) |
|
||||||
.max(Comparator.naturalOrder()) |
|
||||||
.orElseThrow(NoAvailablePeerException::new); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public EthPeer getPeer( |
|
||||||
final Collection<EthPeer> usedEthPeers, |
|
||||||
final long requiredPeerHeight, |
|
||||||
final SubProtocol requiredSubProtocol) |
|
||||||
throws NoAvailablePeerException { |
|
||||||
return getPeer( |
|
||||||
(candidatePeer) -> |
|
||||||
isPeerUnused(candidatePeer, usedEthPeers) |
|
||||||
&& (protocolSpecSupplier.get().isPoS() |
|
||||||
|| isPeerHeightHighEnough(candidatePeer, requiredPeerHeight)) |
|
||||||
&& isPeerProtocolSuitable(candidatePeer, requiredSubProtocol)); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public Optional<EthPeer> getPeerByPeerId(final PeerId peerId) { |
|
||||||
return Optional.ofNullable(ethPeersByPeerId.get(peerId)); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void addPeer(final EthPeer ethPeer) { |
|
||||||
ethPeersByPeerId.put(ethPeer.getConnection().getPeer(), ethPeer); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public void removePeer(final PeerId peerId) { |
|
||||||
ethPeersByPeerId.remove(peerId); |
|
||||||
} |
|
||||||
|
|
||||||
private boolean isPeerUnused(final EthPeer ethPeer, final Collection<EthPeer> usedEthPeers) { |
|
||||||
return !usedEthPeers.contains(ethPeer); |
|
||||||
} |
|
||||||
|
|
||||||
private boolean isPeerHeightHighEnough(final EthPeer ethPeer, final long requiredHeight) { |
|
||||||
return ethPeer.chainState().getEstimatedHeight() >= requiredHeight; |
|
||||||
} |
|
||||||
|
|
||||||
private boolean isPeerProtocolSuitable(final EthPeer ethPeer, final SubProtocol protocol) { |
|
||||||
return ethPeer.getProtocolName().equals(protocol.getName()); |
|
||||||
} |
|
||||||
} |
|
@ -1,135 +0,0 @@ |
|||||||
/* |
|
||||||
* Copyright contributors to Hyperledger Besu. |
|
||||||
* |
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
|
||||||
* the License. You may obtain a copy of the License at |
|
||||||
* |
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
* |
|
||||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
|
||||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
|
||||||
* specific language governing permissions and limitations under the License. |
|
||||||
* |
|
||||||
* SPDX-License-Identifier: Apache-2.0 |
|
||||||
*/ |
|
||||||
package org.hyperledger.besu.ethereum.eth.manager.peertask; |
|
||||||
|
|
||||||
import org.hyperledger.besu.ethereum.eth.EthProtocol; |
|
||||||
import org.hyperledger.besu.ethereum.eth.SnapProtocol; |
|
||||||
import org.hyperledger.besu.ethereum.eth.manager.ChainState; |
|
||||||
import org.hyperledger.besu.ethereum.eth.manager.EthPeer; |
|
||||||
import org.hyperledger.besu.ethereum.eth.manager.PeerReputation; |
|
||||||
import org.hyperledger.besu.ethereum.mainnet.ProtocolSpec; |
|
||||||
import org.hyperledger.besu.ethereum.p2p.peers.Peer; |
|
||||||
import org.hyperledger.besu.ethereum.p2p.rlpx.connections.PeerConnection; |
|
||||||
import org.hyperledger.besu.ethereum.p2p.rlpx.wire.SubProtocol; |
|
||||||
|
|
||||||
import java.util.HashSet; |
|
||||||
import java.util.Set; |
|
||||||
|
|
||||||
import org.junit.jupiter.api.Assertions; |
|
||||||
import org.junit.jupiter.api.BeforeEach; |
|
||||||
import org.junit.jupiter.api.Test; |
|
||||||
import org.mockito.Mockito; |
|
||||||
|
|
||||||
public class DefaultPeerSelectorTest { |
|
||||||
|
|
||||||
public DefaultPeerSelector peerSelector; |
|
||||||
|
|
||||||
@BeforeEach |
|
||||||
public void beforeTest() { |
|
||||||
ProtocolSpec protocolSpec = Mockito.mock(ProtocolSpec.class); |
|
||||||
Mockito.when(protocolSpec.isPoS()).thenReturn(false); |
|
||||||
peerSelector = new DefaultPeerSelector(() -> protocolSpec); |
|
||||||
} |
|
||||||
|
|
||||||
@Test |
|
||||||
public void testGetPeer() throws NoAvailablePeerException { |
|
||||||
EthPeer expectedPeer = createTestPeer(10, EthProtocol.get(), 5); |
|
||||||
peerSelector.addPeer(expectedPeer); |
|
||||||
EthPeer excludedForLowChainHeightPeer = createTestPeer(5, EthProtocol.get(), 50); |
|
||||||
peerSelector.addPeer(excludedForLowChainHeightPeer); |
|
||||||
EthPeer excludedForWrongProtocolPeer = createTestPeer(10, SnapProtocol.get(), 50); |
|
||||||
peerSelector.addPeer(excludedForWrongProtocolPeer); |
|
||||||
EthPeer excludedForLowReputationPeer = createTestPeer(10, EthProtocol.get(), 1); |
|
||||||
peerSelector.addPeer(excludedForLowReputationPeer); |
|
||||||
EthPeer excludedForBeingAlreadyUsedPeer = createTestPeer(10, EthProtocol.get(), 50); |
|
||||||
peerSelector.addPeer(excludedForBeingAlreadyUsedPeer); |
|
||||||
|
|
||||||
Set<EthPeer> usedEthPeers = new HashSet<>(); |
|
||||||
usedEthPeers.add(excludedForBeingAlreadyUsedPeer); |
|
||||||
|
|
||||||
EthPeer result = peerSelector.getPeer(usedEthPeers, 10, EthProtocol.get()); |
|
||||||
|
|
||||||
Assertions.assertSame(expectedPeer, result); |
|
||||||
} |
|
||||||
|
|
||||||
@Test |
|
||||||
public void testGetPeerButNoPeerMatchesFilter() { |
|
||||||
EthPeer expectedPeer = createTestPeer(10, EthProtocol.get(), 5); |
|
||||||
peerSelector.addPeer(expectedPeer); |
|
||||||
EthPeer excludedForLowChainHeightPeer = createTestPeer(5, EthProtocol.get(), 50); |
|
||||||
peerSelector.addPeer(excludedForLowChainHeightPeer); |
|
||||||
EthPeer excludedForWrongProtocolPeer = createTestPeer(10, SnapProtocol.get(), 50); |
|
||||||
peerSelector.addPeer(excludedForWrongProtocolPeer); |
|
||||||
EthPeer excludedForLowReputationPeer = createTestPeer(10, EthProtocol.get(), 1); |
|
||||||
peerSelector.addPeer(excludedForLowReputationPeer); |
|
||||||
EthPeer excludedForBeingAlreadyUsedPeer = createTestPeer(10, EthProtocol.get(), 50); |
|
||||||
peerSelector.addPeer(excludedForBeingAlreadyUsedPeer); |
|
||||||
|
|
||||||
Set<EthPeer> usedEthPeers = new HashSet<>(); |
|
||||||
usedEthPeers.add(excludedForBeingAlreadyUsedPeer); |
|
||||||
|
|
||||||
Assertions.assertThrows( |
|
||||||
NoAvailablePeerException.class, |
|
||||||
() -> peerSelector.getPeer(usedEthPeers, 10, new MockSubProtocol())); |
|
||||||
} |
|
||||||
|
|
||||||
private EthPeer createTestPeer( |
|
||||||
final long chainHeight, final SubProtocol protocol, final int reputation) { |
|
||||||
EthPeer ethPeer = Mockito.mock(EthPeer.class); |
|
||||||
PeerConnection peerConnection = Mockito.mock(PeerConnection.class); |
|
||||||
Peer peer = Mockito.mock(Peer.class); |
|
||||||
ChainState chainState = Mockito.mock(ChainState.class); |
|
||||||
PeerReputation peerReputation = Mockito.mock(PeerReputation.class); |
|
||||||
|
|
||||||
Mockito.when(ethPeer.getConnection()).thenReturn(peerConnection); |
|
||||||
Mockito.when(peerConnection.getPeer()).thenReturn(peer); |
|
||||||
Mockito.when(ethPeer.getProtocolName()).thenReturn(protocol.getName()); |
|
||||||
Mockito.when(ethPeer.chainState()).thenReturn(chainState); |
|
||||||
Mockito.when(chainState.getEstimatedHeight()).thenReturn(chainHeight); |
|
||||||
Mockito.when(ethPeer.getReputation()).thenReturn(peerReputation); |
|
||||||
Mockito.when(peerReputation.getScore()).thenReturn(reputation); |
|
||||||
|
|
||||||
Mockito.when(ethPeer.compareTo(Mockito.any(EthPeer.class))) |
|
||||||
.thenAnswer( |
|
||||||
(invocationOnMock) -> { |
|
||||||
EthPeer otherPeer = invocationOnMock.getArgument(0, EthPeer.class); |
|
||||||
return Integer.compare(reputation, otherPeer.getReputation().getScore()); |
|
||||||
}); |
|
||||||
return ethPeer; |
|
||||||
} |
|
||||||
|
|
||||||
private static class MockSubProtocol implements SubProtocol { |
|
||||||
|
|
||||||
@Override |
|
||||||
public String getName() { |
|
||||||
return "Mock"; |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public int messageSpace(final int protocolVersion) { |
|
||||||
throw new UnsupportedOperationException(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public boolean isValidMessageCode(final int protocolVersion, final int code) { |
|
||||||
throw new UnsupportedOperationException(); |
|
||||||
} |
|
||||||
|
|
||||||
@Override |
|
||||||
public String messageName(final int protocolVersion, final int code) { |
|
||||||
throw new UnsupportedOperationException(); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,39 @@ |
|||||||
|
/* |
||||||
|
* Copyright contributors to Hyperledger Besu. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with |
||||||
|
* the License. You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on |
||||||
|
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the |
||||||
|
* specific language governing permissions and limitations under the License. |
||||||
|
* |
||||||
|
* SPDX-License-Identifier: Apache-2.0 |
||||||
|
*/ |
||||||
|
package org.hyperledger.besu.ethereum.p2p.discovery; |
||||||
|
|
||||||
|
import org.hyperledger.besu.util.number.Percentage; |
||||||
|
|
||||||
|
import java.util.Collection; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import org.apache.commons.net.util.SubnetUtils; |
||||||
|
import org.apache.tuweni.bytes.Bytes; |
||||||
|
|
||||||
|
public record P2PDiscoveryConfiguration( |
||||||
|
Boolean p2pEnabled, |
||||||
|
Boolean peerDiscoveryEnabled, |
||||||
|
String p2pHost, |
||||||
|
String p2pInterface, |
||||||
|
Integer p2pPort, |
||||||
|
Integer maxPeers, |
||||||
|
Boolean isLimitRemoteWireConnectionsEnabled, |
||||||
|
Percentage maxRemoteConnectionsPercentage, |
||||||
|
Boolean randomPeerPriority, |
||||||
|
Collection<Bytes> bannedNodeIds, |
||||||
|
List<SubnetUtils.SubnetInfo> allowedSubnets, |
||||||
|
Boolean poaDiscoveryRetryBootnodes, |
||||||
|
List<String> bootNodes, |
||||||
|
String discoveryDnsUrl) {} |
Loading…
Reference in new issue