diff --git a/.github/workflows/analyzers.yml b/.github/workflows/analyzers.yml index 8bf6a462b9..30b98c7342 100644 --- a/.github/workflows/analyzers.yml +++ b/.github/workflows/analyzers.yml @@ -6,10 +6,26 @@ jobs: clang_format: runs-on: ubuntu-18.04 steps: - - uses: actions/checkout@50fbc62 + - uses: actions/checkout@50fbc622fc4ef5163becd7fab6573eac35f8462e - name: Get clang-format 8 env: DEBIAN_FRONTEND: noninteractive run: sudo update-alternatives --install /usr/bin/clang-format clang-format /usr/bin/clang-format-8 1000 - name: Clang Format - run: ci/check-commit-format.sh \ No newline at end of file + run: ci/check-commit-format.sh + + cmake_format: + runs-on: ubuntu-18.04 + if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository + steps: + - uses: actions/checkout@50fbc622fc4ef5163becd7fab6573eac35f8462e + - uses: actions/setup-python@41b7212b1668f5de9d65e9c82aa777e6bbedb3a8 + with: + python-version: '3.x' + architecture: 'x64' + - uses: BSFishy/pip-action@8f2d471d809dc20b6ada98c91910b6ae6243f318 + with: + packages: | + cmake-format + - name: Check cmake-format + run: bash ci/check-cmake-format.sh diff --git a/.github/workflows/beta_artifacts.yml b/.github/workflows/beta_artifacts.yml index 04d2c76744..218c01bb4d 100644 --- a/.github/workflows/beta_artifacts.yml +++ b/.github/workflows/beta_artifacts.yml @@ -18,9 +18,13 @@ jobs: - uses: actions/checkout@722adc6 - uses: chrislennon/action-aws-cli@f0f8671 - name: tag - run: echo "::set-env name=TAG::`git describe --tags $GITHUB_SHA`" - - name: Checkout Submodules - run: git submodule update --init --recursive + run: | + echo "TAG=${{ github.event.inputs.ref }}" >> $GITHUB_ENV + - uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f + with: + submodules: "recursive" + ref: ${{ github.event.inputs.ref }} + repository: ${{ github.event.inputs.repo }} - name: Fetch Deps run: ci/actions/osx/install_deps.sh - name: Build Artifact @@ -38,9 +42,13 @@ jobs: - uses: actions/checkout@722adc6 - uses: chrislennon/action-aws-cli@f0f8671 - name: tag - run: echo "::set-env name=TAG::`git describe --tags $GITHUB_SHA`" - - name: Checkout Submodules - run: git submodule update --init --recursive + run: | + echo "TAG=${{ github.event.inputs.ref }}" >> $GITHUB_ENV + - uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f + with: + submodules: "recursive" + ref: ${{ github.event.inputs.ref }} + repository: ${{ github.event.inputs.repo }} - name: Fetch Deps run: ci/actions/linux/install_deps.sh - name: Build Artifact @@ -58,16 +66,29 @@ jobs: - uses: actions/checkout@722adc6 - uses: chrislennon/action-aws-cli@f0f8671 - name: tag - run: echo "::set-env name=TAG::`git describe --tags $GITHUB_SHA`" - - name: Checkout Submodules - run: git submodule update --init --recursive + run: | + echo "TAG=${{ github.event.inputs.ref }}" >> $GITHUB_ENV + - uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f + with: + submodules: "recursive" + ref: ${{ github.event.inputs.ref }} + repository: ${{ github.event.inputs.repo }} - name: Fetch Deps run: ci/actions/linux/install_deps.sh - name: Deploy Docker (nanocurrency/nano-beta) run: TRAVIS_TAG=${TAG} ci/actions/linux/deploy-docker.sh env: DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - + + - name: Login to ghcr.io + uses: docker/login-action@adb73476b6e06caddec5db0bc1deacbec8cdd947 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GHCR_PAT }} + - name: Deploy Docker (ghcr.io) + run: ci/actions/linux/ghcr_push.sh + windows_job: runs-on: windows-latest steps: @@ -75,10 +96,12 @@ jobs: - uses: chrislennon/action-aws-cli@f0f8671 - name: tag run: | - $TRAVIS_TAG=git describe --tags $GITHUB_SHA - echo "::set-env name=TAG::$TRAVIS_TAG" - - name: Checkout Submodules - run: git submodule update --init --recursive + Write-Output "TAG=${{ github.event.inputs.ref }}" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + - uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f + with: + submodules: "recursive" + ref: ${{ github.event.inputs.ref }} + repository: ${{ github.event.inputs.repo }} - name: Fetch Deps run: ci/actions/windows/install_deps.ps1 - name: Build Artifact diff --git a/.github/workflows/develop.yml b/.github/workflows/develop.yml index 6bfe426e68..4a42219576 100644 --- a/.github/workflows/develop.yml +++ b/.github/workflows/develop.yml @@ -8,11 +8,19 @@ jobs: linux_job: runs-on: ubuntu-18.04 steps: - - uses: actions/checkout@722adc6 - - name: Checkout Submodules - run: git submodule update --init --recursive + - uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f + with: + submodules: "recursive" - name: Fetch Deps run: ci/actions/linux/install_deps.sh + - name: Login to ghcr.io + uses: docker/login-action@adb73476b6e06caddec5db0bc1deacbec8cdd947 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GHCR_PAT }} + - name: Deploy Docker (ghcr.io) + run: ci/actions/linux/ghcr_push.sh - name: Deploy Docker (nanocurrency/nano-env) run: ci/actions/linux/deploy-docker.sh env: diff --git a/.github/workflows/live_artifacts.yml b/.github/workflows/live_artifacts.yml index 0c85a7fad0..07ab3f7907 100644 --- a/.github/workflows/live_artifacts.yml +++ b/.github/workflows/live_artifacts.yml @@ -17,9 +17,13 @@ jobs: - uses: actions/checkout@722adc6 - uses: chrislennon/action-aws-cli@f0f8671 - name: tag - run: echo "::set-env name=TAG::`git describe --tags $GITHUB_SHA`" - - name: Checkout Submodules - run: git submodule update --init --recursive + run: | + echo "TAG=${{ github.event.inputs.ref }}" >> $GITHUB_ENV + - uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f + with: + submodules: "recursive" + ref: ${{ github.event.inputs.ref }} + repository: ${{ github.event.inputs.repo }} - name: Fetch Deps run: ci/actions/osx/install_deps.sh - name: Build Artifact @@ -37,9 +41,13 @@ jobs: - uses: actions/checkout@722adc6 - uses: chrislennon/action-aws-cli@f0f8671 - name: tag - run: echo "::set-env name=TAG::`git describe --tags $GITHUB_SHA`" - - name: Checkout Submodules - run: git submodule update --init --recursive + run: | + echo "TAG=${{ github.event.inputs.ref }}" >> $GITHUB_ENV + - uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f + with: + submodules: "recursive" + ref: ${{ github.event.inputs.ref }} + repository: ${{ github.event.inputs.repo }} - name: Fetch Deps run: ci/actions/linux/install_deps.sh - name: Build Artifact @@ -57,16 +65,29 @@ jobs: - uses: actions/checkout@722adc6 - uses: chrislennon/action-aws-cli@f0f8671 - name: tag - run: echo "::set-env name=TAG::`git describe --tags $GITHUB_SHA`" - - name: Checkout Submodules - run: git submodule update --init --recursive + run: | + echo "TAG=${{ github.event.inputs.ref }}" >> $GITHUB_ENV + - uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f + with: + submodules: "recursive" + ref: ${{ github.event.inputs.ref }} + repository: ${{ github.event.inputs.repo }} - name: Fetch Deps run: ci/actions/linux/install_deps.sh - name: Deploy Docker (nanocurrency/nano) run: TRAVIS_TAG=${TAG} ci/actions/linux/deploy-docker.sh env: DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} - + + - name: Login to ghcr.io + uses: docker/login-action@adb73476b6e06caddec5db0bc1deacbec8cdd947 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GHCR_PAT }} + - name: Deploy Docker (ghcr.io + run: ci/actions/linux/ghcr_push.sh + windows_job: runs-on: windows-latest steps: @@ -74,10 +95,12 @@ jobs: - uses: chrislennon/action-aws-cli@f0f8671 - name: tag run: | - $TRAVIS_TAG=git describe --tags $GITHUB_SHA - echo "::set-env name=TAG::$TRAVIS_TAG" - - name: Checkout Submodules - run: git submodule update --init --recursive + Write-Output "TAG=${{ github.event.inputs.ref }}" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + - uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f + with: + submodules: "recursive" + ref: ${{ github.event.inputs.ref }} + repository: ${{ github.event.inputs.repo }} - name: Fetch Deps run: ci/actions/windows/install_deps.ps1 - name: Build Artifact diff --git a/.github/workflows/release_test.yml b/.github/workflows/release_test.yml index 5ea8160154..8dff20195c 100644 --- a/.github/workflows/release_test.yml +++ b/.github/workflows/release_test.yml @@ -14,9 +14,10 @@ jobs: env: BOOST_ROOT: /tmp/boost steps: - - uses: actions/checkout@722adc6 - - name: Checkout Submodules - run: git submodule update --init --recursive + - uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f + with: + submodules: "recursive" + - name: Fetch Deps run: TEST=1 ci/actions/osx/install_deps.sh - name: Run Tests @@ -26,9 +27,10 @@ jobs: runs-on: ubuntu-18.04 timeout-minutes: 60 steps: - - uses: actions/checkout@722adc6 - - name: Checkout Submodules - run: git submodule update --init --recursive + - uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f + with: + submodules: "recursive" + - name: Fetch Deps run: ci/actions/linux/install_deps.sh - name: Run Tests @@ -38,9 +40,10 @@ jobs: runs-on: ubuntu-18.04 timeout-minutes: 60 steps: - - uses: actions/checkout@722adc6 - - name: Checkout Submodules - run: git submodule update --init --recursive + - uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f + with: + submodules: "recursive" + - name: Fetch Deps run: ci/actions/linux/install_deps.sh - name: Run Tests @@ -50,9 +53,9 @@ jobs: runs-on: windows-latest timeout-minutes: 60 steps: - - uses: actions/checkout@722adc6 - - name: Checkout Submodules - run: git submodule update --init --recursive + - uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f + with: + submodules: "recursive" - name: Fetch Deps run: ci/actions/windows/install_deps.ps1 - name: Run Tests diff --git a/.github/workflows/rocksdb_release_tests.yml b/.github/workflows/rocksdb_release_tests.yml new file mode 100644 index 0000000000..de2fbe34e7 --- /dev/null +++ b/.github/workflows/rocksdb_release_tests.yml @@ -0,0 +1,48 @@ +name: RocksDB Release Tests + +on: + push: + tags: '*' + +env: + RELEASE: 1 + artifact: 0 + TEST_USE_ROCKSDB: 1 + +jobs: + osx_test: + runs-on: macos-latest + env: + BOOST_ROOT: /tmp/boost + steps: + - uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f + with: + submodules: "recursive" + - name: Fetch Deps + run: TEST=1 ci/actions/osx/install_deps.sh + - name: Run Tests + run: ci/build-travis.sh "/tmp/qt/lib/cmake/Qt5"; + + gcc_test: + runs-on: ubuntu-18.04 + timeout-minutes: 60 + steps: + - uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f + with: + submodules: "recursive" + - name: Fetch Deps + run: ci/actions/linux/install_deps.sh + - name: Run Tests + run: docker run -e TEST_USE_ROCKSDB -v ${PWD}:/workspace nanocurrency/nano-env:gcc /bin/bash -c "cd /workspace && RELEASE=1 ./ci/build-travis.sh /usr/lib/x86_64-linux-gnu/cmake/Qt5 ${PWD}" + + clang_test: + runs-on: ubuntu-18.04 + timeout-minutes: 60 + steps: + - uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f + with: + submodules: "recursive" + - name: Fetch Deps + run: ci/actions/linux/install_deps.sh + - name: Run Tests + run: docker run -e TEST_USE_ROCKSDB -v ${PWD}:/workspace nanocurrency/nano-env:clang-6 /bin/bash -c "cd /workspace && RELEASE=1 ./ci/build-travis.sh /usr/lib/x86_64-linux-gnu/cmake/Qt5 ${PWD}" diff --git a/.github/workflows/rocksdb_tests.yml b/.github/workflows/rocksdb_tests.yml new file mode 100644 index 0000000000..94b52d0425 --- /dev/null +++ b/.github/workflows/rocksdb_tests.yml @@ -0,0 +1,68 @@ +name: RocksDB Tests + +on: [push, pull_request] + +env: + RELEASE: 0 + artifact: 0 + TEST_USE_ROCKSDB: 1 + +jobs: + osx_test: + runs-on: macos-latest + env: + BOOST_ROOT: /tmp/boost + DEADLINE_SCALE_FACTOR: 2 + if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository + steps: + - uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f + with: + submodules: "recursive" + - name: Fetch Deps + run: TEST=1 ci/actions/osx/install_deps.sh + - name: Run Tests + run: ci/build-travis.sh "/tmp/qt/lib/cmake/Qt5"; + + gcc_test: + runs-on: ubuntu-18.04 + timeout-minutes: 60 + if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository + steps: + - uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f + with: + submodules: "recursive" + - name: Fetch Deps + run: ci/actions/linux/install_deps.sh + - name: Run Tests + run: docker run -e TEST_USE_ROCKSDB -v ${PWD}:/workspace nanocurrency/nano-env:gcc /bin/bash -c "cd /workspace && ./ci/build-travis.sh /usr/lib/x86_64-linux-gnu/cmake/Qt5 ${PWD}" + + clang_test: + runs-on: ubuntu-18.04 + timeout-minutes: 60 + if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository + steps: + - uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f + with: + submodules: "recursive" + - name: Fetch Deps + run: ci/actions/linux/install_deps.sh + - name: Run Tests + run: docker run -e TEST_USE_ROCKSDB -v ${PWD}:/workspace nanocurrency/nano-env:clang-6 /bin/bash -c "cd /workspace && ./ci/build-travis.sh /usr/lib/x86_64-linux-gnu/cmake/Qt5 ${PWD}" + + windows_test: + runs-on: windows-latest + timeout-minutes: 60 + env: + RELEASE: 1 + DEADLINE_SCALE_FACTOR: 2 + if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository + steps: + - uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f + with: + submodules: "recursive" + - name: Windows Defender + run: ci/actions/windows/disable_windows_defender.ps1 + - name: Fetch Deps + run: ci/actions/windows/install_deps.ps1 + - name: Run Tests + run: ci/actions/windows/build.ps1 diff --git a/.github/workflows/test_network_artifacts.yml b/.github/workflows/test_network_artifacts.yml new file mode 100644 index 0000000000..479b8efba0 --- /dev/null +++ b/.github/workflows/test_network_artifacts.yml @@ -0,0 +1,121 @@ +name: Test +on: + workflow_dispatch: + inputs: + repo: + description: "repo" + default: "nanocurrency/nano-node" + required: true + ref: + description: "tag to build" + default: "develop" + required: true +env: + artifact: 1 + TEST: 1 + +jobs: + osx_job: + runs-on: macos-latest + timeout-minutes: 90 + env: + BOOST_ROOT: /tmp/boost + steps: + - name: tag + run: | + echo "TAG=${{ github.event.inputs.ref }}" >> $GITHUB_ENV + - uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f + with: + submodules: "recursive" + ref: ${{ github.event.inputs.ref }} + repository: ${{ github.event.inputs.repo }} + - name: Fetch Deps + run: ci/actions/osx/install_deps.sh + - name: Build Artifact + run: TRAVIS_TAG=${TAG} ci/build-deploy.sh "/tmp/qt/lib/cmake/Qt5"; + - name: Deploy Artifact + run: ci/actions/deploy.sh + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + AWS_DEFAULT_REGION: us-east-2 + + linux_job: + runs-on: ubuntu-18.04 + timeout-minutes: 90 + steps: + - name: tag + run: | + echo "TAG=${{ github.event.inputs.ref }}" >> $GITHUB_ENV + - uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f + with: + submodules: "recursive" + ref: ${{ github.event.inputs.ref }} + repository: ${{ github.event.inputs.repo }} + - name: Fetch Deps + env: + COMPILER: gcc + run: ci/actions/linux/install_deps.sh + - name: Build Artifact + run: docker run -e TEST -v ${GITHUB_WORKSPACE}:/workspace nanocurrency/nano-env:gcc /bin/bash -c "cd /workspace && TRAVIS_TAG=${TAG} ci/build-deploy.sh /usr/lib/x86_64-linux-gnu/cmake/Qt5" + - name: Deploy Artifact + run: ci/actions/deploy.sh + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + AWS_DEFAULT_REGION: us-east-2 + + linux_docker_job: + runs-on: ubuntu-18.04 + timeout-minutes: 90 + steps: + - name: tag + run: | + echo "TAG=${{ github.event.inputs.ref }}" >> $GITHUB_ENV + - uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f + with: + submodules: "recursive" + ref: ${{ github.event.inputs.ref }} + repository: ${{ github.event.inputs.repo }} + - name: Fetch Deps + env: + COMPILER: gcc + run: ci/actions/linux/install_deps.sh + - name: Deploy Docker (nanocurrency/nano) + run: TRAVIS_TAG=${TAG} ci/actions/linux/deploy-docker.sh + env: + DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }} + - name: Login to ghcr.io + uses: docker/login-action@adb73476b6e06caddec5db0bc1deacbec8cdd947 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GHCR_PAT }} + - name: Deploy Docker (ghcr.io) + run: ci/actions/linux/ghcr_push.sh + + windows_job: + runs-on: windows-latest + timeout-minutes: 90 + steps: + - name: tag + run: | + Write-Output "TAG=${{ github.event.inputs.ref }}" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append + - uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f + with: + submodules: "recursive" + ref: ${{ github.event.inputs.ref }} + repository: ${{ github.event.inputs.repo }} + - name: Fetch Deps + run: ci/actions/windows/install_deps.ps1 + - name: Build Artifact + run: ci/actions/windows/build.ps1 + env: + CSC_LINK: ${{ secrets.CSC_LINK }} + CSC_KEY_PASSWORD: ${{ secrets.CSC_KEY_PASSWORD }} + - name: Deploy Artifact + run: ci/actions/windows/deploy.ps1 + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + AWS_DEFAULT_REGION: us-east-2 \ No newline at end of file diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index a9ade4d623..62f10c829f 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -12,9 +12,9 @@ jobs: env: BOOST_ROOT: /tmp/boost steps: - - uses: actions/checkout@722adc6 - - name: Checkout Submodules - run: git submodule update --init --recursive + - uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f + with: + submodules: "recursive" - name: Fetch Deps run: TEST=1 ci/actions/osx/install_deps.sh - name: Run Tests @@ -24,9 +24,9 @@ jobs: runs-on: ubuntu-18.04 timeout-minutes: 60 steps: - - uses: actions/checkout@722adc6 - - name: Checkout Submodules - run: git submodule update --init --recursive + - uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f + with: + submodules: "recursive" - name: Fetch Deps run: ci/actions/linux/install_deps.sh - name: Run Tests @@ -36,9 +36,9 @@ jobs: runs-on: ubuntu-18.04 timeout-minutes: 60 steps: - - uses: actions/checkout@722adc6 - - name: Checkout Submodules - run: git submodule update --init --recursive + - uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f + with: + submodules: "recursive" - name: Fetch Deps run: ci/actions/linux/install_deps.sh - name: Run Tests @@ -48,7 +48,9 @@ jobs: runs-on: windows-latest timeout-minutes: 60 steps: - - uses: actions/checkout@722adc6 + - uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f + with: + submodules: "recursive" - name: Windows Defender run: ci/actions/windows/disable_windows_defender.ps1 - name: Checkout Submodules diff --git a/CMakeLists.txt b/CMakeLists.txt index 45583763a1..16b09d7660 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,7 +36,7 @@ if(MSVC) endif() set (CPACK_PACKAGE_VERSION_MAJOR "21") -set (CPACK_PACKAGE_VERSION_MINOR "2") +set (CPACK_PACKAGE_VERSION_MINOR "3") set (CPACK_PACKAGE_VERSION_PATCH "0") set (CPACK_PACKAGE_VERSION_PRE_RELEASE "0") set (CPACK_PACKAGE_VENDOR "Nano Currency") diff --git a/nano/core_test/active_transactions.cpp b/nano/core_test/active_transactions.cpp index 987483c0ca..42f92af659 100644 --- a/nano/core_test/active_transactions.cpp +++ b/nano/core_test/active_transactions.cpp @@ -124,7 +124,6 @@ TEST (active_transactions, keep_local) { ASSERT_NO_ERROR (system.poll ()); } - ASSERT_EQ (0, node.active.recently_dropped.size ()); while (!node.active.empty ()) { nano::lock_guard active_guard (node.active.mutex); @@ -146,7 +145,6 @@ TEST (active_transactions, keep_local) { ASSERT_NO_ERROR (system.poll ()); } - ASSERT_EQ (1, node.active.recently_dropped.size ()); ASSERT_EQ (1, node.stats.count (nano::stat::type::election, nano::stat::detail::election_drop)); } @@ -990,7 +988,6 @@ TEST (active_transactions, restart_dropped) auto send (std::make_shared (nano::test_genesis_key.pub, genesis.hash (), nano::test_genesis_key.pub, nano::genesis_amount - nano::xrb_ratio, nano::test_genesis_key.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (genesis.hash ()))); // Process only in ledger and simulate dropping the election ASSERT_EQ (nano::process_result::progress, node.process (*send).code); - node.active.recently_dropped.add (send->qualified_root ()); // Generate higher difficulty work ASSERT_TRUE (node.work_generate_blocking (*send, send->difficulty () + 1).is_initialized ()); // Process the same block with updated work @@ -1003,8 +1000,6 @@ TEST (active_transactions, restart_dropped) ASSERT_NE (nullptr, ledger_block); // Exact same block, including work value must have been re-written ASSERT_EQ (*send, *ledger_block); - // Removed from the dropped elections cache - ASSERT_EQ (std::chrono::steady_clock::time_point{}, node.active.recently_dropped.find (send->qualified_root ())); // Drop election node.active.erase (*send); ASSERT_EQ (0, node.active.size ()); diff --git a/nano/core_test/bootstrap.cpp b/nano/core_test/bootstrap.cpp index 7751c147a6..83759f22e5 100644 --- a/nano/core_test/bootstrap.cpp +++ b/nano/core_test/bootstrap.cpp @@ -376,181 +376,6 @@ TEST (bootstrap_processor, DISABLED_pull_requeue_network_error) ASSERT_EQ (0, node1->stats.count (nano::stat::type::bootstrap, nano::stat::detail::bulk_pull_failed_account, nano::stat::dir::in)); // Requeue is not increasing failed attempts } -TEST (bootstrap_processor, frontiers_unconfirmed) -{ - nano::system system; - nano::node_config node_config (nano::get_available_port (), system.logging); - node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled; - node_config.tcp_io_timeout = std::chrono::seconds (2); - nano::node_flags node_flags; - node_flags.disable_bootstrap_bulk_pull_server = true; - node_flags.disable_bootstrap_bulk_push_client = true; - node_flags.disable_legacy_bootstrap = true; - node_flags.disable_lazy_bootstrap = true; - node_flags.disable_wallet_bootstrap = true; - node_flags.disable_rep_crawler = true; - auto node1 = system.add_node (node_config, node_flags); - nano::genesis genesis; - nano::keypair key1, key2; - // Generating invalid chain - auto send1 (std::make_shared (nano::test_genesis_key.pub, genesis.hash (), nano::test_genesis_key.pub, nano::genesis_amount - nano::Gxrb_ratio, key1.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (genesis.hash ()))); - ASSERT_EQ (nano::process_result::progress, node1->process (*send1).code); - auto send2 (std::make_shared (nano::test_genesis_key.pub, send1->hash (), nano::test_genesis_key.pub, nano::genesis_amount - 2 * nano::Gxrb_ratio, key2.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (send1->hash ()))); - ASSERT_EQ (nano::process_result::progress, node1->process (*send2).code); - auto open1 (std::make_shared (key1.pub, 0, key1.pub, nano::Gxrb_ratio, send1->hash (), key1.prv, key1.pub, *system.work.generate (key1.pub))); - ASSERT_EQ (nano::process_result::progress, node1->process (*open1).code); - auto open2 (std::make_shared (key2.pub, 0, key2.pub, nano::Gxrb_ratio, send2->hash (), key2.prv, key2.pub, *system.work.generate (key2.pub))); - ASSERT_EQ (nano::process_result::progress, node1->process (*open2).code); - - node_config.peering_port = nano::get_available_port (); - node_flags.disable_bootstrap_bulk_pull_server = false; - node_flags.disable_rep_crawler = false; - auto node2 = system.add_node (node_config, node_flags); - // Generating valid chain - auto send3 (std::make_shared (nano::test_genesis_key.pub, genesis.hash (), nano::test_genesis_key.pub, nano::genesis_amount - nano::xrb_ratio, key1.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (genesis.hash ()))); - ASSERT_EQ (nano::process_result::progress, node2->process (*send3).code); - auto open3 (std::make_shared (key1.pub, 0, key1.pub, nano::xrb_ratio, send3->hash (), key1.prv, key1.pub, *system.work.generate (key1.pub))); - ASSERT_EQ (nano::process_result::progress, node2->process (*open3).code); - system.wallet (1)->insert_adhoc (nano::test_genesis_key.prv); - - // Ensure node2 can generate votes - node2->block_confirm (send3); - ASSERT_TIMELY (5s, node2->ledger.cache.cemented_count == 3); - - // Test node to restart bootstrap - node_config.peering_port = nano::get_available_port (); - node_flags.disable_legacy_bootstrap = false; - auto node3 = system.add_node (node_config, node_flags); - system.deadline_set (5s); - while (node3->rep_crawler.representative_count () == 0) - { - ASSERT_NO_ERROR (system.poll ()); - } - //Add single excluded peers record (2 records are required to drop peer) - node3->network.excluded_peers.add (nano::transport::map_endpoint_to_tcp (node1->network.endpoint ()), 0); - ASSERT_FALSE (node3->network.excluded_peers.check (nano::transport::map_endpoint_to_tcp (node1->network.endpoint ()))); - node3->bootstrap_initiator.bootstrap (node1->network.endpoint ()); - system.deadline_set (15s); - while (node3->bootstrap_initiator.in_progress ()) - { - ASSERT_NO_ERROR (system.poll ()); - } - ASSERT_FALSE (node3->ledger.block_exists (send1->hash ())); - ASSERT_FALSE (node3->ledger.block_exists (open1->hash ())); - ASSERT_EQ (1, node3->stats.count (nano::stat::type::bootstrap, nano::stat::detail::frontier_confirmation_failed, nano::stat::dir::in)); // failed request from node1 - ASSERT_TRUE (node3->network.excluded_peers.check (nano::transport::map_endpoint_to_tcp (node1->network.endpoint ()))); -} - -TEST (bootstrap_processor, frontiers_confirmed) -{ - nano::system system; - nano::node_config node_config (nano::get_available_port (), system.logging); - node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled; - node_config.tcp_io_timeout = std::chrono::seconds (2); - nano::node_flags node_flags; - node_flags.disable_bootstrap_bulk_pull_server = true; - node_flags.disable_bootstrap_bulk_push_client = true; - node_flags.disable_legacy_bootstrap = true; - node_flags.disable_lazy_bootstrap = true; - node_flags.disable_wallet_bootstrap = true; - node_flags.disable_rep_crawler = true; - auto node1 = system.add_node (node_config, node_flags); - nano::genesis genesis; - nano::keypair key1, key2; - // Generating valid chain - auto send1 (std::make_shared (nano::test_genesis_key.pub, genesis.hash (), nano::test_genesis_key.pub, nano::genesis_amount - nano::Gxrb_ratio, key1.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (genesis.hash ()))); - ASSERT_EQ (nano::process_result::progress, node1->process (*send1).code); - auto send2 (std::make_shared (nano::test_genesis_key.pub, send1->hash (), nano::test_genesis_key.pub, nano::genesis_amount - 2 * nano::Gxrb_ratio, key2.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (send1->hash ()))); - ASSERT_EQ (nano::process_result::progress, node1->process (*send2).code); - auto open1 (std::make_shared (key1.pub, 0, key1.pub, nano::Gxrb_ratio, send1->hash (), key1.prv, key1.pub, *system.work.generate (key1.pub))); - ASSERT_EQ (nano::process_result::progress, node1->process (*open1).code); - auto open2 (std::make_shared (key2.pub, 0, key2.pub, nano::Gxrb_ratio, send2->hash (), key2.prv, key2.pub, *system.work.generate (key2.pub))); - ASSERT_EQ (nano::process_result::progress, node1->process (*open2).code); - system.wallet (0)->insert_adhoc (nano::test_genesis_key.prv); - - // Confirm all blocks so node1 is free to generate votes - node1->block_confirm (send1); - ASSERT_TIMELY (5s, node1->ledger.cache.cemented_count == 5); - - // Test node to bootstrap - node_config.peering_port = nano::get_available_port (); - node_flags.disable_legacy_bootstrap = false; - node_flags.disable_rep_crawler = false; - auto node2 = system.add_node (node_config, node_flags); - system.deadline_set (5s); - while (node2->rep_crawler.representative_count () == 0) - { - ASSERT_NO_ERROR (system.poll ()); - } - node2->bootstrap_initiator.bootstrap (node1->network.endpoint ()); - system.deadline_set (10s); - while (node2->bootstrap_initiator.current_attempt () != nullptr && !node2->bootstrap_initiator.current_attempt ()->frontiers_confirmed) - { - ASSERT_NO_ERROR (system.poll ()); - } - ASSERT_EQ (1, node2->stats.count (nano::stat::type::bootstrap, nano::stat::detail::frontier_confirmation_successful, nano::stat::dir::in)); // Successful request from node1 - ASSERT_EQ (0, node2->stats.count (nano::stat::type::bootstrap, nano::stat::detail::frontier_confirmation_failed, nano::stat::dir::in)); -} - -TEST (bootstrap_processor, frontiers_unconfirmed_threshold) -{ - nano::system system; - nano::node_config node_config (nano::get_available_port (), system.logging); - node_config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled; - node_config.tcp_io_timeout = std::chrono::seconds (2); - node_config.bootstrap_fraction_numerator = 4; - nano::node_flags node_flags; - node_flags.disable_bootstrap_bulk_pull_server = true; - node_flags.disable_bootstrap_bulk_push_client = true; - node_flags.disable_legacy_bootstrap = true; - node_flags.disable_lazy_bootstrap = true; - node_flags.disable_wallet_bootstrap = true; - node_flags.disable_rep_crawler = true; - auto node1 = system.add_node (node_config, node_flags); - nano::genesis genesis; - nano::keypair key1, key2; - // Generating invalid chain - auto threshold (node1->gap_cache.bootstrap_threshold () + 1); - ASSERT_LT (threshold, node1->config.online_weight_minimum.number ()); - auto send1 (std::make_shared (nano::test_genesis_key.pub, genesis.hash (), nano::test_genesis_key.pub, nano::genesis_amount - threshold, key1.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (genesis.hash ()))); - ASSERT_EQ (nano::process_result::progress, node1->process (*send1).code); - auto send2 (std::make_shared (nano::test_genesis_key.pub, send1->hash (), nano::test_genesis_key.pub, nano::genesis_amount - threshold - nano::Gxrb_ratio, key2.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, *system.work.generate (send1->hash ()))); - ASSERT_EQ (nano::process_result::progress, node1->process (*send2).code); - auto open1 (std::make_shared (key1.pub, 0, key1.pub, threshold, send1->hash (), key1.prv, key1.pub, *system.work.generate (key1.pub))); - ASSERT_EQ (nano::process_result::progress, node1->process (*open1).code); - auto open2 (std::make_shared (key2.pub, 0, key2.pub, nano::Gxrb_ratio, send2->hash (), key2.prv, key2.pub, *system.work.generate (key2.pub))); - ASSERT_EQ (nano::process_result::progress, node1->process (*open2).code); - system.wallet (0)->insert_adhoc (key1.prv); // Small representative - - // Test node with large representative - node_config.peering_port = nano::get_available_port (); - auto node2 = system.add_node (node_config, node_flags); - system.wallet (1)->insert_adhoc (nano::test_genesis_key.prv); - - // Test node to bootstrap - node_config.peering_port = nano::get_available_port (); - node_flags.disable_legacy_bootstrap = false; - node_flags.disable_rep_crawler = false; - auto node3 = system.add_node (node_config, node_flags); - ASSERT_EQ (nano::process_result::progress, node3->process (*send1).code); - ASSERT_EQ (nano::process_result::progress, node3->process (*open1).code); // Change known representative weight - system.deadline_set (5s); - while (node3->rep_crawler.representative_count () < 2) - { - ASSERT_NO_ERROR (system.poll ()); - } - node3->bootstrap_initiator.bootstrap (node1->network.endpoint ()); - system.deadline_set (15s); - while (node3->stats.count (nano::stat::type::bootstrap, nano::stat::detail::frontier_confirmation_failed, nano::stat::dir::in) < 1) - { - ASSERT_NO_ERROR (system.poll ()); - } - ASSERT_FALSE (node3->ledger.block_exists (send2->hash ())); - ASSERT_FALSE (node3->ledger.block_exists (open2->hash ())); - ASSERT_EQ (1, node3->stats.count (nano::stat::type::bootstrap, nano::stat::detail::frontier_confirmation_failed, nano::stat::dir::in)); // failed confirmation - ASSERT_EQ (0, node3->stats.count (nano::stat::type::bootstrap, nano::stat::detail::frontier_confirmation_successful, nano::stat::dir::in)); -} - TEST (bootstrap_processor, push_diamond) { nano::system system; @@ -1133,6 +958,154 @@ TEST (frontier_req, time_cutoff) ASSERT_TRUE (request2->frontier.is_zero ()); } +TEST (frontier_req, confirmed_frontier) +{ + nano::system system (1); + auto node1 = system.nodes[0]; + nano::genesis genesis; + nano::keypair key_before_genesis; + // Public key before genesis in accounts table + while (key_before_genesis.pub.number () >= nano::test_genesis_key.pub.number ()) + { + key_before_genesis = nano::keypair (); + } + nano::keypair key_after_genesis; + // Public key after genesis in accounts table + while (key_after_genesis.pub.number () <= nano::test_genesis_key.pub.number ()) + { + key_after_genesis = nano::keypair (); + } + + auto send1 (std::make_shared (nano::test_genesis_key.pub, genesis.hash (), nano::test_genesis_key.pub, nano::genesis_amount - nano::Gxrb_ratio, key_before_genesis.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, 0)); + node1->work_generate_blocking (*send1); + ASSERT_EQ (nano::process_result::progress, node1->process (*send1).code); + auto send2 (std::make_shared (nano::test_genesis_key.pub, send1->hash (), nano::test_genesis_key.pub, nano::genesis_amount - 2 * nano::Gxrb_ratio, key_after_genesis.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, 0)); + node1->work_generate_blocking (*send2); + ASSERT_EQ (nano::process_result::progress, node1->process (*send2).code); + auto receive1 (std::make_shared (key_before_genesis.pub, 0, nano::test_genesis_key.pub, nano::Gxrb_ratio, send1->hash (), key_before_genesis.prv, key_before_genesis.pub, 0)); + node1->work_generate_blocking (*receive1); + ASSERT_EQ (nano::process_result::progress, node1->process (*receive1).code); + auto receive2 (std::make_shared (key_after_genesis.pub, 0, nano::test_genesis_key.pub, nano::Gxrb_ratio, send2->hash (), key_after_genesis.prv, key_after_genesis.pub, 0)); + node1->work_generate_blocking (*receive2); + ASSERT_EQ (nano::process_result::progress, node1->process (*receive2).code); + + // Request for all accounts (confirmed only) + auto connection (std::make_shared (nullptr, node1)); + auto req = std::make_unique (); + req->start.clear (); + req->age = std::numeric_limitsage)>::max (); + req->count = std::numeric_limitscount)>::max (); + ASSERT_FALSE (req->header.frontier_req_is_only_confirmed_present ()); + req->header.flag_set (nano::message_header::frontier_req_only_confirmed); + ASSERT_TRUE (req->header.frontier_req_is_only_confirmed_present ()); + connection->requests.push (std::unique_ptr{}); + auto request (std::make_shared (connection, std::move (req))); + ASSERT_EQ (nano::test_genesis_key.pub, request->current); + ASSERT_EQ (genesis.hash (), request->frontier); + + // Request starting with account before genesis (confirmed only) + auto connection2 (std::make_shared (nullptr, node1)); + auto req2 = std::make_unique (); + req2->start = key_before_genesis.pub; + req2->age = std::numeric_limitsage)>::max (); + req2->count = std::numeric_limitscount)>::max (); + ASSERT_FALSE (req2->header.frontier_req_is_only_confirmed_present ()); + req2->header.flag_set (nano::message_header::frontier_req_only_confirmed); + ASSERT_TRUE (req2->header.frontier_req_is_only_confirmed_present ()); + connection2->requests.push (std::unique_ptr{}); + auto request2 (std::make_shared (connection2, std::move (req2))); + ASSERT_EQ (nano::test_genesis_key.pub, request2->current); + ASSERT_EQ (genesis.hash (), request2->frontier); + + // Request starting with account after genesis (confirmed only) + auto connection3 (std::make_shared (nullptr, node1)); + auto req3 = std::make_unique (); + req3->start = key_after_genesis.pub; + req3->age = std::numeric_limitsage)>::max (); + req3->count = std::numeric_limitscount)>::max (); + ASSERT_FALSE (req3->header.frontier_req_is_only_confirmed_present ()); + req3->header.flag_set (nano::message_header::frontier_req_only_confirmed); + ASSERT_TRUE (req3->header.frontier_req_is_only_confirmed_present ()); + connection3->requests.push (std::unique_ptr{}); + auto request3 (std::make_shared (connection3, std::move (req3))); + ASSERT_TRUE (request3->current.is_zero ()); + ASSERT_TRUE (request3->frontier.is_zero ()); + + // Request for all accounts (unconfirmed blocks) + auto connection4 (std::make_shared (nullptr, node1)); + auto req4 = std::make_unique (); + req4->start.clear (); + req4->age = std::numeric_limitsage)>::max (); + req4->count = std::numeric_limitscount)>::max (); + ASSERT_FALSE (req4->header.frontier_req_is_only_confirmed_present ()); + connection4->requests.push (std::unique_ptr{}); + auto request4 (std::make_shared (connection4, std::move (req4))); + ASSERT_EQ (key_before_genesis.pub, request4->current); + ASSERT_EQ (receive1->hash (), request4->frontier); + + // Request starting with account after genesis (unconfirmed blocks) + auto connection5 (std::make_shared (nullptr, node1)); + auto req5 = std::make_unique (); + req5->start = key_after_genesis.pub; + req5->age = std::numeric_limitsage)>::max (); + req5->count = std::numeric_limitscount)>::max (); + ASSERT_FALSE (req5->header.frontier_req_is_only_confirmed_present ()); + connection5->requests.push (std::unique_ptr{}); + auto request5 (std::make_shared (connection5, std::move (req5))); + ASSERT_EQ (key_after_genesis.pub, request5->current); + ASSERT_EQ (receive2->hash (), request5->frontier); + + // Confirm account before genesis (confirmed only) + nano::blocks_confirm (*node1, { send1, receive1 }); + { + auto election1 = node1->active.election (send1->qualified_root ()); + ASSERT_NE (election1, nullptr); + auto election2 = node1->active.election (receive1->qualified_root ()); + ASSERT_NE (election2, nullptr); + nano::lock_guard guard (node1->active.mutex); + election2->confirm_once (); + election1->confirm_once (); + } + ASSERT_TIMELY (5s, node1->block_confirmed (send1->hash ()) && node1->block_confirmed (receive1->hash ())); + auto connection6 (std::make_shared (nullptr, node1)); + auto req6 = std::make_unique (); + req6->start = key_before_genesis.pub; + req6->age = std::numeric_limitsage)>::max (); + req6->count = std::numeric_limitscount)>::max (); + ASSERT_FALSE (req6->header.frontier_req_is_only_confirmed_present ()); + req6->header.flag_set (nano::message_header::frontier_req_only_confirmed); + ASSERT_TRUE (req6->header.frontier_req_is_only_confirmed_present ()); + connection6->requests.push (std::unique_ptr{}); + auto request6 (std::make_shared (connection6, std::move (req6))); + ASSERT_EQ (key_before_genesis.pub, request6->current); + ASSERT_EQ (receive1->hash (), request6->frontier); + + // Confirm account after genesis (confirmed only) + nano::blocks_confirm (*node1, { send2, receive2 }); + { + auto election3 = node1->active.election (send2->qualified_root ()); + ASSERT_NE (election3, nullptr); + auto election4 = node1->active.election (receive2->qualified_root ()); + ASSERT_NE (election4, nullptr); + nano::lock_guard guard (node1->active.mutex); + election3->confirm_once (); + election4->confirm_once (); + } + ASSERT_TIMELY (5s, node1->block_confirmed (send2->hash ()) && node1->block_confirmed (receive2->hash ())); + auto connection7 (std::make_shared (nullptr, node1)); + auto req7 = std::make_unique (); + req7->start = key_after_genesis.pub; + req7->age = std::numeric_limitsage)>::max (); + req7->count = std::numeric_limitscount)>::max (); + ASSERT_FALSE (req7->header.frontier_req_is_only_confirmed_present ()); + req7->header.flag_set (nano::message_header::frontier_req_only_confirmed); + ASSERT_TRUE (req7->header.frontier_req_is_only_confirmed_present ()); + connection7->requests.push (std::unique_ptr{}); + auto request7 (std::make_shared (connection7, std::move (req7))); + ASSERT_EQ (key_after_genesis.pub, request7->current); + ASSERT_EQ (receive2->hash (), request7->frontier); +} + TEST (bulk, genesis) { nano::system system; diff --git a/nano/core_test/confirmation_height.cpp b/nano/core_test/confirmation_height.cpp index 688168e2af..9ac8aa3306 100644 --- a/nano/core_test/confirmation_height.cpp +++ b/nano/core_test/confirmation_height.cpp @@ -318,7 +318,6 @@ TEST (confirmation_height, gap_live) system.add_node (node_config, node_flags); nano::keypair destination; system.wallet (0)->insert_adhoc (nano::test_genesis_key.prv); - system.wallet (1)->insert_adhoc (destination.prv); nano::genesis genesis; auto send1 (std::make_shared (nano::genesis_account, genesis.hash (), nano::genesis_account, nano::genesis_amount - nano::Gxrb_ratio, destination.pub, nano::test_genesis_key.prv, nano::test_genesis_key.pub, 0)); diff --git a/nano/core_test/confirmation_solicitor.cpp b/nano/core_test/confirmation_solicitor.cpp index d4156c76a8..d669bbe275 100644 --- a/nano/core_test/confirmation_solicitor.cpp +++ b/nano/core_test/confirmation_solicitor.cpp @@ -21,7 +21,7 @@ TEST (confirmation_solicitor, batches) // Solicitor will only solicit from this representative nano::representative representative (nano::test_genesis_key.pub, nano::genesis_amount, channel1); std::vector representatives{ representative }; - nano::confirmation_solicitor solicitor (node2.network, node2.network_params.network); + nano::confirmation_solicitor solicitor (node2.network, node2.config); solicitor.prepare (representatives); // Ensure the representatives are correct ASSERT_EQ (1, representatives.size ()); @@ -37,7 +37,6 @@ TEST (confirmation_solicitor, batches) auto election (std::make_shared (node2, send, nullptr, false, nano::election_behavior::normal)); ASSERT_FALSE (solicitor.add (*election)); } - ASSERT_EQ (1, solicitor.max_confirm_req_batches); // Reached the maximum amount of requests for the channel auto election (std::make_shared (node2, send, nullptr, false, nano::election_behavior::normal)); ASSERT_TRUE (solicitor.add (*election)); @@ -64,7 +63,7 @@ TEST (confirmation_solicitor, different_hash) // Solicitor will only solicit from this representative nano::representative representative (nano::test_genesis_key.pub, nano::genesis_amount, channel1); std::vector representatives{ representative }; - nano::confirmation_solicitor solicitor (node2.network, node2.network_params.network); + nano::confirmation_solicitor solicitor (node2.network, node2.config); solicitor.prepare (representatives); // Ensure the representatives are correct ASSERT_EQ (1, representatives.size ()); @@ -97,7 +96,7 @@ TEST (confirmation_solicitor, bypass_max_requests_cap) node_flags.disable_udp = false; auto & node1 = *system.add_node (node_flags); auto & node2 = *system.add_node (node_flags); - nano::confirmation_solicitor solicitor (node2.network, node2.network_params.network); + nano::confirmation_solicitor solicitor (node2.network, node2.config); std::vector representatives; auto max_representatives = std::max (solicitor.max_election_requests, solicitor.max_election_broadcasts); representatives.reserve (max_representatives + 1); diff --git a/nano/core_test/node.cpp b/nano/core_test/node.cpp index d6ac8f60d4..2cca62a471 100644 --- a/nano/core_test/node.cpp +++ b/nano/core_test/node.cpp @@ -345,6 +345,47 @@ TEST (node, auto_bootstrap_reverse) node1->stop (); } +TEST (node, auto_bootstrap_age) +{ + nano::system system; + nano::node_config config (nano::get_available_port (), system.logging); + config.frontiers_confirmation = nano::frontiers_confirmation_mode::disabled; + nano::node_flags node_flags; + node_flags.disable_bootstrap_bulk_push_client = true; + node_flags.disable_lazy_bootstrap = true; + node_flags.bootstrap_interval = 1; + auto node0 = system.add_node (config, node_flags); + auto node1 (std::make_shared (system.io_ctx, nano::unique_path (), system.alarm, nano::node_config (nano::get_available_port (), system.logging), system.work, node_flags)); + ASSERT_FALSE (node1->init_error ()); + node1->start (); + system.nodes.push_back (node1); + //ASSERT_NE (nullptr, nano::establish_tcp (system, *node1, node0->network.endpoint ())); + std::shared_ptr result; + debug_assert (!node1->flags.disable_tcp_realtime); + std::promise> promise; + auto callback = [&promise](std::shared_ptr channel_a) { promise.set_value (channel_a); }; + auto future = promise.get_future (); + node1->network.tcp_channels.start_tcp (node0->network.endpoint (), callback); + auto error = system.poll_until_true (2s, [&future] { return future.wait_for (0s) == std::future_status::ready; }); + if (!error) + { + auto channel = future.get (); + EXPECT_NE (nullptr, channel); + if (channel) + { + result = node1->network.tcp_channels.find_channel (channel->get_tcp_endpoint ()); + } + } + // ------------------- + ASSERT_TIMELY (10s, node1->bootstrap_initiator.in_progress ()); + // 4 bootstraps with frontiers age + ASSERT_TIMELY (10s, node0->stats.count (nano::stat::type::bootstrap, nano::stat::detail::initiate_legacy_age, nano::stat::dir::out) >= 3); + // More attempts with frontiers age + ASSERT_GE (node0->stats.count (nano::stat::type::bootstrap, nano::stat::detail::initiate_legacy_age, nano::stat::dir::out), node0->stats.count (nano::stat::type::bootstrap, nano::stat::detail::initiate, nano::stat::dir::out)); + + node1->stop (); +} + TEST (node, receive_gap) { nano::system system (1); @@ -3108,8 +3149,8 @@ TEST (node, epoch_conflict_confirm) ASSERT_EQ (nano::process_result::progress, node0->block_processor.process_one (transaction, events, send2).code); ASSERT_EQ (nano::process_result::progress, node0->block_processor.process_one (transaction, events, open).code); } - node0->process_active (change); - node0->process_active (epoch_open); + node0->process_local (change, false); + node0->process_local (epoch_open, false); system.deadline_set (5s); while (!node0->block (change->hash ()) || !node0->block (epoch_open->hash ()) || !node1->block (change->hash ()) || !node1->block (epoch_open->hash ())) { @@ -4347,14 +4388,14 @@ TEST (node, deferred_dependent_elections) .representative (nano::test_genesis_key.pub) .sign (key.prv, key.pub) .build (); - node.process_active (send1); + node.process_local (send1, false); node.block_processor.flush (); auto election_send1 = node.active.election (send1->qualified_root ()); ASSERT_NE (nullptr, election_send1); // Should process and republish but not start an election for any dependent blocks - node.process_active (open); - node.process_active (send2); + node.process_local (open, false); + node.process_local (send2, false); node.block_processor.flush (); ASSERT_TRUE (node.block (open->hash ())); ASSERT_TRUE (node.block (send2->hash ())); @@ -4364,10 +4405,12 @@ TEST (node, deferred_dependent_elections) ASSERT_TIMELY (2s, node2.block (send2->hash ())); // Re-processing older blocks with updated work also does not start an election - node.work_generate_blocking (*open, open->difficulty ()); - node.process_active (open); + node.work_generate_blocking (*open, open->difficulty () + 1); + node.process_local (open, false); node.block_processor.flush (); ASSERT_FALSE (node.active.active (open->qualified_root ())); + /// However, work is still updated + ASSERT_TIMELY (3s, node.store.block_get (node.store.tx_begin_read (), open->hash ())->block_work () == open->block_work ()); // It is however possible to manually start an election from elsewhere node.block_confirm (open); @@ -4376,10 +4419,14 @@ TEST (node, deferred_dependent_elections) // Dropping an election allows restarting it [with higher work] node.active.erase (*open); ASSERT_FALSE (node.active.active (open->qualified_root ())); - ASSERT_NE (std::chrono::steady_clock::time_point{}, node.active.recently_dropped.find (open->qualified_root ())); - node.process_active (open); + /// The election was dropped but it's still not possible to restart it + node.work_generate_blocking (*open, open->difficulty () + 1); + ASSERT_FALSE (node.active.active (open->qualified_root ())); + node.process_local (open, false); node.block_processor.flush (); - ASSERT_TRUE (node.active.active (open->qualified_root ())); + ASSERT_FALSE (node.active.active (open->qualified_root ())); + /// However, work is still updated + ASSERT_TIMELY (3s, node.store.block_get (node.store.tx_begin_read (), open->hash ())->block_work () == open->block_work ()); // Frontier confirmation also starts elections ASSERT_NO_ERROR (system.poll_until_true (5s, [&node, &send2] { @@ -4420,14 +4467,14 @@ TEST (node, deferred_dependent_elections) ASSERT_FALSE (node.active.active (receive->qualified_root ())); ASSERT_FALSE (node.ledger.rollback (node.store.tx_begin_write (), receive->hash ())); ASSERT_FALSE (node.block (receive->hash ())); - node.process_active (receive); + node.process_local (receive, false); node.block_processor.flush (); ASSERT_TRUE (node.block (receive->hash ())); ASSERT_FALSE (node.active.active (receive->qualified_root ())); // Processing a fork will also not start an election ASSERT_EQ (nano::process_result::fork, node.process (*fork).code); - node.process_active (fork); + node.process_local (fork, false); node.block_processor.flush (); ASSERT_FALSE (node.active.active (receive->qualified_root ())); @@ -4440,7 +4487,15 @@ TEST (node, deferred_dependent_elections) ASSERT_TIMELY (2s, node.active.active (receive->qualified_root ())); node.active.erase (*receive); ASSERT_FALSE (node.active.active (receive->qualified_root ())); - node.process_active (fork); + node.process_local (fork, false); + node.block_processor.flush (); + ASSERT_TRUE (node.active.active (receive->qualified_root ())); + + /// If dropped, the election can be restarted once higher work is provided + node.active.erase (*fork); + ASSERT_FALSE (node.active.active (fork->qualified_root ())); + node.work_generate_blocking (*receive, receive->difficulty () + 1); + node.process_active (receive); node.block_processor.flush (); ASSERT_TRUE (node.active.active (receive->qualified_root ())); } diff --git a/nano/core_test/toml.cpp b/nano/core_test/toml.cpp index 76c9658ac9..de038c61e0 100644 --- a/nano/core_test/toml.cpp +++ b/nano/core_test/toml.cpp @@ -187,6 +187,7 @@ TEST (toml, daemon_config_deserialize_defaults) ASSERT_EQ (conf.node.work_peers, defaults.node.work_peers); ASSERT_EQ (conf.node.work_threads, defaults.node.work_threads); ASSERT_EQ (conf.node.max_queued_requests, defaults.node.max_queued_requests); + ASSERT_EQ (conf.node.confirm_req_batches_max, defaults.node.confirm_req_batches_max); ASSERT_EQ (conf.node.logging.bulk_pull_logging_value, defaults.node.logging.bulk_pull_logging_value); ASSERT_EQ (conf.node.logging.flush, defaults.node.logging.flush); @@ -379,7 +380,7 @@ TEST (toml, array) config_node.push ("items", "item 1"); config_node.push ("items", "item 2"); int i = 1; - config_node.array_entries_required ("items", [&i](std::string item) { + config_node.array_entries_required ("items", [&i] (std::string item) { ASSERT_TRUE (item == std::string ("item ") + std::to_string (i)); i++; }); @@ -602,6 +603,7 @@ TEST (toml, daemon_config_deserialize_no_defaults) ASSERT_NE (conf.node.work_peers, defaults.node.work_peers); ASSERT_NE (conf.node.work_threads, defaults.node.work_threads); ASSERT_NE (conf.node.max_queued_requests, defaults.node.max_queued_requests); + ASSERT_EQ (conf.node.confirm_req_batches_max, defaults.node.confirm_req_batches_max); ASSERT_NE (conf.node.logging.bulk_pull_logging_value, defaults.node.logging.bulk_pull_logging_value); ASSERT_NE (conf.node.logging.flush, defaults.node.logging.flush); @@ -841,6 +843,21 @@ TEST (toml, daemon_config_deserialize_errors) ASSERT_EQ (toml.get_error ().get_message (), "election_hint_weight_percent must be a number between 5 and 50"); } + + { + std::stringstream ss; + ss << R"toml( + [node] + confirm_req_batches_max = 0 + )toml"; + + nano::tomlconfig toml; + toml.read (ss); + nano::daemon_config conf; + conf.deserialize_toml (toml); + + ASSERT_EQ (toml.get_error ().get_message (), "confirm_req_batches_max must be between 1 and 100"); + } } TEST (toml, daemon_read_config) diff --git a/nano/core_test/vote_processor.cpp b/nano/core_test/vote_processor.cpp index a6317f7636..8096f4af17 100644 --- a/nano/core_test/vote_processor.cpp +++ b/nano/core_test/vote_processor.cpp @@ -222,7 +222,7 @@ TEST (vote_processor, no_broadcast_local) ASSERT_EQ (vote->sequence, existing->second.sequence); // Ensure the vote, from a local representative, was not broadcast on processing - it should be flooded on generation instead ASSERT_EQ (0, node.stats.count (nano::stat::type::message, nano::stat::detail::confirm_ack, nano::stat::dir::out)); - ASSERT_EQ (1, node.stats.count (nano::stat::type::message, nano::stat::detail::publish, nano::stat::dir::out)); + ASSERT_EQ (2, node.stats.count (nano::stat::type::message, nano::stat::detail::publish, nano::stat::dir::out)); // Repeat test with no representative // Erase account from the wallet @@ -254,7 +254,7 @@ TEST (vote_processor, no_broadcast_local) ASSERT_EQ (vote2->sequence, existing2->second.sequence); // Ensure the vote was broadcast ASSERT_EQ (1, node.stats.count (nano::stat::type::message, nano::stat::detail::confirm_ack, nano::stat::dir::out)); - ASSERT_EQ (2, node.stats.count (nano::stat::type::message, nano::stat::detail::publish, nano::stat::dir::out)); + ASSERT_EQ (4, node.stats.count (nano::stat::type::message, nano::stat::detail::publish, nano::stat::dir::out)); // Repeat test with a PR in the wallet // Increase the genesis weight again @@ -287,5 +287,5 @@ TEST (vote_processor, no_broadcast_local) ASSERT_EQ (vote3->sequence, existing3->second.sequence); // Ensure the vote wass not broadcasst ASSERT_EQ (1, node.stats.count (nano::stat::type::message, nano::stat::detail::confirm_ack, nano::stat::dir::out)); - ASSERT_EQ (3, node.stats.count (nano::stat::type::message, nano::stat::detail::publish, nano::stat::dir::out)); + ASSERT_EQ (6, node.stats.count (nano::stat::type::message, nano::stat::detail::publish, nano::stat::dir::out)); } diff --git a/nano/lib/lmdbconfig.hpp b/nano/lib/lmdbconfig.hpp index 342c03d126..4474a835a0 100644 --- a/nano/lib/lmdbconfig.hpp +++ b/nano/lib/lmdbconfig.hpp @@ -45,6 +45,6 @@ class lmdb_config final /** Sync strategy for the ledger database */ sync_strategy sync{ always }; uint32_t max_databases{ 128 }; - size_t map_size{ 128ULL * 1024 * 1024 * 1024 }; + size_t map_size{ 256ULL * 1024 * 1024 * 1024 }; }; } diff --git a/nano/lib/stats.cpp b/nano/lib/stats.cpp index cb7770d41e..ce746fadfc 100644 --- a/nano/lib/stats.cpp +++ b/nano/lib/stats.cpp @@ -544,6 +544,9 @@ std::string nano::stat::detail_to_string (uint32_t key) case nano::stat::detail::initiate: res = "initiate"; break; + case nano::stat::detail::initiate_legacy_age: + res = "initiate_legacy_age"; + break; case nano::stat::detail::initiate_lazy: res = "initiate_lazy"; break; diff --git a/nano/lib/stats.hpp b/nano/lib/stats.hpp index 54ae0119e2..ae863c30f7 100644 --- a/nano/lib/stats.hpp +++ b/nano/lib/stats.hpp @@ -244,6 +244,7 @@ class stat final // bootstrap, callback initiate, + initiate_legacy_age, initiate_lazy, initiate_wallet_lazy, diff --git a/nano/nano_node/daemon.cpp b/nano/nano_node/daemon.cpp index e3deaaa65c..3821831960 100644 --- a/nano/nano_node/daemon.cpp +++ b/nano/nano_node/daemon.cpp @@ -10,6 +10,8 @@ #include #include +#include + #include #include diff --git a/nano/node/active_transactions.cpp b/nano/node/active_transactions.cpp index 46bb43581e..9aef345b3d 100644 --- a/nano/node/active_transactions.cpp +++ b/nano/node/active_transactions.cpp @@ -19,7 +19,6 @@ size_t constexpr nano::active_transactions::max_active_elections_frontier_insert constexpr std::chrono::minutes nano::active_transactions::expired_optimistic_election_info_cutoff; nano::active_transactions::active_transactions (nano::node & node_a, nano::confirmation_height_processor & confirmation_height_processor_a) : -recently_dropped (node_a.stats), confirmation_height_processor (confirmation_height_processor_a), node (node_a), multipliers_cb (20, 1.), @@ -284,7 +283,7 @@ void nano::active_transactions::request_confirm (nano::unique_lock & debug_assert (!mutex.try_lock ()); // Only representatives ready to receive batched confirm_req - nano::confirmation_solicitor solicitor (node.network, node.network_params.network); + nano::confirmation_solicitor solicitor (node.network, node.config); solicitor.prepare (node.rep_crawler.principal_representatives (std::numeric_limits::max ())); nano::vote_generator_session generator_session (generator); @@ -781,6 +780,10 @@ nano::election_insertion_result nano::active_transactions::insert_impl (std::sha // Non-priority elections generate votes when they gain priority in the future if (result.election && result.election->prioritized ()) { + if (!node.flags.disable_block_processor_republishing) + { + node.network.flood_block (block_a, nano::buffer_drop_policy::no_limiter_drop); + } result.election->generate_votes (); } } @@ -965,33 +968,30 @@ bool nano::active_transactions::update_difficulty_impl (nano::active_transaction bool nano::active_transactions::restart (std::shared_ptr const & block_a, nano::write_transaction const & transaction_a) { - // Only guaranteed to restart the election if the new block is received within 2 minutes of its election being dropped - constexpr std::chrono::minutes recently_dropped_cutoff{ 2 }; bool error = true; - if (recently_dropped.find (block_a->qualified_root ()) > std::chrono::steady_clock::now () - recently_dropped_cutoff) + auto hash (block_a->hash ()); + auto ledger_block (node.store.block_get (transaction_a, hash)); + if (ledger_block != nullptr && ledger_block->block_work () != block_a->block_work () && !node.block_confirmed_or_being_confirmed (transaction_a, hash)) { - auto hash (block_a->hash ()); - auto ledger_block (node.store.block_get (transaction_a, hash)); - if (ledger_block != nullptr && ledger_block->block_work () != block_a->block_work () && !node.block_confirmed_or_being_confirmed (transaction_a, hash)) + if (block_a->difficulty () > ledger_block->difficulty ()) { - if (block_a->difficulty () > ledger_block->difficulty ()) - { - // Re-writing the block is necessary to avoid the same work being received later to force restarting the election - // The existing block is re-written, not the arriving block, as that one might not have gone through a full signature check - ledger_block->block_work_set (block_a->block_work ()); + // Re-writing the block is necessary to avoid the same work being received later to force restarting the election + // The existing block is re-written, not the arriving block, as that one might not have gone through a full signature check + ledger_block->block_work_set (block_a->block_work ()); - auto block_count = node.ledger.cache.block_count.load (); - node.store.block_put (transaction_a, hash, *ledger_block); - debug_assert (node.ledger.cache.block_count.load () == block_count); + auto block_count = node.ledger.cache.block_count.load (); + node.store.block_put (transaction_a, hash, *ledger_block); + debug_assert (node.ledger.cache.block_count.load () == block_count); + // Restart election for the upgraded block, previously dropped from elections + if (node.ledger.dependents_confirmed (transaction_a, *ledger_block)) + { // Restart election for the upgraded block, previously dropped from elections auto previous_balance = node.ledger.balance (transaction_a, ledger_block->previous ()); auto insert_result = insert (ledger_block, previous_balance); if (insert_result.inserted) { error = false; - insert_result.election->transition_active (); - recently_dropped.erase (ledger_block->qualified_root ()); node.stats.inc (nano::stat::type::election, nano::stat::detail::election_restart); } } @@ -1433,47 +1433,3 @@ std::unique_ptr nano::collect_container_info (ac composite->add_component (collect_container_info (active_transactions.generator, "generator")); return composite; } - -nano::dropped_elections::dropped_elections (nano::stat & stats_a) : -stats (stats_a) -{ -} - -void nano::dropped_elections::add (nano::qualified_root const & root_a) -{ - stats.inc (nano::stat::type::election, nano::stat::detail::election_drop); - nano::lock_guard guard (mutex); - auto & items_by_sequence = items.get (); - items_by_sequence.emplace_back (nano::election_timepoint{ std::chrono::steady_clock::now (), root_a }); - if (items.size () > capacity) - { - items_by_sequence.pop_front (); - } -} - -void nano::dropped_elections::erase (nano::qualified_root const & root_a) -{ - nano::lock_guard guard (mutex); - items.get ().erase (root_a); -} - -std::chrono::steady_clock::time_point nano::dropped_elections::find (nano::qualified_root const & root_a) const -{ - nano::lock_guard guard (mutex); - auto & items_by_root = items.get (); - auto existing (items_by_root.find (root_a)); - if (existing != items_by_root.end ()) - { - return existing->time; - } - else - { - return std::chrono::steady_clock::time_point{}; - } -} - -size_t nano::dropped_elections::size () const -{ - nano::lock_guard guard (mutex); - return items.size (); -} diff --git a/nano/node/active_transactions.hpp b/nano/node/active_transactions.hpp index 6a64847e92..8f0bdfb1fb 100644 --- a/nano/node/active_transactions.hpp +++ b/nano/node/active_transactions.hpp @@ -94,33 +94,6 @@ class frontiers_confirmation_info bool aggressive_mode{ false }; }; -class dropped_elections final -{ -public: - dropped_elections (nano::stat &); - void add (nano::qualified_root const &); - void erase (nano::qualified_root const &); - std::chrono::steady_clock::time_point find (nano::qualified_root const &) const; - size_t size () const; - - static size_t constexpr capacity{ 16 * 1024 }; - - // clang-format off - class tag_sequence {}; - class tag_root {}; - using ordered_dropped = boost::multi_index_container>, - mi::hashed_unique, - mi::member>>>; - // clang-format on - -private: - ordered_dropped items; - mutable std::mutex mutex; - nano::stat & stats; -}; - class election_insertion_result final { public: @@ -208,7 +181,6 @@ class active_transactions final std::unordered_map> blocks; std::deque list_recently_cemented (); std::deque recently_cemented; - dropped_elections recently_dropped; void add_recently_cemented (nano::election_status const &); void add_recently_confirmed (nano::qualified_root const &, nano::block_hash const &); diff --git a/nano/node/blockprocessor.cpp b/nano/node/blockprocessor.cpp index 010ab6bcca..4850a37b34 100644 --- a/nano/node/blockprocessor.cpp +++ b/nano/node/blockprocessor.cpp @@ -309,10 +309,6 @@ void nano::block_processor::process_live (nano::block_hash const & hash_a, std:: { node.network.flood_block_initial (block_a); } - else if (!node.flags.disable_block_processor_republishing) - { - node.network.flood_block (block_a, nano::buffer_drop_policy::no_limiter_drop); - } if (node.websocket_server && node.websocket_server->any_subscriber (nano::websocket::topic::new_unconfirmed_block)) { diff --git a/nano/node/bootstrap/bootstrap.cpp b/nano/node/bootstrap/bootstrap.cpp index ca1d9b4926..d2cab0c91d 100644 --- a/nano/node/bootstrap/bootstrap.cpp +++ b/nano/node/bootstrap/bootstrap.cpp @@ -31,7 +31,7 @@ nano::bootstrap_initiator::~bootstrap_initiator () stop (); } -void nano::bootstrap_initiator::bootstrap (bool force, std::string id_a) +void nano::bootstrap_initiator::bootstrap (bool force, std::string id_a, uint32_t const frontiers_age_a) { if (force) { @@ -40,8 +40,8 @@ void nano::bootstrap_initiator::bootstrap (bool force, std::string id_a) nano::unique_lock lock (mutex); if (!stopped && find_attempt (nano::bootstrap_mode::legacy) == nullptr) { - node.stats.inc (nano::stat::type::bootstrap, nano::stat::detail::initiate, nano::stat::dir::out); - auto legacy_attempt (std::make_shared (node.shared (), attempts.incremental++, id_a)); + node.stats.inc (nano::stat::type::bootstrap, frontiers_age_a == std::numeric_limits::max () ? nano::stat::detail::initiate : nano::stat::detail::initiate_legacy_age, nano::stat::dir::out); + auto legacy_attempt (std::make_shared (node.shared (), attempts.incremental++, id_a, frontiers_age_a)); attempts_list.push_back (legacy_attempt); attempts.add (legacy_attempt); lock.unlock (); @@ -67,7 +67,7 @@ void nano::bootstrap_initiator::bootstrap (nano::endpoint const & endpoint_a, bo stop_attempts (); node.stats.inc (nano::stat::type::bootstrap, nano::stat::detail::initiate, nano::stat::dir::out); nano::lock_guard lock (mutex); - auto legacy_attempt (std::make_shared (node.shared (), attempts.incremental++, id_a)); + auto legacy_attempt (std::make_shared (node.shared (), attempts.incremental++, id_a, std::numeric_limits::max ())); attempts_list.push_back (legacy_attempt); attempts.add (legacy_attempt); if (frontiers_confirmed) diff --git a/nano/node/bootstrap/bootstrap.hpp b/nano/node/bootstrap/bootstrap.hpp index 5e139e5018..64cc81203d 100644 --- a/nano/node/bootstrap/bootstrap.hpp +++ b/nano/node/bootstrap/bootstrap.hpp @@ -83,7 +83,7 @@ class bootstrap_initiator final explicit bootstrap_initiator (nano::node &); ~bootstrap_initiator (); void bootstrap (nano::endpoint const &, bool add_to_peers = true, bool frontiers_confirmed = false, std::string id_a = ""); - void bootstrap (bool force = false, std::string id_a = ""); + void bootstrap (bool force = false, std::string id_a = "", uint32_t const frontiers_age_a = std::numeric_limits::max ()); void bootstrap_lazy (nano::hash_or_account const &, bool force = false, bool confirmed = true, std::string id_a = ""); void bootstrap_wallet (std::deque &); void run_bootstrap (); diff --git a/nano/node/bootstrap/bootstrap_attempt.cpp b/nano/node/bootstrap/bootstrap_attempt.cpp index 01a3e2a009..9d9db2e773 100644 --- a/nano/node/bootstrap/bootstrap_attempt.cpp +++ b/nano/node/bootstrap/bootstrap_attempt.cpp @@ -116,11 +116,6 @@ std::string nano::bootstrap_attempt::mode_text () return mode_text; } -void nano::bootstrap_attempt::restart_condition () -{ - debug_assert (mode == nano::bootstrap_mode::legacy); -} - void nano::bootstrap_attempt::add_frontier (nano::pull_info const &) { debug_assert (mode == nano::bootstrap_mode::legacy); @@ -198,8 +193,9 @@ size_t nano::bootstrap_attempt::wallet_size () return 0; } -nano::bootstrap_attempt_legacy::bootstrap_attempt_legacy (std::shared_ptr node_a, uint64_t incremental_id_a, std::string id_a) : -nano::bootstrap_attempt (node_a, nano::bootstrap_mode::legacy, incremental_id_a, id_a) +nano::bootstrap_attempt_legacy::bootstrap_attempt_legacy (std::shared_ptr node_a, uint64_t incremental_id_a, std::string id_a, uint32_t const frontiers_age_a) : +nano::bootstrap_attempt (node_a, nano::bootstrap_mode::legacy, incremental_id_a, id_a), +frontiers_age (frontiers_age_a) { node->bootstrap_initiator.notify_listeners (true); } @@ -314,55 +310,6 @@ void nano::bootstrap_attempt_legacy::add_recent_pull (nano::block_hash const & h } } -void nano::bootstrap_attempt_legacy::restart_condition () -{ - /* Conditions to start frontiers confirmation: - - not completed frontiers confirmation - - more than 256 pull retries usually indicating issues with requested pulls - - or 128k processed blocks indicating large bootstrap */ - if (!frontiers_confirmation_pending && !frontiers_confirmed && (requeued_pulls > (!node->network_params.network.is_test_network () ? nano::bootstrap_limits::requeued_pulls_limit : nano::bootstrap_limits::requeued_pulls_limit_test) || total_blocks > nano::bootstrap_limits::frontier_confirmation_blocks_limit)) - { - frontiers_confirmation_pending = true; - } -} - -void nano::bootstrap_attempt_legacy::attempt_restart_check (nano::unique_lock & lock_a) -{ - if (frontiers_confirmation_pending) - { - auto confirmed (confirm_frontiers (lock_a)); - debug_assert (lock_a.owns_lock ()); - if (!confirmed) - { - node->stats.inc (nano::stat::type::bootstrap, nano::stat::detail::frontier_confirmation_failed, nano::stat::dir::in); - auto score (node->network.excluded_peers.add (endpoint_frontier_request, node->network.size ())); - if (score >= nano::peer_exclusion::score_limit) - { - node->logger.always_log (boost::str (boost::format ("Adding peer %1% to excluded peers list with score %2% after %3% seconds bootstrap attempt") % endpoint_frontier_request % score % std::chrono::duration_cast (std::chrono::steady_clock::now () - attempt_start).count ())); - auto channel = node->network.find_channel (nano::transport::map_tcp_to_endpoint (endpoint_frontier_request)); - if (channel != nullptr) - { - node->network.erase (*channel); - } - } - lock_a.unlock (); - stop (); - lock_a.lock (); - // Start new bootstrap connection - auto node_l (node->shared ()); - node->background ([node_l]() { - node_l->bootstrap_initiator.bootstrap (true); - }); - } - else - { - node->stats.inc (nano::stat::type::bootstrap, nano::stat::detail::frontier_confirmation_successful, nano::stat::dir::in); - } - frontiers_confirmed = confirmed; - frontiers_confirmation_pending = false; - } -} - bool nano::bootstrap_attempt_legacy::confirm_frontiers (nano::unique_lock & lock_a) { bool confirmed (false); @@ -510,7 +457,7 @@ bool nano::bootstrap_attempt_legacy::request_frontier (nano::unique_lock (connection_l, this_l)); - client->run (); + client->run (frontiers_age); frontiers = client; future = client->promise.get_future (); } @@ -589,9 +536,8 @@ void nano::bootstrap_attempt_legacy::run () while (still_pulling ()) { // clang-format off - condition.wait (lock, [&stopped = stopped, &pulling = pulling, &frontiers_confirmation_pending = frontiers_confirmation_pending] { return stopped || pulling == 0 || frontiers_confirmation_pending; }); + condition.wait (lock, [&stopped = stopped, &pulling = pulling] { return stopped || pulling == 0; }); // clang-format on - attempt_restart_check (lock); } // Flushing may resolve forks which can add more pulls node->logger.try_log ("Flushing unchecked blocks"); @@ -623,5 +569,5 @@ void nano::bootstrap_attempt_legacy::get_information (boost::property_tree::ptre tree_a.put ("frontier_pulls", std::to_string (frontier_pulls.size ())); tree_a.put ("frontiers_received", static_cast (frontiers_received)); tree_a.put ("frontiers_confirmed", static_cast (frontiers_confirmed)); - tree_a.put ("frontiers_confirmation_pending", static_cast (frontiers_confirmation_pending)); + tree_a.put ("frontiers_age", std::to_string (frontiers_age)); } diff --git a/nano/node/bootstrap/bootstrap_attempt.hpp b/nano/node/bootstrap/bootstrap_attempt.hpp index 732c9e1e97..58defc090a 100644 --- a/nano/node/bootstrap/bootstrap_attempt.hpp +++ b/nano/node/bootstrap/bootstrap_attempt.hpp @@ -24,7 +24,6 @@ class bootstrap_attempt : public std::enable_shared_from_this void pull_finished (); bool should_log (); std::string mode_text (); - virtual void restart_condition (); virtual void add_frontier (nano::pull_info const &); virtual void add_bulk_push_target (nano::block_hash const &, nano::block_hash const &); virtual bool request_bulk_push_target (std::pair &); @@ -60,7 +59,7 @@ class bootstrap_attempt : public std::enable_shared_from_this class bootstrap_attempt_legacy : public bootstrap_attempt { public: - explicit bootstrap_attempt_legacy (std::shared_ptr node_a, uint64_t incremental_id_a, std::string id_a = ""); + explicit bootstrap_attempt_legacy (std::shared_ptr node_a, uint64_t incremental_id_a, std::string id_a = "", uint32_t const frontiers_age_a = std::numeric_limits::max ()); void run () override; bool consume_future (std::future &); void stop () override; @@ -72,8 +71,6 @@ class bootstrap_attempt_legacy : public bootstrap_attempt bool request_bulk_push_target (std::pair &) override; void add_recent_pull (nano::block_hash const &) override; void run_start (nano::unique_lock &); - void restart_condition () override; - void attempt_restart_check (nano::unique_lock &); bool confirm_frontiers (nano::unique_lock &); void get_information (boost::property_tree::ptree &) override; nano::tcp_endpoint endpoint_frontier_request; @@ -83,6 +80,6 @@ class bootstrap_attempt_legacy : public bootstrap_attempt std::deque recent_pulls_head; std::vector> bulk_push_targets; std::atomic account_count{ 0 }; - std::atomic frontiers_confirmation_pending{ false }; + uint32_t frontiers_age; }; } diff --git a/nano/node/bootstrap/bootstrap_connections.cpp b/nano/node/bootstrap/bootstrap_connections.cpp index 70e8729d05..ac86f075ff 100644 --- a/nano/node/bootstrap/bootstrap_connections.cpp +++ b/nano/node/bootstrap/bootstrap_connections.cpp @@ -395,11 +395,7 @@ void nano::bootstrap_connections::requeue_pull (nano::pull_info const & pull_a, if (attempt_l != nullptr) { ++attempt_l->requeued_pulls; - if (attempt_l->mode == nano::bootstrap_mode::legacy) - { - attempt_l->restart_condition (); - } - else if (attempt_l->mode == nano::bootstrap_mode::lazy) + if (attempt_l->mode == nano::bootstrap_mode::lazy) { pull.count = attempt_l->lazy_batch_size (); } diff --git a/nano/node/bootstrap/bootstrap_frontier.cpp b/nano/node/bootstrap/bootstrap_frontier.cpp index f5335e1936..3282e7ee99 100644 --- a/nano/node/bootstrap/bootstrap_frontier.cpp +++ b/nano/node/bootstrap/bootstrap_frontier.cpp @@ -12,12 +12,13 @@ constexpr unsigned nano::bootstrap_limits::bulk_push_cost_limit; constexpr size_t nano::frontier_req_client::size_frontier; -void nano::frontier_req_client::run () +void nano::frontier_req_client::run (uint32_t const frontiers_age_a) { nano::frontier_req request; request.start.clear (); - request.age = std::numeric_limits::max (); + request.age = frontiers_age_a; request.count = std::numeric_limits::max (); + frontiers_age = frontiers_age_a; auto this_l (shared_from_this ()); connection->channel->send ( request, [this_l](boost::system::error_code const & ec, size_t size_a) { @@ -75,7 +76,7 @@ void nano::frontier_req_client::receive_frontier () void nano::frontier_req_client::unsynced (nano::block_hash const & head, nano::block_hash const & end) { - if (bulk_push_cost < nano::bootstrap_limits::bulk_push_cost_limit) + if (bulk_push_cost < nano::bootstrap_limits::bulk_push_cost_limit && frontiers_age == std::numeric_limits::max ()) { attempt->add_bulk_push_target (head, end); if (end.is_zero ()) @@ -320,16 +321,32 @@ void nano::frontier_req_server::next () if (accounts.empty ()) { auto now (nano::seconds_since_epoch ()); - bool skip_old (request->age != std::numeric_limitsage)>::max ()); + bool disable_age_filter (request->age == std::numeric_limitsage)>::max ()); size_t max_size (128); auto transaction (connection->node->store.tx_begin_read ()); - for (auto i (connection->node->store.latest_begin (transaction, current.number () + 1)), n (connection->node->store.latest_end ()); i != n && accounts.size () != max_size; ++i) + if (!send_confirmed ()) { - nano::account_info const & info (i->second); - if (!skip_old || (now - info.modified) <= request->age) + for (auto i (connection->node->store.latest_begin (transaction, current.number () + 1)), n (connection->node->store.latest_end ()); i != n && accounts.size () != max_size; ++i) + { + nano::account_info const & info (i->second); + if (disable_age_filter || (now - info.modified) <= request->age) + { + nano::account const & account (i->first); + accounts.emplace_back (account, info.head); + } + } + } + else + { + for (auto i (connection->node->store.confirmation_height_begin (transaction, current.number () + 1)), n (connection->node->store.confirmation_height_end ()); i != n && accounts.size () != max_size; ++i) { - nano::account const & account (i->first); - accounts.emplace_back (account, info.head); + nano::confirmation_height_info const & info (i->second); + nano::block_hash const & confirmed_frontier (info.frontier); + if (!confirmed_frontier.is_zero ()) + { + nano::account const & account (i->first); + accounts.emplace_back (account, confirmed_frontier); + } } } /* If loop breaks before max_size, then latest_end () is reached @@ -345,3 +362,8 @@ void nano::frontier_req_server::next () frontier = account_pair.second; accounts.pop_front (); } + +bool nano::frontier_req_server::send_confirmed () +{ + return request->header.frontier_req_is_only_confirmed_present (); +} diff --git a/nano/node/bootstrap/bootstrap_frontier.hpp b/nano/node/bootstrap/bootstrap_frontier.hpp index 90a4419e60..fb17d70499 100644 --- a/nano/node/bootstrap/bootstrap_frontier.hpp +++ b/nano/node/bootstrap/bootstrap_frontier.hpp @@ -14,7 +14,7 @@ class frontier_req_client final : public std::enable_shared_from_this, std::shared_ptr); ~frontier_req_client (); - void run (); + void run (uint32_t const frontiers_age_a); void receive_frontier (); void received_frontier (boost::system::error_code const &, size_t); void unsynced (nano::block_hash const &, nano::block_hash const &); @@ -31,6 +31,7 @@ class frontier_req_client final : public std::enable_shared_from_this> accounts; + uint32_t frontiers_age{ std::numeric_limits::max () }; static size_t constexpr size_frontier = sizeof (nano::account) + sizeof (nano::block_hash); }; class bootstrap_server; @@ -44,6 +45,7 @@ class frontier_req_server final : public std::enable_shared_from_this connection; nano::account current; nano::block_hash frontier; diff --git a/nano/node/common.cpp b/nano/node/common.cpp index dbb660326b..0a3aab3a6f 100644 --- a/nano/node/common.cpp +++ b/nano/node/common.cpp @@ -175,6 +175,19 @@ bool nano::message_header::bulk_pull_is_count_present () const return result; } +bool nano::message_header::frontier_req_is_only_confirmed_present () const +{ + auto result (false); + if (type == nano::message_type::frontier_req) + { + if (extensions.test (frontier_req_only_confirmed)) + { + result = true; + } + } + return result; +} + bool nano::message_header::node_id_handshake_is_query () const { auto result (false); diff --git a/nano/node/common.hpp b/nano/node/common.hpp index 4672b7783a..0df4db768c 100644 --- a/nano/node/common.hpp +++ b/nano/node/common.hpp @@ -209,6 +209,8 @@ class message_header final void flag_set (uint8_t); static uint8_t constexpr bulk_pull_count_present_flag = 0; bool bulk_pull_is_count_present () const; + static uint8_t constexpr frontier_req_only_confirmed = 1; + bool frontier_req_is_only_confirmed_present () const; static uint8_t constexpr node_id_handshake_query_flag = 0; static uint8_t constexpr node_id_handshake_response_flag = 1; bool node_id_handshake_is_query () const; diff --git a/nano/node/confirmation_solicitor.cpp b/nano/node/confirmation_solicitor.cpp index c8c20755f9..221d8fd0d8 100644 --- a/nano/node/confirmation_solicitor.cpp +++ b/nano/node/confirmation_solicitor.cpp @@ -1,14 +1,15 @@ #include #include +#include using namespace std::chrono_literals; -nano::confirmation_solicitor::confirmation_solicitor (nano::network & network_a, nano::network_constants const & params_a) : -max_confirm_req_batches (params_a.is_test_network () ? 1 : 20), -max_block_broadcasts (params_a.is_test_network () ? 4 : 30), +nano::confirmation_solicitor::confirmation_solicitor (nano::network & network_a, nano::node_config const & config_a) : +max_block_broadcasts (config_a.network_params.network.is_test_network () ? 4 : 30), max_election_requests (50), max_election_broadcasts (std::max (network_a.fanout () / 2, 1)), -network (network_a) +network (network_a), +config (config_a) { } @@ -56,7 +57,7 @@ bool nano::confirmation_solicitor::add (nano::election const & election_a) debug_assert (prepared); bool error (true); unsigned count = 0; - auto const max_channel_requests (max_confirm_req_batches * nano::network::confirm_req_hashes_max); + auto const max_channel_requests (config.confirm_req_batches_max * nano::network::confirm_req_hashes_max); auto const & hash (election_a.status.winner->hash ()); for (auto i (representatives_requests.begin ()); i != representatives_requests.end () && count < max_election_requests;) { diff --git a/nano/node/confirmation_solicitor.hpp b/nano/node/confirmation_solicitor.hpp index ef04cca67d..ed699302f2 100644 --- a/nano/node/confirmation_solicitor.hpp +++ b/nano/node/confirmation_solicitor.hpp @@ -9,11 +9,12 @@ namespace nano { class election; class node; +class node_config; /** This class accepts elections that need further votes before they can be confirmed and bundles them in to single confirm_req packets */ class confirmation_solicitor final { public: - confirmation_solicitor (nano::network &, nano::network_constants const &); + confirmation_solicitor (nano::network &, nano::node_config const &); /** Prepare object for batching election confirmation requests*/ void prepare (std::vector const &); /** Broadcast the winner of an election if the broadcast limit has not been reached. Returns false if the broadcast was performed */ @@ -22,8 +23,6 @@ class confirmation_solicitor final bool add (nano::election const &); /** Dispatch bundled requests to each channel*/ void flush (); - /** Maximum amount of confirmation requests (batches) to be sent to each channel */ - size_t const max_confirm_req_batches; /** Global maximum amount of block broadcasts */ size_t const max_block_broadcasts; /** Maximum amount of requests to be sent per election, bypassed if an existing vote is for a different hash*/ @@ -33,6 +32,7 @@ class confirmation_solicitor final private: nano::network & network; + nano::node_config const & config; unsigned rebroadcasted{ 0 }; std::vector representatives_requests; diff --git a/nano/node/election.cpp b/nano/node/election.cpp index b7d148ed29..7d2abe85fd 100644 --- a/nano/node/election.cpp +++ b/nano/node/election.cpp @@ -434,7 +434,7 @@ void nano::election::cleanup () } if (unconfirmed) { - node.active.recently_dropped.add (winner_root); + node.stats.inc (nano::stat::type::election, nano::stat::detail::election_drop); // Clear network filter in another thread node.worker.push_task ([node_l = node.shared (), blocks_l = std::move (blocks)]() { @@ -493,6 +493,10 @@ void nano::election::generate_votes () debug_assert (!node.active.mutex.try_lock ()); if (node.config.enable_voting && node.wallets.reps ().voting > 0) { + if (!node.flags.disable_block_processor_republishing) + { + node.network.flood_block (status.winner, nano::buffer_drop_policy::no_limiter_drop); + } node.active.generator.add (status.winner->hash ()); } } diff --git a/nano/node/node.cpp b/nano/node/node.cpp index d240dd6e07..d4df69835c 100644 --- a/nano/node/node.cpp +++ b/nano/node/node.cpp @@ -821,7 +821,45 @@ void nano::node::ongoing_bootstrap () ++warmed_up; } } - bootstrap_initiator.bootstrap (); + if (network_params.network.is_test_network () && flags.bootstrap_interval != 0) + { + // For test purposes allow faster automatic bootstraps + next_wakeup = std::chrono::seconds (flags.bootstrap_interval); + ++warmed_up; + } + // Differential bootstrap with max age (75% of all legacy attempts) + uint32_t frontiers_age (std::numeric_limits::max ()); + auto bootstrap_weight_reached (ledger.cache.block_count >= ledger.bootstrap_weight_max_blocks); + auto previous_bootstrap_count (stats.count (nano::stat::type::bootstrap, nano::stat::detail::initiate, nano::stat::dir::out) + stats.count (nano::stat::type::bootstrap, nano::stat::detail::initiate_legacy_age, nano::stat::dir::out)); + /* + - Maximum value for 25% of attempts or if block count is below preconfigured value (initial bootstrap not finished) + - Node shutdown time minus 1 hour for start attempts (warm up) + - Default age value otherwise (1 day for live network, 1 hour for beta) + */ + if (bootstrap_weight_reached) + { + if (warmed_up < 3) + { + // Find last online weight sample (last active time for node) + uint64_t last_sample_time (0); + auto transaction (store.tx_begin_read ()); + for (auto i (store.online_weight_begin (transaction)), n (store.online_weight_end ()); i != n; ++i) + { + last_sample_time = i->first; + } + uint64_t time_since_last_sample = std::chrono::duration_cast (std::chrono::system_clock::now ().time_since_epoch ()).count () - last_sample_time / std::pow (10, 9); // Nanoseconds to seconds + if (time_since_last_sample + 60 * 60 < std::numeric_limits::max ()) + { + frontiers_age = std::max (time_since_last_sample + 60 * 60, network_params.bootstrap.default_frontiers_age_seconds); + } + } + else if (previous_bootstrap_count % 4 != 0) + { + frontiers_age = network_params.bootstrap.default_frontiers_age_seconds; + } + } + // Bootstrap and schedule for next attempt + bootstrap_initiator.bootstrap (false, boost::str (boost::format ("auto_bootstrap_%1%") % previous_bootstrap_count), frontiers_age); std::weak_ptr node_w (shared_from_this ()); alarm.add (std::chrono::steady_clock::now () + next_wakeup, [node_w]() { if (auto node_l = node_w.lock ()) diff --git a/nano/node/nodeconfig.cpp b/nano/node/nodeconfig.cpp index 1289e733df..9ca1cc534b 100644 --- a/nano/node/nodeconfig.cpp +++ b/nano/node/nodeconfig.cpp @@ -106,6 +106,7 @@ nano::error nano::node_config::serialize_toml (nano::tomlconfig & toml) const toml.put ("max_work_generate_multiplier", max_work_generate_multiplier, "Maximum allowed difficulty multiplier for work generation.\ntype:double,[1..]"); toml.put ("frontiers_confirmation", serialize_frontiers_confirmation (frontiers_confirmation), "Mode controlling frontier confirmation rate.\ntype:string,{auto,always,disabled}"); toml.put ("max_queued_requests", max_queued_requests, "Limit for number of queued confirmation requests for one channel, after which new requests are dropped until the queue drops below this value.\ntype:uint32"); + toml.put ("confirm_req_batches_max", confirm_req_batches_max, "Limit for the number of confirmation requests for one channel per request attempt\ntype:uint32"); auto work_peers_l (toml.create_array ("work_peers", "A list of \"address:port\" entries to identify work peers.")); for (auto i (work_peers.begin ()), n (work_peers.end ()); i != n; ++i) @@ -367,6 +368,7 @@ nano::error nano::node_config::deserialize_toml (nano::tomlconfig & toml) toml.get ("max_work_generate_multiplier", max_work_generate_multiplier); toml.get ("max_queued_requests", max_queued_requests); + toml.get ("confirm_req_batches_max", confirm_req_batches_max); if (toml.has_key ("frontiers_confirmation")) { @@ -432,6 +434,10 @@ nano::error nano::node_config::deserialize_toml (nano::tomlconfig & toml) { toml.get_error ().set ((boost::format ("block_processor_batch_max_time value must be equal or larger than %1%ms") % network_params.node.process_confirmed_interval.count ()).str ()); } + if (confirm_req_batches_max < 1 || confirm_req_batches_max > 100) + { + toml.get_error ().set ("confirm_req_batches_max must be between 1 and 100"); + } } catch (std::runtime_error const & ex) { diff --git a/nano/node/nodeconfig.hpp b/nano/node/nodeconfig.hpp index 1c2cd7ea2d..7e891d5a46 100644 --- a/nano/node/nodeconfig.hpp +++ b/nano/node/nodeconfig.hpp @@ -100,6 +100,7 @@ class node_config std::chrono::seconds work_watcher_period{ std::chrono::seconds (5) }; double max_work_generate_multiplier{ 64. }; uint32_t max_queued_requests{ 512 }; + uint32_t confirm_req_batches_max{ network_params.network.is_test_network () ? 1u : 2u }; nano::rocksdb_config rocksdb_config; nano::lmdb_config lmdb_config; nano::frontiers_confirmation_mode frontiers_confirmation{ nano::frontiers_confirmation_mode::automatic }; @@ -149,5 +150,6 @@ class node_flags final size_t block_processor_verification_size{ 0 }; size_t inactive_votes_cache_size{ 16 * 1024 }; size_t vote_processor_capacity{ 144 * 1024 }; + size_t bootstrap_interval{ 0 }; // For testing only }; } diff --git a/nano/node/repcrawler.cpp b/nano/node/repcrawler.cpp index f4a5bed75e..6bc44524ae 100644 --- a/nano/node/repcrawler.cpp +++ b/nano/node/repcrawler.cpp @@ -160,7 +160,8 @@ void nano::rep_crawler::query (std::vectorrep_crawler.remove (hash); + auto target_finished_processed (node_l->vote_processor.total_processed + node_l->vote_processor.size ()); + node_l->rep_crawler.throttled_remove (hash, target_finished_processed); } }); } @@ -172,6 +173,24 @@ void nano::rep_crawler::query (std::shared_ptr const & query (peers); } +void nano::rep_crawler::throttled_remove (nano::block_hash const & hash_a, uint64_t const target_finished_processed) +{ + if (node.vote_processor.total_processed >= target_finished_processed) + { + remove (hash_a); + } + else + { + std::weak_ptr node_w (node.shared ()); + node.alarm.add (std::chrono::steady_clock::now () + std::chrono::seconds (5), [node_w, hash_a, target_finished_processed]() { + if (auto node_l = node_w.lock ()) + { + node_l->rep_crawler.throttled_remove (hash_a, target_finished_processed); + } + }); + } +} + bool nano::rep_crawler::is_pr (nano::transport::channel const & channel_a) const { nano::lock_guard lock (probable_reps_mutex); diff --git a/nano/node/repcrawler.hpp b/nano/node/repcrawler.hpp index a18d2e4743..ebf42e2d15 100644 --- a/nano/node/repcrawler.hpp +++ b/nano/node/repcrawler.hpp @@ -83,6 +83,9 @@ class rep_crawler final /** Remove block hash from list of active rep queries */ void remove (nano::block_hash const &); + /** Remove block hash from with delay depending on vote processor size */ + void throttled_remove (nano::block_hash const &, uint64_t const); + /** Attempt to determine if the peer manages one or more representative accounts */ void query (std::vector> const & channels_a); diff --git a/nano/node/vote_processor.cpp b/nano/node/vote_processor.cpp index c76cd8f6f6..80be66c5e7 100644 --- a/nano/node/vote_processor.cpp +++ b/nano/node/vote_processor.cpp @@ -75,6 +75,7 @@ void nano::vote_processor::process_loop () lock.unlock (); condition.notify_all (); + total_processed += votes_l.size (); lock.lock (); if (log_this_iteration && elapsed.stop () > std::chrono::milliseconds (100)) diff --git a/nano/node/vote_processor.hpp b/nano/node/vote_processor.hpp index 48735553a1..23d3d4d7e4 100644 --- a/nano/node/vote_processor.hpp +++ b/nano/node/vote_processor.hpp @@ -46,6 +46,7 @@ class vote_processor final bool half_full (); void calculate_weights (); void stop (); + std::atomic total_processed{ 0 }; private: void process_loop (); diff --git a/nano/secure/common.cpp b/nano/secure/common.cpp index eea6f0a2af..26f90a0483 100644 --- a/nano/secure/common.cpp +++ b/nano/secure/common.cpp @@ -164,6 +164,7 @@ nano::bootstrap_constants::bootstrap_constants (nano::network_constants & networ lazy_retry_limit = network_constants.is_test_network () ? 2 : frontier_retry_limit * 10; lazy_destinations_retry_limit = network_constants.is_test_network () ? 1 : frontier_retry_limit / 4; gap_cache_bootstrap_start_interval = network_constants.is_test_network () ? std::chrono::milliseconds (5) : std::chrono::milliseconds (30 * 1000); + default_frontiers_age_seconds = network_constants.is_test_network () ? 1 : network_constants.is_beta_network () ? 60 * 60 : 24 * 60 * 60; // 1 second for dev network, 1 hour for beta, 24 hours for live } /* Convenience constants for core_test which is always on the test network */ diff --git a/nano/secure/common.hpp b/nano/secure/common.hpp index 3ceab93a5f..567128fd54 100644 --- a/nano/secure/common.hpp +++ b/nano/secure/common.hpp @@ -456,6 +456,7 @@ class bootstrap_constants unsigned lazy_retry_limit; unsigned lazy_destinations_retry_limit; std::chrono::milliseconds gap_cache_bootstrap_start_interval; + uint32_t default_frontiers_age_seconds; }; /** Constants whose value depends on the active network */