diff --git a/.github/workflows/prcy-build-factory-debug.yml b/.github/workflows/prcy-build-factory-debug.yml index ad6add0f4c..90aafaa68e 100644 --- a/.github/workflows/prcy-build-factory-debug.yml +++ b/.github/workflows/prcy-build-factory-debug.yml @@ -3,14 +3,14 @@ # Copyright (c) 2020 The PRivaCY Coin Developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. -name: Github Actions CI for PRCY - DEBUG_LOCKORDER +name: Github Actions CI for PRCY (Ubuntu 20 --enable-debug) on: [push, pull_request] env: SOURCE_ARTIFACT: source jobs: create-source-distribution: name: Create Source Distribution - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 if: "contains(github.event.head_commit.message, '[debug]')" env: ARTIFACT_DIR: source @@ -23,22 +23,17 @@ jobs: export TAG=v${VERSION} echo "VERSION=${VERSION}" >> $GITHUB_ENV echo "TAG=${TAG}" >> $GITHUB_ENV + - name: Append Commit Hash to Development Builds + if: "!contains(github.ref, 'master')" + shell: bash + run: | + export VERSION=${{ env.VERSION }}-${GITHUB_SHA::7} + echo "VERSION=${VERSION}" >> $GITHUB_ENV - name: Print Variables run: | echo "VERSION=${VERSION}" echo "TAG=${TAG}" printenv - # May need qt and protobuf to configure qt and include prcycoin-qt.1 in distribution - - name: Install Required Packages - run: | - sudo apt-get update - sudo apt-get install -y build-essential libtool bsdmainutils autotools-dev autoconf pkg-config automake python3 - sudo apt-get install -y libssl1.0-dev libzmq5 libgmp-dev libevent-dev libboost-all-dev libsodium-dev cargo - sudo apt-get install -y libqt5gui5 libqt5core5a libqt5dbus5 qttools5-dev qttools5-dev-tools libprotobuf-dev protobuf-compiler libqrencode-dev - sudo apt-get install -y software-properties-common g++-multilib binutils-gold patch - sudo add-apt-repository ppa:pivx/pivx - sudo apt-get update - sudo apt-get install -y libdb4.8-dev libdb4.8++-dev - name: Create Distribution Tarball run: | mkdir -p $ARTIFACT_DIR @@ -59,13 +54,13 @@ jobs: build-x86_64-linux: name: Build for x86 Linux 64bit needs: create-source-distribution - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 env: ARTIFACT_DIR: prcycoin-x86_64-linux-debug TEST_LOG_ARTIFACT_DIR: test-logs steps: - name: Getting Source - uses: actions/download-artifact@v1 + uses: actions/download-artifact@v4.1.7 with: name: ${{ env.SOURCE_ARTIFACT }} - name: Extract Archives @@ -78,6 +73,12 @@ jobs: run: | export VERSION=$(cat $SOURCE_ARTIFACT/version.txt | sed 's/[^0-9,.]//g') echo "VERSION=${VERSION}" >> $GITHUB_ENV + - name: Append Commit Hash to Development Builds + if: "!contains(github.ref, 'master')" + shell: bash + run: | + export VERSION=${{ env.VERSION }}-${GITHUB_SHA::7} + echo "VERSION=${VERSION}" >> $GITHUB_ENV - name: Install Required Packages run: | sudo apt-get update @@ -88,7 +89,7 @@ jobs: - name: Build PRCY run: | ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/x86_64-pc-linux-gnu) --enable-upnp-default CXXFLAGS="-DDEBUG_LOCKORDER -g" + CONFIG_SITE=$(realpath depends/x86_64-pc-linux-gnu/share/config.site) ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-upnp-default --enable-glibc-back-compat --enable-reduce-exports --enable-debug make -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Prepare Files for Artifact @@ -105,12 +106,12 @@ jobs: build-win64: name: Build for Win64 needs: create-source-distribution - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 env: ARTIFACT_DIR: prcycoin-win64-debug steps: - name: Getting Source - uses: actions/download-artifact@v1 + uses: actions/download-artifact@v4.1.7 with: name: ${{ env.SOURCE_ARTIFACT }} - name: Extract Archives @@ -123,6 +124,12 @@ jobs: run: | export VERSION=$(cat $SOURCE_ARTIFACT/version.txt | sed 's/[^0-9,.]//g') echo "VERSION=${VERSION}" >> $GITHUB_ENV + - name: Append Commit Hash to Development Builds + if: "!contains(github.ref, 'master')" + shell: bash + run: | + export VERSION=${{ env.VERSION }}-${GITHUB_SHA::7} + echo "VERSION=${VERSION}" >> $GITHUB_ENV - name: Install Required Packages run: | sudo apt-get update @@ -137,7 +144,7 @@ jobs: - name: Build PRCY run: | ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/x86_64-w64-mingw32) --enable-upnp-default CXXFLAGS="-DDEBUG_LOCKORDER -g" + CONFIG_SITE=$(realpath depends/x86_64-w64-mingw32/share/config.site) ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-upnp-default --enable-reduce-exports --enable-debug make -j$(nproc) make deploy -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} @@ -154,13 +161,13 @@ jobs: build-osx64: name: Build for MacOSX needs: create-source-distribution - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 env: ARTIFACT_DIR: prcycoin-macosx-debug SDK_URL: https://bitcoincore.org/depends-sources/sdks steps: - name: Getting Source - uses: actions/download-artifact@v1 + uses: actions/download-artifact@v4.1.7 with: name: ${{ env.SOURCE_ARTIFACT }} - name: Extract Archives @@ -172,8 +179,8 @@ jobs: shell: bash run: | export VERSION=$(cat $SOURCE_ARTIFACT/version.txt | sed 's/[^0-9,.]//g') - export XCODE_VERSION=10.2.1 - export XCODE_BUILD_ID=10E1001 + export XCODE_VERSION=12.1 + export XCODE_BUILD_ID=12A7403 echo "VERSION=${VERSION}" >> $GITHUB_ENV echo "XCODE_VERSION=${XCODE_VERSION}" >> $GITHUB_ENV echo "XCODE_BUILD_ID=${XCODE_BUILD_ID}" >> $GITHUB_ENV @@ -181,10 +188,16 @@ jobs: export OSX_SDK_PATH=depends/sdk-sources/$OSX_SDK_BASENAME echo "OSX_SDK_BASENAME=${OSX_SDK_BASENAME}" >> $GITHUB_ENV echo "OSX_SDK_PATH=${OSX_SDK_PATH}" >> $GITHUB_ENV + - name: Append Commit Hash to Development Builds + if: "!contains(github.ref, 'master')" + shell: bash + run: | + export VERSION=${{ env.VERSION }}-${GITHUB_SHA::7} + echo "VERSION=${VERSION}" >> $GITHUB_ENV - name: Install Required Packages run: | sudo apt-get update - sudo apt-get install -y python3-setuptools libcap-dev zlib1g-dev cmake librsvg2-bin libtiff-tools imagemagick libz-dev libbz2-dev libtinfo5 + sudo apt-get install -y python3-setuptools libcap-dev libtinfo5 - name: Get macOS SDK run: | mkdir -p depends/sdk-sources depends/SDKs @@ -196,12 +209,12 @@ jobs: fi working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Build Dependencies - run: make -C depends HOST=x86_64-apple-darwin16 -j$(nproc) + run: make -C depends HOST=x86_64-apple-darwin18 -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Build PRCY run: | ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/x86_64-apple-darwin16) --enable-upnp-default CXXFLAGS="-DDEBUG_LOCKORDER -g" + CONFIG_SITE=$(realpath depends/x86_64-apple-darwin18/share/config.site) ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-upnp-default --enable-reduce-exports --enable-debug make -j$(nproc) make deploy -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} @@ -217,12 +230,12 @@ jobs: build-aarch64-linux: name: Build for ARM Linux 64bit needs: create-source-distribution - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 env: ARTIFACT_DIR: prcycoin-aarch64-linux-debug steps: - name: Getting Source - uses: actions/download-artifact@v1 + uses: actions/download-artifact@v4.1.7 with: name: ${{ env.SOURCE_ARTIFACT }} - name: Extract Archives @@ -235,17 +248,23 @@ jobs: run: | export VERSION=$(cat $SOURCE_ARTIFACT/version.txt | sed 's/[^0-9,.]//g') echo "VERSION=${VERSION}" >> $GITHUB_ENV + - name: Append Commit Hash to Development Builds + if: "!contains(github.ref, 'master')" + shell: bash + run: | + export VERSION=${{ env.VERSION }}-${GITHUB_SHA::7} + echo "VERSION=${VERSION}" >> $GITHUB_ENV - name: Install Required Packages run: | sudo apt-get update - sudo apt-get install -y python3-zmq libcap-dev cmake g++-aarch64-linux-gnu + sudo apt-get install -y python3-zmq g++-aarch64-linux-gnu - name: Build Dependencies run: make -C depends HOST=aarch64-linux-gnu -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Build PRCY run: | ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/aarch64-linux-gnu) --enable-upnp-default CXXFLAGS="-DDEBUG_LOCKORDER -g" + CONFIG_SITE=$(realpath depends/aarch64-linux-gnu/share/config.site) ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-upnp-default --enable-glibc-back-compat --enable-reduce-exports --enable-debug make -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Prepare Files for Artifact @@ -261,12 +280,12 @@ jobs: build-arm-linux-gnueabihf: name: Build for ARM Linux 32bit needs: create-source-distribution - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 env: ARTIFACT_DIR: prcycoin-arm32-debug steps: - name: Getting Source - uses: actions/download-artifact@v1 + uses: actions/download-artifact@v4.1.7 with: name: ${{ env.SOURCE_ARTIFACT }} - name: Extract Archives @@ -279,17 +298,23 @@ jobs: run: | export VERSION=$(cat $SOURCE_ARTIFACT/version.txt | sed 's/[^0-9,.]//g') echo "VERSION=${VERSION}" >> $GITHUB_ENV + - name: Append Commit Hash to Development Builds + if: "!contains(github.ref, 'master')" + shell: bash + run: | + export VERSION=${{ env.VERSION }}-${GITHUB_SHA::7} + echo "VERSION=${VERSION}" >> $GITHUB_ENV - name: Install Required Packages run: | sudo apt-get update - sudo apt-get install -y g++-arm-linux-gnueabihf libzmq5 libgmp-dev + sudo apt-get install -y g++-arm-linux-gnueabihf - name: Build Dependencies run: make -C depends -j$(nproc) HOST=arm-linux-gnueabihf working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Build PRCY run: | ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/arm-linux-gnueabihf) --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++ --enable-upnp-default CXXFLAGS="-DDEBUG_LOCKORDER -g" + CONFIG_SITE=$(realpath depends/arm-linux-gnueabihf/share/config.site) ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-glibc-back-compat --enable-reduce-exports --enable-upnp-default CXXFLAGS=-Wno-psabi --enable-debug make -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Prepare Files for Artifact @@ -305,12 +330,12 @@ jobs: build-riscv64-linux-gnu: name: Build for RISC-V 64-bit needs: create-source-distribution - runs-on: ubuntu-18.04 + runs-on: ubuntu-20.04 env: ARTIFACT_DIR: prcycoin-riscv64-debug steps: - name: Getting Source - uses: actions/download-artifact@v1 + uses: actions/download-artifact@v4.1.7 with: name: ${{ env.SOURCE_ARTIFACT }} - name: Extract Archives @@ -323,26 +348,32 @@ jobs: run: | export VERSION=$(cat $SOURCE_ARTIFACT/version.txt | sed 's/[^0-9,.]//g') echo "VERSION=${VERSION}" >> $GITHUB_ENV + - name: Append Commit Hash to Development Builds + if: "!contains(github.ref, 'master')" + shell: bash + run: | + export VERSION=${{ env.VERSION }}-${GITHUB_SHA::7} + echo "VERSION=${VERSION}" >> $GITHUB_ENV - name: Install Required Packages run: | sudo apt-get update sudo apt-get install -y g++-riscv64-linux-gnu binutils-riscv64-linux-gnu - name: Build Dependencies - run: make -C depends -j$(nproc) HOST=riscv64-linux-gnu NO_QT=1 + run: make -C depends -j$(nproc) HOST=riscv64-linux-gnu working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Build PRCY run: | ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/riscv64-linux-gnu) --enable-reduce-exports LDFLAGS=-static-libstdc++ --enable-upnp-default CXXFLAGS="-DDEBUG_LOCKORDER -g" + CONFIG_SITE=$(realpath depends/riscv64-linux-gnu/share/config.site) ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-reduce-exports --enable-upnp-default --enable-debug make -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Prepare Files for Artifact run: | mkdir -p $ARTIFACT_DIR - chmod +x $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind} - mv $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind} $ARTIFACT_DIR + chmod +x $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} + mv $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} $ARTIFACT_DIR - name: Upload Artifact uses: actions/upload-artifact@v1 with: name: prcycoin-v${{ env.VERSION }}-riscv64-debug - path: ${{ env.ARTIFACT_DIR }} \ No newline at end of file + path: ${{ env.ARTIFACT_DIR }} diff --git a/.github/workflows/prcy-build-factory-ubuntu20.yml b/.github/workflows/prcy-build-factory-ubuntu20.yml deleted file mode 100644 index 9e173eaa8c..0000000000 --- a/.github/workflows/prcy-build-factory-ubuntu20.yml +++ /dev/null @@ -1,432 +0,0 @@ -# Copyright (c) 2018-2020 The Veil developers -# Copyright (c) 2020 The DAPS Project -# Copyright (c) 2020 The PRivaCY Coin Developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. -name: Github Actions CI for PRCY (Ubuntu 20) -on: [push, pull_request] -env: - SOURCE_ARTIFACT: source -jobs: - create-source-distribution: - name: Create Source Distribution - runs-on: ubuntu-20.04 - if: "contains(github.event.head_commit.message, '[focal]')" - env: - ARTIFACT_DIR: source - steps: - - name: Checkout - uses: actions/checkout@v3 - - name: Create Version Variable - run: | - export VERSION=$(cat version.txt | sed 's/[^0-9,.]//g') - export TAG=v${VERSION} - echo "VERSION=${VERSION}" >> $GITHUB_ENV - echo "TAG=${TAG}" >> $GITHUB_ENV - - name: Append Commit Hash to Development Builds - if: "!contains(github.ref, 'master')" - shell: bash - run: | - export VERSION=${{ env.VERSION }}-${GITHUB_SHA::7} - echo "VERSION=${VERSION}" >> $GITHUB_ENV - - name: Print Variables - run: | - echo "VERSION=${VERSION}" - echo "TAG=${TAG}" - printenv - - name: Create Distribution Tarball - run: | - mkdir -p $ARTIFACT_DIR - touch prcycoin.tar.gz - tar -czf prcycoin.tar.gz --exclude=prcycoin.tar.gz . - - name: Download Dependencies - run: make -C depends download - - name: Create Dependencies Tarball - run: tar -czf depends.tar.gz depends - - name: Prepare Files for Artifact - run: | - mv depends.tar.gz prcycoin.tar.gz $ARTIFACT_DIR - - name: Upload Artifact - uses: actions/upload-artifact@v1 - with: - name: ${{ env.SOURCE_ARTIFACT }} - path: ${{ env.ARTIFACT_DIR }} - build-linux: - name: Build for Linux - needs: create-source-distribution - runs-on: ubuntu-18.04 - env: - ARTIFACT_DIR: prcycoin-linux - TEST_LOG_ARTIFACT_DIR: test-logs - steps: - - name: Getting Source - uses: actions/download-artifact@v1 - with: - name: ${{ env.SOURCE_ARTIFACT }} - - name: Extract Archives - run: | - tar -xzf prcycoin.tar.gz --strip-components=1 - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Set Env - shell: bash - run: | - export VERSION=$(cat $SOURCE_ARTIFACT/version.txt | sed 's/[^0-9,.]//g') - echo "VERSION=${VERSION}" >> $GITHUB_ENV - - name: Append Commit Hash to Development Builds - if: "!contains(github.ref, 'master')" - shell: bash - run: | - export VERSION=${{ env.VERSION }}-${GITHUB_SHA::7} - echo "VERSION=${VERSION}" >> $GITHUB_ENV - # May need qt and protobuf to configure qt and include prcycoin-qt.1 in distribution - - name: Install Required Packages - run: | - sudo apt-get update - sudo apt-get install -y libssl1.0-dev libevent-dev libboost-all-dev - sudo apt-get install -y libqt5gui5 libqt5core5a libqt5dbus5 qttools5-dev qttools5-dev-tools libprotobuf-dev protobuf-compiler libqrencode-dev - sudo add-apt-repository ppa:pivx/pivx - sudo apt-get update - sudo apt-get install -y libdb4.8-dev libdb4.8++-dev - - name: Build PRCY - run: | - ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --enable-upnp-default - make -j$(nproc) - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Prepare Files for Artifact - run: | - mkdir -p $ARTIFACT_DIR - strip $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} - chmod +x $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} - mv $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} $ARTIFACT_DIR - - name: Upload Artifact - uses: actions/upload-artifact@v1 - with: - name: prcycoin-v${{ env.VERSION }}-linux - path: ${{ env.ARTIFACT_DIR }} - build-x86_64-linux: - name: Build for x86 Linux 64bit - needs: create-source-distribution - runs-on: ubuntu-20.04 - env: - ARTIFACT_DIR: prcycoin-x86_64-linux - TEST_LOG_ARTIFACT_DIR: test-logs - steps: - - name: Getting Source - uses: actions/download-artifact@v1 - with: - name: ${{ env.SOURCE_ARTIFACT }} - - name: Extract Archives - run: | - tar -xzf depends.tar.gz - tar -xzf prcycoin.tar.gz --strip-components=1 - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Set Env - shell: bash - run: | - export VERSION=$(cat $SOURCE_ARTIFACT/version.txt | sed 's/[^0-9,.]//g') - echo "VERSION=${VERSION}" >> $GITHUB_ENV - - name: Append Commit Hash to Development Builds - if: "!contains(github.ref, 'master')" - shell: bash - run: | - export VERSION=${{ env.VERSION }}-${GITHUB_SHA::7} - echo "VERSION=${VERSION}" >> $GITHUB_ENV - - name: Install Required Packages - run: | - sudo apt-get update - sudo apt-get install -y python3-zmq - - name: Build Dependencies - run: make -C depends -j$(nproc) - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Build PRCY - run: | - ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/x86_64-pc-linux-gnu) --enable-upnp-default - make -j$(nproc) - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Prepare Files for Artifact - run: | - mkdir -p $ARTIFACT_DIR - strip $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} - chmod +x $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} - mv $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} $ARTIFACT_DIR - - name: Upload Artifact - uses: actions/upload-artifact@v1 - with: - name: prcycoin-v${{ env.VERSION }}-x86_64-linux - path: ${{ env.ARTIFACT_DIR }} - build-win64: - name: Build for Win64 - needs: create-source-distribution - runs-on: ubuntu-20.04 - env: - ARTIFACT_DIR: prcycoin-win64 - steps: - - name: Getting Source - uses: actions/download-artifact@v1 - with: - name: ${{ env.SOURCE_ARTIFACT }} - - name: Extract Archives - run: | - tar -xzf depends.tar.gz - tar -xzf prcycoin.tar.gz --strip-components=1 - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Set Env - shell: bash - run: | - export VERSION=$(cat $SOURCE_ARTIFACT/version.txt | sed 's/[^0-9,.]//g') - echo "VERSION=${VERSION}" >> $GITHUB_ENV - - name: Append Commit Hash to Development Builds - if: "!contains(github.ref, 'master')" - shell: bash - run: | - export VERSION=${{ env.VERSION }}-${GITHUB_SHA::7} - echo "VERSION=${VERSION}" >> $GITHUB_ENV - - name: Install Required Packages - run: | - sudo apt-get update - sudo apt-get install -y g++-mingw-w64-x86-64 gcc-mingw-w64-x86-64 nsis - - name: Switch MinGW GCC and G++ to POSIX Threading - run: | - sudo update-alternatives --set x86_64-w64-mingw32-gcc /usr/bin/x86_64-w64-mingw32-gcc-posix - sudo update-alternatives --set x86_64-w64-mingw32-g++ /usr/bin/x86_64-w64-mingw32-g++-posix - - name: Build Dependencies - run: make -C depends -j$(nproc) HOST=x86_64-w64-mingw32 - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Build PRCY - run: | - ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/x86_64-w64-mingw32) --enable-upnp-default - make -j$(nproc) - make deploy -j$(nproc) - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Prepare Files for Artifact - run: | - mkdir -p $ARTIFACT_DIR - strip $SOURCE_ARTIFACT/src/{prcycoin-cli.exe,prcycoin-tx.exe,prcycoind.exe,qt/prcycoin-qt.exe} - mv $SOURCE_ARTIFACT/{prcycoin-*.exe,src/prcycoin-cli.exe,src/prcycoin-tx.exe,src/prcycoind.exe,src/qt/prcycoin-qt.exe} $ARTIFACT_DIR - - name: Upload Artifact - uses: actions/upload-artifact@v1 - with: - name: prcycoin-v${{ env.VERSION }}-win64 - path: ${{ env.ARTIFACT_DIR }} - build-osx64: - name: Build for MacOSX - needs: create-source-distribution - runs-on: ubuntu-20.04 - env: - ARTIFACT_DIR: prcycoin-macosx - SDK_URL: https://bitcoincore.org/depends-sources/sdks - steps: - - name: Getting Source - uses: actions/download-artifact@v1 - with: - name: ${{ env.SOURCE_ARTIFACT }} - - name: Extract Archives - run: | - tar -xzf depends.tar.gz - tar -xzf prcycoin.tar.gz --strip-components=1 - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Set Env - shell: bash - run: | - export VERSION=$(cat $SOURCE_ARTIFACT/version.txt | sed 's/[^0-9,.]//g') - export XCODE_VERSION=11.3.1 - export XCODE_BUILD_ID=11C505 - echo "VERSION=${VERSION}" >> $GITHUB_ENV - echo "XCODE_VERSION=${XCODE_VERSION}" >> $GITHUB_ENV - echo "XCODE_BUILD_ID=${XCODE_BUILD_ID}" >> $GITHUB_ENV - export OSX_SDK_BASENAME=Xcode-$XCODE_VERSION-$XCODE_BUILD_ID-extracted-SDK-with-libcxx-headers.tar.gz - export OSX_SDK_PATH=depends/sdk-sources/$OSX_SDK_BASENAME - echo "OSX_SDK_BASENAME=${OSX_SDK_BASENAME}" >> $GITHUB_ENV - echo "OSX_SDK_PATH=${OSX_SDK_PATH}" >> $GITHUB_ENV - - name: Append Commit Hash to Development Builds - if: "!contains(github.ref, 'master')" - shell: bash - run: | - export VERSION=${{ env.VERSION }}-${GITHUB_SHA::7} - echo "VERSION=${VERSION}" >> $GITHUB_ENV - - name: Install Required Packages - run: | - sudo apt-get update - sudo apt-get install -y python3-setuptools libcap-dev librsvg2-bin libtiff-tools - - name: Get macOS SDK - run: | - mkdir -p depends/sdk-sources depends/SDKs - if [ -n "${{ env.XCODE_VERSION }}" ] && [ ! -f "${{ env.OSX_SDK_PATH }}" ]; then - curl --location --fail "${{ env.SDK_URL }}/${{ env.OSX_SDK_BASENAME }}" -o "${{ env.OSX_SDK_PATH }}" - fi - if [ -n "${{ env.XCODE_VERSION }}" ] && [ -f "${{ env.OSX_SDK_PATH }}" ]; then - tar -C "depends/SDKs" -xf "${{ env.OSX_SDK_PATH }}" - fi - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Build Dependencies - run: make -C depends HOST=x86_64-apple-darwin16 -j$(nproc) - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Build PRCY - run: | - ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/x86_64-apple-darwin16) --enable-upnp-default - make -j$(nproc) - make deploy -j$(nproc) - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Prepare Files for Artifact - run: | - mkdir -p $ARTIFACT_DIR - mv $SOURCE_ARTIFACT/{*.dmg,src/prcycoin-cli,src/prcycoin-tx,src/prcycoind,src/qt/prcycoin-qt} $ARTIFACT_DIR - - name: Upload Artifact - uses: actions/upload-artifact@v1 - with: - name: prcycoin-v${{ env.VERSION }}-macosx - path: ${{ env.ARTIFACT_DIR }} - build-aarch64-linux: - name: Build for ARM Linux 64bit - needs: create-source-distribution - runs-on: ubuntu-20.04 - env: - ARTIFACT_DIR: prcycoin-aarch64-linux - steps: - - name: Getting Source - uses: actions/download-artifact@v1 - with: - name: ${{ env.SOURCE_ARTIFACT }} - - name: Extract Archives - run: | - tar -xzf depends.tar.gz - tar -xzf prcycoin.tar.gz --strip-components=1 - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Set Env - shell: bash - run: | - export VERSION=$(cat $SOURCE_ARTIFACT/version.txt | sed 's/[^0-9,.]//g') - echo "VERSION=${VERSION}" >> $GITHUB_ENV - - name: Append Commit Hash to Development Builds - if: "!contains(github.ref, 'master')" - shell: bash - run: | - export VERSION=${{ env.VERSION }}-${GITHUB_SHA::7} - echo "VERSION=${VERSION}" >> $GITHUB_ENV - - name: Install Required Packages - run: | - sudo apt-get update - sudo apt-get install -y python3-zmq g++-aarch64-linux-gnu - - name: Build Dependencies - run: make -C depends HOST=aarch64-linux-gnu -j$(nproc) - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Build PRCY - run: | - ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/aarch64-linux-gnu) --enable-upnp-default - make -j$(nproc) - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Prepare Files for Artifact - run: | - mkdir -p $ARTIFACT_DIR - chmod +x $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} - mv $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} $ARTIFACT_DIR - - name: Upload Artifact - uses: actions/upload-artifact@v1 - with: - name: prcycoin-v${{ env.VERSION }}-aarch64-linux - path: ${{ env.ARTIFACT_DIR }} - build-arm-linux-gnueabihf: - name: Build for ARM Linux 32bit - needs: create-source-distribution - runs-on: ubuntu-20.04 - env: - ARTIFACT_DIR: prcycoin-arm32 - steps: - - name: Getting Source - uses: actions/download-artifact@v1 - with: - name: ${{ env.SOURCE_ARTIFACT }} - - name: Extract Archives - run: | - tar -xzf depends.tar.gz - tar -xzf prcycoin.tar.gz --strip-components=1 - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Set Env - shell: bash - run: | - export VERSION=$(cat $SOURCE_ARTIFACT/version.txt | sed 's/[^0-9,.]//g') - echo "VERSION=${VERSION}" >> $GITHUB_ENV - - name: Append Commit Hash to Development Builds - if: "!contains(github.ref, 'master')" - shell: bash - run: | - export VERSION=${{ env.VERSION }}-${GITHUB_SHA::7} - echo "VERSION=${VERSION}" >> $GITHUB_ENV - - name: Install Required Packages - run: | - sudo apt-get update - sudo apt-get install -y g++-arm-linux-gnueabihf - - name: Build Dependencies - run: make -C depends -j$(nproc) HOST=arm-linux-gnueabihf - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Build PRCY - run: | - ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/arm-linux-gnueabihf) --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++ --enable-upnp-default - make -j$(nproc) - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Prepare Files for Artifact - run: | - mkdir -p $ARTIFACT_DIR - chmod +x $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} - mv $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} $ARTIFACT_DIR - - name: Upload Artifact - uses: actions/upload-artifact@v1 - with: - name: prcycoin-v${{ env.VERSION }}-arm32 - path: ${{ env.ARTIFACT_DIR }} - build-riscv64-linux-gnu: - name: Build for RISC-V 64-bit - needs: create-source-distribution - runs-on: ubuntu-20.04 - env: - ARTIFACT_DIR: prcycoin-riscv64 - steps: - - name: Getting Source - uses: actions/download-artifact@v1 - with: - name: ${{ env.SOURCE_ARTIFACT }} - - name: Extract Archives - run: | - tar -xzf depends.tar.gz - tar -xzf prcycoin.tar.gz --strip-components=1 - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Set Env - shell: bash - run: | - export VERSION=$(cat $SOURCE_ARTIFACT/version.txt | sed 's/[^0-9,.]//g') - echo "VERSION=${VERSION}" >> $GITHUB_ENV - - name: Append Commit Hash to Development Builds - if: "!contains(github.ref, 'master')" - shell: bash - run: | - export VERSION=${{ env.VERSION }}-${GITHUB_SHA::7} - echo "VERSION=${VERSION}" >> $GITHUB_ENV - - name: Install Required Packages - run: | - sudo apt-get update - sudo apt-get install -y g++-riscv64-linux-gnu binutils-riscv64-linux-gnu - - name: Build Dependencies - run: make -C depends -j$(nproc) HOST=riscv64-linux-gnu NO_QT=1 - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Build PRCY - run: | - ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/riscv64-linux-gnu) --enable-reduce-exports LDFLAGS=-static-libstdc++ --enable-upnp-default - make -j$(nproc) - working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Prepare Files for Artifact - run: | - mkdir -p $ARTIFACT_DIR - chmod +x $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind} - mv $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind} $ARTIFACT_DIR - - name: Upload Artifact - uses: actions/upload-artifact@v1 - with: - name: prcycoin-v${{ env.VERSION }}-riscv64 - path: ${{ env.ARTIFACT_DIR }} diff --git a/.github/workflows/prcy-build-factory.yml b/.github/workflows/prcy-build-factory.yml index 40d5bf5765..b7246ca25b 100644 --- a/.github/workflows/prcy-build-factory.yml +++ b/.github/workflows/prcy-build-factory.yml @@ -3,14 +3,14 @@ # Copyright (c) 2020 The PRivaCY Coin Developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. -name: Github Actions CI for PRCY +name: Github Actions CI for PRCY (Ubuntu 20) on: [push, pull_request] env: SOURCE_ARTIFACT: source jobs: create-source-distribution: name: Create Source Distribution - runs-on: ubuntu-18.04 + runs-on: ubuntu-22.04 env: ARTIFACT_DIR: source steps: @@ -46,7 +46,7 @@ jobs: run: | mv depends.tar.gz prcycoin.tar.gz $ARTIFACT_DIR - name: Upload Artifact - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v4 with: name: ${{ env.SOURCE_ARTIFACT }} path: ${{ env.ARTIFACT_DIR }} @@ -59,7 +59,7 @@ jobs: TEST_LOG_ARTIFACT_DIR: test-logs steps: - name: Getting Source - uses: actions/download-artifact@v1 + uses: actions/download-artifact@v4.1.7 with: name: ${{ env.SOURCE_ARTIFACT }} - name: Extract Archives @@ -99,20 +99,20 @@ jobs: chmod +x $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} mv $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} $ARTIFACT_DIR - name: Upload Artifact - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v4 with: name: prcycoin-v${{ env.VERSION }}-linux path: ${{ env.ARTIFACT_DIR }} build-x86_64-linux: name: Build for x86 Linux 64bit needs: create-source-distribution - runs-on: ubuntu-18.04 + runs-on: ubuntu-22.04 env: ARTIFACT_DIR: prcycoin-x86_64-linux TEST_LOG_ARTIFACT_DIR: test-logs steps: - name: Getting Source - uses: actions/download-artifact@v1 + uses: actions/download-artifact@v4.1.7 with: name: ${{ env.SOURCE_ARTIFACT }} - name: Extract Archives @@ -138,10 +138,10 @@ jobs: - name: Build Dependencies run: make -C depends -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} - - name: Build PRCY + - name: Build PRCY run: | ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/x86_64-pc-linux-gnu) --enable-upnp-default --enable-glibc-back-compat --enable-reduce-exports + ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/x86_64-pc-linux-gnu) --enable-upnp-default make -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Prepare Files for Artifact @@ -151,19 +151,19 @@ jobs: chmod +x $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} mv $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} $ARTIFACT_DIR - name: Upload Artifact - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v4 with: name: prcycoin-v${{ env.VERSION }}-x86_64-linux path: ${{ env.ARTIFACT_DIR }} build-win64: name: Build for Win64 needs: create-source-distribution - runs-on: ubuntu-18.04 + runs-on: ubuntu-22.04 env: ARTIFACT_DIR: prcycoin-win64 steps: - name: Getting Source - uses: actions/download-artifact@v1 + uses: actions/download-artifact@v4.1.7 with: name: ${{ env.SOURCE_ARTIFACT }} - name: Extract Archives @@ -196,7 +196,7 @@ jobs: - name: Build PRCY run: | ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/x86_64-w64-mingw32) --enable-upnp-default --enable-reduce-exports + ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/x86_64-w64-mingw32) --enable-upnp-default make -j$(nproc) make deploy -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} @@ -206,20 +206,20 @@ jobs: strip $SOURCE_ARTIFACT/src/{prcycoin-cli.exe,prcycoin-tx.exe,prcycoind.exe,qt/prcycoin-qt.exe} mv $SOURCE_ARTIFACT/{prcycoin-*.exe,src/prcycoin-cli.exe,src/prcycoin-tx.exe,src/prcycoind.exe,src/qt/prcycoin-qt.exe} $ARTIFACT_DIR - name: Upload Artifact - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v4 with: name: prcycoin-v${{ env.VERSION }}-win64 path: ${{ env.ARTIFACT_DIR }} build-osx64: name: Build for MacOSX needs: create-source-distribution - runs-on: ubuntu-18.04 + runs-on: ubuntu-22.04 env: ARTIFACT_DIR: prcycoin-macosx SDK_URL: https://bitcoincore.org/depends-sources/sdks steps: - name: Getting Source - uses: actions/download-artifact@v1 + uses: actions/download-artifact@v4.1.7 with: name: ${{ env.SOURCE_ARTIFACT }} - name: Extract Archives @@ -266,7 +266,7 @@ jobs: - name: Build PRCY run: | ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/x86_64-apple-darwin16) --enable-upnp-default --enable-reduce-exports + ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/x86_64-apple-darwin16) --enable-upnp-default make -j$(nproc) make deploy -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} @@ -275,19 +275,19 @@ jobs: mkdir -p $ARTIFACT_DIR mv $SOURCE_ARTIFACT/{*.dmg,src/prcycoin-cli,src/prcycoin-tx,src/prcycoind,src/qt/prcycoin-qt} $ARTIFACT_DIR - name: Upload Artifact - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v4 with: name: prcycoin-v${{ env.VERSION }}-macosx path: ${{ env.ARTIFACT_DIR }} build-aarch64-linux: name: Build for ARM Linux 64bit needs: create-source-distribution - runs-on: ubuntu-18.04 + runs-on: ubuntu-22.04 env: ARTIFACT_DIR: prcycoin-aarch64-linux steps: - name: Getting Source - uses: actions/download-artifact@v1 + uses: actions/download-artifact@v4.1.7 with: name: ${{ env.SOURCE_ARTIFACT }} - name: Extract Archives @@ -316,7 +316,7 @@ jobs: - name: Build PRCY run: | ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/aarch64-linux-gnu) --enable-upnp-default --enable-glibc-back-compat --enable-reduce-exports + ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/aarch64-linux-gnu) --enable-upnp-default make -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Prepare Files for Artifact @@ -325,19 +325,19 @@ jobs: chmod +x $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} mv $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} $ARTIFACT_DIR - name: Upload Artifact - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v4 with: name: prcycoin-v${{ env.VERSION }}-aarch64-linux path: ${{ env.ARTIFACT_DIR }} build-arm-linux-gnueabihf: name: Build for ARM Linux 32bit needs: create-source-distribution - runs-on: ubuntu-18.04 + runs-on: ubuntu-22.04 env: ARTIFACT_DIR: prcycoin-arm32 steps: - name: Getting Source - uses: actions/download-artifact@v1 + uses: actions/download-artifact@v4.1.7 with: name: ${{ env.SOURCE_ARTIFACT }} - name: Extract Archives @@ -366,7 +366,7 @@ jobs: - name: Build PRCY run: | ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/arm-linux-gnueabihf) --enable-glibc-back-compat --enable-reduce-exports --enable-upnp-default CXXFLAGS=-Wno-psabi + ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/arm-linux-gnueabihf) --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++ --enable-upnp-default make -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Prepare Files for Artifact @@ -375,19 +375,19 @@ jobs: chmod +x $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} mv $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} $ARTIFACT_DIR - name: Upload Artifact - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v4 with: name: prcycoin-v${{ env.VERSION }}-arm32 path: ${{ env.ARTIFACT_DIR }} build-riscv64-linux-gnu: name: Build for RISC-V 64-bit needs: create-source-distribution - runs-on: ubuntu-18.04 + runs-on: ubuntu-22.04 env: ARTIFACT_DIR: prcycoin-riscv64 steps: - name: Getting Source - uses: actions/download-artifact@v1 + uses: actions/download-artifact@v4.1.7 with: name: ${{ env.SOURCE_ARTIFACT }} - name: Extract Archives @@ -411,21 +411,21 @@ jobs: sudo apt-get update sudo apt-get install -y g++-riscv64-linux-gnu binutils-riscv64-linux-gnu - name: Build Dependencies - run: make -C depends -j$(nproc) HOST=riscv64-linux-gnu + run: make -C depends -j$(nproc) HOST=riscv64-linux-gnu NO_QT=1 working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Build PRCY run: | ./autogen.sh - ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/riscv64-linux-gnu) --enable-reduce-exports --enable-upnp-default + ./configure --disable-jni --disable-tests --disable-gui-tests --disable-bench --prefix=$(realpath depends/riscv64-linux-gnu) --enable-reduce-exports LDFLAGS=-static-libstdc++ --enable-upnp-default make -j$(nproc) working-directory: ${{ env.SOURCE_ARTIFACT }} - name: Prepare Files for Artifact run: | mkdir -p $ARTIFACT_DIR - chmod +x $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} - mv $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind,qt/prcycoin-qt} $ARTIFACT_DIR + chmod +x $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind} + mv $SOURCE_ARTIFACT/src/{prcycoin-cli,prcycoin-tx,prcycoind} $ARTIFACT_DIR - name: Upload Artifact - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v4 with: name: prcycoin-v${{ env.VERSION }}-riscv64 path: ${{ env.ARTIFACT_DIR }} diff --git a/.gitignore b/.gitignore index 81fcffeb57..10b2d8046c 100644 --- a/.gitignore +++ b/.gitignore @@ -40,6 +40,7 @@ libtool src/config/prcycoin-config.h src/config/prcycoin-config.h.in src/config/stamp-h1 +src/obj src/secp256k1-mw/build-aux/compile src/secp256k1-mw/build-aux/config.guess src/secp256k1-mw/build-aux/config.sub @@ -100,7 +101,6 @@ src/qt/test/moc*.cpp Makefile prcycoin-qt PRCYcoin-Qt.app -background.tiff* # Unit-tests Makefile.test @@ -118,7 +118,6 @@ qrc_*.cpp build osx_volname dist/ -*.background.tiff #lcov *.gcno diff --git a/.python-version b/.python-version new file mode 100644 index 0000000000..8b7b0b52e5 --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.6.12 diff --git a/.travis.yml b/.travis.yml index c133a5bd94..ef88979392 100644 --- a/.travis.yml +++ b/.travis.yml @@ -85,20 +85,11 @@ jobs: PACKAGES="python3 nsis g++-mingw-w64-x86-64 wine-binfmt wine64" GOAL="install" BITCOIN_CONFIG="--enable-reduce-exports" -# 32-bit + dash - - stage: test - env: >- - HOST=i686-pc-linux-gnu - PACKAGES="g++-multilib python3-zmq" - DEP_OPTS="NO_QT=1" - GOAL="install" - BITCOIN_CONFIG="--enable-zmq --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++" - CONFIG_SHELL="/bin/dash" # x86_64 Linux (uses qt5 dev package instead of depends Qt to speed up build and avoid timeout) - stage: test env: >- HOST=x86_64-unknown-linux-gnu - PACKAGES="python3-zmq qtbase5-dev qttools5-dev-tools protobuf-compiler libdbus-1-dev libharfbuzz-dev libprotobuf-dev" + PACKAGES="python3-zmq qtbase5-dev qttools5-dev-tools libdbus-1-dev libharfbuzz-dev" DEP_OPTS="NO_QT=1 NO_UPNP=1 DEBUG=1 ALLOW_HOST_PACKAGES=1" GOAL="install" BITCOIN_CONFIG="--enable-zmq --with-gui=qt5 --enable-glibc-back-compat --enable-reduce-exports CPPFLAGS=-DDEBUG_LOCKORDER" @@ -106,7 +97,7 @@ jobs: - stage: test env: >- HOST=x86_64-unknown-linux-gnu - PACKAGES="python3-zmq qtbase5-dev qttools5-dev-tools libssl1.0-dev libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-chrono-dev libboost-program-options-dev libboost-test-dev libboost-thread-dev libdb5.3++-dev libminiupnpc-dev libzmq3-dev libprotobuf-dev protobuf-compiler libqrencode-dev" + PACKAGES="python3-zmq qtbase5-dev qttools5-dev-tools libssl1.0-dev libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-chrono-dev libboost-program-options-dev libboost-test-dev libboost-thread-dev libdb5.3++-dev libminiupnpc-dev libzmq3-dev libqrencode-dev" NO_DEPENDS=1 GOAL="install" BITCOIN_CONFIG="--enable-zmq --with-incompatible-bdb --enable-glibc-back-compat --enable-reduce-exports --with-gui=qt5 CPPFLAGS=-DDEBUG_LOCKORDER" @@ -114,7 +105,7 @@ jobs: # - stage: test # env: >- # HOST=x86_64-unknown-linux-gnu -# PACKAGES="clang python3-zmq qtbase5-dev qttools5-dev-tools libssl1.0-dev libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-chrono-dev libboost-program-options-dev libboost-test-dev libboost-thread-dev libdb5.3++-dev libminiupnpc-dev libzmq3-dev libprotobuf-dev protobuf-compiler libqrencode-dev" +# PACKAGES="clang python3-zmq qtbase5-dev qttools5-dev-tools libssl1.0-dev libevent-dev bsdmainutils libboost-system-dev libboost-filesystem-dev libboost-chrono-dev libboost-program-options-dev libboost-test-dev libboost-thread-dev libdb5.3++-dev libminiupnpc-dev libzmq3-dev libqrencode-dev" # NO_DEPENDS=1 # RUN_BENCH=true # RUN_FUNCTIONAL_TESTS=false # Disabled for now, can be combined with the other x86_64 linux NO_DEPENDS job when functional tests pass the sanitizers @@ -131,7 +122,7 @@ jobs: # Cross-Mac - stage: test env: >- - HOST=x86_64-apple-darwin16 + HOST=x86_64-apple-darwin18 PACKAGES="cmake imagemagick libcap-dev librsvg2-bin libz-dev libbz2-dev libtiff-tools python-dev python3-setuptools-git" OSX_SDK=10.14 RUN_UNIT_TESTS=false diff --git a/COPYING b/COPYING index f765ab8bf2..cc796c3b01 100644 --- a/COPYING +++ b/COPYING @@ -2,7 +2,7 @@ Copyright (c) 2009-2015 Bitcoin Developers Copyright (c) 2014-2015 Dash Developers Copyright (c) 2015-2018 PIVX Developers Copyright (c) 2018-2020 DAPScoin Developers -Copyright (c) 2020-2023 PRCYcoin Developers +Copyright (c) 2020-2024 PRCYcoin Developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/Makefile.am b/Makefile.am index 980792cc52..877d154de3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -4,7 +4,7 @@ # Pattern rule to print variables, e.g. make print-top_srcdir print-%: - @echo $* = $($*) + @echo '$*' = '$($*)' ACLOCAL_AMFLAGS = -I build-aux/m4 SUBDIRS = src @@ -32,9 +32,6 @@ space := $(empty) $(empty) OSX_APP=PRCYcoin-Qt.app OSX_VOLNAME = $(subst $(space),-,$(PACKAGE_NAME)) OSX_DMG = $(OSX_VOLNAME).dmg -OSX_BACKGROUND_SVG=background.svg -OSX_BACKGROUND_IMAGE=background.tiff -OSX_BACKGROUND_IMAGE_DPIS=36 72 OSX_DEPLOY_SCRIPT=$(top_srcdir)/contrib/macdeploy/macdeployqtplus OSX_INSTALLER_ICONS=$(top_srcdir)/src/qt/res/icons/bitcoin.icns OSX_PLIST=$(top_builddir)/share/qt/Info.plist #not installed @@ -66,7 +63,6 @@ LINUX_PACKAGING = $(top_srcdir)/share/pixmaps/prcycoin16.xpm \ $(top_srcdir)/share/pixmaps/prcycoin128.png OSX_PACKAGING = $(OSX_DEPLOY_SCRIPT) $(OSX_INSTALLER_ICONS) \ - $(top_srcdir)/contrib/macdeploy/$(OSX_BACKGROUND_SVG) \ $(top_srcdir)/contrib/macdeploy/detached-sig-apply.sh \ $(top_srcdir)/contrib/macdeploy/detached-sig-create.sh @@ -120,45 +116,23 @@ osx_volname: echo $(OSX_VOLNAME) >$@ if BUILD_DARWIN -$(OSX_DMG): $(OSX_APP_BUILT) $(OSX_PACKAGING) $(OSX_BACKGROUND_IMAGE) +$(OSX_DMG): $(OSX_APP_BUILT) $(OSX_PACKAGING) $(PYTHON) $(OSX_DEPLOY_SCRIPT) $(OSX_APP) $(OSX_VOLNAME) -translations-dir=$(QT_TRANSLATION_DIR) -dmg -$(OSX_BACKGROUND_IMAGE).png: contrib/macdeploy/$(OSX_BACKGROUND_SVG) - sed 's/PACKAGE_NAME/$(PACKAGE_NAME)/' < "$<" | $(RSVG_CONVERT) -f png -d 36 -p 36 -o $@ -$(OSX_BACKGROUND_IMAGE)@2x.png: contrib/macdeploy/$(OSX_BACKGROUND_SVG) - sed 's/PACKAGE_NAME/$(PACKAGE_NAME)/' < "$<" | $(RSVG_CONVERT) -f png -d 72 -p 72 -o $@ -$(OSX_BACKGROUND_IMAGE): $(OSX_BACKGROUND_IMAGE).png $(OSX_BACKGROUND_IMAGE)@2x.png - tiffutil -cathidpicheck $^ -out $@ - deploydir: $(OSX_DMG) else APP_DIST_DIR=$(top_builddir)/dist -APP_DIST_EXTRAS=$(APP_DIST_DIR)/.background/$(OSX_BACKGROUND_IMAGE) $(APP_DIST_DIR)/.DS_Store $(APP_DIST_DIR)/Applications - -$(APP_DIST_DIR)/Applications: - @rm -f $@ - @cd $(@D); $(LN_S) /Applications $(@F) - -$(APP_DIST_EXTRAS): $(APP_DIST_DIR)/$(OSX_APP)/Contents/MacOS/PRCYcoin-Qt -$(OSX_DMG): $(APP_DIST_EXTRAS) - $(GENISOIMAGE) -no-cache-inodes -D -l -probe -V "$(OSX_VOLNAME)" -no-pad -r -dir-mode 0755 -apple -o $@ dist - -dpi%.$(OSX_BACKGROUND_IMAGE): contrib/macdeploy/$(OSX_BACKGROUND_SVG) - sed 's/PACKAGE_NAME/$(PACKAGE_NAME)/' < "$<" | $(RSVG_CONVERT) -f png -d $* -p $* | $(IMAGEMAGICK_CONVERT) - $@ -OSX_BACKGROUND_IMAGE_DPIFILES := $(foreach dpi,$(OSX_BACKGROUND_IMAGE_DPIS),dpi$(dpi).$(OSX_BACKGROUND_IMAGE)) -$(APP_DIST_DIR)/.background/$(OSX_BACKGROUND_IMAGE): $(OSX_BACKGROUND_IMAGE_DPIFILES) - $(MKDIR_P) $(@D) - $(TIFFCP) -c none $(OSX_BACKGROUND_IMAGE_DPIFILES) $@ +$(OSX_DMG): deploydir + $(XORRISOFS) -D -l -V "$(OSX_VOLNAME)" -no-pad -r -dir-mode 0755 -o $@ dist -- $(if $(SOURCE_DATE_EPOCH),-volume_date all_file_dates =$(SOURCE_DATE_EPOCH)) $(APP_DIST_DIR)/$(OSX_APP)/Contents/MacOS/PRCYcoin-Qt: $(OSX_APP_BUILT) $(OSX_PACKAGING) - INSTALLNAMETOOL=$(INSTALLNAMETOOL) OTOOL=$(OTOOL) STRIP=$(STRIP) $(PYTHON) $(OSX_DEPLOY_SCRIPT) $(OSX_APP) $(OSX_VOLNAME) -translations-dir=$(QT_TRANSLATION_DIR) + INSTALL_NAME_TOOL=$(INSTALL_NAME_TOOL) OTOOL=$(OTOOL) STRIP=$(STRIP) $(PYTHON) $(OSX_DEPLOY_SCRIPT) $(OSX_APP) $(OSX_VOLNAME) -translations-dir=$(QT_TRANSLATION_DIR) -deploydir: $(APP_DIST_EXTRAS) +deploydir: $(APP_DIST_DIR)/$(OSX_APP)/Contents/MacOS/PRCYcoin-Qt endif if TARGET_DARWIN -appbundle: $(OSX_APP_BUILT) deploy: $(OSX_DMG) endif if TARGET_WINDOWS @@ -276,4 +250,4 @@ clean-docs: clean-local: clean-docs rm -rf coverage_percent.txt test_prcycoin.coverage/ total.coverage/ test/tmp/ cache/ $(OSX_APP) rm -rf test/functional/__pycache__ test/functional/test_framework/__pycache__ test/cache share/rpcauth/__pycache__ - rm -rf osx_volname dist/ dpi36.background.tiff dpi72.background.tiff + rm -rf osx_volname dist/ diff --git a/build-aux/m4/ax_boost_base.m4 b/build-aux/m4/ax_boost_base.m4 index 6635bd711c..b1fed7a50a 100644 --- a/build-aux/m4/ax_boost_base.m4 +++ b/build-aux/m4/ax_boost_base.m4 @@ -10,10 +10,10 @@ # # Test for the Boost C++ libraries of a particular version (or newer) # -# If no path to the installed boost library is given the macro search -# under /usr, /usr/local, /opt, /opt/local, and /opt/homebrew and evaluates the -# $BOOST_ROOT environment variable. Further documentation is available at -# . +# If no path to the installed boost library is given the macro searchs +# under /usr, /usr/local, /opt, /opt/local and /opt/homebrew and evaluates +# the $BOOST_ROOT environment variable. Further documentation is available +# at . # # This macro calls: # @@ -33,7 +33,7 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 49 +#serial 52 # example boost program (need to pass version) m4_define([_AX_BOOST_BASE_PROGRAM], @@ -114,7 +114,7 @@ AC_DEFUN([_AX_BOOST_BASE_RUNDETECT],[ AS_CASE([${host_cpu}], [x86_64],[libsubdirs="lib64 libx32 lib lib64"], [mips*64*],[libsubdirs="lib64 lib32 lib lib64"], - [ppc64|powerpc64|s390x|sparc64|aarch64|ppc64le|powerpc64le|riscv64],[libsubdirs="lib64 lib lib64"], + [ppc64|powerpc64|s390x|sparc64|aarch64|ppc64le|powerpc64le|riscv64|e2k|loongarch64],[libsubdirs="lib64 lib lib64"], [libsubdirs="lib"] ) @@ -123,15 +123,10 @@ AC_DEFUN([_AX_BOOST_BASE_RUNDETECT],[ dnl are almost assuredly the ones desired. AS_CASE([${host_cpu}], [i?86],[multiarch_libsubdir="lib/i386-${host_os}"], + [armv7l],[multiarch_libsubdir="lib/arm-${host_os}"], [multiarch_libsubdir="lib/${host_cpu}-${host_os}"] ) - dnl some arches may advertise a cpu type that doesn't line up with their - dnl prefix's cpu type. For example, uname may report armv7l while libs are - dnl installed to /usr/lib/arm-linux-gnueabihf. Try getting the compiler's - dnl value for an extra chance of finding the correct path. - libsubdirs="lib/`$CXX -dumpmachine 2>/dev/null` $libsubdirs" - dnl first we check the system location for boost libraries dnl this location is chosen if boost libraries are installed with the --layout=system option dnl or if you install boost with RPM diff --git a/build-aux/m4/ax_boost_chrono.m4 b/build-aux/m4/ax_boost_chrono.m4 index 6ea77b9b3e..4cd3b86041 100644 --- a/build-aux/m4/ax_boost_chrono.m4 +++ b/build-aux/m4/ax_boost_chrono.m4 @@ -29,7 +29,7 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 4 +#serial 5 AC_DEFUN([AX_BOOST_CHRONO], [ @@ -105,7 +105,7 @@ AC_DEFUN([AX_BOOST_CHRONO], fi if test "x$ax_lib" = "x"; then - AC_MSG_ERROR(Could not find a version of the library!) + AC_MSG_ERROR(Could not find a version of the Boost::Chrono library!) fi if test "x$link_chrono" = "xno"; then AC_MSG_ERROR(Could not link against $ax_lib !) diff --git a/build-aux/m4/ax_boost_filesystem.m4 b/build-aux/m4/ax_boost_filesystem.m4 index f5c9d56470..12f7bc5e2e 100644 --- a/build-aux/m4/ax_boost_filesystem.m4 +++ b/build-aux/m4/ax_boost_filesystem.m4 @@ -1,5 +1,5 @@ # =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_boost_filesystem.html +# https://www.gnu.org/software/autoconf-archive/ax_boost_filesystem.html # =========================================================================== # # SYNOPSIS @@ -31,7 +31,7 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 26 +#serial 28 AC_DEFUN([AX_BOOST_FILESYSTEM], [ @@ -80,7 +80,6 @@ AC_DEFUN([AX_BOOST_FILESYSTEM], if test "x$ax_cv_boost_filesystem" = "xyes"; then AC_DEFINE(HAVE_BOOST_FILESYSTEM,,[define if the Boost::Filesystem library is available]) BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'` - ax_lib= if test "x$ax_boost_user_filesystem_lib" = "x"; then for libextension in `ls -r $BOOSTLIBDIR/libboost_filesystem* 2>/dev/null | sed 's,.*/lib,,' | sed 's,\..*,,'` ; do ax_lib=${libextension} @@ -105,7 +104,7 @@ AC_DEFUN([AX_BOOST_FILESYSTEM], fi if test "x$ax_lib" = "x"; then - AC_MSG_ERROR(Could not find a version of the boost_filesystem library!) + AC_MSG_ERROR(Could not find a version of the Boost::Filesystem library!) fi if test "x$link_filesystem" != "xyes"; then AC_MSG_ERROR(Could not link against $ax_lib !) diff --git a/build-aux/m4/ax_boost_program_options.m4 b/build-aux/m4/ax_boost_program_options.m4 index 2bdb593716..7d23da4648 100644 --- a/build-aux/m4/ax_boost_program_options.m4 +++ b/build-aux/m4/ax_boost_program_options.m4 @@ -1,6 +1,6 @@ -# ============================================================================ -# http://www.gnu.org/software/autoconf-archive/ax_boost_program_options.html -# ============================================================================ +# ============================================================================= +# https://www.gnu.org/software/autoconf-archive/ax_boost_program_options.html +# ============================================================================= # # SYNOPSIS # @@ -29,7 +29,7 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 24 +#serial 26 AC_DEFUN([AX_BOOST_PROGRAM_OPTIONS], [ @@ -96,7 +96,7 @@ AC_DEFUN([AX_BOOST_PROGRAM_OPTIONS], done fi if test "x$ax_lib" = "x"; then - AC_MSG_ERROR(Could not find a version of the boost_program_options library!) + AC_MSG_ERROR(Could not find a version of the Boost::Program_Options library!) fi if test "x$link_program_options" != "xyes"; then AC_MSG_ERROR([Could not link against [$ax_lib] !]) diff --git a/build-aux/m4/ax_boost_system.m4 b/build-aux/m4/ax_boost_system.m4 index 207d7be8de..323e2a676a 100644 --- a/build-aux/m4/ax_boost_system.m4 +++ b/build-aux/m4/ax_boost_system.m4 @@ -31,7 +31,7 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 19 +#serial 20 AC_DEFUN([AX_BOOST_SYSTEM], [ @@ -108,7 +108,7 @@ AC_DEFUN([AX_BOOST_SYSTEM], fi if test "x$ax_lib" = "x"; then - AC_MSG_ERROR(Could not find a version of the library!) + AC_MSG_ERROR(Could not find a version of the Boost::System library!) fi if test "x$link_system" = "xno"; then AC_MSG_ERROR(Could not link against $ax_lib !) diff --git a/build-aux/m4/ax_boost_thread.m4 b/build-aux/m4/ax_boost_thread.m4 index 9f0bd0b23c..75e80e6e75 100644 --- a/build-aux/m4/ax_boost_thread.m4 +++ b/build-aux/m4/ax_boost_thread.m4 @@ -1,5 +1,5 @@ # =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_boost_thread.html +# https://www.gnu.org/software/autoconf-archive/ax_boost_thread.html # =========================================================================== # # SYNOPSIS @@ -30,73 +30,96 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 27 +#serial 33 AC_DEFUN([AX_BOOST_THREAD], [ - AC_ARG_WITH([boost-thread], - AS_HELP_STRING([--with-boost-thread@<:@=special-lib@:>@], - [use the Thread library from boost - it is possible to specify a certain library for the linker - e.g. --with-boost-thread=boost_thread-gcc-mt ]), + AC_ARG_WITH([boost-thread], + AS_HELP_STRING([--with-boost-thread@<:@=special-lib@:>@], + [use the Thread library from boost - + it is possible to specify a certain library for the linker + e.g. --with-boost-thread=boost_thread-gcc-mt ]), [ - if test "$withval" = "no"; then - want_boost="no" - elif test "$withval" = "yes"; then + if test "$withval" = "yes"; then want_boost="yes" ax_boost_user_thread_lib="" else - want_boost="yes" - ax_boost_user_thread_lib="$withval" - fi + want_boost="yes" + ax_boost_user_thread_lib="$withval" + fi ], [want_boost="yes"] - ) + ) - if test "x$want_boost" = "xyes"; then + if test "x$want_boost" = "xyes"; then AC_REQUIRE([AC_PROG_CC]) AC_REQUIRE([AC_CANONICAL_BUILD]) - CPPFLAGS_SAVED="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" - export CPPFLAGS + CPPFLAGS_SAVED="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS" + export CPPFLAGS - LDFLAGS_SAVED="$LDFLAGS" - LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" - export LDFLAGS + LDFLAGS_SAVED="$LDFLAGS" + LDFLAGS="$LDFLAGS $BOOST_LDFLAGS" + export LDFLAGS AC_CACHE_CHECK(whether the Boost::Thread library is available, - ax_cv_boost_thread, + ax_cv_boost_thread, [AC_LANG_PUSH([C++]) - CXXFLAGS_SAVE=$CXXFLAGS + CXXFLAGS_SAVE=$CXXFLAGS + + case "x$host_os" in + xsolaris ) + CXXFLAGS="-pthreads $CXXFLAGS" + break; + ;; + xmingw32 ) + CXXFLAGS="-mthreads $CXXFLAGS" + break; + ;; + *android* ) + break; + ;; + * ) + CXXFLAGS="-pthread $CXXFLAGS" + break; + ;; + esac - if test "x$host_os" = "xsolaris" ; then - CXXFLAGS="-pthreads $CXXFLAGS" - elif test "x$host_os" = "xmingw32" ; then - CXXFLAGS="-mthreads $CXXFLAGS" - else - CXXFLAGS="-pthread $CXXFLAGS" - fi - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include ]], - [[boost::thread_group thrds; - return 0;]])], - ax_cv_boost_thread=yes, ax_cv_boost_thread=no) - CXXFLAGS=$CXXFLAGS_SAVE + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM( + [[@%:@include ]], + [[boost::thread_group thrds; + return 0;]])], + ax_cv_boost_thread=yes, ax_cv_boost_thread=no) + CXXFLAGS=$CXXFLAGS_SAVE AC_LANG_POP([C++]) - ]) - if test "x$ax_cv_boost_thread" = "xyes"; then - if test "x$host_os" = "xsolaris" ; then - BOOST_CPPFLAGS="-pthreads $BOOST_CPPFLAGS" - elif test "x$host_os" = "xmingw32" ; then - BOOST_CPPFLAGS="-mthreads $BOOST_CPPFLAGS" - else - BOOST_CPPFLAGS="-pthread $BOOST_CPPFLAGS" - fi + ]) + if test "x$ax_cv_boost_thread" = "xyes"; then + case "x$host_os" in + xsolaris ) + BOOST_CPPFLAGS="-pthreads $BOOST_CPPFLAGS" + break; + ;; + xmingw32 ) + BOOST_CPPFLAGS="-mthreads $BOOST_CPPFLAGS" + break; + ;; + *android* ) + break; + ;; + * ) + BOOST_CPPFLAGS="-pthread $BOOST_CPPFLAGS" + break; + ;; + esac - AC_SUBST(BOOST_CPPFLAGS) + AC_SUBST(BOOST_CPPFLAGS) - AC_DEFINE(HAVE_BOOST_THREAD,,[define if the Boost::Thread library is available]) + AC_DEFINE(HAVE_BOOST_THREAD,, + [define if the Boost::Thread library is available]) BOOSTLIBDIR=`echo $BOOST_LDFLAGS | sed -e 's/@<:@^\/@:>@*//'` - LDFLAGS_SAVE=$LDFLAGS + LDFLAGS_SAVE=$LDFLAGS case "x$host_os" in *bsd* ) LDFLAGS="-pthread $LDFLAGS" @@ -104,47 +127,61 @@ AC_DEFUN([AX_BOOST_THREAD], ;; esac if test "x$ax_boost_user_thread_lib" = "x"; then - ax_lib= for libextension in `ls -r $BOOSTLIBDIR/libboost_thread* 2>/dev/null | sed 's,.*/lib,,' | sed 's,\..*,,'`; do ax_lib=${libextension} - AC_CHECK_LIB($ax_lib, exit, - [BOOST_THREAD_LIB="-l$ax_lib"; AC_SUBST(BOOST_THREAD_LIB) link_thread="yes"; break], + AC_CHECK_LIB($ax_lib, exit, + [link_thread="yes"; break], [link_thread="no"]) - done + done if test "x$link_thread" != "xyes"; then for libextension in `ls -r $BOOSTLIBDIR/boost_thread* 2>/dev/null | sed 's,.*/,,' | sed 's,\..*,,'`; do ax_lib=${libextension} - AC_CHECK_LIB($ax_lib, exit, - [BOOST_THREAD_LIB="-l$ax_lib"; AC_SUBST(BOOST_THREAD_LIB) link_thread="yes"; break], + AC_CHECK_LIB($ax_lib, exit, + [link_thread="yes"; break], [link_thread="no"]) - done + done fi else for ax_lib in $ax_boost_user_thread_lib boost_thread-$ax_boost_user_thread_lib; do - AC_CHECK_LIB($ax_lib, exit, - [BOOST_THREAD_LIB="-l$ax_lib"; AC_SUBST(BOOST_THREAD_LIB) link_thread="yes"; break], + AC_CHECK_LIB($ax_lib, exit, + [link_thread="yes"; break], [link_thread="no"]) done fi if test "x$ax_lib" = "x"; then - AC_MSG_ERROR(Could not find a version of the boost_thread library!) + AC_MSG_ERROR(Could not find a version of the Boost::Thread library!) fi - if test "x$link_thread" = "xno"; then - AC_MSG_ERROR(Could not link against $ax_lib !) - else - case "x$host_os" in - *bsd* ) - BOOST_LDFLAGS="-pthread $BOOST_LDFLAGS" - break; - ;; - esac - - fi - fi + if test "x$link_thread" = "xno"; then + AC_MSG_ERROR(Could not link against $ax_lib !) + else + BOOST_THREAD_LIB="-l$ax_lib" + case "x$host_os" in + *bsd* ) + BOOST_LDFLAGS="-pthread $BOOST_LDFLAGS" + break; + ;; + xsolaris ) + BOOST_THREAD_LIB="$BOOST_THREAD_LIB -lpthread" + break; + ;; + xmingw32 ) + break; + ;; + *android* ) + break; + ;; + * ) + BOOST_THREAD_LIB="$BOOST_THREAD_LIB -lpthread" + break; + ;; + esac + AC_SUBST(BOOST_THREAD_LIB) + fi + fi - CPPFLAGS="$CPPFLAGS_SAVED" - LDFLAGS="$LDFLAGS_SAVED" - fi + CPPFLAGS="$CPPFLAGS_SAVED" + LDFLAGS="$LDFLAGS_SAVED" + fi ]) diff --git a/build-aux/m4/ax_boost_unit_test_framework.m4 b/build-aux/m4/ax_boost_unit_test_framework.m4 index 3d8e93e964..4cca32fcfd 100644 --- a/build-aux/m4/ax_boost_unit_test_framework.m4 +++ b/build-aux/m4/ax_boost_unit_test_framework.m4 @@ -29,7 +29,7 @@ # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 21 +#serial 22 AC_DEFUN([AX_BOOST_UNIT_TEST_FRAMEWORK], [ @@ -124,7 +124,7 @@ AC_DEFUN([AX_BOOST_UNIT_TEST_FRAMEWORK], done fi if test "x$ax_lib" = "x"; then - AC_MSG_ERROR(Could not find a version of the library!) + AC_MSG_ERROR(Could not find a version of the Boost::Unit_Test_Framework library!) fi if test "x$link_unit_test_framework" != "xyes"; then AC_MSG_ERROR(Could not link against $ax_lib !) diff --git a/build-aux/m4/ax_cxx_compile_stdcxx.m4 b/build-aux/m4/ax_cxx_compile_stdcxx.m4 index f147cee3b1..43087b2e68 100644 --- a/build-aux/m4/ax_cxx_compile_stdcxx.m4 +++ b/build-aux/m4/ax_cxx_compile_stdcxx.m4 @@ -1,5 +1,5 @@ # =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html +# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html # =========================================================================== # # SYNOPSIS @@ -33,21 +33,23 @@ # Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov # Copyright (c) 2015 Paul Norman # Copyright (c) 2015 Moritz Klammler +# Copyright (c) 2016, 2018 Krzesimir Nowak +# Copyright (c) 2019 Enji Cooper # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. -#serial 4 +#serial 11 dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro dnl (serial version number 13). AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl - m4_if([$1], [11], [], - [$1], [14], [], - [$1], [17], [m4_fatal([support for C++17 not yet implemented in AX_CXX_COMPILE_STDCXX])], + m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"], + [$1], [14], [ax_cxx_compile_alternatives="14 1y"], + [$1], [17], [ax_cxx_compile_alternatives="17 1z"], [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl m4_if([$2], [], [], [$2], [ext], [], @@ -57,26 +59,13 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true], [$3], [optional], [ax_cxx_compile_cxx$1_required=false], [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])]) - m4_if([$4], [], [ax_cxx_compile_cxx$1_try_default=true], - [$4], [default], [ax_cxx_compile_cxx$1_try_default=true], - [$4], [nodefault], [ax_cxx_compile_cxx$1_try_default=false], - [m4_fatal([invalid fourth argument `$4' to AX_CXX_COMPILE_STDCXX])]) AC_LANG_PUSH([C++])dnl ac_success=no - m4_if([$4], [nodefault], [], [dnl - AC_CACHE_CHECK(whether $CXX supports C++$1 features by default, - ax_cv_cxx_compile_cxx$1, - [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], - [ax_cv_cxx_compile_cxx$1=yes], - [ax_cv_cxx_compile_cxx$1=no])]) - if test x$ax_cv_cxx_compile_cxx$1 = xyes; then - ac_success=yes - fi]) - m4_if([$2], [noext], [], [dnl if test x$ac_success = xno; then - for switch in -std=gnu++$1 -std=gnu++0x; do + for alternative in ${ax_cxx_compile_alternatives}; do + switch="-std=gnu++${alternative}" cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, $cachevar, @@ -102,22 +91,27 @@ AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl dnl HP's aCC needs +std=c++11 according to: dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf dnl Cray's crayCC needs "-h std=c++11" - for switch in -std=c++$1 -std=c++0x +std=c++$1 "-h std=c++$1"; do - cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) - AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, - $cachevar, - [ac_save_CXX="$CXX" - CXX="$CXX $switch" - AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], - [eval $cachevar=yes], - [eval $cachevar=no]) - CXX="$ac_save_CXX"]) - if eval test x\$$cachevar = xyes; then - CXX="$CXX $switch" - if test -n "$CXXCPP" ; then - CXXCPP="$CXXCPP $switch" + for alternative in ${ax_cxx_compile_alternatives}; do + for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, + $cachevar, + [ac_save_CXX="$CXX" + CXX="$CXX $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXX="$ac_save_CXX"]) + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break fi - ac_success=yes + done + if test x$ac_success = xyes; then break fi done @@ -154,6 +148,11 @@ m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 ) +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_17 +) dnl Tests for new features in C++11 @@ -191,11 +190,13 @@ namespace cxx11 struct Base { + virtual ~Base() {} virtual void f() {} }; struct Derived : public Base { + virtual ~Derived() override {} virtual void f() override {} }; @@ -524,7 +525,7 @@ namespace cxx14 } - namespace test_digit_seperators + namespace test_digit_separators { constexpr auto ten_million = 100'000'000; @@ -566,3 +567,385 @@ namespace cxx14 #endif // __cplusplus >= 201402L ]]) + + +dnl Tests for new features in C++17 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[ + +// If the compiler admits that it is not ready for C++17, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201703L + +#error "This is not a C++17 compiler" + +#else + +#include +#include +#include + +namespace cxx17 +{ + + namespace test_constexpr_lambdas + { + + constexpr int foo = [](){return 42;}(); + + } + + namespace test::nested_namespace::definitions + { + + } + + namespace test_fold_expression + { + + template + int multiply(Args... args) + { + return (args * ... * 1); + } + + template + bool all(Args... args) + { + return (args && ...); + } + + } + + namespace test_extended_static_assert + { + + static_assert (true); + + } + + namespace test_auto_brace_init_list + { + + auto foo = {5}; + auto bar {5}; + + static_assert(std::is_same, decltype(foo)>::value); + static_assert(std::is_same::value); + } + + namespace test_typename_in_template_template_parameter + { + + template typename X> struct D; + + } + + namespace test_fallthrough_nodiscard_maybe_unused_attributes + { + + int f1() + { + return 42; + } + + [[nodiscard]] int f2() + { + [[maybe_unused]] auto unused = f1(); + + switch (f1()) + { + case 17: + f1(); + [[fallthrough]]; + case 42: + f1(); + } + return f1(); + } + + } + + namespace test_extended_aggregate_initialization + { + + struct base1 + { + int b1, b2 = 42; + }; + + struct base2 + { + base2() { + b3 = 42; + } + int b3; + }; + + struct derived : base1, base2 + { + int d; + }; + + derived d1 {{1, 2}, {}, 4}; // full initialization + derived d2 {{}, {}, 4}; // value-initialized bases + + } + + namespace test_general_range_based_for_loop + { + + struct iter + { + int i; + + int& operator* () + { + return i; + } + + const int& operator* () const + { + return i; + } + + iter& operator++() + { + ++i; + return *this; + } + }; + + struct sentinel + { + int i; + }; + + bool operator== (const iter& i, const sentinel& s) + { + return i.i == s.i; + } + + bool operator!= (const iter& i, const sentinel& s) + { + return !(i == s); + } + + struct range + { + iter begin() const + { + return {0}; + } + + sentinel end() const + { + return {5}; + } + }; + + void f() + { + range r {}; + + for (auto i : r) + { + [[maybe_unused]] auto v = i; + } + } + + } + + namespace test_lambda_capture_asterisk_this_by_value + { + + struct t + { + int i; + int foo() + { + return [*this]() + { + return i; + }(); + } + }; + + } + + namespace test_enum_class_construction + { + + enum class byte : unsigned char + {}; + + byte foo {42}; + + } + + namespace test_constexpr_if + { + + template + int f () + { + if constexpr(cond) + { + return 13; + } + else + { + return 42; + } + } + + } + + namespace test_selection_statement_with_initializer + { + + int f() + { + return 13; + } + + int f2() + { + if (auto i = f(); i > 0) + { + return 3; + } + + switch (auto i = f(); i + 4) + { + case 17: + return 2; + + default: + return 1; + } + } + + } + + namespace test_template_argument_deduction_for_class_templates + { + + template + struct pair + { + pair (T1 p1, T2 p2) + : m1 {p1}, + m2 {p2} + {} + + T1 m1; + T2 m2; + }; + + void f() + { + [[maybe_unused]] auto p = pair{13, 42u}; + } + + } + + namespace test_non_type_auto_template_parameters + { + + template + struct B + {}; + + B<5> b1; + B<'a'> b2; + + } + + namespace test_structured_bindings + { + + int arr[2] = { 1, 2 }; + std::pair pr = { 1, 2 }; + + auto f1() -> int(&)[2] + { + return arr; + } + + auto f2() -> std::pair& + { + return pr; + } + + struct S + { + int x1 : 2; + volatile double y1; + }; + + S f3() + { + return {}; + } + + auto [ x1, y1 ] = f1(); + auto& [ xr1, yr1 ] = f1(); + auto [ x2, y2 ] = f2(); + auto& [ xr2, yr2 ] = f2(); + const auto [ x3, y3 ] = f3(); + + } + + namespace test_exception_spec_type_system + { + + struct Good {}; + struct Bad {}; + + void g1() noexcept; + void g2(); + + template + Bad + f(T*, T*); + + template + Good + f(T1*, T2*); + + static_assert (std::is_same_v); + + } + + namespace test_inline_variables + { + + template void f(T) + {} + + template inline T g(T) + { + return T{}; + } + + template<> inline void f<>(int) + {} + + template<> int g<>(int) + { + return 5; + } + + } + +} // namespace cxx17 + +#endif // __cplusplus < 201703L + +]]) diff --git a/build-aux/m4/bitcoin_find_bdb48.m4 b/build-aux/m4/bitcoin_find_bdb48.m4 index ea9c795daa..2dbf0ea099 100644 --- a/build-aux/m4/bitcoin_find_bdb48.m4 +++ b/build-aux/m4/bitcoin_find_bdb48.m4 @@ -74,5 +74,4 @@ AC_DEFUN([BITCOIN_FIND_BDB48],[ AC_MSG_ERROR([libdb_cxx missing, ]AC_PACKAGE_NAME[ requires this library for wallet functionality (--disable-wallet to disable wallet functionality)]) fi fi - AC_SUBST(BDB_LIBS) ]) diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index b1ebde2846..5cc6c78552 100644 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -64,6 +64,13 @@ AC_DEFUN([BITCOIN_QT_INIT],[ ], [bitcoin_qt_want_version=auto]) + AS_IF([test "x$with_gui" = xqt5_debug], + [AS_CASE([$host], + [*darwin*], [qt_lib_suffix=_debug], + [*mingw*], [qt_lib_suffix=d], + [qt_lib_suffix= ]); bitcoin_qt_want_version=qt5], + [qt_lib_suffix= ]) + AC_ARG_WITH([qt-incdir],[AS_HELP_STRING([--with-qt-incdir=INC_DIR],[specify qt include path (overridden by pkgconfig)])], [qt_include_path=$withval], []) AC_ARG_WITH([qt-libdir],[AS_HELP_STRING([--with-qt-libdir=LIB_DIR],[specify qt lib path (overridden by pkgconfig)])], [qt_lib_path=$withval], []) AC_ARG_WITH([qt-plugindir],[AS_HELP_STRING([--with-qt-plugindir=PLUGIN_DIR],[specify qt plugin path (overridden by pkgconfig)])], [qt_plugin_path=$withval], []) @@ -72,41 +79,38 @@ AC_DEFUN([BITCOIN_QT_INIT],[ AC_ARG_WITH([qtdbus], [AS_HELP_STRING([--with-qtdbus], - [enable DBus support (default is yes if qt is enabled and QtDBus is found)])], + [enable DBus support (default is yes if qt is enabled and QtDBus is found, except on Android)])], [use_dbus=$withval], [use_dbus=auto]) + dnl Android doesn't support D-Bus and certainly doesn't use it for notifications + case $host in + *android*) + if test "x$use_dbus" != xyes; then + use_dbus=no + fi + ;; + esac + AC_SUBST(QT_TRANSLATION_DIR,$qt_translation_path) ]) -dnl Find the appropriate version of Qt libraries and includes. -dnl Inputs: $1: Whether or not pkg-config should be used. yes|no. Default: yes. -dnl Inputs: $2: If $1 is "yes" and --with-gui=auto, which qt version should be -dnl tried first. -dnl Outputs: See _BITCOIN_QT_FIND_LIBS_* +dnl Find Qt libraries and includes. +dnl +dnl BITCOIN_QT_CONFIGURE([MINIMUM-VERSION]) +dnl +dnl Outputs: See _BITCOIN_QT_FIND_LIBS dnl Outputs: Sets variables for all qt-related tools. dnl Outputs: bitcoin_enable_qt, bitcoin_enable_qt_dbus, bitcoin_enable_qt_test AC_DEFUN([BITCOIN_QT_CONFIGURE],[ - use_pkgconfig=$1 - - if test "x$use_pkgconfig" = x; then - use_pkgconfig=yes - fi - - if test "x$use_pkgconfig" = xyes; then - BITCOIN_QT_CHECK([_BITCOIN_QT_FIND_LIBS_WITH_PKGCONFIG]) - else - BITCOIN_QT_CHECK([_BITCOIN_QT_FIND_LIBS_WITHOUT_PKGCONFIG]) - fi - - dnl This is ugly and complicated. Yuck. Works as follows: - dnl For Qt5, we can check a header to find out whether Qt is build - dnl statically. When Qt is built statically, some plugins must be linked into - dnl the final binary as well. - dnl With Qt5, languages moved into core and the WindowsIntegration plugin was - dnl added. - dnl _BITCOIN_QT_CHECK_STATIC_PLUGINS does a quick link-check and appends the - dnl results to QT_LIBS. + qt_version=">= $1" + qt_lib_prefix="Qt5" + BITCOIN_QT_CHECK([_BITCOIN_QT_FIND_LIBS]) + + dnl We check a header to find out whether Qt is built statically. + dnl When Qt is built statically, some plugins must be linked into + dnl the final binary as well. _BITCOIN_QT_CHECK_STATIC_PLUGIN does + dnl a quick link-check and appends the results to QT_LIBS. BITCOIN_QT_CHECK([ TEMP_CPPFLAGS=$CPPFLAGS TEMP_CXXFLAGS=$CXXFLAGS @@ -114,42 +118,50 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[ CXXFLAGS="$PIC_FLAGS $CXXFLAGS" _BITCOIN_QT_IS_STATIC if test "x$bitcoin_cv_static_qt" = xyes; then - _BITCOIN_QT_FIND_STATIC_PLUGINS - AC_DEFINE(QT_STATICPLUGIN, 1, [Define this symbol if qt plugins are static]) - AC_CACHE_CHECK(for Qt < 5.4, bitcoin_cv_need_acc_widget,[ - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - #include - #ifndef QT_VERSION - # include - #endif - ]], - [[ - #if QT_VERSION >= 0x050400 - choke - #endif - ]])], - [bitcoin_cv_need_acc_widget=yes], - [bitcoin_cv_need_acc_widget=no]) - ]) - if test "x$bitcoin_cv_need_acc_widget" = xyes; then - _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(AccessibleFactory)], [-lqtaccessiblewidgets]) + _BITCOIN_QT_CHECK_STATIC_LIBS + + if test "x$qt_plugin_path" != x; then + if test -d "$qt_plugin_path/platforms"; then + QT_LIBS="$QT_LIBS -L$qt_plugin_path/platforms" + fi + if test -d "$qt_plugin_path/styles"; then + QT_LIBS="$QT_LIBS -L$qt_plugin_path/styles" + fi + if test -d "$qt_plugin_path/accessible"; then + QT_LIBS="$QT_LIBS -L$qt_plugin_path/accessible" + fi + if test -d "$qt_plugin_path/platforms/android"; then + QT_LIBS="$QT_LIBS -L$qt_plugin_path/platforms/android -lqtfreetype -lEGL" + fi fi + + AC_DEFINE(QT_STATICPLUGIN, 1, [Define this symbol if qt plugins are static]) if test "x$TARGET_OS" != xandroid; then - _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(QMinimalIntegrationPlugin)],[-lqminimal]) - AC_DEFINE(QT_QPA_PLATFORM_MINIMAL, 1, [Define this symbol if the minimal qt platform exists]) + _BITCOIN_QT_CHECK_STATIC_PLUGIN([QMinimalIntegrationPlugin], [-lqminimal]) + AC_DEFINE(QT_QPA_PLATFORM_MINIMAL, 1, [Define this symbol if the minimal qt platform exists]) fi if test "x$TARGET_OS" = xwindows; then - _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin)],[-lqwindows]) + dnl Linking against wtsapi32 is required. See #17749 and + dnl https://bugreports.qt.io/browse/QTBUG-27097. + AX_CHECK_LINK_FLAG([-lwtsapi32], [QT_LIBS="$QT_LIBS -lwtsapi32"], [AC_MSG_ERROR([could not link against -lwtsapi32])]) + _BITCOIN_QT_CHECK_STATIC_PLUGIN([QWindowsIntegrationPlugin], [-lqwindows]) + _BITCOIN_QT_CHECK_STATIC_PLUGIN([QWindowsVistaStylePlugin], [-lqwindowsvistastyle]) AC_DEFINE(QT_QPA_PLATFORM_WINDOWS, 1, [Define this symbol if the qt platform is windows]) elif test "x$TARGET_OS" = xlinux; then - _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(QXcbIntegrationPlugin)],[-lqxcb -lxcb-static]) + dnl workaround for https://bugreports.qt.io/browse/QTBUG-74874 + AX_CHECK_LINK_FLAG([-lxcb-shm], [QT_LIBS="$QT_LIBS -lxcb-shm"], [AC_MSG_ERROR([could not link against -lxcb-shm])]) + _BITCOIN_QT_CHECK_STATIC_PLUGIN([QXcbIntegrationPlugin], [-lqxcb]) AC_DEFINE(QT_QPA_PLATFORM_XCB, 1, [Define this symbol if the qt platform is xcb]) elif test "x$TARGET_OS" = xdarwin; then - AX_CHECK_LINK_FLAG([[-framework IOKit]],[QT_LIBS="$QT_LIBS -framework IOKit"],[AC_MSG_ERROR(could not iokit framework)]) - _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin)],[-lqcocoa]) + AX_CHECK_LINK_FLAG([[-framework Carbon]],[QT_LIBS="$QT_LIBS -framework Carbon"],[AC_MSG_ERROR(could not link against Carbon framework)]) + AX_CHECK_LINK_FLAG([[-framework IOSurface]],[QT_LIBS="$QT_LIBS -framework IOSurface"],[AC_MSG_ERROR(could not link against IOSurface framework)]) + AX_CHECK_LINK_FLAG([[-framework Metal]],[QT_LIBS="$QT_LIBS -framework Metal"],[AC_MSG_ERROR(could not link against Metal framework)]) + AX_CHECK_LINK_FLAG([[-framework QuartzCore]],[QT_LIBS="$QT_LIBS -framework QuartzCore"],[AC_MSG_ERROR(could not link against QuartzCore framework)]) + _BITCOIN_QT_CHECK_STATIC_PLUGIN([QCocoaIntegrationPlugin], [-lqcocoa]) + _BITCOIN_QT_CHECK_STATIC_PLUGIN([QMacStylePlugin], [-lqmacstyle]) AC_DEFINE(QT_QPA_PLATFORM_COCOA, 1, [Define this symbol if the qt platform is cocoa]) elif test "x$TARGET_OS" = xandroid; then - QT_LIBS="-Wl,--export-dynamic,--undefined=JNI_OnLoad -lqtforandroid -ljnigraphics -landroid -lqtfreetype -lQt5EglSupport $QT_LIBS" + QT_LIBS="-Wl,--export-dynamic,--undefined=JNI_OnLoad -lqtforandroid -ljnigraphics -landroid -lqtfreetype $QT_LIBS" AC_DEFINE(QT_QPA_PLATFORM_ANDROID, 1, [Define this symbol if the qt platform is android]) fi fi @@ -157,8 +169,8 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[ CXXFLAGS=$TEMP_CXXFLAGS ]) - if test "x$use_pkgconfig$qt_bin_path" = xyes; then - qt_bin_path="`$PKG_CONFIG --variable=host_bins Qt5Core 2>/dev/null`" + if test "x$qt_bin_path" = x; then + qt_bin_path="`$PKG_CONFIG --variable=host_bins ${qt_lib_prefix}Core 2>/dev/null`" fi if test "x$use_hardening" != xno; then @@ -213,13 +225,14 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[ BITCOIN_QT_PATH_PROGS([RCC], [rcc-qt5 rcc5 rcc], $qt_bin_path) BITCOIN_QT_PATH_PROGS([LRELEASE], [lrelease-qt5 lrelease5 lrelease], $qt_bin_path) BITCOIN_QT_PATH_PROGS([LUPDATE], [lupdate-qt5 lupdate5 lupdate],$qt_bin_path, yes) + BITCOIN_QT_PATH_PROGS([LCONVERT], [lconvert-qt5 lconvert5 lconvert], $qt_bin_path, yes) MOC_DEFS='-DHAVE_CONFIG_H -I$(srcdir)' case $host in *darwin*) BITCOIN_QT_CHECK([ MOC_DEFS="${MOC_DEFS} -DQ_OS_MAC" - base_frameworks="-framework Foundation -framework ApplicationServices -framework AppKit" + base_frameworks="-framework Foundation -framework AppKit" AX_CHECK_LINK_FLAG([[$base_frameworks]],[QT_LIBS="$QT_LIBS $base_frameworks"],[AC_MSG_ERROR(could not find base frameworks)]) ]) ;; @@ -231,7 +244,7 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[ dnl enable qt support - AC_MSG_CHECKING(whether to build ]AC_PACKAGE_NAME[ GUI) + AC_MSG_CHECKING([whether to build ]AC_PACKAGE_NAME[ GUI]) BITCOIN_QT_CHECK([ bitcoin_enable_qt=yes bitcoin_enable_qt_test=yes @@ -246,80 +259,44 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[ AC_MSG_ERROR([libQtDBus not found. Install libQtDBus or remove --with-qtdbus.]) fi if test "x$LUPDATE" = x; then - AC_MSG_WARN([lupdate is required to update qt translations]) + AC_MSG_WARN([lupdate tool is required to update Qt translations.]) + fi + if test "x$LCONVERT" = x; then + AC_MSG_WARN([lconvert tool is required to update Qt translations.]) fi ],[ bitcoin_enable_qt=no ]) - AC_MSG_RESULT([$bitcoin_enable_qt (Qt5)]) + if test x$bitcoin_enable_qt = xyes; then + AC_MSG_RESULT([$bitcoin_enable_qt ($qt_lib_prefix)]) + else + AC_MSG_RESULT([$bitcoin_enable_qt]) + fi AC_SUBST(QT_PIE_FLAGS) AC_SUBST(QT_INCLUDES) AC_SUBST(QT_LIBS) AC_SUBST(QT_LDFLAGS) AC_SUBST(QT_DBUS_INCLUDES) - AC_SUBST(QT_DBUS_LIBS) AC_SUBST(QT_TEST_INCLUDES) - AC_SUBST(QT_TEST_LIBS) AC_SUBST(QT_SELECT, qt5) AC_SUBST(MOC_DEFS) ]) -dnl All macros below are internal and should _not_ be used from the main -dnl configure.ac. -dnl ---- +dnl All macros below are internal and should _not_ be used from configure.ac. -dnl Internal. Check if the included version of Qt is Qt5. -dnl Requires: INCLUDES must be populated as necessary. -dnl Output: bitcoin_cv_qt5=yes|no -AC_DEFUN([_BITCOIN_QT_CHECK_QT5],[ - AC_CACHE_CHECK(for Qt 5, bitcoin_cv_qt5,[ - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - #include - #ifndef QT_VERSION - # include - #endif - ]], - [[ - #if QT_VERSION < 0x050000 || QT_VERSION_MAJOR < 5 - choke - #endif - ]])], - [bitcoin_cv_qt5=yes], - [bitcoin_cv_qt5=no]) -])]) - -dnl Internal. Check if the included version of Qt is greater than Qt58. -dnl Requires: INCLUDES must be populated as necessary. -dnl Output: bitcoin_cv_qt5=yes|no -AC_DEFUN([_BITCOIN_QT_CHECK_QT58],[ - AC_CACHE_CHECK(for > Qt 5.7, bitcoin_cv_qt58,[ - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - #include - #ifndef QT_VERSION - # include - #endif - ]], - [[ - #if QT_VERSION_MINOR < 8 - choke - #endif - ]])], - [bitcoin_cv_qt58=yes], - [bitcoin_cv_qt58=no]) -])]) - - -dnl Internal. Check if the linked version of Qt was built as static libs. -dnl Requires: Qt5. +dnl Internal. Check if the linked version of Qt was built statically. +dnl +dnl _BITCOIN_QT_IS_STATIC +dnl --------------------- +dnl dnl Requires: INCLUDES and LIBS must be populated as necessary. dnl Output: bitcoin_cv_static_qt=yes|no -dnl Output: Defines QT_STATICPLUGIN if plugins are static. AC_DEFUN([_BITCOIN_QT_IS_STATIC],[ AC_CACHE_CHECK(for static Qt, bitcoin_cv_static_qt,[ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include - #ifndef QT_VERSION OR QT_VERSION_STR + #ifndef QT_VERSION # include #endif ]], @@ -331,208 +308,92 @@ AC_DEFUN([_BITCOIN_QT_IS_STATIC],[ [bitcoin_cv_static_qt=yes], [bitcoin_cv_static_qt=no]) ]) - if test "x$bitcoin_cv_static_qt" = xyes; then - AC_DEFINE(QT_STATICPLUGIN, 1, [Define this symbol for static Qt plugins]) - fi ]) -dnl Internal. Check if the link-requirements for static plugins are met. +dnl Internal. Check if the link-requirements for a static plugin are met. +dnl +dnl _BITCOIN_QT_CHECK_STATIC_PLUGIN(PLUGIN, LIBRARIES) +dnl -------------------------------------------------- +dnl dnl Requires: INCLUDES and LIBS must be populated as necessary. -dnl Inputs: $1: A series of Q_IMPORT_PLUGIN(). +dnl Inputs: $1: A static plugin name. dnl Inputs: $2: The libraries that resolve $1. dnl Output: QT_LIBS is prepended or configure exits. -AC_DEFUN([_BITCOIN_QT_CHECK_STATIC_PLUGINS],[ - AC_MSG_CHECKING(for static Qt plugins: $2) +AC_DEFUN([_BITCOIN_QT_CHECK_STATIC_PLUGIN], [ + AC_MSG_CHECKING([for $1 ($2)]) CHECK_STATIC_PLUGINS_TEMP_LIBS="$LIBS" - LIBS="$2 $QT_LIBS $LIBS" + LIBS="$2${qt_lib_suffix} $QT_LIBS $LIBS" AC_LINK_IFELSE([AC_LANG_PROGRAM([[ - #define QT_STATICPLUGIN - #include - $1]], - [[return 0;]])], - [AC_MSG_RESULT(yes); QT_LIBS="$2 $QT_LIBS"], - [AC_MSG_RESULT(no); BITCOIN_QT_FAIL(Could not resolve: $2)]) + #include + Q_IMPORT_PLUGIN($1) + ]])], + [AC_MSG_RESULT([yes]); QT_LIBS="$2${qt_lib_suffix} $QT_LIBS"], + [AC_MSG_RESULT([no]); BITCOIN_QT_FAIL([$1 not found.])]) LIBS="$CHECK_STATIC_PLUGINS_TEMP_LIBS" ]) -dnl Internal. Find paths necessary for linking qt static plugins -dnl Inputs: qt_plugin_path. optional. -dnl Outputs: QT_LIBS is appended -AC_DEFUN([_BITCOIN_QT_FIND_STATIC_PLUGINS],[ - if test "x$qt_plugin_path" != x; then - QT_LIBS="$QT_LIBS -L$qt_plugin_path/platforms" - if test -d "$qt_plugin_path/accessible"; then - QT_LIBS="$QT_LIBS -L$qt_plugin_path/accessible" - fi - if test -d "$qt_plugin_path/platforms/android"; then - QT_LIBS="$QT_LIBS -L$qt_plugin_path/platforms/android -lqtfreetype -lEGL" - fi - if test "x$use_pkgconfig" = xyes; then - : dnl - m4_ifdef([PKG_CHECK_MODULES],[ - if test x$bitcoin_cv_qt58 = xno; then - PKG_CHECK_MODULES([QTPLATFORM], [Qt5PlatformSupport], [QT_LIBS="$QTPLATFORM_LIBS $QT_LIBS"]) - else - PKG_CHECK_MODULES([QTFONTDATABASE], [Qt5FontDatabaseSupport], [QT_LIBS="-lQt5FontDatabaseSupport $QT_LIBS"]) - PKG_CHECK_MODULES([QTEVENTDISPATCHER], [Qt5EventDispatcherSupport], [QT_LIBS="-lQt5EventDispatcherSupport $QT_LIBS"]) - PKG_CHECK_MODULES([QTTHEME], [Qt5ThemeSupport], [QT_LIBS="-lQt5ThemeSupport $QT_LIBS"]) - PKG_CHECK_MODULES([QTDEVICEDISCOVERY], [Qt5DeviceDiscoverySupport], [QT_LIBS="-lQt5DeviceDiscoverySupport $QT_LIBS"]) - PKG_CHECK_MODULES([QTACCESSIBILITY], [Qt5AccessibilitySupport], [QT_LIBS="-lQt5AccessibilitySupport $QT_LIBS"]) - PKG_CHECK_MODULES([QTFB], [Qt5FbSupport], [QT_LIBS="-lQt5FbSupport $QT_LIBS"]) - fi - if test "x$TARGET_OS" = xlinux; then - if ${PKG_CONFIG} --exists "Qt5Core >= 5.5" 2>/dev/null; then - PKG_CHECK_MODULES([QTXCBQPA], [Qt5XcbQpa], [QT_LIBS="$QTXCBQPA_LIBS $QT_LIBS"]) - fi - elif test "x$TARGET_OS" = xdarwin; then - PKG_CHECK_MODULES([QTCLIPBOARD], [Qt5ClipboardSupport], [QT_LIBS="-lQt5ClipboardSupport $QT_LIBS"]) - PKG_CHECK_MODULES([QTGRAPHICS], [Qt5GraphicsSupport], [QT_LIBS="-lQt5GraphicsSupport $QT_LIBS"]) - PKG_CHECK_MODULES([QTCGL], [Qt5CglSupport], [QT_LIBS="-lQt5CglSupport $QT_LIBS"]) - fi - ]) - else - if test "x$TARGET_OS" = xwindows; then - AC_CACHE_CHECK(for Qt >= 5.6, bitcoin_cv_need_platformsupport,[ - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - #include - #ifndef QT_VERSION - # include - #endif - ]], - [[ - #if QT_VERSION < 0x050600 || QT_VERSION_MINOR < 6 - choke - #endif - ]])], - [bitcoin_cv_need_platformsupport=yes], - [bitcoin_cv_need_platformsupport=no]) - ]) - if test "x$bitcoin_cv_need_platformsupport" = xyes; then - if test x$bitcoin_cv_qt58 = xno; then - BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}PlatformSupport],[main],,BITCOIN_QT_FAIL(lib$QT_LIB_PREFIXPlatformSupport not found))) - else - BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}FontDatabaseSupport],[main],,BITCOIN_QT_FAIL(lib$QT_LIB_PREFIXFontDatabaseSupport not found))) - BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}EventDispatcherSupport],[main],,BITCOIN_QT_FAIL(lib$QT_LIB_PREFIXEventDispatcherSupport not found))) - BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}ThemeSupport],[main],,BITCOIN_QT_FAIL(lib$QT_LIB_PREFIXThemeSupport not found))) - BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}FbSupport],[main],,BITCOIN_QT_FAIL(lib$QT_LIB_PREFIXFbSupport not found))) - BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}DeviceDiscoverySupport],[main],,BITCOIN_QT_FAIL(lib$QT_LIB_PREFIXDeviceDiscoverySupport not found))) - BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}AccessibilitySupport],[main],,BITCOIN_QT_FAIL(lib$QT_LIB_PREFIXAccessibilitySupport not found))) - QT_LIBS="$QT_LIBS -lversion -ldwmapi -luxtheme" - fi - fi - fi - fi - fi +dnl Internal. Check Qt static libs with PKG_CHECK_MODULES. +dnl +dnl _BITCOIN_QT_CHECK_STATIC_LIBS +dnl ----------------------------- +dnl +dnl Outputs: QT_LIBS is prepended. +AC_DEFUN([_BITCOIN_QT_CHECK_STATIC_LIBS], [ + PKG_CHECK_MODULES([QT_ACCESSIBILITY], [${qt_lib_prefix}AccessibilitySupport${qt_lib_suffix}], [QT_LIBS="$QT_ACCESSIBILITY_LIBS $QT_LIBS"]) + PKG_CHECK_MODULES([QT_DEVICEDISCOVERY], [${qt_lib_prefix}DeviceDiscoverySupport${qt_lib_suffix}], [QT_LIBS="$QT_DEVICEDISCOVERY_LIBS $QT_LIBS"]) + PKG_CHECK_MODULES([QT_EDID], [${qt_lib_prefix}EdidSupport${qt_lib_suffix}], [QT_LIBS="$QT_EDID_LIBS $QT_LIBS"]) + PKG_CHECK_MODULES([QT_EVENTDISPATCHER], [${qt_lib_prefix}EventDispatcherSupport${qt_lib_suffix}], [QT_LIBS="$QT_EVENTDISPATCHER_LIBS $QT_LIBS"]) + PKG_CHECK_MODULES([QT_FB], [${qt_lib_prefix}FbSupport${qt_lib_suffix}], [QT_LIBS="$QT_FB_LIBS $QT_LIBS"]) + PKG_CHECK_MODULES([QT_FONTDATABASE], [${qt_lib_prefix}FontDatabaseSupport${qt_lib_suffix}], [QT_LIBS="$QT_FONTDATABASE_LIBS $QT_LIBS"]) + PKG_CHECK_MODULES([QT_THEME], [${qt_lib_prefix}ThemeSupport${qt_lib_suffix}], [QT_LIBS="$QT_THEME_LIBS $QT_LIBS"]) + if test "x$TARGET_OS" = xlinux; then + PKG_CHECK_MODULES([QT_INPUT], [${qt_lib_prefix}InputSupport], [QT_LIBS="$QT_INPUT_LIBS $QT_LIBS"]) + PKG_CHECK_MODULES([QT_SERVICE], [${qt_lib_prefix}ServiceSupport], [QT_LIBS="$QT_SERVICE_LIBS $QT_LIBS"]) + PKG_CHECK_MODULES([QT_XCBQPA], [${qt_lib_prefix}XcbQpa], [QT_LIBS="$QT_XCBQPA_LIBS $QT_LIBS"]) + elif test "x$TARGET_OS" = xdarwin; then + PKG_CHECK_MODULES([QT_CLIPBOARD], [${qt_lib_prefix}ClipboardSupport${qt_lib_suffix}], [QT_LIBS="$QT_CLIPBOARD_LIBS $QT_LIBS"]) + PKG_CHECK_MODULES([QT_GRAPHICS], [${qt_lib_prefix}GraphicsSupport${qt_lib_suffix}], [QT_LIBS="$QT_GRAPHICS_LIBS $QT_LIBS"]) + PKG_CHECK_MODULES([QT_SERVICE], [${qt_lib_prefix}ServiceSupport${qt_lib_suffix}], [QT_LIBS="$QT_SERVICE_LIBS $QT_LIBS"]) + elif test "x$TARGET_OS" = xwindows; then + PKG_CHECK_MODULES([QT_WINDOWSUIAUTOMATION], [${qt_lib_prefix}WindowsUIAutomationSupport${qt_lib_suffix}], [QT_LIBS="$QT_WINDOWSUIAUTOMATION_LIBS $QT_LIBS"]) + elif test "x$TARGET_OS" = xandroid; then + PKG_CHECK_MODULES([QT_EGL], [${qt_lib_prefix}EglSupport], [QT_LIBS="$QT_EGL_LIBS $QT_LIBS"]) + fi ]) dnl Internal. Find Qt libraries using pkg-config. -dnl Inputs: bitcoin_qt_want_version (from --with-gui=). The version to check -dnl first. -dnl Inputs: $1: If bitcoin_qt_want_version is "auto", check for this version -dnl first. +dnl +dnl _BITCOIN_QT_FIND_LIBS +dnl --------------------- +dnl dnl Outputs: All necessary QT_* variables are set. dnl Outputs: have_qt_test and have_qt_dbus are set (if applicable) to yes|no. -AC_DEFUN([_BITCOIN_QT_FIND_LIBS_WITH_PKGCONFIG],[ - m4_ifdef([PKG_CHECK_MODULES],[ - QT_LIB_PREFIX=Qt5 - qt5_modules="Qt5Core Qt5Gui Qt5Network Qt5Widgets Qt5Concurrent" - BITCOIN_QT_CHECK([ - PKG_CHECK_MODULES([QT5], [$qt5_modules], [QT_INCLUDES="$QT5_CFLAGS"; QT_LIBS="$QT5_LIBS" have_qt=yes],[have_qt=no]) - - if test "x$have_qt" != xyes; then - have_qt=no - BITCOIN_QT_FAIL([Qt dependencies not found]) - fi - ]) - BITCOIN_QT_CHECK([ - PKG_CHECK_MODULES([QT_TEST], [${QT_LIB_PREFIX}Test], [QT_TEST_INCLUDES="$QT_TEST_CFLAGS"; have_qt_test=yes], [have_qt_test=no]) - if test "x$use_dbus" != xno; then - PKG_CHECK_MODULES([QT_DBUS], [${QT_LIB_PREFIX}DBus], [QT_DBUS_INCLUDES="$QT_DBUS_CFLAGS"; have_qt_dbus=yes], [have_qt_dbus=no]) - fi - ]) +AC_DEFUN([_BITCOIN_QT_FIND_LIBS],[ + BITCOIN_QT_CHECK([ + PKG_CHECK_MODULES([QT_CORE], [${qt_lib_prefix}Core${qt_lib_suffix} $qt_version], [QT_INCLUDES="$QT_CORE_CFLAGS $QT_INCLUDES" QT_LIBS="$QT_CORE_LIBS $QT_LIBS"], + [BITCOIN_QT_FAIL([${qt_lib_prefix}Core${qt_lib_suffix} $qt_version not found])]) ]) - true; dnl -]) - -dnl Internal. Find Qt libraries without using pkg-config. Version is deduced -dnl from the discovered headers. -dnl Inputs: bitcoin_qt_want_version (from --with-gui=). The version to use. -dnl If "auto", the version will be discovered by _BITCOIN_QT_CHECK_QT5. -dnl Outputs: All necessary QT_* variables are set. -dnl Outputs: have_qt_test and have_qt_dbus are set (if applicable) to yes|no. -AC_DEFUN([_BITCOIN_QT_FIND_LIBS_WITHOUT_PKGCONFIG],[ - TEMP_CPPFLAGS="$CPPFLAGS" - TEMP_CXXFLAGS="$CXXFLAGS" - CXXFLAGS="$PIC_FLAGS $CXXFLAGS" - TEMP_LIBS="$LIBS" BITCOIN_QT_CHECK([ - if test "x$qt_include_path" != x; then - QT_INCLUDES="-I$qt_include_path -I$qt_include_path/QtCore -I$qt_include_path/QtGui -I$qt_include_path/QtWidgets -I$qt_include_path/QtNetwork -I$qt_include_path/QtTest -I$qt_include_path/QtDBus -I$qt_include_path/QtConcurrent" - CPPFLAGS="$QT_INCLUDES $CPPFLAGS" - fi + PKG_CHECK_MODULES([QT_GUI], [${qt_lib_prefix}Gui${qt_lib_suffix} $qt_version], [QT_INCLUDES="$QT_GUI_CFLAGS $QT_INCLUDES" QT_LIBS="$QT_GUI_LIBS $QT_LIBS"], + [BITCOIN_QT_FAIL([${qt_lib_prefix}Gui${qt_lib_suffix} $qt_version not found])]) ]) - - BITCOIN_QT_CHECK([AC_CHECK_HEADER([QtPlugin],,BITCOIN_QT_FAIL(QtCore headers missing))]) - BITCOIN_QT_CHECK([AC_CHECK_HEADER([QApplication],, BITCOIN_QT_FAIL(QtGui headers missing))]) - BITCOIN_QT_CHECK([AC_CHECK_HEADER([QLocalSocket],, BITCOIN_QT_FAIL(QtNetwork headers missing))]) - BITCOIN_QT_CHECK([AC_CHECK_HEADER([QtConcurrent],, BITCOIN_QT_FAIL(QtConcurrent headers missing))]) - BITCOIN_QT_CHECK([ - if test "x$bitcoin_qt_want_version" = xauto; then - _BITCOIN_QT_CHECK_QT5 - _BITCOIN_QT_CHECK_QT58 - fi - QT_LIB_PREFIX=Qt5 + PKG_CHECK_MODULES([QT_WIDGETS], [${qt_lib_prefix}Widgets${qt_lib_suffix} $qt_version], [QT_INCLUDES="$QT_WIDGETS_CFLAGS $QT_INCLUDES" QT_LIBS="$QT_WIDGETS_LIBS $QT_LIBS"], + [BITCOIN_QT_FAIL([${qt_lib_prefix}Widgets${qt_lib_suffix} $qt_version not found])]) ]) - BITCOIN_QT_CHECK([ - LIBS= - if test "x$qt_lib_path" != x; then - LIBS="$LIBS -L$qt_lib_path" - fi - - if test "x$TARGET_OS" = xwindows; then - AC_CHECK_LIB([imm32], [main],, BITCOIN_QT_FAIL(libimm32 not found)) - fi + PKG_CHECK_MODULES([QT_NETWORK], [${qt_lib_prefix}Network${qt_lib_suffix} $qt_version], [QT_INCLUDES="$QT_NETWORK_CFLAGS $QT_INCLUDES" QT_LIBS="$QT_NETWORK_LIBS $QT_LIBS"], + [BITCOIN_QT_FAIL([${qt_lib_prefix}Network${qt_lib_suffix} $qt_version not found])]) + ]) + BITCOIN_QT_CHECK([ + PKG_CHECK_MODULES([QT_CONCURRENT], [${qt_lib_prefix}Concurrent${qt_lib_suffix} $qt_version], [QT_INCLUDES="$QT_CONCURRENT_CFLAGS $QT_INCLUDES" QT_LIBS="$QT_CONCURRENT_LIBS $QT_LIBS"], + [BITCOIN_QT_FAIL([${qt_lib_prefix}Concurrent${qt_lib_suffix} $qt_version not found])]) ]) - - BITCOIN_QT_CHECK(AC_CHECK_LIB([z] ,[main],,AC_MSG_WARN([zlib not found. Assuming qt has it built-in]))) - if test x$bitcoin_cv_qt58 = xno; then - BITCOIN_QT_CHECK(AC_SEARCH_LIBS([png_error] ,[qtpng png],,AC_MSG_WARN([libpng not found. Assuming qt has it built-in]))) - BITCOIN_QT_CHECK(AC_SEARCH_LIBS([pcre16_exec], [qtpcre pcre16],,AC_MSG_WARN([libpcre16 not found. Assuming qt has it built-in]))) - else - BITCOIN_QT_CHECK(AC_SEARCH_LIBS([png_error] ,[qtlibpng png],,AC_MSG_WARN([libpng not found. Assuming qt has it built-in]))) - BITCOIN_QT_CHECK(AC_SEARCH_LIBS([pcre2_match_16], [qtpcre2 libqtpcre2],,AC_MSG_WARN([libqtpcre2 not found. Assuming qt has it built-in]))) - fi - BITCOIN_QT_CHECK(AC_SEARCH_LIBS([hb_ot_tags_from_script] ,[qtharfbuzzng qtharfbuzz harfbuzz],,AC_MSG_WARN([libharfbuzz not found. Assuming qt has it built-in or support is disabled]))) - BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}Core] ,[main],,BITCOIN_QT_FAIL(lib${QT_LIB_PREFIX}Core not found))) - BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}Gui] ,[main],,BITCOIN_QT_FAIL(lib${QT_LIB_PREFIX}Gui not found))) - BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}Network],[main],,BITCOIN_QT_FAIL(lib${QT_LIB_PREFIX}Network not found))) - BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}Widgets],[main],,BITCOIN_QT_FAIL(lib${QT_LIB_PREFIX}Widgets not found))) - BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}Concurrent],[main],,BITCOIN_QT_FAIL(lib${QT_LIB_PREFIX}Concurrent not found))) - QT_LIBS="$LIBS" - LIBS="$TEMP_LIBS" BITCOIN_QT_CHECK([ - LIBS= - if test "x$qt_lib_path" != x; then - LIBS="-L$qt_lib_path" - fi - AC_CHECK_LIB([${QT_LIB_PREFIX}Test], [main],, have_qt_test=no) - AC_CHECK_HEADER([QTest],, have_qt_test=no) - QT_TEST_LIBS="$LIBS" + PKG_CHECK_MODULES([QT_TEST], [${qt_lib_prefix}Test${qt_lib_suffix} $qt_version], [QT_TEST_INCLUDES="$QT_TEST_CFLAGS"; have_qt_test=yes], [have_qt_test=no]) if test "x$use_dbus" != xno; then - LIBS= - if test "x$qt_lib_path" != x; then - LIBS="-L$qt_lib_path" - fi - AC_CHECK_LIB([${QT_LIB_PREFIX}DBus], [main],, have_qt_dbus=no) - AC_CHECK_HEADER([QtDBus],, have_qt_dbus=no) - QT_DBUS_LIBS="$LIBS" + PKG_CHECK_MODULES([QT_DBUS], [${qt_lib_prefix}DBus $qt_version], [QT_DBUS_INCLUDES="$QT_DBUS_CFLAGS"; have_qt_dbus=yes], [have_qt_dbus=no]) fi ]) - CPPFLAGS="$TEMP_CPPFLAGS" - CXXFLAGS="$TEMP_CXXFLAGS" - LIBS="$TEMP_LIBS" ]) - diff --git a/configure.ac b/configure.ac index c073b22348..fdd5819b98 100644 --- a/configure.ac +++ b/configure.ac @@ -6,13 +6,19 @@ define(_CLIENT_VERSION_REVISION, 0) define(_CLIENT_VERSION_BUILD, 6) define(_CLIENT_VERSION_RC, 0) define(_CLIENT_VERSION_IS_RELEASE, true) -define(_COPYRIGHT_YEAR, 2023) +define(_COPYRIGHT_YEAR, 2024) AC_INIT([PRCYcoin],m4_join([.], _CLIENT_VERSION_MAJOR, _CLIENT_VERSION_MINOR, _CLIENT_VERSION_REVISION, m4_if(_CLIENT_VERSION_BUILD, [0], [], _CLIENT_VERSION_BUILD))m4_if(_CLIENT_VERSION_RC, [0], [], [rc]_CLIENT_VERSION_RC),[https://github.com/PRCYCoin/PRCYCoin/issues],[prcycoin],[https://www.prcycoin.com]) AC_CONFIG_SRCDIR([src/main.cpp]) AC_CONFIG_HEADERS([src/config/prcycoin-config.h]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_MACRO_DIR([build-aux/m4]) +m4_ifndef([PKG_PROG_PKG_CONFIG], [m4_fatal([PKG_PROG_PKG_CONFIG macro not found. Please install pkg-config and re-run autogen.sh])]) +PKG_PROG_PKG_CONFIG +if test "x$PKG_CONFIG" = x; then + AC_MSG_ERROR([pkg-config not found]) +fi + BITCOIN_DAEMON_NAME=prcycoind BITCOIN_GUI_NAME=prcycoin-qt BITCOIN_CLI_NAME=prcycoin-cli @@ -34,14 +40,14 @@ dnl faketime breaks configure and is only needed for make. Disable it here. unset FAKETIME dnl Automake init set-up and checks -AM_INIT_AUTOMAKE([no-define subdir-objects foreign]) +AM_INIT_AUTOMAKE([1.13 no-define subdir-objects foreign]) dnl faketime messes with timestamps and causes configure to be re-run. dnl --disable-maintainer-mode can be used to bypass this. AM_MAINTAINER_MODE([enable]) dnl make the compilation flags quiet unless V=1 is used -m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) +AM_SILENT_RULES([yes]) dnl Compiler checks (here before libtool). if test "x${CXXFLAGS+set}" = "xset"; then @@ -60,6 +66,9 @@ case $host in ;; esac +dnl Require C++17 compiler (no GNU extensions) +AX_CXX_COMPILE_STDCXX([17], [noext], [mandatory]) + dnl Check if -latomic is required for CHECK_ATOMIC @@ -77,12 +86,10 @@ LT_INIT([pic-only]) dnl Check/return PATH for base programs. AC_PATH_TOOL(AR, ar) -AC_PATH_TOOL(RANLIB, ranlib) -AC_PATH_TOOL(STRIP, strip) AC_PATH_TOOL(GCOV, gcov) AC_PATH_PROG(LCOV, lcov) -dnl Python 3.x is supported from 3.4 on (see https://github.com/bitcoin/bitcoin/issues/7893) -AC_PATH_PROGS([PYTHON], [python3.7 python3.6 python3.5 python3.4 python3 python]) +dnl Python 3.6 is specified in .python-version and should be used if available, see doc/dependencies.md +AC_PATH_PROGS([PYTHON], [python3.6 python3.7 python3.8 python3.9 python3 python]) AC_PATH_PROG(GENHTML, genhtml) AC_PATH_PROG([GIT], [git]) AC_PATH_PROG(CCACHE,ccache) @@ -208,8 +215,6 @@ AC_ARG_ENABLE([zmq], [use_zmq=$enableval], [use_zmq=yes]) -AC_ARG_WITH([protoc-bindir],[AS_HELP_STRING([--with-protoc-bindir=BIN_DIR],[specify protoc bin path])], [protoc_bin_path=$withval], []) - AC_ARG_ENABLE(man, [AS_HELP_STRING([--disable-man], [do not install man pages (default is to install)])],, @@ -243,6 +248,11 @@ AC_ARG_ENABLE([werror], [enable_werror=$enableval], [enable_werror=no]) +AC_ARG_ENABLE([lto], + [AS_HELP_STRING([--enable-lto],[build using LTO (default is no)])], + [enable_lto=$enableval], + [enable_lto=no]) + AC_LANG_PUSH([C++]) AX_CHECK_COMPILE_FLAG([-Werror],[CXXFLAG_WERROR="-Werror"],[CXXFLAG_WERROR=""]) @@ -270,6 +280,11 @@ if test "x$enable_debug" = xyes; then AX_CHECK_COMPILE_FLAG([-ftrapv],[DEBUG_CXXFLAGS="$DEBUG_CXXFLAGS -ftrapv"],,[[$CXXFLAG_WERROR]]) fi +if test "x$enable_lto" = "xyes"; then + AX_CHECK_COMPILE_FLAG([-flto], [LTO_CXXFLAGS="$LTO_CXXFLAGS -flto"], [AC_MSG_ERROR([compile failed with -flto])], [$CXXFLAG_WERROR]) + AX_CHECK_LINK_FLAG([-flto], [LTO_LDFLAGS="$LTO_LDFLAGS -flto"], [AC_MSG_ERROR([link failed with -flto])], [$CXXFLAG_WERROR]) +fi + if test x$use_sanitizers != x; then # First check if the compiler accepts flags. If an incompatible pair like # -fsanitize=address,thread is used here, this check will fail. This will also @@ -317,6 +332,7 @@ if test "x$CXXFLAGS_overridden" = "xno"; then AX_CHECK_COMPILE_FLAG([-Wunused-local-typedef],[NOWARN_CXXFLAGS="$NOWARN_CXXFLAGS -Wno-unused-local-typedef"],,[[$CXXFLAG_WERROR]]) AX_CHECK_COMPILE_FLAG([-Wdeprecated-register],[NOWARN_CXXFLAGS="$NOWARN_CXXFLAGS -Wno-deprecated-register"],,[[$CXXFLAG_WERROR]]) AX_CHECK_COMPILE_FLAG([-Wimplicit-fallthrough],[NOWARN_CXXFLAGS="$NOWARN_CXXFLAGS -Wno-implicit-fallthrough"],,[[$CXXFLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wdeprecated-copy],[NOWARN_CXXFLAGS="$NOWARN_CXXFLAGS -Wno-deprecated-copy"],,[[$CXXFLAG_WERROR]]) fi enable_sse42=no @@ -445,33 +461,23 @@ AC_ARG_WITH([daemon], [build_bitcoind=$withval], [build_bitcoind=yes]) -use_pkgconfig=yes case $host in *mingw*) - - #pkgconfig does more harm than good with MinGW - use_pkgconfig=no - TARGET_OS=windows - AC_CHECK_LIB([mingwthrd], [main],, AC_MSG_ERROR(libmingwthrd missing)) - AC_CHECK_LIB([kernel32], [main],, AC_MSG_ERROR(libkernel32 missing)) - AC_CHECK_LIB([user32], [main],, AC_MSG_ERROR(libuser32 missing)) - AC_CHECK_LIB([gdi32], [main],, AC_MSG_ERROR(libgdi32 missing)) - AC_CHECK_LIB([comdlg32], [main],, AC_MSG_ERROR(libcomdlg32 missing)) - AC_CHECK_LIB([winspool], [main],, AC_MSG_ERROR(libwinspool missing)) - AC_CHECK_LIB([winmm], [main],, AC_MSG_ERROR(libwinmm missing)) - AC_CHECK_LIB([shell32], [main],, AC_MSG_ERROR(libshell32 missing)) - AC_CHECK_LIB([comctl32], [main],, AC_MSG_ERROR(libcomctl32 missing)) - AC_CHECK_LIB([ole32], [main],, AC_MSG_ERROR(libole32 missing)) - AC_CHECK_LIB([oleaut32], [main],, AC_MSG_ERROR(liboleaut32 missing)) - AC_CHECK_LIB([uuid], [main],, AC_MSG_ERROR(libuuid missing)) - AC_CHECK_LIB([rpcrt4], [main],, AC_MSG_ERROR(librpcrt4 missing)) - AC_CHECK_LIB([advapi32], [main],, AC_MSG_ERROR(libadvapi32 missing)) - AC_CHECK_LIB([ws2_32], [main],, AC_MSG_ERROR(libws2_32 missing)) - AC_CHECK_LIB([mswsock], [main],, AC_MSG_ERROR(libmswsock missing)) - AC_CHECK_LIB([shlwapi], [main],, AC_MSG_ERROR(libshlwapi missing)) - AC_CHECK_LIB([iphlpapi], [main],, AC_MSG_ERROR(libiphlpapi missing)) - AC_CHECK_LIB([crypt32], [main],, AC_MSG_ERROR(libcrypt32 missing)) + AC_CHECK_LIB([kernel32], [GetModuleFileNameA],, AC_MSG_ERROR(libkernel32 missing)) + AC_CHECK_LIB([user32], [main],, AC_MSG_ERROR(libuser32 missing)) + AC_CHECK_LIB([gdi32], [main],, AC_MSG_ERROR(libgdi32 missing)) + AC_CHECK_LIB([comdlg32], [main],, AC_MSG_ERROR(libcomdlg32 missing)) + AC_CHECK_LIB([winmm], [main],, AC_MSG_ERROR(libwinmm missing)) + AC_CHECK_LIB([shell32], [SHGetSpecialFolderPathW],, AC_MSG_ERROR(libshell32 missing)) + AC_CHECK_LIB([comctl32], [main],, AC_MSG_ERROR(libcomctl32 missing)) + AC_CHECK_LIB([ole32], [CoCreateInstance],, AC_MSG_ERROR(libole32 missing)) + AC_CHECK_LIB([oleaut32], [main],, AC_MSG_ERROR(liboleaut32 missing)) + AC_CHECK_LIB([uuid], [main],, AC_MSG_ERROR(libuuid missing)) + AC_CHECK_LIB([advapi32], [CryptAcquireContextW],, AC_MSG_ERROR(libadvapi32 missing)) + AC_CHECK_LIB([ws2_32], [WSAStartup],, AC_MSG_ERROR(libws2_32 missing)) + AC_CHECK_LIB([shlwapi], [PathRemoveFileSpecW],, AC_MSG_ERROR(libshlwapi missing)) + AC_CHECK_LIB([iphlpapi], [GetAdaptersAddresses],, AC_MSG_ERROR(libiphlpapi missing)) # -static is interpreted by libtool, where it has a different meaning. # In libtool-speak, it's -all-static. @@ -487,7 +493,7 @@ case $host in AC_MSG_ERROR("windres not found") fi - CPPFLAGS="$CPPFLAGS -D_MT -DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB" + CPPFLAGS="$CPPFLAGS -D_MT -DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB -D_WIN32_WINNT=0x0601 -D_WIN32_IE=0x0501 -DWIN32_LEAN_AND_MEAN" LEVELDB_TARGET_FLAGS="-DOS_WINDOWS" if test "x$CXXFLAGS_overridden" = "xno"; then CXXFLAGS="$CXXFLAGS -w" @@ -507,7 +513,6 @@ case $host in LEVELDB_TARGET_FLAGS="-DOS_MACOSX" if test x$cross_compiling != xyes; then BUILD_OS=darwin - AC_PATH_PROGS([RSVG_CONVERT], [rsvg-convert rsvg],rsvg-convert) AC_CHECK_PROG([BREW],brew, brew) if test x$BREW = xbrew; then dnl These Homebrew packages may be keg-only, meaning that they won't be found @@ -538,12 +543,9 @@ case $host in BUILD_OS=darwin ;; *) - AC_PATH_TOOL([INSTALLNAMETOOL], [install_name_tool], install_name_tool) + AC_PATH_TOOL([INSTALL_NAME_TOOL], [install_name_tool], install_name_tool) AC_PATH_TOOL([OTOOL], [otool], otool) - AC_PATH_PROGS([GENISOIMAGE], [genisoimage mkisofs],genisoimage) - AC_PATH_PROGS([RSVG_CONVERT], [rsvg-convert rsvg],rsvg-convert) - AC_PATH_PROGS([IMAGEMAGICK_CONVERT], [convert],convert) - AC_PATH_PROGS([TIFFCP], [tiffcp],tiffcp) + AC_PATH_PROGS([XORRISOFS], [xorrisofs], xorrisofs) dnl libtool will try to strip the static lib, which is a problem for dnl cross-builds because strip attempts to call a hard-coded ld, @@ -561,22 +563,27 @@ case $host in *android*) dnl make sure android stays above linux for hosts like *linux-android* TARGET_OS=android + case $host in + *x86_64*) + ANDROID_ARCH=x86_64 + ;; + *aarch64*) + ANDROID_ARCH=arm64-v8a + ;; + *armv7a*) + ANDROID_ARCH=armeabi-v7a + ;; + *i686*) + ANDROID_ARCH=i686 + ;; + *) AC_MSG_ERROR("Could not determine Android arch") ;; + esac ;; *linux*) TARGET_OS=linux ;; esac -if test x$use_pkgconfig = xyes; then - m4_ifndef([PKG_PROG_PKG_CONFIG], [AC_MSG_ERROR(PKG_PROG_PKG_CONFIG macro not found. Please install pkg-config and re-run autogen.sh.)]) - m4_ifdef([PKG_PROG_PKG_CONFIG], [ - PKG_PROG_PKG_CONFIG - if test x"$PKG_CONFIG" = "x"; then - AC_MSG_ERROR(pkg-config not found.) - fi - ]) -fi - if test x$use_extended_functional_tests != xno; then AC_SUBST(EXTENDED_FUNCTIONAL_TESTS, --extended) fi @@ -696,6 +703,7 @@ fi dnl this flag screws up non-darwin gcc even when the check fails. special-case it. if test x$TARGET_OS = xdarwin; then AX_CHECK_LINK_FLAG([[-Wl,-dead_strip]], [LDFLAGS="$LDFLAGS -Wl,-dead_strip"]) + AX_CHECK_LINK_FLAG([[-Wl,-dead_strip_dylibs]], [LDFLAGS="$LDFLAGS -Wl,-dead_strip_dylibs"]) fi AC_CHECK_HEADERS([endian.h sys/endian.h byteswap.h stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h sys/select.h sys/prctl.h]) @@ -902,14 +910,6 @@ if test x$use_reduce_exports = xyes; then [AC_MSG_ERROR([Cannot set default symbol visibility. Use --disable-reduce-exports.])]) fi -LEVELDB_CPPFLAGS= -LIBLEVELDB= -LIBMEMENV= -AM_CONDITIONAL([EMBEDDED_LEVELDB],[true]) -AC_SUBST(LEVELDB_CPPFLAGS) -AC_SUBST(LIBLEVELDB) -AC_SUBST(LIBMEMENV) - if test x$enable_wallet != xno; then dnl Check for libdb_cxx only if wallet enabled BITCOIN_FIND_BDB48 @@ -927,7 +927,7 @@ fi BITCOIN_QT_INIT dnl sets $bitcoin_enable_qt, $bitcoin_enable_qt_test, $bitcoin_enable_qt_dbus -BITCOIN_QT_CONFIGURE([$use_pkgconfig], [qt5]) +BITCOIN_QT_CONFIGURE([5.5.1]) if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests$use_bench = xnonononono; then use_boost=no @@ -937,11 +937,8 @@ fi if test x$use_boost = xyes; then -dnl Minimum required Boost version -define(MINIMUM_REQUIRED_BOOST, 1.57.0) - -dnl Check for boost libs -AX_BOOST_BASE([MINIMUM_REQUIRED_BOOST]) +dnl Check for Boost headers +AX_BOOST_BASE([1.64.0],[],[AC_MSG_ERROR([Boost is not available!])]) if test x$want_boost = xno; then AC_MSG_ERROR([[only libbitcoinconsensus can be built without boost]]) fi @@ -950,11 +947,6 @@ AX_BOOST_FILESYSTEM AX_BOOST_PROGRAM_OPTIONS AX_BOOST_THREAD AX_BOOST_CHRONO - -dnl Boost 1.56 through 1.62 allow using std::atomic instead of its own atomic -dnl counter implementations. In 1.63 and later the std::atomic approach is default. -m4_pattern_allow(DBOOST_AC_USE_STD_ATOMIC) dnl otherwise it's treated like a macro -BOOST_CPPFLAGS="-DBOOST_SP_USE_STD_ATOMIC -DBOOST_AC_USE_STD_ATOMIC $BOOST_CPPFLAGS" fi if test x$use_reduce_exports = xyes; then @@ -998,80 +990,31 @@ if test x$use_boost = xyes; then BOOST_LIBS="$BOOST_LDFLAGS $BOOST_SYSTEM_LIB $BOOST_FILESYSTEM_LIB $BOOST_PROGRAM_OPTIONS_LIB $BOOST_THREAD_LIB $BOOST_CHRONO_LIB" fi -if test x$use_pkgconfig = xyes; then - : dnl - m4_ifdef( - [PKG_CHECK_MODULES], - [ - PKG_CHECK_MODULES([SSL], [libssl],, [AC_MSG_ERROR(openssl not found.)]) - PKG_CHECK_MODULES([CRYPTO], [libcrypto],,[AC_MSG_ERROR(libcrypto not found.)]) - BITCOIN_QT_CHECK([PKG_CHECK_MODULES([PROTOBUF], [protobuf], [have_protobuf=yes], [BITCOIN_QT_FAIL(libprotobuf not found)])]) - if test x$use_qr != xno; then - BITCOIN_QT_CHECK([PKG_CHECK_MODULES([QR], [libqrencode], [have_qrencode=yes], [have_qrencode=no])]) - fi - if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests != xnononono; then - PKG_CHECK_MODULES([EVENT], [libevent],, [AC_MSG_ERROR(libevent not found.)]) - if test x$TARGET_OS != xwindows; then - PKG_CHECK_MODULES([EVENT_PTHREADS], [libevent_pthreads],, [AC_MSG_ERROR(libevent_pthreads not found.)]) - fi - fi - - if test "x$use_zmq" = "xyes"; then - PKG_CHECK_MODULES([ZMQ],[libzmq >= 4], - [AC_DEFINE([ENABLE_ZMQ],[1],[Define to 1 to enable ZMQ functions])], - [AC_DEFINE([ENABLE_ZMQ],[0],[Define to 1 to enable ZMQ functions]) - AC_MSG_WARN([libzmq version 4.x or greater not found, disabling]) - use_zmq=no]) - else - AC_DEFINE_UNQUOTED([ENABLE_ZMQ],[0],[Define to 1 to enable ZMQ functions]) - fi - ] - ) -else - AC_CHECK_HEADER([openssl/crypto.h],,AC_MSG_ERROR(libcrypto headers missing)) - AC_CHECK_LIB([crypto], [main],CRYPTO_LIBS=-lcrypto, AC_MSG_ERROR(libcrypto missing)) +AC_CHECK_HEADER([openssl/crypto.h],,AC_MSG_ERROR(libcrypto headers missing)) +AC_CHECK_LIB([crypto], [main],CRYPTO_LIBS=-lcrypto, AC_MSG_ERROR(libcrypto missing)) - AC_CHECK_HEADER([openssl/ssl.h],, AC_MSG_ERROR(libssl headers missing),) - AC_CHECK_LIB([ssl], [main],SSL_LIBS=-lssl, AC_MSG_ERROR(libssl missing)) +AC_CHECK_HEADER([openssl/ssl.h],, AC_MSG_ERROR(libssl headers missing),) +AC_CHECK_LIB([ssl], [main],SSL_LIBS=-lssl, AC_MSG_ERROR(libssl missing)) - if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests != xnononono; then - AC_CHECK_HEADER([event2/event.h],, AC_MSG_ERROR(libevent headers missing),) - AC_CHECK_LIB([event],[main],EVENT_LIBS=-levent,AC_MSG_ERROR(libevent missing)) - if test x$TARGET_OS != xwindows; then - AC_CHECK_LIB([event_pthreads],[main],EVENT_PTHREADS_LIBS=-levent_pthreads,AC_MSG_ERROR(libevent_pthreads missing)) - fi +dnl libevent check +if test x$build_bitcoin_cli$build_bitcoind$bitcoin_enable_qt$use_tests$use_bench != xnonononono; then + PKG_CHECK_MODULES([EVENT], [libevent >= 2.0.21], [use_libevent=yes], [AC_MSG_ERROR([libevent version 2.0.21 or greater not found.])]) + if test x$TARGET_OS != xwindows; then + PKG_CHECK_MODULES([EVENT_PTHREADS], [libevent_pthreads >= 2.0.21],, [AC_MSG_ERROR([libevent_pthreads version 2.0.21 or greater not found.])]) fi +fi - if test "x$use_zmq" = "xyes"; then - AC_CHECK_HEADER([zmq.h], - [AC_DEFINE([ENABLE_ZMQ],[1],[Define to 1 to enable ZMQ functions])], - [AC_MSG_WARN([zmq.h not found, disabling zmq support]) - use_zmq=no - AC_DEFINE([ENABLE_ZMQ],[0],[Define to 1 to enable ZMQ functions])]) - AC_CHECK_LIB([zmq],[zmq_ctx_shutdown],ZMQ_LIBS=-lzmq, - [AC_MSG_WARN([libzmq >= 4.0 not found, disabling zmq support]) - use_zmq=no - AC_DEFINE([ENABLE_ZMQ],[0],[Define to 1 to enable ZMQ functions])]) - else - AC_DEFINE_UNQUOTED([ENABLE_ZMQ],[0],[Define to 1 to enable ZMQ functions]) - fi +dnl QR Code encoding library check - if test "x$use_zmq" = "xyes"; then - dnl Assume libzmq was built for static linking - case $host in - *mingw*) - ZMQ_CFLAGS="$ZMQ_CFLAGS -DZMQ_STATIC" - ;; - esac - fi - - BITCOIN_QT_CHECK(AC_CHECK_LIB([protobuf] ,[main],[PROTOBUF_LIBS=-lprotobuf], BITCOIN_QT_FAIL(libprotobuf not found))) - if test x$use_qr != xno; then - BITCOIN_QT_CHECK([AC_CHECK_LIB([qrencode], [main],[QR_LIBS=-lqrencode], [have_qrencode=no])]) - BITCOIN_QT_CHECK([AC_CHECK_HEADER([qrencode.h],, have_qrencode=no)]) - fi +if test "x$use_qr" != xno; then + BITCOIN_QT_CHECK([PKG_CHECK_MODULES([QR], [libqrencode], [have_qrencode=yes], [have_qrencode=no])]) fi +dnl curl check +PKG_CHECK_MODULES([CURL], [libcurl],, [AC_MSG_ERROR([libcurl not found.])]) +AC_CHECK_HEADER([curl/curl.h],, [AC_MSG_ERROR([libcurl header not found.])]) +AC_CHECK_LIB([curl], [main],CURL_LIBS=-lcurl, AC_MSG_ERROR(libcurl missing)) + save_CXXFLAGS="${CXXFLAGS}" CXXFLAGS="${CXXFLAGS} ${CRYPTO_CFLAGS} ${SSL_CFLAGS}" AC_CHECK_DECLS([EVP_MD_CTX_new],,,[AC_INCLUDES_DEFAULT @@ -1087,6 +1030,27 @@ AC_CHECK_LIB([crypto],[RAND_egd],[],[ ) ]) +dnl ZMQ check + +if test "x$use_zmq" = xyes; then + PKG_CHECK_MODULES([ZMQ], [libzmq >= 4], + AC_DEFINE([ENABLE_ZMQ], [1], [Define to 1 to enable ZMQ functions]), + [AC_DEFINE([ENABLE_ZMQ], [0], [Define to 1 to enable ZMQ functions]) + AC_MSG_WARN([libzmq version 4.x or greater not found, disabling]) + use_zmq=no]) +else + AC_DEFINE_UNQUOTED([ENABLE_ZMQ], [0], [Define to 1 to enable ZMQ functions]) +fi + +if test "x$use_zmq" = xyes; then + dnl Assume libzmq was built for static linking + case $host in + *mingw*) + ZMQ_CFLAGS="$ZMQ_CFLAGS -DZMQ_STATIC" + ;; + esac +fi + dnl univalue check need_bundled_univalue=yes @@ -1095,48 +1059,28 @@ if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests$use_ben need_bundled_univalue=no else -if test x$system_univalue != xno ; then - found_univalue=no - if test x$use_pkgconfig = xyes; then - : #NOP - m4_ifdef( - [PKG_CHECK_MODULES], - [ - PKG_CHECK_MODULES([UNIVALUE],[libunivalue >= 1.0.4],[found_univalue=yes],[true]) - ] - ) - else - AC_CHECK_HEADER([univalue.h],[ - AC_CHECK_LIB([univalue], [main],[ - UNIVALUE_LIBS=-lunivalue - found_univalue=yes - ],[true]) - ],[true]) + if test x$system_univalue != xno; then + PKG_CHECK_MODULES([UNIVALUE], [libunivalue >= 1.0.4], [found_univalue=yes], [found_univalue=no]) + if test x$found_univalue = xyes; then + system_univalue=yes + need_bundled_univalue=no + elif test x$system_univalue = xyes; then + AC_MSG_ERROR([univalue not found]) + else + system_univalue=no + fi fi - if test x$found_univalue = xyes ; then - system_univalue=yes - need_bundled_univalue=no - elif test x$system_univalue = xyes ; then - AC_MSG_ERROR([univalue not found]) - else - system_univalue=no + if test x$need_bundled_univalue = xyes; then + UNIVALUE_CFLAGS='-I$(srcdir)/univalue/include' + UNIVALUE_LIBS='univalue/libunivalue.la' fi fi -if test x$need_bundled_univalue = xyes ; then - UNIVALUE_CFLAGS='-I$(srcdir)/univalue/include' - UNIVALUE_LIBS='univalue/libunivalue.la' -fi - -fi - AM_CONDITIONAL([EMBEDDED_UNIVALUE],[test x$need_bundled_univalue = xyes]) AC_SUBST(UNIVALUE_CFLAGS) AC_SUBST(UNIVALUE_LIBS) -BITCOIN_QT_PATH_PROGS([PROTOC], [protoc],$protoc_bin_path) - AC_MSG_CHECKING([whether to build prcycoind]) AM_CONDITIONAL([BUILD_BITCOIND], [test x$build_bitcoind = xyes]) AC_MSG_RESULT($build_bitcoind) @@ -1322,6 +1266,8 @@ AC_SUBST(GPROF_LDFLAGS) AC_SUBST(HARDENED_CXXFLAGS) AC_SUBST(HARDENED_CPPFLAGS) AC_SUBST(HARDENED_LDFLAGS) +AC_SUBST(LTO_CXXFLAGS) +AC_SUBST(LTO_LDFLAGS) AC_SUBST(PIC_FLAGS) AC_SUBST(PIE_FLAGS) AC_SUBST(SANITIZER_CXXFLAGS) @@ -1340,11 +1286,8 @@ AC_SUBST(MINIUPNPC_CPPFLAGS) AC_SUBST(MINIUPNPC_LIBS) AC_SUBST(CRYPTO_LIBS) AC_SUBST(SSL_LIBS) -AC_SUBST(EVENT_LIBS) -AC_SUBST(EVENT_PTHREADS_LIBS) -AC_SUBST(ZMQ_LIBS) -AC_SUBST(PROTOBUF_LIBS) -AC_SUBST(QR_LIBS) +AC_SUBST(CURL_CFLAGS) +AC_SUBST(CURL_LIBS) AC_SUBST(USE_NUM_OPENSSL) AC_SUBST(HAVE_FDATASYNC) AC_SUBST(HAVE_FULLFSYNC) @@ -1357,6 +1300,7 @@ AC_CONFIG_FILES([Makefile src/Makefile doc/man/Makefile share/setup.nsi share/qt AC_CONFIG_FILES([contrib/devtools/split-debug.sh],[chmod +x contrib/devtools/split-debug.sh]) AM_COND_IF([HAVE_DOXYGEN], [AC_CONFIG_FILES([doc/Doxyfile])]) AC_CONFIG_LINKS([contrib/filter-lcov.py:contrib/filter-lcov.py]) +AC_CONFIG_LINKS([contrib/macdeploy/background.tiff:contrib/macdeploy/background.tiff]) AC_CONFIG_LINKS([test/functional/test_runner.py:test/functional/test_runner.py]) AC_CONFIG_LINKS([test/util/bitcoin-util-test.py:test/util/bitcoin-util-test.py]) AC_CONFIG_LINKS([test/util/rpcauth-test.py:test/util/rpcauth-test.py]) @@ -1430,6 +1374,7 @@ echo " sanitizers = $use_sanitizers" echo " debug enabled = $enable_debug" echo " gprof enabled = $enable_gprof" echo " werror = $enable_werror" +echo " LTO = $enable_lto" echo echo " target os = $TARGET_OS" echo " build os = $BUILD_OS" @@ -1438,8 +1383,9 @@ echo " CC = $CC" echo " CFLAGS = $CFLAGS" echo " CPPFLAGS = $DEBUG_CPPFLAGS $HARDENED_CPPFLAGS $CPPFLAGS" echo " CXX = $CXX" -echo " CXXFLAGS = $DEBUG_CXXFLAGS $HARDENED_CXXFLAGS $WARN_CXXFLAGS $NOWARN_CXXFLAGS $ERROR_CXXFLAGS $GPROF_CXXFLAGS $CXXFLAGS" -echo " LDFLAGS = $PTHREAD_CFLAGS $HARDENED_LDFLAGS $GPROF_LDFLAGS $LDFLAGS" +echo " CXXFLAGS = $LTO_CXXFLAGS $DEBUG_CXXFLAGS $HARDENED_CXXFLAGS $WARN_CXXFLAGS $NOWARN_CXXFLAGS $ERROR_CXXFLAGS $GPROF_CXXFLAGS $CXXFLAGS" +echo " LDFLAGS = $LTO_LDFLAGS $PTHREAD_CFLAGS $HARDENED_LDFLAGS $GPROF_LDFLAGS $LDFLAGS" +echo " AR = $AR" echo " ARFLAGS = $ARFLAGS" echo " PIC_FLAGS = $PIC_FLAGS" echo " QT_PIE_FLAGS = $QT_PIE_FLAGS" diff --git a/contrib/devtools/symbol-check.py b/contrib/devtools/symbol-check.py index 044b28bbbf..eb5d538f6b 100644 --- a/contrib/devtools/symbol-check.py +++ b/contrib/devtools/symbol-check.py @@ -70,6 +70,8 @@ 'libX11-xcb.so.1', # part of X11 'libX11.so.6', # part of X11 'libxcb.so.1', # part of X11 +'libxkbcommon.so.0', # keyboard keymapping +'libxkbcommon-x11.so.0', # keyboard keymapping 'libfontconfig.so.1', # font support 'libfreetype.so.6', # font parsing 'libdl.so.2' # programming interface to dynamic linker diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index fcfc58afde..c8548d46fe 100644 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -23,6 +23,7 @@ packages: - "g++-8-multilib" - "gcc-8-multilib" - "binutils-gold" +- "bison" - "git" - "pkg-config" - "autoconf" @@ -40,7 +41,7 @@ script: | set -e -o pipefail WRAP_DIR=$HOME/wrapped - HOSTS="i686-pc-linux-gnu x86_64-linux-gnu arm-linux-gnueabihf aarch64-linux-gnu" + HOSTS="x86_64-linux-gnu arm-linux-gnueabihf aarch64-linux-gnu" CONFIGFLAGS="--enable-glibc-back-compat --enable-reduce-exports --disable-bench --disable-gui-tests" FAKETIME_HOST_PROGS="gcc g++" FAKETIME_PROGS="date ar ranlib nm" @@ -48,8 +49,6 @@ script: | HOST_CXXFLAGS="-O2 -g" HOST_LDFLAGS=-static-libstdc++ - export QT_RCC_TEST=1 - export QT_RCC_SOURCE_DATE_OVERRIDE=1 export TZ="UTC" export BUILD_DIR=`pwd` mkdir -p ${WRAP_DIR} diff --git a/contrib/gitian-descriptors/gitian-osx-signer.yml b/contrib/gitian-descriptors/gitian-osx-signer.yml index 936954a8c3..ba7fff5260 100644 --- a/contrib/gitian-descriptors/gitian-osx-signer.yml +++ b/contrib/gitian-descriptors/gitian-osx-signer.yml @@ -7,6 +7,7 @@ architectures: - "amd64" packages: - "faketime" +- "xorriso" remotes: - "url": "https://github.com/prcycoin/prcycoin-detached-sigs.git" "dir": "signature" @@ -18,7 +19,7 @@ script: | WRAP_DIR=$HOME/wrapped mkdir -p ${WRAP_DIR} export PATH=`pwd`:$PATH - FAKETIME_PROGS="dmg genisoimage" + FAKETIME_PROGS="dmg xorrisofs" # Create global faketime wrappers for prog in ${FAKETIME_PROGS}; do @@ -36,5 +37,5 @@ script: | tar -xf ${UNSIGNED} OSX_VOLNAME="$(cat osx_volname)" ./detached-sig-apply.sh ${UNSIGNED} signature/osx - ${WRAP_DIR}/genisoimage -no-cache-inodes -D -l -probe -V "${OSX_VOLNAME}" -no-pad -r -dir-mode 0755 -apple -o uncompressed.dmg signed-app + ${WRAP_DIR}/xorrisofs -D -l -V "${OSX_VOLNAME}" -no-pad -r -dir-mode 0755 -o uncompressed.dmg signed-app ${WRAP_DIR}/dmg dmg uncompressed.dmg ${OUTDIR}/${SIGNED} diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml index 5297bacd7d..bdefcf0b2d 100644 --- a/contrib/gitian-descriptors/gitian-osx.yml +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -6,21 +6,18 @@ suites: - "bionic" architectures: - "amd64" -packages: +packages: - "ca-certificates" - "curl" - "g++" - "git" - "pkg-config" - "autoconf" -- "librsvg2-bin" -- "libtiff-tools" - "libtool" - "automake" - "faketime" - "bsdmainutils" - "cmake" -- "imagemagick" - "libcap-dev" - "libz-dev" - "libbz2-dev" @@ -28,22 +25,21 @@ packages: - "python3-dev" - "python3-setuptools" - "fonts-tuffy" +- "xorriso" remotes: - "url": "https://github.com/prcycoin/prcycoin.git" "dir": "prcycoin" files: -- "Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers.tar.gz" +- "Xcode-12.1-12A7403-extracted-SDK-with-libcxx-headers.tar.gz" script: | set -e -o pipefail WRAP_DIR=$HOME/wrapped - HOSTS="x86_64-apple-darwin16" - CONFIGFLAGS="--enable-reduce-exports --disable-bench --disable-gui-tests GENISOIMAGE=$WRAP_DIR/genisoimage" + HOSTS="x86_64-apple-darwin18" + CONFIGFLAGS="--enable-reduce-exports --disable-bench --disable-gui-tests XORRISOFS=${WRAP_DIR}/xorrisofs DMG=${WRAP_DIR}/dmg" FAKETIME_HOST_PROGS="" FAKETIME_PROGS="ar ranlib date dmg genisoimage" - export QT_RCC_TEST=1 - export QT_RCC_SOURCE_DATE_OVERRIDE=1 export TZ="UTC" export BUILD_DIR=`pwd` mkdir -p ${WRAP_DIR} @@ -89,7 +85,7 @@ script: | BASEPREFIX=`pwd`/depends mkdir -p ${BASEPREFIX}/SDKs - tar -C ${BASEPREFIX}/SDKs -xf ${BUILD_DIR}/Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers.tar.gz + tar -C ${BASEPREFIX}/SDKs -xf ${BUILD_DIR}/Xcode-12.1-12A7403-extracted-SDK-with-libcxx-headers.tar.gz # Build dependencies for each host for i in $HOSTS; do @@ -140,12 +136,11 @@ script: | make osx_volname make deploydir - OSX_VOLNAME="$(cat osx_volname)" mkdir -p unsigned-app-${i} cp osx_volname unsigned-app-${i}/ cp contrib/macdeploy/detached-sig-apply.sh unsigned-app-${i} cp contrib/macdeploy/detached-sig-create.sh unsigned-app-${i} - cp ${BASEPREFIX}/${i}/native/bin/dmg ${BASEPREFIX}/${i}/native/bin/genisoimage unsigned-app-${i} + cp ${BASEPREFIX}/${i}/native/bin/dmg unsigned-app-${i} cp ${BASEPREFIX}/${i}/native/bin/${i}-codesign_allocate unsigned-app-${i}/codesign_allocate cp ${BASEPREFIX}/${i}/native/bin/${i}-pagestuff unsigned-app-${i}/pagestuff mv dist unsigned-app-${i} @@ -153,8 +148,7 @@ script: | find . | sort | tar --mtime="$REFERENCE_DATETIME" --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-osx-unsigned.tar.gz popd - make deploy - ${WRAP_DIR}/dmg dmg "${OSX_VOLNAME}.dmg" ${OUTDIR}/${DISTNAME}-osx-unsigned.dmg + make deploy OSX_DMG="${OUTDIR}/${DISTNAME}-osx-unsigned.dmg" cd installed find . -name "lib*.la" -delete diff --git a/contrib/gitian-descriptors/gitian-win.yml b/contrib/gitian-descriptors/gitian-win.yml index d09e95f6f3..a82034718b 100644 --- a/contrib/gitian-descriptors/gitian-win.yml +++ b/contrib/gitian-descriptors/gitian-win.yml @@ -37,8 +37,6 @@ script: | HOST_CFLAGS="-O2 -g" HOST_CXXFLAGS="-O2 -g" - export QT_RCC_TEST=1 - export QT_RCC_SOURCE_DATE_OVERRIDE=1 export TZ="UTC" export BUILD_DIR=`pwd` mkdir -p ${WRAP_DIR} diff --git a/contrib/guix/README.md b/contrib/guix/README.md new file mode 100644 index 0000000000..113bdcbc13 --- /dev/null +++ b/contrib/guix/README.md @@ -0,0 +1,226 @@ +# Bootstrappable PRCYcoin Builds + +This directory contains the files necessary to perform bootstrappable PRCYcoin +builds. + +[Bootstrappability][b17e] furthers our binary security guarantees by allowing us +to _audit and reproduce_ our toolchain instead of blindly _trusting_ binary +downloads. + +We achieve bootstrappability by using Guix as a functional package manager. + +## Requirements + +Conservatively, a x86_64 machine with: + +- 2 or more logical cores +- 4GB of free disk space on the partition that /gnu/store will reside in +- 24GB of free disk space on the partition that the PRCYcoin git repository + resides in + +> Note: these requirements are slightly less onerous than those of Gitian builds + +## Setup + +### Installing Guix + +If you're just testing this out, you can use the +[Dockerfile][fanquake/guix-docker] for convenience. It automatically speeds up +your builds by [using substitutes](#speeding-up-builds-with-substitute-servers). +If you don't want this behaviour, refer to the [next +section](#choosing-your-security-model). + +Otherwise, follow the [Guix installation guide][guix/bin-install]. + +> Note: For those who like to keep their filesystems clean, Guix is designed to +> be very standalone and _will not_ conflict with your system's package +> manager/existing setup. It _only_ touches `/var/guix`, `/gnu`, and +> `~/.config/guix`. + +### Choosing your security model + +Guix allows us to achieve better binary security by using our CPU time to build +everything from scratch. However, it doesn't sacrifice user choice in pursuit of +this: users can decide whether or not to bootstrap and to use substitutes. + +After installation, you may want to consider [adding substitute +servers](#speeding-up-builds-with-substitute-servers) to speed up your build if +that fits your security model (say, if you're just testing that this works). +This is skippable if you're using the [Dockerfile][fanquake/guix-docker]. + +If you prefer not to use any substitutes, make sure to set +`ADDITIONAL_GUIX_ENVIRONMENT_FLAGS` like the following snippet. The first build +will take a while, but the resulting packages will be cached for future builds. + +```sh +export ADDITIONAL_GUIX_ENVIRONMENT_FLAGS='--no-substitutes' +``` + +Likewise, to perform a bootstrapped build (takes even longer): + +```sh +export ADDITIONAL_GUIX_ENVIRONMENT_FLAGS='--bootstrap --no-substitutes' +``` + +### Using a version of Guix with `guix time-machine` capabilities + +> Note: This entire section can be skipped if you are already using a version of +> Guix that has [the `guix time-machine` command][guix/time-machine]. + +Once Guix is installed, if it doesn't have the `guix time-machine` command, pull +the latest `guix`. + +```sh +guix pull --max-jobs=4 # change number of jobs accordingly +``` + +Make sure that you are using your current profile. (You are prompted to do this +at the end of the `guix pull`) + +```bash +export PATH="${HOME}/.config/guix/current/bin${PATH:+:}$PATH" +``` + +## Usage + +### As a Development Environment + +For a PRCYcoin depends development environment, simply invoke + +```sh +guix environment --manifest=contrib/guix/manifest.scm +``` + +And you'll land back in your shell with all the build dependencies required for +a `depends` build injected into your environment. + +### As a Tool for Deterministic Builds + +From the top of a clean PRCYcoin repository: + +```sh +./contrib/guix/guix-build.sh +``` + +After the build finishes successfully (check the status code please), compare +hashes: + +```sh +find output/ -type f -print0 | sort -z | xargs -r0 sha256sum +``` + +#### Recognized environment variables + +* _**HOSTS**_ + + Override the space-separated list of platform triples for which to perform a + bootstrappable build. _(defaults to "x86\_64-linux-gnu + arm-linux-gnueabihf aarch64-linux-gnu riscv64-linux-gnu")_ + + > Windows and OS X platform triplet support are WIP. + +* _**SOURCES_PATH**_ + + Set the depends tree download cache for sources. This is passed through to the + depends tree. Setting this to the same directory across multiple builds of the + depends tree can eliminate unnecessary redownloading of package sources. + +* _**MAX_JOBS**_ + + Override the maximum number of jobs to run simultaneously, you might want to + do so on a memory-limited machine. This may be passed to `make` as in `make + --jobs="$MAX_JOBS"` or `xargs` as in `xargs -P"$MAX_JOBS"`. _(defaults to the + value of `nproc` outside the container)_ + +* _**SOURCE_DATE_EPOCH**_ + + Override the reference UNIX timestamp used for bit-for-bit reproducibility, + the variable name conforms to [standard][r12e/source-date-epoch]. _(defaults + to the output of `$(git log --format=%at -1)`)_ + +* _**V**_ + + If non-empty, will pass `V=1` to all `make` invocations, making `make` output + verbose. + +* _**ADDITIONAL_GUIX_ENVIRONMENT_FLAGS**_ + + Additional flags to be passed to `guix environment`. For a fully-bootstrapped + build, set this to `--bootstrap --no-substitutes` (refer to the [security + model section](#choosing-your-security-model) for more details). Note that a + fully-bootstrapped build will take quite a long time on the first run. + +## Tips and Tricks + +### Speeding up builds with substitute servers + +_This whole section is automatically done in the convenience +[Dockerfiles][fanquake/guix-docker]_ + +For those who are used to life in the fast _(and trustful)_ lane, you can use +[substitute servers][guix/substitutes] to enable binary downloads of packages. + +> For those who only want to use substitutes from the official Guix build farm +> and have authorized the build farm's signing key during Guix's installation, +> you don't need to do anything. + +#### Authorize the signing keys + +For the official Guix build farm at https://ci.guix.gnu.org, run as root: + +``` +guix archive --authorize < ~root/.config/guix/current/share/guix/ci.guix.gnu.org.pub +``` + +For dongcarl's substitute server at https://guix.carldong.io, run as root: + +```sh +wget -qO- 'https://guix.carldong.io/signing-key.pub' | guix archive --authorize +``` + +#### Use the substitute servers + +The official Guix build farm at https://ci.guix.gnu.org is automatically used +unless the `--no-substitutes` flag is supplied. + +This can be overridden for all `guix` invocations by passing the +`--substitute-urls` option to your invocation of `guix-daemon`. This can also be +overridden on a call-by-call basis by passing the same `--substitute-urls` +option to client tools such at `guix environment`. + +To use dongcarl's substitute server for PRCYcoin builds after having +[authorized his signing key](#authorize-the-signing-keys): + +``` +export ADDITIONAL_GUIX_ENVIRONMENT_FLAGS='--substitute-urls="https://guix.carldong.io https://ci.guix.gnu.org"' +``` + +## FAQ + +### How can I trust the binary installation? + +As mentioned at the bottom of [this manual page][guix/bin-install]: + +> The binary installation tarballs can be (re)produced and verified simply by +> running the following command in the Guix source tree: +> +> make guix-binary.x86_64-linux.tar.xz + +### When will Guix be packaged in debian? + +Vagrant Cascadian has been making good progress on this +[here][debian/guix-package]. We have all the pieces needed to put up an APT +repository and will likely put one up soon. + +[b17e]: http://bootstrappable.org/ +[r12e/source-date-epoch]: https://reproducible-builds.org/docs/source-date-epoch/ + +[guix/install.sh]: https://git.savannah.gnu.org/cgit/guix.git/plain/etc/guix-install.sh +[guix/bin-install]: https://www.gnu.org/software/guix/manual/en/html_node/Binary-Installation.html +[guix/env-setup]: https://www.gnu.org/software/guix/manual/en/html_node/Build-Environment-Setup.html +[guix/substitutes]: https://www.gnu.org/software/guix/manual/en/html_node/Substitutes.html +[guix/substitute-server-auth]: https://www.gnu.org/software/guix/manual/en/html_node/Substitute-Server-Authorization.html +[guix/time-machine]: https://guix.gnu.org/manual/en/html_node/Invoking-guix-time_002dmachine.html + +[debian/guix-package]: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=850644 +[fanquake/guix-docker]: https://github.com/fanquake/core-review/tree/master/guix diff --git a/contrib/guix/guix-build.sh b/contrib/guix/guix-build.sh new file mode 100644 index 0000000000..06edc4efed --- /dev/null +++ b/contrib/guix/guix-build.sh @@ -0,0 +1,115 @@ +#!/usr/bin/env bash +export LC_ALL=C +set -e -o pipefail + +# Determine the maximum number of jobs to run simultaneously (overridable by +# environment) +MAX_JOBS="${MAX_JOBS:-$(nproc)}" + +# Download the depends sources now as we won't have internet access in the build +# container +make -C "${PWD}/depends" -j"$MAX_JOBS" download ${V:+V=1} ${SOURCES_PATH:+SOURCES_PATH="$SOURCES_PATH"} + +# Determine the reference time used for determinism (overridable by environment) +SOURCE_DATE_EPOCH="${SOURCE_DATE_EPOCH:-$(git log --format=%at -1)}" + +# Execute "$@" in a pinned, possibly older version of Guix, for reproducibility +# across time. +time-machine() { + guix time-machine --url=https://github.com/dongcarl/guix.git \ + --commit=b066c25026f21fb57677aa34692a5034338e7ee3 \ + -- "$@" +} + +# Function to be called when building for host ${1} and the user interrupts the +# build +int_trap() { +cat << EOF +** INT received while building ${1}, you may want to clean up the relevant + output, deploy, and distsrc-* directories before rebuilding +Hint: To blow everything away, you may want to use: + $ git clean -xdff --exclude='/depends/SDKs/*' +Specifically, this will remove all files without an entry in the index, +excluding the SDK directory. Practically speaking, this means that all ignored +and untracked files and directories will be wiped, allowing you to start anew. +EOF +} + +# Deterministically build PRCYcoin for HOSTs (overridable by environment) +# shellcheck disable=SC2153 +for host in ${HOSTS=x86_64-linux-gnu arm-linux-gnueabihf aarch64-linux-gnu riscv64-linux-gnu x86_64-w64-mingw32}; do + + # Display proper warning when the user interrupts the build + trap 'int_trap ${host}' INT + + ( + # Required for 'contrib/guix/manifest.scm' to output the right manifest + # for the particular $HOST we're building for + export HOST="$host" + + # Run the build script 'contrib/guix/libexec/build.sh' in the build + # container specified by 'contrib/guix/manifest.scm'. + # + # Explanation of `guix environment` flags: + # + # --container run command within an isolated container + # + # Running in an isolated container minimizes build-time differences + # between machines and improves reproducibility + # + # --pure unset existing environment variables + # + # Same rationale as --container + # + # --no-cwd do not share current working directory with an + # isolated container + # + # When --container is specified, the default behavior is to share + # the current working directory with the isolated container at the + # same exact path (e.g. mapping '/home/satoshi/prcycoin/' to + # '/home/satoshi/prcycoin/'). This means that the $PWD inside the + # container becomes a source of irreproducibility. --no-cwd disables + # this behaviour. + # + # --share=SPEC for containers, share writable host file system + # according to SPEC + # + # --share="$PWD"=/prcycoin + # + # maps our current working directory to /prcycoin + # inside the isolated container, which we later cd + # into. + # + # While we don't want to map our current working directory to the + # same exact path (as this introduces irreproducibility), we do want + # it to be at a _fixed_ path _somewhere_ inside the isolated + # container so that we have something to build. '/prcycoin' was + # chosen arbitrarily. + # + # ${SOURCES_PATH:+--share="$SOURCES_PATH"} + # + # make the downloaded depends sources path available + # inside the isolated container + # + # The isolated container has no network access as it's in a + # different network namespace from the main machine, so we have to + # make the downloaded depends sources available to it. The sources + # should have been downloaded prior to this invocation. + # + # shellcheck disable=SC2086 + time-machine environment --manifest="${PWD}/contrib/guix/manifest.scm" \ + --container \ + --pure \ + --no-cwd \ + --share="$PWD"=/prcycoin \ + ${SOURCES_PATH:+--share="$SOURCES_PATH"} \ + ${ADDITIONAL_GUIX_ENVIRONMENT_FLAGS} \ + -- env HOST="$host" \ + MAX_JOBS="$MAX_JOBS" \ + SOURCE_DATE_EPOCH="${SOURCE_DATE_EPOCH:?unable to determine value}" \ + ${V:+V=1} \ + ${SOURCES_PATH:+SOURCES_PATH="$SOURCES_PATH"} \ + bash -c "cd /prcycoin && bash contrib/guix/libexec/build.sh" + ) + +done diff --git a/contrib/guix/libexec/build.sh b/contrib/guix/libexec/build.sh new file mode 100644 index 0000000000..27d0ce8944 --- /dev/null +++ b/contrib/guix/libexec/build.sh @@ -0,0 +1,316 @@ +#!/usr/bin/env bash +export LC_ALL=C +set -e -o pipefail +export TZ=UTC + +# Check that environment variables assumed to be set by the environment are set +echo "Building for platform triple ${HOST:?not set} with reference timestamp ${SOURCE_DATE_EPOCH:?not set}..." +echo "At most ${MAX_JOBS:?not set} jobs will run at once..." + +##################### +# Environment Setup # +##################### + +# The depends folder also serves as a base-prefix for depends packages for +# $HOSTs after successfully building. +BASEPREFIX="${PWD}/depends" + +# Setup an output directory for our build +OUTDIR="${OUTDIR:-${PWD}/output}" +[ -e "$OUTDIR" ] || mkdir -p "$OUTDIR" + +# Setup the directory where our PRCYcoin build for HOST will occur +DISTSRC="${DISTSRC:-${PWD}/distsrc-${HOST}}" +if [ -e "$DISTSRC" ]; then + echo "DISTSRC directory '${DISTSRC}' exists, probably because of previous builds... Aborting..." + exit 1 +else + mkdir -p "$DISTSRC" +fi + +# Given a package name and an output name, return the path of that output in our +# current guix environment +store_path() { + grep --extended-regexp "/[^-]{32}-${1}-[^-]+${2:+-${2}}" "${GUIX_ENVIRONMENT}/manifest" \ + | head --lines=1 \ + | sed --expression='s|^[[:space:]]*"||' \ + --expression='s|"[[:space:]]*$||' +} + +# Set environment variables to point Guix's cross-toolchain to the right +# includes/libs for $HOST +case "$HOST" in + *mingw*) + # Determine output paths to use in CROSS_* environment variables + CROSS_GLIBC="$(store_path "mingw-w64-x86_64-winpthreads")" + CROSS_GCC="$(store_path "gcc-cross-${HOST}")" + CROSS_GCC_LIBS=( "${CROSS_GCC}/lib/gcc/${HOST}"/* ) # This expands to an array of directories... + CROSS_GCC_LIB="${CROSS_GCC_LIBS[0]}" # ...we just want the first one (there should only be one) + + NATIVE_GCC="$(store_path gcc-glibc-2.27-toolchain)" + export LIBRARY_PATH="${NATIVE_GCC}/lib:${NATIVE_GCC}/lib64" + export CPATH="${NATIVE_GCC}/include" + + export CROSS_C_INCLUDE_PATH="${CROSS_GCC_LIB}/include:${CROSS_GCC_LIB}/include-fixed:${CROSS_GLIBC}/include" + export CROSS_CPLUS_INCLUDE_PATH="${CROSS_GCC}/include/c++:${CROSS_GCC}/include/c++/${HOST}:${CROSS_GCC}/include/c++/backward:${CROSS_C_INCLUDE_PATH}" + export CROSS_LIBRARY_PATH="${CROSS_GCC}/lib:${CROSS_GCC}/${HOST}/lib:${CROSS_GCC_LIB}:${CROSS_GLIBC}/lib" + ;; + *linux*) + CROSS_GLIBC="$(store_path "glibc-cross-${HOST}")" + CROSS_GLIBC_STATIC="$(store_path "glibc-cross-${HOST}" static)" + CROSS_KERNEL="$(store_path "linux-libre-headers-cross-${HOST}")" + CROSS_GCC="$(store_path "gcc-cross-${HOST}")" + CROSS_GCC_LIBS=( "${CROSS_GCC}/lib/gcc/${HOST}"/* ) # This expands to an array of directories... + CROSS_GCC_LIB="${CROSS_GCC_LIBS[0]}" # ...we just want the first one (there should only be one) + + # NOTE: CROSS_C_INCLUDE_PATH is missing ${CROSS_GCC_LIB}/include-fixed, because + # the limits.h in it is missing a '#include_next ' + export CROSS_C_INCLUDE_PATH="${CROSS_GCC_LIB}/include:${CROSS_GLIBC}/include:${CROSS_KERNEL}/include" + export CROSS_CPLUS_INCLUDE_PATH="${CROSS_GCC}/include/c++:${CROSS_GCC}/include/c++/${HOST}:${CROSS_GCC}/include/c++/backward:${CROSS_C_INCLUDE_PATH}" + export CROSS_LIBRARY_PATH="${CROSS_GCC}/lib:${CROSS_GCC}/${HOST}/lib:${CROSS_GCC_LIB}:${CROSS_GLIBC}/lib:${CROSS_GLIBC_STATIC}/lib" + ;; + *) + exit 1 ;; +esac + +# Sanity check CROSS_*_PATH directories +IFS=':' read -ra PATHS <<< "${CROSS_C_INCLUDE_PATH}:${CROSS_CPLUS_INCLUDE_PATH}:${CROSS_LIBRARY_PATH}" +for p in "${PATHS[@]}"; do + if [ ! -d "$p" ]; then + echo "'$p' doesn't exist or isn't a directory... Aborting..." + exit 1 + fi +done + +# Disable Guix ld auto-rpath behavior +export GUIX_LD_WRAPPER_DISABLE_RPATH=yes + +# Make /usr/bin if it doesn't exist +[ -e /usr/bin ] || mkdir -p /usr/bin + +# Symlink file and env to a conventional path +[ -e /usr/bin/file ] || ln -s --no-dereference "$(command -v file)" /usr/bin/file +[ -e /usr/bin/env ] || ln -s --no-dereference "$(command -v env)" /usr/bin/env + +# Determine the correct value for -Wl,--dynamic-linker for the current $HOST +case "$HOST" in + *linux*) + glibc_dynamic_linker=$( + case "$HOST" in + i686-linux-gnu) echo /lib/ld-linux.so.2 ;; + x86_64-linux-gnu) echo /lib64/ld-linux-x86-64.so.2 ;; + arm-linux-gnueabihf) echo /lib/ld-linux-armhf.so.3 ;; + aarch64-linux-gnu) echo /lib/ld-linux-aarch64.so.1 ;; + riscv64-linux-gnu) echo /lib/ld-linux-riscv64-lp64d.so.1 ;; + *) exit 1 ;; + esac + ) + ;; +esac + +# Environment variables for determinism +export TAR_OPTIONS="--owner=0 --group=0 --numeric-owner --mtime='@${SOURCE_DATE_EPOCH}' --sort=name" +export TZ="UTC" + +#################### +# Depends Building # +#################### + +# Build the depends tree, overriding variables that assume multilib gcc +make -C depends --jobs="$MAX_JOBS" HOST="$HOST" \ + ${V:+V=1} \ + ${SOURCES_PATH+SOURCES_PATH="$SOURCES_PATH"} \ + i686_linux_CC=i686-linux-gnu-gcc \ + i686_linux_CXX=i686-linux-gnu-g++ \ + i686_linux_AR=i686-linux-gnu-ar \ + i686_linux_RANLIB=i686-linux-gnu-ranlib \ + i686_linux_NM=i686-linux-gnu-nm \ + i686_linux_STRIP=i686-linux-gnu-strip \ + x86_64_linux_CC=x86_64-linux-gnu-gcc \ + x86_64_linux_CXX=x86_64-linux-gnu-g++ \ + x86_64_linux_AR=x86_64-linux-gnu-ar \ + x86_64_linux_RANLIB=x86_64-linux-gnu-ranlib \ + x86_64_linux_NM=x86_64-linux-gnu-nm \ + x86_64_linux_STRIP=x86_64-linux-gnu-strip \ + qt_config_opts_i686_linux='-platform linux-g++ -xplatform bitcoin-linux-g++' + + +########################### +# Source Tarball Building # +########################### + +# Create the source tarball and move it to "${OUTDIR}/src" if not already there +if [ -z "$(find "${OUTDIR}/src" -name 'prcycoin-*.tar.gz')" ]; then + ./autogen.sh + env CONFIG_SITE="${BASEPREFIX}/${HOST}/share/config.site" ./configure --prefix=/ + make dist GZIP_ENV='-9n' ${V:+V=1} + mkdir -p "${OUTDIR}/src" + mv "$(find "${PWD}" -name 'prcycoin-*.tar.gz')" "${OUTDIR}/src/" +fi + +# Determine the full path to our source tarball +SOURCEDIST="$(find "${OUTDIR}/src" -name 'prcycoin-*.tar.gz')" +# Determine our distribution name (e.g. prcycoin-0.18.0) +DISTNAME="$(basename "$SOURCEDIST" '.tar.gz')" + +########################### +# Binary Tarball Building # +########################### + +# CONFIGFLAGS +CONFIGFLAGS="--enable-reduce-exports --disable-bench --disable-gui-tests" +case "$HOST" in + *linux*) CONFIGFLAGS+=" --enable-glibc-back-compat" ;; +esac + +# CFLAGS +HOST_CFLAGS="-O2 -g" +case "$HOST" in + *linux*) HOST_CFLAGS+=" -ffile-prefix-map=${PWD}=." ;; + *mingw*) HOST_CFLAGS+=" -fno-ident" ;; +esac + +# CXXFLAGS +HOST_CXXFLAGS="$HOST_CFLAGS" + +# LDFLAGS +case "$HOST" in + *linux*) HOST_LDFLAGS="-Wl,--as-needed -Wl,--dynamic-linker=$glibc_dynamic_linker -static-libstdc++" ;; + *mingw*) HOST_LDFLAGS="-Wl,--no-insert-timestamp" ;; +esac + +# Make $HOST-specific native binaries from depends available in $PATH +export PATH="${BASEPREFIX}/${HOST}/native/bin:${PATH}" +( + cd "$DISTSRC" + + # Extract the source tarball + tar --strip-components=1 -xf "${SOURCEDIST}" + + # Configure this DISTSRC for $HOST + # shellcheck disable=SC2086 + env CONFIG_SITE="${BASEPREFIX}/${HOST}/share/config.site" \ + ./configure --prefix=/ \ + --disable-ccache \ + --disable-maintainer-mode \ + --disable-dependency-tracking \ + ${CONFIGFLAGS} \ + CFLAGS="${HOST_CFLAGS}" \ + CXXFLAGS="${HOST_CXXFLAGS}" \ + ${HOST_LDFLAGS:+LDFLAGS="${HOST_LDFLAGS}"} + + sed -i.old 's/-lstdc++ //g' config.status libtool src/univalue/config.status src/univalue/libtool + + # Build PRCYcoin + make --jobs="$MAX_JOBS" ${V:+V=1} + + # Perform basic ELF security checks on a series of executables. + make -C src --jobs=1 check-security ${V:+V=1} + + case "$HOST" in + *linux*|*mingw*) + # Check that executables only contain allowed gcc, glibc and libstdc++ + # version symbols for Linux distro back-compatibility. + make -C src --jobs=1 check-symbols ${V:+V=1} + ;; + esac + + # Make the os-specific installers + case "$HOST" in + *mingw*) + make deploy ${V:+V=1} + ;; + esac + + # Setup the directory where our PRCYcoin build for HOST will be + # installed. This directory will also later serve as the input for our + # binary tarballs. + INSTALLPATH="${PWD}/installed/${DISTNAME}" + mkdir -p "${INSTALLPATH}" + # Install built PRCYcoin to $INSTALLPATH + make install DESTDIR="${INSTALLPATH}" ${V:+V=1} + + case "$HOST" in + *mingw*) + cp -f --target-directory="$OUTDIR" ./*-setup-unsigned.exe + ;; + esac + ( + cd installed + + case "$HOST" in + *mingw*) + mv --target-directory="$DISTNAME"/lib/ "$DISTNAME"/bin/*.dll + ;; + esac + + # Prune libtool and object archives + find . -name "lib*.la" -delete + find . -name "lib*.a" -delete + + # Prune pkg-config files + rm -r "${DISTNAME}/lib/pkgconfig" + + # Split binaries and libraries from their debug symbols + { + find "${DISTNAME}/bin" -type f -executable -print0 + find "${DISTNAME}/lib" -type f -print0 + } | xargs -0 -n1 -P"$MAX_JOBS" -I{} "${DISTSRC}/contrib/devtools/split-debug.sh" {} {} {}.dbg + + case "$HOST" in + *mingw*) + cp "${DISTSRC}/doc/README_windows.txt" "${DISTNAME}/readme.txt" + ;; + *linux*) + cp "${DISTSRC}/doc/README.md" "${DISTNAME}/" + ;; + esac + + # Finally, deterministically produce {non-,}debug binary tarballs ready + # for release + case "$HOST" in + *mingw*) + find "${DISTNAME}" -not -name "*.dbg" -print0 \ + | xargs -0r touch --no-dereference --date="@${SOURCE_DATE_EPOCH}" + find "${DISTNAME}" -not -name "*.dbg" \ + | sort \ + | zip -X@ "${OUTDIR}/${DISTNAME}-${HOST//x86_64-w64-mingw32/win64}.zip" \ + || ( rm -f "${OUTDIR}/${DISTNAME}-${HOST//x86_64-w64-mingw32/win64}.zip" && exit 1 ) + find "${DISTNAME}" -name "*.dbg" -print0 \ + | xargs -0r touch --no-dereference --date="@${SOURCE_DATE_EPOCH}" + find "${DISTNAME}" -name "*.dbg" \ + | sort \ + | zip -X@ "${OUTDIR}/${DISTNAME}-${HOST//x86_64-w64-mingw32/win64}-debug.zip" \ + || ( rm -f "${OUTDIR}/${DISTNAME}-${HOST//x86_64-w64-mingw32/win64}-debug.zip" && exit 1 ) + ;; + *linux*) + find "${DISTNAME}" -not -name "*.dbg" -print0 \ + | sort --zero-terminated \ + | tar --create --no-recursion --mode='u+rw,go+r-w,a+X' --null --files-from=- \ + | gzip -9n > "${OUTDIR}/${DISTNAME}-${HOST}.tar.gz" \ + || ( rm -f "${OUTDIR}/${DISTNAME}-${HOST}.tar.gz" && exit 1 ) + find "${DISTNAME}" -name "*.dbg" -print0 \ + | sort --zero-terminated \ + | tar --create --no-recursion --mode='u+rw,go+r-w,a+X' --null --files-from=- \ + | gzip -9n > "${OUTDIR}/${DISTNAME}-${HOST}-debug.tar.gz" \ + || ( rm -f "${OUTDIR}/${DISTNAME}-${HOST}-debug.tar.gz" && exit 1 ) + ;; + esac + ) +) + +case "$HOST" in + *mingw*) + cp -rf --target-directory=. contrib/windeploy + ( + cd ./windeploy + mkdir unsigned + cp --target-directory=unsigned/ "$OUTDIR"/prcycoin-*-setup-unsigned.exe + find . -print0 \ + | sort --zero-terminated \ + | tar --create --no-recursion --mode='u+rw,go+r-w,a+X' --null --files-from=- \ + | gzip -9n > "${OUTDIR}/${DISTNAME}-win-unsigned.tar.gz" \ + || ( rm -f "${OUTDIR}/${DISTNAME}-win-unsigned.tar.gz" && exit 1 ) + ) + ;; +esac diff --git a/contrib/guix/manifest.scm b/contrib/guix/manifest.scm new file mode 100644 index 0000000000..7e4a190940 --- /dev/null +++ b/contrib/guix/manifest.scm @@ -0,0 +1,195 @@ +(use-modules (gnu) + (gnu packages) + (gnu packages autotools) + (gnu packages base) + (gnu packages bash) + (gnu packages check) + (gnu packages commencement) + (gnu packages compression) + (gnu packages cross-base) + (gnu packages file) + (gnu packages gawk) + (gnu packages gcc) + (gnu packages installers) + (gnu packages linux) + (gnu packages mingw) + (gnu packages perl) + (gnu packages pkg-config) + (gnu packages python) + (gnu packages shells) + (guix build-system gnu) + (guix build-system trivial) + (guix gexp) + (guix packages) + (guix profiles) + (guix utils)) + +(define (make-ssp-fixed-gcc xgcc) + "Given a XGCC package, return a modified package that uses the SSP function +from glibc instead of from libssp.so. Our `symbol-check' script will complain if +we link against libssp.so, and thus will ensure that this works properly. + +Taken from: +http://www.linuxfromscratch.org/hlfs/view/development/chapter05/gcc-pass1.html" + (package + (inherit xgcc) + (arguments + (substitute-keyword-arguments (package-arguments xgcc) + ((#:make-flags flags) + `(cons "gcc_cv_libc_provides_ssp=yes" ,flags)))))) + +(define (make-gcc-rpath-link xgcc) + "Given a XGCC package, return a modified package that replace each instance of +-rpath in the default system spec that's inserted by Guix with -rpath-link" + (package + (inherit xgcc) + (arguments + (substitute-keyword-arguments (package-arguments xgcc) + ((#:phases phases) + `(modify-phases ,phases + (add-after 'pre-configure 'replace-rpath-with-rpath-link + (lambda _ + (substitute* (cons "gcc/config/rs6000/sysv4.h" + (find-files "gcc/config" + "^gnu-user.*\\.h$")) + (("-rpath=") "-rpath-link=")) + #t)))))))) + +(define (make-cross-toolchain target + base-gcc-for-libc + base-kernel-headers + base-libc + base-gcc) + "Create a cross-compilation toolchain package for TARGET" + (let* ((xbinutils (cross-binutils target)) + ;; 1. Build a cross-compiling gcc without targeting any libc, derived + ;; from BASE-GCC-FOR-LIBC + (xgcc-sans-libc (cross-gcc target + #:xgcc base-gcc-for-libc + #:xbinutils xbinutils)) + ;; 2. Build cross-compiled kernel headers with XGCC-SANS-LIBC, derived + ;; from BASE-KERNEL-HEADERS + (xkernel (cross-kernel-headers target + base-kernel-headers + xgcc-sans-libc + xbinutils)) + ;; 3. Build a cross-compiled libc with XGCC-SANS-LIBC and XKERNEL, + ;; derived from BASE-LIBC + (xlibc (cross-libc target + base-libc + xgcc-sans-libc + xbinutils + xkernel)) + ;; 4. Build a cross-compiling gcc targeting XLIBC, derived from + ;; BASE-GCC + (xgcc (cross-gcc target + #:xgcc base-gcc + #:xbinutils xbinutils + #:libc xlibc))) + ;; Define a meta-package that propagates the resulting XBINUTILS, XLIBC, and + ;; XGCC + (package + (name (string-append target "-toolchain")) + (version (package-version xgcc)) + (source #f) + (build-system trivial-build-system) + (arguments '(#:builder (begin (mkdir %output) #t))) + (propagated-inputs + `(("binutils" ,xbinutils) + ("libc" ,xlibc) + ("libc:static" ,xlibc "static") + ("gcc" ,xgcc))) + (synopsis (string-append "Complete GCC tool chain for " target)) + (description (string-append "This package provides a complete GCC tool +chain for " target " development.")) + (home-page (package-home-page xgcc)) + (license (package-license xgcc))))) + +(define* (make-prcycoin-cross-toolchain target + #:key + (base-gcc-for-libc gcc-5) + (base-kernel-headers linux-libre-headers-4.19) + (base-libc glibc-2.27) + (base-gcc (make-gcc-rpath-link gcc-9))) + "Convenience wrapper around MAKE-CROSS-TOOLCHAIN with default values +desirable for building PRCYcoin release binaries." + (make-cross-toolchain target + base-gcc-for-libc + base-kernel-headers + base-libc + base-gcc)) + +(define (make-gcc-with-pthreads gcc) + (package-with-extra-configure-variable gcc "--enable-threads" "posix")) + +(define (make-mingw-pthreads-cross-toolchain target) + "Create a cross-compilation toolchain package for TARGET" + (let* ((xbinutils (cross-binutils target)) + (pthreads-xlibc mingw-w64-x86_64-winpthreads) + (pthreads-xgcc (make-gcc-with-pthreads + (cross-gcc target + #:xgcc (make-ssp-fixed-gcc gcc-9) + #:xbinutils xbinutils + #:libc pthreads-xlibc)))) + ;; Define a meta-package that propagates the resulting XBINUTILS, XLIBC, and + ;; XGCC + (package + (name (string-append target "-posix-toolchain")) + (version (package-version pthreads-xgcc)) + (source #f) + (build-system trivial-build-system) + (arguments '(#:builder (begin (mkdir %output) #t))) + (propagated-inputs + `(("binutils" ,xbinutils) + ("libc" ,pthreads-xlibc) + ("gcc" ,pthreads-xgcc))) + (synopsis (string-append "Complete GCC tool chain for " target)) + (description (string-append "This package provides a complete GCC tool +chain for " target " development.")) + (home-page (package-home-page pthreads-xgcc)) + (license (package-license pthreads-xgcc))))) + + +(packages->manifest + (append + (list ;; The Basics + bash-minimal + which + coreutils + util-linux + ;; File(system) inspection + file + grep + diffutils + findutils + ;; File transformation + patch + gawk + sed + ;; Compression and archiving + tar + bzip2 + gzip + xz + zlib + ;; Build tools + gnu-make + libtool + autoconf + automake + pkg-config + ;; Scripting + perl + python-3.7 + ;; Native gcc 9 toolchain targeting glibc 2.27 + (make-gcc-toolchain gcc-9 glibc-2.27)) + (let ((target (getenv "HOST"))) + (cond ((string-suffix? "-mingw32" target) + ;; Windows + (list zip (make-mingw-pthreads-cross-toolchain "x86_64-w64-mingw32") nsis-x86_64)) + ((string-contains target "riscv64-linux-") + (list (make-prcycoin-cross-toolchain "riscv64-linux-gnu" + #:base-gcc-for-libc gcc-7))) + ((string-contains target "-linux-") + (list (make-prcycoin-cross-toolchain target))) + (else '()))))) diff --git a/contrib/macdeploy/README.md b/contrib/macdeploy/README.md index d21fce7d71..897453d2cf 100644 --- a/contrib/macdeploy/README.md +++ b/contrib/macdeploy/README.md @@ -13,9 +13,9 @@ When complete, it will have produced `PRCYcoin-Core.dmg`. ### Step 1: Obtaining `Xcode.app` Our current macOS SDK -(`Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers.tar.gz`) can be +(`Xcode-12.1-12A7403-extracted-SDK-with-libcxx-headers.tar.gz`) can be extracted from -[Xcode_11.3.1.xip](https://download.developer.apple.com/Developer_Tools/Xcode_11.3.1/Xcode_11.3.1.xip). +[Xcode_12.1.xip](https://download.developer.apple.com/Developer_Tools/Xcode_12.1/Xcode_12.1.xip). An Apple ID is needed to download this. After Xcode version 7.x, Apple started shipping the `Xcode.app` in a `.xip` @@ -27,25 +27,25 @@ approach (tested on Debian Buster) is outlined below: apt install cpio git clone https://github.com/bitcoin-core/apple-sdk-tools.git -# Unpack Xcode_11.3.1.xip and place the resulting Xcode.app in your current +# Unpack Xcode_12.1.xip and place the resulting Xcode.app in your current # working directory -python3 apple-sdk-tools/extract_xcode.py -f Xcode_11.3.1.xip | cpio -d -i +python3 apple-sdk-tools/extract_xcode.py -f Xcode_12.1.xip | cpio -d -i ``` On macOS the process is more straightforward: ```bash -xip -x Xcode_11.3.1.xip +xip -x Xcode_12.1.xip ``` -### Step 2: Generating `Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers.tar.gz` from `Xcode.app` +### Step 2: Generating `Xcode-12.1-12A7403-extracted-SDK-with-libcxx-headers.tar.gz` from `Xcode.app` -To generate `Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers.tar.gz`, run +To generate `Xcode-12.1-12A7403-extracted-SDK-with-libcxx-headers.tar.gz`, run the script [`gen-sdk`](./gen-sdk) with the path to `Xcode.app` (extracted in the previous stage) as the first argument. ```bash -# Generate a Xcode-11.3.1-11C505-extracted-SDK-with-libcxx-headers.tar.gz from +# Generate a Xcode-12.1-12A7403-extracted-SDK-with-libcxx-headers.tar.gz from # the supplied Xcode.app ./contrib/macdeploy/gen-sdk '/path/to/Xcode.app' ``` @@ -92,22 +92,9 @@ created using these tools. The build process has been designed to avoid includin SDK's files in Gitian's outputs. All interim tarballs are fully deterministic and may be freely redistributed. -`genisoimage` is used to create the initial DMG. It is not deterministic as-is, so it has been -patched. A system `genisoimage` will work fine, but it will not be deterministic because -the file-order will change between invocations. The patch can be seen here: [cdrkit-deterministic.patch](https://github.com/prcycoin/prcycoin/blob/master/depends/patches/native_cdrkit/cdrkit-deterministic.patch). -No effort was made to fix this cleanly, so it likely leaks memory badly, however it's only used for -a single invocation, so that's no real concern. +[`xorrisofs`](https://www.gnu.org/software/xorriso/) is used to create the DMG. -`genisoimage` cannot compress DMGs, so afterwards, the DMG tool from the -`libdmg-hfsplus` project is used to compress it. There are several bugs in this tool and its -maintainer has seemingly abandoned the project. - -The DMG tool has the ability to create DMGs from scratch as well, but this functionality is -broken. Only the compression feature is currently used. Ideally, the creation could be fixed -and `genisoimage` would no longer be necessary. - -Background images and other features can be added to DMG files by inserting a -`.DS_Store` during creation. +A background image is added to DMG files by inserting a `.DS_Store` during creation. As of OS X 10.9 Mavericks, using an Apple-blessed key to sign binaries is a requirement in order to satisfy the new Gatekeeper requirements. Because this private key cannot be diff --git a/contrib/macdeploy/background.svg b/contrib/macdeploy/background.svg deleted file mode 100644 index 9c330af451..0000000000 --- a/contrib/macdeploy/background.svg +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - PACKAGE_NAME - - - - - diff --git a/contrib/macdeploy/background.tiff b/contrib/macdeploy/background.tiff new file mode 100644 index 0000000000..1fb088c837 Binary files /dev/null and b/contrib/macdeploy/background.tiff differ diff --git a/contrib/macdeploy/macdeployqtplus b/contrib/macdeploy/macdeployqtplus index 0ea8982623..4a4630aeac 100644 --- a/contrib/macdeploy/macdeployqtplus +++ b/contrib/macdeploy/macdeployqtplus @@ -16,8 +16,7 @@ # along with this program. If not, see . # -import plistlib -import sys, re, os, shutil, stat, os.path +import sys, re, os, platform, shutil, stat, subprocess, os.path from argparse import ArgumentParser from ds_store import DSStore from mac_alias import Alias @@ -53,7 +52,7 @@ class FrameworkInfo(object): return False def __str__(self): - return f""" Framework name: {frameworkName} + return f""" Framework name: {self.frameworkName} Framework directory: {self.frameworkDirectory} Framework path: {self.frameworkPath} Binary name: {self.binaryName} @@ -85,8 +84,8 @@ class FrameworkInfo(object): if line == "": return None - # Don't deploy system libraries (exception for libQtuitools and libQtlucene). - if line.startswith("/System/Library/") or line.startswith("@executable_path") or (line.startswith("/usr/lib/") and "libQt" not in line): + # Don't deploy system libraries + if line.startswith("/System/Library/") or line.startswith("@executable_path") or line.startswith("/usr/lib/"): return None m = cls.reOLine.match(line) @@ -212,7 +211,7 @@ def getFrameworks(binaryPath: str, verbose: int) -> List[FrameworkInfo]: return libraries def runInstallNameTool(action: str, *args): - installnametoolbin=os.getenv("INSTALLNAMETOOL", "install_name_tool") + installnametoolbin=os.getenv("INSTALL_NAME_TOOL", "install_name_tool") run([installnametoolbin, "-"+action] + list(args), check=True) def changeInstallName(oldName: str, newName: str, binaryPath: str, verbose: int): @@ -246,56 +245,47 @@ def copyFramework(framework: FrameworkInfo, path: str, verbose: int) -> Optional toDir = os.path.join(path, framework.destinationDirectory) toPath = os.path.join(toDir, framework.binaryName) - if not os.path.exists(fromPath): - raise RuntimeError(f"No file at {fromPath}") - if os.path.exists(toPath): - return None # Already there + if framework.isDylib(): + if not os.path.exists(fromPath): + raise RuntimeError(f"No file at {fromPath}") - if not os.path.exists(toDir): - os.makedirs(toDir) + if os.path.exists(toPath): + return None # Already there - shutil.copy2(fromPath, toPath) - if verbose: - print("Copied:", fromPath) - print(" to:", toPath) + if not os.path.exists(toDir): + os.makedirs(toDir) + + shutil.copy2(fromPath, toPath) + if verbose: + print("Copied:", fromPath) + print(" to:", toPath) + else: + to_dir = os.path.join(path, "Contents", "Frameworks", framework.frameworkName) + if os.path.exists(to_dir): + return None # Already there + + from_dir = framework.frameworkPath + if not os.path.exists(from_dir): + raise RuntimeError(f"No directory at {from_dir}") + + shutil.copytree(from_dir, to_dir, symlinks=True) + if verbose: + print("Copied:", from_dir) + print(" to:", to_dir) + + headers_link = os.path.join(to_dir, "Headers") + if os.path.exists(headers_link): + os.unlink(headers_link) + + headers_dir = os.path.join(to_dir, framework.binaryDirectory, "Headers") + if os.path.exists(headers_dir): + shutil.rmtree(headers_dir) permissions = os.stat(toPath) if not permissions.st_mode & stat.S_IWRITE: os.chmod(toPath, permissions.st_mode | stat.S_IWRITE) - if not framework.isDylib(): # Copy resources for real frameworks - - linkfrom = os.path.join(path, "Contents","Frameworks", framework.frameworkName, "Versions", "Current") - linkto = framework.version - if not os.path.exists(linkfrom): - os.symlink(linkto, linkfrom) - print("Linked:", linkfrom, "->", linkto) - fromResourcesDir = framework.sourceResourcesDirectory - if os.path.exists(fromResourcesDir): - toResourcesDir = os.path.join(path, framework.destinationResourcesDirectory) - shutil.copytree(fromResourcesDir, toResourcesDir, symlinks=True) - if verbose: - print("Copied resources:", fromResourcesDir) - print(" to:", toResourcesDir) - fromContentsDir = framework.sourceVersionContentsDirectory - if not os.path.exists(fromContentsDir): - fromContentsDir = framework.sourceContentsDirectory - if os.path.exists(fromContentsDir): - toContentsDir = os.path.join(path, framework.destinationVersionContentsDirectory) - shutil.copytree(fromContentsDir, toContentsDir, symlinks=True) - if verbose: - print("Copied Contents:", fromContentsDir) - print(" to:", toContentsDir) - elif framework.frameworkName.startswith("libQtGui"): # Copy qt_menu.nib (applies to non-framework layout) - qtMenuNibSourcePath = os.path.join(framework.frameworkDirectory, "Resources", "qt_menu.nib") - qtMenuNibDestinationPath = os.path.join(path, "Contents", "Resources", "qt_menu.nib") - if os.path.exists(qtMenuNibSourcePath) and not os.path.exists(qtMenuNibDestinationPath): - shutil.copytree(qtMenuNibSourcePath, qtMenuNibDestinationPath, symlinks=True) - if verbose: - print("Copied for libQtGui:", qtMenuNibSourcePath) - print(" to:", qtMenuNibDestinationPath) - return toPath def deployFrameworks(frameworks: List[FrameworkInfo], bundlePath: str, binaryPath: str, strip: bool, verbose: int, deploymentInfo: Optional[DeploymentInfo] = None) -> DeploymentInfo: @@ -351,112 +341,20 @@ def deployFrameworksForAppBundle(applicationBundle: ApplicationBundleInfo, strip return deployFrameworks(frameworks, applicationBundle.path, applicationBundle.binaryPath, strip, verbose) def deployPlugins(appBundleInfo: ApplicationBundleInfo, deploymentInfo: DeploymentInfo, strip: bool, verbose: int): - # Lookup available plugins, exclude unneeded plugins = [] if deploymentInfo.pluginPath is None: return for dirpath, dirnames, filenames in os.walk(deploymentInfo.pluginPath): pluginDirectory = os.path.relpath(dirpath, deploymentInfo.pluginPath) - if pluginDirectory == "designer": - # Skip designer plugins - continue - elif pluginDirectory == "printsupport": - # Skip printsupport plugins + + if pluginDirectory not in ['styles', 'platforms']: continue - elif pluginDirectory == "sqldrivers": - # Deploy the sql plugins only if QtSql is in use - if not deploymentInfo.usesFramework("QtSql"): - continue - elif pluginDirectory == "script": - # Deploy the script plugins only if QtScript is in use - if not deploymentInfo.usesFramework("QtScript"): - continue - elif pluginDirectory == "qmltooling" or pluginDirectory == "qml1tooling": - # Deploy the qml plugins only if QtDeclarative is in use - if not deploymentInfo.usesFramework("QtDeclarative"): - continue - elif pluginDirectory == "bearer": - # Deploy the bearer plugins only if QtNetwork is in use - if not deploymentInfo.usesFramework("QtNetwork"): - continue - elif pluginDirectory == "position": - # Deploy the position plugins only if QtPositioning is in use - if not deploymentInfo.usesFramework("QtPositioning"): - continue - elif pluginDirectory == "sensors" or pluginDirectory == "sensorgestures": - # Deploy the sensor plugins only if QtSensors is in use - if not deploymentInfo.usesFramework("QtSensors"): - continue - elif pluginDirectory == "audio" or pluginDirectory == "playlistformats": - # Deploy the audio plugins only if QtMultimedia is in use - if not deploymentInfo.usesFramework("QtMultimedia"): - continue - elif pluginDirectory == "mediaservice": - # Deploy the mediaservice plugins only if QtMultimediaWidgets is in use - if not deploymentInfo.usesFramework("QtMultimediaWidgets"): - continue - elif pluginDirectory == "canbus": - # Deploy the canbus plugins only if QtSerialBus is in use - if not deploymentInfo.usesFramework("QtSerialBus"): - continue - elif pluginDirectory == "webview": - # Deploy the webview plugins only if QtWebView is in use - if not deploymentInfo.usesFramework("QtWebView"): - continue - elif pluginDirectory == "gamepads": - # Deploy the webview plugins only if QtGamepad is in use - if not deploymentInfo.usesFramework("QtGamepad"): - continue - elif pluginDirectory == "geoservices": - # Deploy the webview plugins only if QtLocation is in use - if not deploymentInfo.usesFramework("QtLocation"): - continue - elif pluginDirectory == "texttospeech": - # Deploy the texttospeech plugins only if QtTextToSpeech is in use - if not deploymentInfo.usesFramework("QtTextToSpeech"): - continue - elif pluginDirectory == "virtualkeyboard": - # Deploy the virtualkeyboard plugins only if QtVirtualKeyboard is in use - if not deploymentInfo.usesFramework("QtVirtualKeyboard"): - continue - elif pluginDirectory == "sceneparsers": - # Deploy the virtualkeyboard plugins only if Qt3DCore is in use - if not deploymentInfo.usesFramework("Qt3DCore"): - continue - elif pluginDirectory == "renderplugins": - # Deploy the renderplugins plugins only if Qt3DCore is in use - if not deploymentInfo.usesFramework("Qt3DCore"): - continue - elif pluginDirectory == "geometryloaders": - # Deploy the geometryloaders plugins only if Qt3DCore is in use - if not deploymentInfo.usesFramework("Qt3DCore"): - continue for pluginName in filenames: pluginPath = os.path.join(pluginDirectory, pluginName) - if pluginName.endswith("_debug.dylib"): - # Skip debug plugins + + if pluginName.split('.')[0] not in ['libqminimal', 'libqcocoa', 'libqmacstyle']: continue - elif pluginPath == "imageformats/libqsvg.dylib" or pluginPath == "iconengines/libqsvgicon.dylib": - # Deploy the svg plugins only if QtSvg is in use - if not deploymentInfo.usesFramework("QtSvg"): - continue - elif pluginPath == "accessible/libqtaccessiblecompatwidgets.dylib": - # Deploy accessibility for Qt3Support only if the Qt3Support is in use - if not deploymentInfo.usesFramework("Qt3Support"): - continue - elif pluginPath == "graphicssystems/libqglgraphicssystem.dylib": - # Deploy the opengl graphicssystem plugin only if QtOpenGL is in use - if not deploymentInfo.usesFramework("QtOpenGL"): - continue - elif pluginPath == "accessible/libqtaccessiblequick.dylib": - # Deploy the accessible qtquick plugin only if QtQuick is in use - if not deploymentInfo.usesFramework("QtQuick"): - continue - elif pluginPath == "platforminputcontexts/libqtvirtualkeyboardplugin.dylib": - # Deploy the virtualkeyboardplugin plugin only if QtVirtualKeyboard is in use - if not deploymentInfo.usesFramework("QtVirtualKeyboard"): - continue plugins.append((pluginDirectory, pluginName)) @@ -524,6 +422,9 @@ if os.path.exists(appname + ".dmg"): print("+ Removing existing DMG +") os.unlink(appname + ".dmg") +if os.path.exists(appname + ".temp.dmg"): + os.unlink(appname + ".temp.dmg") + # ------------------------------------------------ target = os.path.join("dist", "PRCYcoin-Qt.app") @@ -639,6 +540,24 @@ ds['PRCYcoin-Qt.app']['Iloc'] = (128, 156) ds.flush() ds.close() +# ------------------------------------------------ +if platform.system() == "Darwin": + subprocess.check_call(f"codesign --deep --force --sign - {target}", shell=True) + +print("+ Installing background.tiff +") + +bg_path = os.path.join('dist', '.background', 'background.tiff') +os.mkdir(os.path.dirname(bg_path)) + +tiff_path = os.path.join('contrib', 'macdeploy', 'background.tiff') +shutil.copy2(tiff_path, bg_path) + +# ------------------------------------------------ + +print("+ Generating symlink for /Applications +") + +os.symlink("/Applications", os.path.join('dist', "Applications")) + # ------------------------------------------------ if config.dmg is not None: @@ -664,19 +583,6 @@ if config.dmg is not None: print("Attaching temp image...") output = run(["hdiutil", "attach", tempname, "-readwrite"], check=True, universal_newlines=True, stdout=PIPE).stdout - m = re.search(r"/Volumes/(.+$)", output) - disk_root = m.group(0) - - print("+ Applying fancy settings +") - - bg_path = os.path.join(disk_root, ".background", os.path.basename('background.tiff')) - os.mkdir(os.path.dirname(bg_path)) - if verbose: - print('background.tiff', "->", bg_path) - shutil.copy2('background.tiff', bg_path) - - os.symlink("/Applications", os.path.join(disk_root, "Applications")) - print("+ Finalizing .dmg disk image +") run(["hdiutil", "detach", f"/Volumes/{appname}"], universal_newlines=True) diff --git a/contrib/prcycoin-qt.pro b/contrib/prcycoin-qt.pro index 0f55b4307b..c0b6296f8d 100644 --- a/contrib/prcycoin-qt.pro +++ b/contrib/prcycoin-qt.pro @@ -86,6 +86,7 @@ HEADERS += src/activemasternode.h \ src/compressor.h \ src/core_io.h \ src/cuckoocache.h \ + src/curl_json.h \ src/crypter.h \ src/eccryptoverify.h \ src/ecdhutil.h \ @@ -215,7 +216,6 @@ HEADERS += src/activemasternode.h \ src/qt/optionsmodel.h \ src/qt/optionspage.h \ src/qt/overviewpage.h \ - src/qt/paymentrequestplus.h \ src/qt/paymentserver.h \ src/qt/peertablemodel.h \ src/qt/qgoogleauth.h \ @@ -413,6 +413,7 @@ SOURCES += src/activemasternode.cpp \ src/compressor.cpp \ src/core_read.cpp \ src/core_write.cpp \ + src/curl_json.cpp \ src/crypter.cpp \ src/prcycoin-cli.cpp \ src/prcycoin-tx.cpp \ @@ -543,7 +544,6 @@ SOURCES += src/activemasternode.cpp \ src/qt/optionsmodel.cpp \ src/qt/optionspage.cpp \ src/qt/overviewpage.cpp \ - src/qt/paymentrequestplus.cpp \ src/qt/paymentserver.cpp \ src/qt/peertablemodel.cpp \ src/qt/qgoogleauth.cpp \ diff --git a/contrib/prcycoind.bash-completion b/contrib/prcycoind.bash-completion index bac417eafd..315b54649a 100644 --- a/contrib/prcycoind.bash-completion +++ b/contrib/prcycoind.bash-completion @@ -15,7 +15,7 @@ _prcycoind() { _get_comp_words_by_ref -n = cur prev words cword case "$cur" in - -conf=*|-pid=*|-loadblock=*|-rootcertificates=*|-rpccookiefile=*|-wallet=*) + -conf=*|-pid=*|-loadblock=*|-rpccookiefile=*|-wallet=*) cur="${cur#*=}" _filedir return 0 diff --git a/depends/Makefile b/depends/Makefile index ce76527e8a..33e7c58b81 100644 --- a/depends/Makefile +++ b/depends/Makefile @@ -2,7 +2,7 @@ # Pattern rule to print variables, e.g. make print-top_srcdir print-%: - @echo $* = $($*) + @echo '$*' = '$($*)' # When invoking a sub-make, keep only the command line variable definitions # matching the pattern in the filter function. @@ -37,7 +37,8 @@ NO_QR ?= NO_WALLET ?= NO_ZMQ ?= NO_UPNP ?= -FALLBACK_DOWNLOAD_PATH ?= https://bitcoincore.org/depends-sources +LTO ?= +FALLBACK_DOWNLOAD_PATH ?= https://bootstrap.prcycoin.com/depends-sources BUILD = $(shell ./config.guess) HOST ?= $(BUILD) @@ -71,6 +72,9 @@ build_vendor=$(word 2,$(subst -, ,$(build))) full_build_os:=$(subst $(build_arch)-$(build_vendor)-,,$(build)) build_os:=$(findstring linux,$(full_build_os)) build_os+=$(findstring darwin,$(full_build_os)) +build_os+=$(findstring freebsd,$(full_build_os)) +build_os+=$(findstring netbsd,$(full_build_os)) +build_os+=$(findstring openbsd,$(full_build_os)) build_os:=$(strip $(build_os)) ifeq ($(build_os),) build_os=$(full_build_os) @@ -81,6 +85,9 @@ host_vendor=$(word 2,$(subst -, ,$(canonical_host))) full_host_os:=$(subst $(host_arch)-$(host_vendor)-,,$(canonical_host)) host_os:=$(findstring linux,$(full_host_os)) host_os+=$(findstring darwin,$(full_host_os)) +host_os+=$(findstring freebsd,$(full_host_os)) +host_os+=$(findstring netbsd,$(full_host_os)) +host_os+=$(findstring openbsd,$(full_host_os)) host_os+=$(findstring mingw32,$(full_host_os)) ifeq (android,$(findstring android,$(full_host_os))) @@ -98,10 +105,6 @@ host_prefix=$($(host_arch)_$(host_os)_prefix) build_prefix=$(host_prefix)/native build_host=$(build) -AT_$(V):= -AT_:=@ -AT:=$(AT_$(V)) - all: install include hosts/$(host_os).mk @@ -110,24 +113,31 @@ include builders/$(build_os).mk include builders/default.mk include packages/packages.mk -build_id_string:=$(BUILD_ID_SALT) -build_id_string+=$(shell $(build_CC) --version 2>/dev/null) -build_id_string+=$(shell $(build_AR) --version 2>/dev/null) -build_id_string+=$(shell $(build_CXX) --version 2>/dev/null) -build_id_string+=$(shell $(build_RANLIB) --version 2>/dev/null) -build_id_string+=$(shell $(build_STRIP) --version 2>/dev/null) - -$(host_arch)_$(host_os)_id_string:=$(HOST_ID_SALT) -$(host_arch)_$(host_os)_id_string+=$(shell $(host_CC) --version 2>/dev/null) -$(host_arch)_$(host_os)_id_string+=$(shell $(host_AR) --version 2>/dev/null) -$(host_arch)_$(host_os)_id_string+=$(shell $(host_CXX) --version 2>/dev/null) -$(host_arch)_$(host_os)_id_string+=$(shell $(host_RANLIB) --version 2>/dev/null) -$(host_arch)_$(host_os)_id_string+=$(shell $(host_STRIP) --version 2>/dev/null) - -ifneq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) -build_id_string+=system_clang -$(host_arch)_$(host_os)_id_string+=system_clang -endif +# Previously, we directly invoked the well-known programs using $(shell ...) +# to contruct build_id_string. However, that was problematic because: +# +# 1. When invoking a shell, GNU Make special-cases exit code 127 (command not +# found) by not capturing the output but instead passing it through. This is +# not done for any other exit code. +# +# 2. Characters like '#' (from these programs' output) would end up in make +# variables like build_id_string, which would be wrongly interpreted by make +# when these variables were used. +# +# Therefore, we should avoid having arbitrary strings in make variables where +# possible. The gen_id script used here hashes the output to construct a +# "make-safe" id. +# +# Also note that these lines need to be: +# +# 1. After including {hosts,builders}/*.mk, since they rely on the tool +# variables (e.g. build_CC, host_STRIP, etc.) to be set. +# +# 2. Before including packages/*.mk (excluding packages/packages.mk), since +# they rely on the build_id variables +# +build_id:=$(shell env CC='$(build_CC)' CXX='$(build_CXX)' AR='$(build_AR)' RANLIB='$(build_RANLIB)' STRIP='$(build_STRIP)' SHA256SUM='$(build_SHA256SUM)' DEBUG='$(DEBUG)' LTO='$(LTO)' ./gen_id '$(BUILD_ID_SALT)') +$(host_arch)_$(host_os)_id:=$(shell env CC='$(host_CC)' CXX='$(host_CXX)' AR='$(host_AR)' RANLIB='$(host_RANLIB)' STRIP='$(host_STRIP)' SHA256SUM='$(build_SHA256SUM)' DEBUG='$(DEBUG)' LTO='$(LTO)' ./gen_id '$(HOST_ID_SALT)') qrencode_packages_$(NO_QR) = $(qrencode_packages) @@ -157,31 +167,52 @@ $(host_arch)_$(host_os)_native_toolchain?=$($(host_os)_native_toolchain) include funcs.mk -binutils_path=$($($(host_arch)_$(host_os)_native_binutils)_prefixbin) -ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) -toolchain_path=$($($(host_arch)_$(host_os)_native_toolchain)_prefixbin) -else -toolchain_path= -endif final_build_id_long+=$(shell $(build_SHA256SUM) config.site.in) final_build_id+=$(shell echo -n "$(final_build_id_long)" | $(build_SHA256SUM) | cut -c-$(HASH_LENGTH)) $(host_prefix)/.stamp_$(final_build_id): $(native_packages) $(packages) - $(AT)rm -rf $(@D) - $(AT)mkdir -p $(@D) - $(AT)echo copying packages: $^ - $(AT)echo to: $(@D) - $(AT)cd $(@D); $(foreach package,$^, tar xf $($(package)_cached); ) - $(AT)touch $@ - + rm -rf $(@D) + mkdir -p $(@D) + echo copying packages: $^ + echo to: $(@D) + cd $(@D); $(foreach package,$^, $(build_TAR) xf $($(package)_cached); ) + touch $@ + +# $PATH is not preserved between ./configure and make by convention. Its +# modification and overriding at ./configure time is (as I understand it) +# supposed to be captured by the AC_{PROG_{,OBJ}CXX,PATH_{PROG,TOOL}} macros, +# which will expand the program names to their full absolute paths. The notable +# exception is command line overriding: ./configure CC=clang, which skips the +# program name expansion step, and works because the user implicitly indicates +# with CC=clang that clang will be available in $PATH at all times, and is most +# likely part of the user's system. +# +# Therefore, when we "seed the autoconf cache"/"override well-known program +# vars" by setting AR= in our config.site, either one of two things needs +# to be true for the build system to work correctly: +# +# 1. If we refer to the program by name (e.g. AR=riscv64-gnu-linux-ar), the +# tool needs to be available in $PATH at all times. +# +# 2. If the tool is _**not**_ expected to be available in $PATH at all times +# (such as is the case for our native_cctools binutils tools), it needs to +# be referred to by its absolute path, such as would be output by the +# AC_PATH_{PROG,TOOL} macros. +# +# Minor note: it is also okay to refer to tools by their absolute path even if +# we expect them to be available in $PATH at all times, more specificity does +# not hurt. $(host_prefix)/share/config.site : config.site.in $(host_prefix)/.stamp_$(final_build_id) - $(AT)@mkdir -p $(@D) - $(AT)sed -e 's|@HOST@|$(host)|' \ - -e 's|@CC@|$(toolchain_path)$(host_CC)|' \ - -e 's|@CXX@|$(toolchain_path)$(host_CXX)|' \ - -e 's|@AR@|$(binutils_path)$(host_AR)|' \ - -e 's|@RANLIB@|$(binutils_path)$(host_RANLIB)|' \ - -e 's|@NM@|$(binutils_path)$(host_NM)|' \ - -e 's|@STRIP@|$(binutils_path)$(host_STRIP)|' \ + @mkdir -p $(@D) + sed -e 's|@HOST@|$(host)|' \ + -e 's|@CC@|$(host_CC)|' \ + -e 's|@CXX@|$(host_CXX)|' \ + -e 's|@AR@|$(host_AR)|' \ + -e 's|@RANLIB@|$(host_RANLIB)|' \ + -e 's|@NM@|$(host_NM)|' \ + -e 's|@STRIP@|$(host_STRIP)|' \ + -e 's|@OTOOL@|$(host_OTOOL)|' \ + -e 's|@INSTALL_NAME_TOOL@|$(host_INSTALL_NAME_TOOL)|' \ + -e 's|@DSYMUTIL@|$(host_DSYMUTIL)|' \ -e 's|@build_os@|$(build_os)|' \ -e 's|@host_os@|$(host_os)|' \ -e 's|@CFLAGS@|$(strip $(host_CFLAGS) $(host_$(release_type)_CFLAGS))|' \ @@ -194,9 +225,10 @@ $(host_prefix)/share/config.site : config.site.in $(host_prefix)/.stamp_$(final_ -e 's|@no_zmq@|$(NO_ZMQ)|' \ -e 's|@no_wallet@|$(NO_WALLET)|' \ -e 's|@no_upnp@|$(NO_UPNP)|' \ + -e 's|@lto@|$(LTO)|' \ -e 's|@debug@|$(DEBUG)|' \ $< > $@ - $(AT)touch $@ + touch $@ define check_or_remove_cached @@ -226,7 +258,7 @@ clean-all: clean @rm -rf $(SOURCES_PATH) x86_64* i686* mips* arm* aarch64* riscv32* riscv64* clean: - @rm -rf $(WORK_PATH) $(BASE_CACHE) $(BUILD) + @rm -rf $(WORK_PATH) $(BASE_CACHE) $(BUILD) *.log install: check-packages $(host_prefix)/share/config.site @@ -234,7 +266,7 @@ install: check-packages $(host_prefix)/share/config.site download-one: check-sources $(all_sources) download-osx: - @$(MAKE) -s HOST=x86_64-apple-darwin14 download-one + @$(MAKE) -s HOST=x86_64-apple-darwin download-one download-linux: @$(MAKE) -s HOST=x86_64-unknown-linux-gnu download-one download-win: @@ -244,3 +276,4 @@ download: download-osx download-linux download-win $(foreach package,$(all_packages),$(eval $(call ext_add_stages,$(package)))) .PHONY: install cached clean clean-all download-one download-osx download-linux download-win download check-packages check-sources +$(V).SILENT: \ No newline at end of file diff --git a/depends/README.md b/depends/README.md index bfbe7b9833..62cb9d28da 100644 --- a/depends/README.md +++ b/depends/README.md @@ -12,16 +12,23 @@ For example: make HOST=x86_64-w64-mingw32 -j4 -A prefix will be generated that's suitable for plugging into Bitcoin's -configure. In the above example, a dir named x86_64-w64-mingw32 will be -created. To use it for Bitcoin: +**Bitcoin Core's `configure` script by default will ignore the depends output.** In +order for it to pick up libraries, tools, and settings from the depends build, +you must set the `CONFIG_SITE` environment variable to point to a `config.site` settings file. +In the above example, a file named `depends/x86_64-w64-mingw32/share/config.site` will be +created. To use it during compilation: - ./configure --prefix=`pwd`/depends/x86_64-w64-mingw32 + CONFIG_SITE=$PWD/depends/x86_64-w64-mingw32/share/config.site ./configure -Common `host-platform-triplets` for cross compilation are: +The default install prefix when using `config.site` is `--prefix=depends/`, +so depends build outputs will be installed in that location. +Common `host-platform-triplet`s for cross compilation are: + +- `i686-pc-linux-gnu` for Linux 32 bit +- `x86_64-pc-linux-gnu` for x86 Linux - `x86_64-w64-mingw32` for Win64 -- `x86_64-apple-darwin16` for macOS +- `x86_64-apple-darwin18` for macOS - `arm-linux-gnueabihf` for Linux ARM 32 bit - `aarch64-linux-gnu` for Linux ARM 64 bit - `riscv32-linux-gnu` for Linux RISC-V 32 bit @@ -37,7 +44,7 @@ The paths are automatically configured and no other options are needed unless ta #### For macOS cross compilation - sudo apt-get install curl librsvg2-bin libtiff-tools bsdmainutils cmake imagemagick libcap-dev libz-dev libbz2-dev python3-setuptools + sudo apt-get install curl bsdmainutils cmake libcap-dev libz-dev libbz2-dev python3-setuptools libtinfo5 Note: You must obtain the macOS SDK before proceeding with a cross-compile. Under the depends directory, create a subdirectory named `SDKs`. @@ -52,7 +59,7 @@ For more information, see [SDK Extraction](../contrib/macdeploy/README.md#sdk-ex Common linux dependencies: - sudo apt-get install make automake cmake curl g++-multilib libtool binutils-gold bsdmainutils pkg-config python3 patch + sudo apt-get install make automake cmake curl g++-multilib libtool binutils-gold bsdmainutils pkg-config python3 patch bison For linux ARM cross compilation: @@ -69,43 +76,36 @@ For linux RISC-V 64-bit cross compilation (there are no packages for 32-bit): RISC-V known issue: gcc-7.3.0 and gcc-7.3.1 result in a broken `test_prcy` executable (see https://github.com/bitcoin/bitcoin/pull/13543), this is apparently fixed in gcc-8.1.0. +### Install the required dependencies: OpenBSD + + pkg_add bash gtar + ### Dependency Options + The following can be set when running make: `make FOO=bar` -
-
SOURCES_PATH
-
downloaded sources will be placed here
-
BASE_CACHE
-
built packages will be placed here
-
SDK_PATH
-
Path where sdk's can be found (used by macOS)
-
FALLBACK_DOWNLOAD_PATH
-
If a source file can't be fetched, try here before giving up
-
NO_QT
-
Don't download/build/cache qt and its dependencies
-
NO_QR
-
Don't download/build/cache packages needed for enabling qrencode
-
NO_ZMQ
-
Don't download/build/cache packages needed for enabling zeromq
-
NO_WALLET
-
Don't download/build/cache libs needed to enable the wallet
-
NO_UPNP
-
Don't download/build/cache packages needed for enabling upnp
-
ALLOW_HOST_PACKAGES
-
Packages that are missed in dependencies (due to `NO_*` option or -build script logic) are searched for among the host system packages using -`pkg-config`. It allows building with packages of other (newer) versions
-
DEBUG
-
disable some optimizations and enable more runtime checking
-
HOST_ID_SALT
-
Optional salt to use when generating host package ids
-
BUILD_ID_SALT
-
Optional salt to use when generating build package ids
-
FORCE_USE_SYSTEM_CLANG
-
(EXPERTS ONLY) When cross-compiling for macOS, use clang found in the -system's $PATH rather than the default prebuilt release of clang -from llvm.org
-
+- `SOURCES_PATH`: Downloaded sources will be placed here +- `BASE_CACHE`: Built packages will be placed here +- `SDK_PATH`: Path where SDKs can be found (used by macOS) +- `FALLBACK_DOWNLOAD_PATH`: If a source file can't be fetched, try here before giving up +- `NO_QT`: Don't download/build/cache Qt and its dependencies +- `NO_QR`: Don't download/build/cache packages needed for enabling qrencode +- `NO_ZMQ`: Don't download/build/cache packages needed for enabling ZeroMQ +- `NO_WALLET`: Don't download/build/cache libs needed to enable the wallet +- `NO_UPNP`: Don't download/build/cache packages needed for enabling UPnP +- `ALLOW_HOST_PACKAGES`: Packages that are missed in dependencies (due to `NO_*` option or + build script logic) are searched for among the host system packages using + `pkg-config`. It allows building with packages of other (newer) versions +- `DEBUG`: Disable some optimizations and enable more runtime checking +- `HOST_ID_SALT`: Optional salt to use when generating host package ids +- `BUILD_ID_SALT`: Optional salt to use when generating build package ids +- `FORCE_USE_SYSTEM_CLANG`: (EXPERTS ONLY) When cross-compiling for macOS, use Clang found in the + system's `$PATH` rather than the default prebuilt release of Clang + from llvm.org. Clang 8 or later is required +- `LOG`: Use file-based logging for individual packages. During a package build its log file + resides in the `depends` directory, and the log file is printed out automatically in case + of build error. After successful build log files are moved along with package archives +- `LTO`: Use LTO when building packages. If some packages are not built, for example `make NO_WALLET=1`, the appropriate options will be passed to bitcoin's configure. In this case, `--disable-wallet`. diff --git a/depends/builders/darwin.mk b/depends/builders/darwin.mk index 986ad9b03d..7858ab0120 100644 --- a/depends/builders/darwin.mk +++ b/depends/builders/darwin.mk @@ -6,6 +6,7 @@ build_darwin_STRIP:=$(shell xcrun -f strip) build_darwin_OTOOL:=$(shell xcrun -f otool) build_darwin_NM:=$(shell xcrun -f nm) build_darwin_INSTALL_NAME_TOOL:=$(shell xcrun -f install_name_tool) +build_darwin_DSYMUTIL:=$(shell xcrun -f dsymutil) build_darwin_SHA256SUM=shasum -a 256 build_darwin_DOWNLOAD=curl --location --fail --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -o @@ -19,5 +20,6 @@ darwin_LIBTOOL:=$(shell xcrun -f libtool) darwin_OTOOL:=$(shell xcrun -f otool) darwin_NM:=$(shell xcrun -f nm) darwin_INSTALL_NAME_TOOL:=$(shell xcrun -f install_name_tool) +darwin_DSYMUTIL:=$(shell xcrun -f dsymutil) darwin_native_binutils= darwin_native_toolchain= diff --git a/depends/builders/default.mk b/depends/builders/default.mk index f097db65d6..cc6dec66c2 100644 --- a/depends/builders/default.mk +++ b/depends/builders/default.mk @@ -1,18 +1,17 @@ default_build_CC = gcc default_build_CXX = g++ default_build_AR = ar +default_build_TAR = tar default_build_RANLIB = ranlib default_build_STRIP = strip default_build_NM = nm -default_build_OTOOL = otool -default_build_INSTALL_NAME_TOOL = install_name_tool define add_build_tool_func build_$(build_os)_$1 ?= $$(default_build_$1) build_$(build_arch)_$(build_os)_$1 ?= $$(build_$(build_os)_$1) build_$1=$$(build_$(build_arch)_$(build_os)_$1) endef -$(foreach var,CC CXX AR RANLIB NM STRIP SHA256SUM DOWNLOAD OTOOL INSTALL_NAME_TOOL,$(eval $(call add_build_tool_func,$(var)))) +$(foreach var,CC CXX AR TAR RANLIB NM STRIP SHA256SUM DOWNLOAD OTOOL INSTALL_NAME_TOOL DSYMUTIL,$(eval $(call add_build_tool_func,$(var)))) define add_build_flags_func build_$(build_arch)_$(build_os)_$1 += $(build_$(build_os)_$1) build_$1=$$(build_$(build_arch)_$(build_os)_$1) diff --git a/depends/builders/freebsd.mk b/depends/builders/freebsd.mk new file mode 100644 index 0000000000..465f58e04d --- /dev/null +++ b/depends/builders/freebsd.mk @@ -0,0 +1,5 @@ +build_freebsd_CC=clang +build_freebsd_CXX=clang++ + +build_freebsd_SHA256SUM = shasum -a 256 +build_freebsd_DOWNLOAD = curl --location --fail --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -o diff --git a/depends/builders/netbsd.mk b/depends/builders/netbsd.mk new file mode 100644 index 0000000000..b7cf1f7514 --- /dev/null +++ b/depends/builders/netbsd.mk @@ -0,0 +1,2 @@ +build_netbsd_SHA256SUM = shasum -a 256 +build_netbsd_DOWNLOAD = curl --location --fail --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -o diff --git a/depends/builders/openbsd.mk b/depends/builders/openbsd.mk new file mode 100644 index 0000000000..44825d106a --- /dev/null +++ b/depends/builders/openbsd.mk @@ -0,0 +1,7 @@ +build_openbsd_CC = clang +build_openbsd_CXX = clang++ + +build_openbsd_SHA256SUM = sha256 +build_openbsd_DOWNLOAD = curl --location --fail --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -o + +build_openbsd_TAR = gtar diff --git a/depends/config.site.in b/depends/config.site.in index 9842a672e6..228628bcbe 100644 --- a/depends/config.site.in +++ b/depends/config.site.in @@ -1,72 +1,88 @@ -depends_prefix="`dirname ${ac_site_file}`/.." +# shellcheck shell=sh disable=SC2034 # Many variables set will be used in + # ./configure but shellcheck doesn't know + # that, hence: disable=SC2034 + +true # Dummy command because shellcheck treats all directives before first + # command as file-wide, and we only want to disable for one line. + # + # See: https://github.com/koalaman/shellcheck/wiki/Directive + +# shellcheck disable=SC2154 +depends_prefix="$(cd "$(dirname "$ac_site_file")/.." && pwd)" cross_compiling=maybe -host_alias=@HOST@ -ac_tool_prefix=${host_alias}- +host_alias="@HOST@" +ac_tool_prefix="${host_alias}-" -if test -z $with_boost; then - with_boost=$depends_prefix +if test -z "$with_boost"; then + with_boost="$depends_prefix" fi -if test -z $with_qt_plugindir; then - with_qt_plugindir=$depends_prefix/plugins +if test -z "$with_qt_plugindir"; then + with_qt_plugindir="${depends_prefix}/plugins" fi -if test -z $with_qt_translationdir; then - with_qt_translationdir=$depends_prefix/translations +if test -z "$with_qt_translationdir"; then + with_qt_translationdir="${depends_prefix}/translations" fi -if test -z $with_qt_bindir && test -z "@no_qt@"; then - with_qt_bindir=$depends_prefix/native/bin +if test -z "$with_qt_bindir" && test -z "@no_qt@"; then + with_qt_bindir="${depends_prefix}/native/bin" fi -if test -z $with_protoc_bindir && test -z "@no_qt@"; then - with_protoc_bindir=$depends_prefix/native/bin +if test -z "$with_mpgen" && test -n "@multiprocess@"; then + with_mpgen="${depends_prefix}/native" fi -if test -z $with_qrencode && test -n "@no_qr@"; then +if test -z "$with_qrencode" && test -n "@no_qr@"; then with_qrencode=no fi -if test -z $enable_wallet && test -n "@no_wallet@"; then +if test -z "$enable_wallet" && test -n "@no_wallet@"; then enable_wallet=no fi -if test -z $with_miniupnpc && test -n "@no_upnp@"; then +if test -z "$enable_multiprocess" && test -n "@multiprocess@"; then + enable_multiprocess=yes +fi + +if test -z "$with_miniupnpc" && test -n "@no_upnp@"; then with_miniupnpc=no fi -if test -z $with_gui && test -n "@no_qt@"; then +if test -z "$with_natpmp" && test -n "@no_natpmp@"; then + with_natpmp=no +fi + +if test -z "$with_gui" && test -n "@no_qt@"; then with_gui=no fi -if test -z $enable_zmq && test -n "@no_zmq@"; then +if test -n "@debug@" && test -z "@no_qt@" && test "x$with_gui" != xno; then + with_gui=qt5_debug +fi + +if test -z "$enable_zmq" && test -n "@no_zmq@"; then enable_zmq=no fi -if test x@host_os@ = xdarwin; then +if test "x@host_os@" = xdarwin; then BREW=no PORT=no fi -if test x@host_os@ = xmingw32; then - if test -z $with_qt_incdir; then - with_qt_incdir=$depends_prefix/include - fi - if test -z $with_qt_libdir; then - with_qt_libdir=$depends_prefix/lib - fi +if test -z "$enable_lto" && test -n "@lto@"; then + enable_lto=yes fi -PATH=$depends_prefix/native/bin:$PATH -PKG_CONFIG="`which pkg-config` --static" +PKG_CONFIG="$(which pkg-config) --static" # These two need to remain exported because pkg-config does not see them # otherwise. That means they must be unexported at the end of configure.ac to # avoid ruining the cache. Sigh. -export PKG_CONFIG_PATH=$depends_prefix/share/pkgconfig:$depends_prefix/lib/pkgconfig +export PKG_CONFIG_PATH="${depends_prefix}/share/pkgconfig:${depends_prefix}/lib/pkgconfig" if test -z "@allow_host_packages@"; then - export PKG_CONFIG_LIBDIR=$depends_prefix/lib/pkgconfig + export PKG_CONFIG_LIBDIR="${depends_prefix}/lib/pkgconfig" fi -CPPFLAGS="-I$depends_prefix/include/ $CPPFLAGS" -LDFLAGS="-L$depends_prefix/lib $LDFLAGS" +CPPFLAGS="-I${depends_prefix}/include/ ${CPPFLAGS}" +LDFLAGS="-L${depends_prefix}/lib ${LDFLAGS}" if test -n "@CC@" -a -z "${CC}"; then CC="@CC@" @@ -74,21 +90,43 @@ fi if test -n "@CXX@" -a -z "${CXX}"; then CXX="@CXX@" fi -PYTHONPATH=$depends_prefix/native/lib/python3/dist-packages:$PYTHONPATH +PYTHONPATH="${depends_prefix}/native/lib/python3/dist-packages${PYTHONPATH:+${PATH_SEPARATOR}}${PYTHONPATH}" if test -n "@AR@"; then - AR=@AR@ - ac_cv_path_ac_pt_AR=${AR} + AR="@AR@" + ac_cv_path_AR="${AR}" fi if test -n "@RANLIB@"; then - RANLIB=@RANLIB@ - ac_cv_path_ac_pt_RANLIB=${RANLIB} + RANLIB="@RANLIB@" + ac_cv_path_ac_pt_RANLIB="${RANLIB}" fi if test -n "@NM@"; then - NM=@NM@ - ac_cv_path_ac_pt_NM=${NM} + NM="@NM@" + ac_cv_path_ac_pt_NM="${NM}" +fi + +if test -n "@STRIP@"; then + STRIP="@STRIP@" + ac_cv_path_ac_pt_STRIP="${STRIP}" +fi + +if test "@host_os@" = darwin; then + if test -n "@OTOOL@"; then + OTOOL="@OTOOL@" + ac_cv_path_OTOOL="${OTOOL}" + fi + + if test -n "@INSTALL_NAME_TOOL@"; then + INSTALL_NAME_TOOL="@INSTALL_NAME_TOOL@" + ac_cv_path_INSTALL_NAME_TOOL="${INSTALL_NAME_TOOL}" + fi + + if test -n "@DSYMUTIL@"; then + DSYMUTIL="@DSYMUTIL@" + ac_cv_path_DSYMUTIL="${DSYMUTIL}" + fi fi if test -n "@debug@"; then @@ -96,14 +134,14 @@ if test -n "@debug@"; then fi if test -n "@CFLAGS@"; then - CFLAGS="@CFLAGS@ $CFLAGS" + CFLAGS="@CFLAGS@ ${CFLAGS}" fi if test -n "@CXXFLAGS@"; then - CXXFLAGS="@CXXFLAGS@ $CXXFLAGS" + CXXFLAGS="@CXXFLAGS@ ${CXXFLAGS}" fi if test -n "@CPPFLAGS@"; then - CPPFLAGS="@CPPFLAGS@ $CPPFLAGS" + CPPFLAGS="@CPPFLAGS@ ${CPPFLAGS}" fi if test -n "@LDFLAGS@"; then - LDFLAGS="@LDFLAGS@ $LDFLAGS" + LDFLAGS="@LDFLAGS@ ${LDFLAGS}" fi diff --git a/depends/funcs.mk b/depends/funcs.mk index 11dfe743d7..dd5d49636c 100644 --- a/depends/funcs.mk +++ b/depends/funcs.mk @@ -1,17 +1,23 @@ define int_vars #Set defaults for vars which may be overridden per-package -$(1)_cc=$($($(1)_type)_CC) -$(1)_cxx=$($($(1)_type)_CXX) -$(1)_objc=$($($(1)_type)_OBJC) -$(1)_objcxx=$($($(1)_type)_OBJCXX) -$(1)_ar=$($($(1)_type)_AR) -$(1)_ranlib=$($($(1)_type)_RANLIB) -$(1)_libtool=$($($(1)_type)_LIBTOOL) -$(1)_nm=$($($(1)_type)_NM) -$(1)_cflags=$($($(1)_type)_CFLAGS) $($($(1)_type)_$(release_type)_CFLAGS) -$(1)_cxxflags=$($($(1)_type)_CXXFLAGS) $($($(1)_type)_$(release_type)_CXXFLAGS) -$(1)_ldflags=$($($(1)_type)_LDFLAGS) $($($(1)_type)_$(release_type)_LDFLAGS) -L$($($(1)_type)_prefix)/lib -$(1)_cppflags=$($($(1)_type)_CPPFLAGS) $($($(1)_type)_$(release_type)_CPPFLAGS) -I$($($(1)_type)_prefix)/include +$(1)_cc=$$($$($(1)_type)_CC) +$(1)_cxx=$$($$($(1)_type)_CXX) +$(1)_objc=$$($$($(1)_type)_OBJC) +$(1)_objcxx=$$($$($(1)_type)_OBJCXX) +$(1)_ar=$$($$($(1)_type)_AR) +$(1)_ranlib=$$($$($(1)_type)_RANLIB) +$(1)_libtool=$$($$($(1)_type)_LIBTOOL) +$(1)_nm=$$($$($(1)_type)_NM) +$(1)_cflags=$$($$($(1)_type)_CFLAGS) \ + $$($$($(1)_type)_$$(release_type)_CFLAGS) +$(1)_cxxflags=$$($$($(1)_type)_CXXFLAGS) \ + $$($$($(1)_type)_$$(release_type)_CXXFLAGS) +$(1)_ldflags=$$($$($(1)_type)_LDFLAGS) \ + $$($$($(1)_type)_$$(release_type)_LDFLAGS) \ + -L$$($($(1)_type)_prefix)/lib +$(1)_cppflags=$$($$($(1)_type)_CPPFLAGS) \ + $$($$($(1)_type)_$$(release_type)_CPPFLAGS) \ + -I$$($$($(1)_type)_prefix)/include $(1)_recipe_hash:= endef @@ -43,7 +49,7 @@ define int_get_build_id $(eval $(1)_dependencies += $($(1)_$(host_arch)_$(host_os)_dependencies) $($(1)_$(host_os)_dependencies)) $(eval $(1)_all_dependencies:=$(call int_get_all_dependencies,$(1),$($($(1)_type)_native_toolchain) $($($(1)_type)_native_binutils) $($(1)_dependencies))) $(foreach dep,$($(1)_all_dependencies),$(eval $(1)_build_id_deps+=$(dep)-$($(dep)_version)-$($(dep)_recipe_hash))) -$(eval $(1)_build_id_long:=$(1)-$($(1)_version)-$($(1)_recipe_hash)-$(release_type) $($(1)_build_id_deps) $($($(1)_type)_id_string)) +$(eval $(1)_build_id_long:=$(1)-$($(1)_version)-$($(1)_recipe_hash)-$(release_type) $($(1)_build_id_deps) $($($(1)_type)_id)) $(eval $(1)_build_id:=$(shell echo -n "$($(1)_build_id_long)" | $(build_SHA256SUM) | cut -c-$(HASH_LENGTH))) final_build_id_long+=$($(package)_build_id_long) @@ -61,6 +67,7 @@ $(1)_cached_checksum:=$(BASE_CACHE)/$(host)/$(1)/$(1)-$($(1)_version)-$($(1)_bui $(1)_patch_dir:=$(base_build_dir)/$(host)/$(1)/$($(1)_version)-$($(1)_build_id)/.patches-$($(1)_build_id) $(1)_prefixbin:=$($($(1)_type)_prefix)/bin/ $(1)_cached:=$(BASE_CACHE)/$(host)/$(1)/$(1)-$($(1)_version)-$($(1)_build_id).tar.gz +$(1)_build_log:=$(BASEDIR)/$(1)-$($(1)_version)-$($(1)_build_id).log $(1)_all_sources=$($(1)_file_name) $($(1)_extra_sources) #stamps @@ -78,11 +85,11 @@ $(1)_download_path_fixed=$(subst :,\:,$$($(1)_download_path)) #default commands # The default behavior for tar will try to set ownership when running as uid 0 and may not succeed, --no-same-owner disables this behavior $(1)_fetch_cmds ?= $(call fetch_file,$(1),$(subst \:,:,$$($(1)_download_path_fixed)),$$($(1)_download_file),$($(1)_file_name),$($(1)_sha256_hash)) -$(1)_extract_cmds ?= mkdir -p $$($(1)_extract_dir) && echo "$$($(1)_sha256_hash) $$($(1)_source)" > $$($(1)_extract_dir)/.$$($(1)_file_name).hash && $(build_SHA256SUM) -c $$($(1)_extract_dir)/.$$($(1)_file_name).hash && tar --no-same-owner --strip-components=1 -xf $$($(1)_source) -$(1)_preprocess_cmds ?= -$(1)_build_cmds ?= -$(1)_config_cmds ?= -$(1)_stage_cmds ?= +$(1)_extract_cmds ?= mkdir -p $$($(1)_extract_dir) && echo "$$($(1)_sha256_hash) $$($(1)_source)" > $$($(1)_extract_dir)/.$$($(1)_file_name).hash && $(build_SHA256SUM) -c $$($(1)_extract_dir)/.$$($(1)_file_name).hash && $(build_TAR) --no-same-owner --strip-components=1 -xf $$($(1)_source) +$(1)_preprocess_cmds ?= true +$(1)_build_cmds ?= true +$(1)_config_cmds ?= true +$(1)_stage_cmds ?= true $(1)_set_vars ?= @@ -130,10 +137,11 @@ $(1)_config_env+=$($(1)_config_env_$(host_arch)_$(host_os)) $($(1)_config_env_$( $(1)_config_env+=PKG_CONFIG_LIBDIR=$($($(1)_type)_prefix)/lib/pkgconfig $(1)_config_env+=PKG_CONFIG_PATH=$($($(1)_type)_prefix)/share/pkgconfig +$(1)_config_env+=PKG_CONFIG_SYSROOT_DIR=/ $(1)_config_env+=PATH=$(build_prefix)/bin:$(PATH) $(1)_build_env+=PATH=$(build_prefix)/bin:$(PATH) $(1)_stage_env+=PATH=$(build_prefix)/bin:$(PATH) -$(1)_autoconf=./configure --host=$($($(1)_type)_host) --disable-dependency-tracking --prefix=$($($(1)_type)_prefix) $$($(1)_config_opts) CC="$$($(1)_cc)" CXX="$$($(1)_cxx)" +$(1)_autoconf=./configure --host=$($($(1)_type)_host) --prefix=$($($(1)_type)_prefix) $$($(1)_config_opts) CC="$$($(1)_cc)" CXX="$$($(1)_cxx)" ifneq ($($(1)_nm),) $(1)_autoconf += NM="$$($(1)_nm)" @@ -159,54 +167,61 @@ endif endef define int_add_cmds +ifneq ($(LOG),) +$(1)_logging = >>$$($(1)_build_log) 2>&1 || { if test -f $$($(1)_build_log); then cat $$($(1)_build_log); fi; exit 1; } +endif + $($(1)_fetched): - $(AT)mkdir -p $$(@D) $(SOURCES_PATH) - $(AT)rm -f $$@ - $(AT)touch $$@ - $(AT)cd $$(@D); $(call $(1)_fetch_cmds,$(1)) - $(AT)cd $($(1)_source_dir); $(foreach source,$($(1)_all_sources),$(build_SHA256SUM) $(source) >> $$(@);) - $(AT)touch $$@ + mkdir -p $$(@D) $(SOURCES_PATH) + rm -f $$@ + touch $$@ + cd $$(@D); $($(1)_fetch_cmds) + cd $($(1)_source_dir); $(foreach source,$($(1)_all_sources),$(build_SHA256SUM) $(source) >> $$(@);) + touch $$@ $($(1)_extracted): | $($(1)_fetched) - $(AT)echo Extracting $(1)... - $(AT)mkdir -p $$(@D) - $(AT)cd $$(@D); $(call $(1)_extract_cmds,$(1)) - $(AT)touch $$@ + echo Extracting $(1)... + mkdir -p $$(@D) + cd $$(@D); $($(1)_extract_cmds) + touch $$@ $($(1)_preprocessed): | $($(1)_extracted) - $(AT)echo Preprocessing $(1)... - $(AT)mkdir -p $$(@D) $($(1)_patch_dir) - $(AT)$(foreach patch,$($(1)_patches),cd $(PATCHES_PATH)/$(1); cp $(patch) $($(1)_patch_dir) ;) - $(AT)cd $$(@D); $(call $(1)_preprocess_cmds, $(1)) - $(AT)touch $$@ + echo Preprocessing $(1)... + mkdir -p $$(@D) $($(1)_patch_dir) + $(foreach patch,$($(1)_patches),cd $(PATCHES_PATH)/$(1); cp $(patch) $($(1)_patch_dir) ;) + { cd $$(@D); $($(1)_preprocess_cmds); } $$($(1)_logging) + touch $$@ $($(1)_configured): | $($(1)_dependencies) $($(1)_preprocessed) - $(AT)echo Configuring $(1)... - $(AT)rm -rf $(host_prefix); mkdir -p $(host_prefix)/lib; cd $(host_prefix); $(foreach package,$($(1)_all_dependencies), tar --no-same-owner -xf $($(package)_cached); ) - $(AT)mkdir -p $$(@D) - $(AT)+cd $$(@D); $($(1)_config_env) $(call $(1)_config_cmds, $(1)) - $(AT)touch $$@ + echo Configuring $(1)... + rm -rf $(host_prefix); mkdir -p $(host_prefix)/lib; cd $(host_prefix); $(foreach package,$($(1)_all_dependencies), $(build_TAR) --no-same-owner -xf $($(package)_cached); ) + mkdir -p $$(@D) + +{ cd $$(@D); export $($(1)_config_env); $($(1)_config_cmds); } $$($(1)_logging) + touch $$@ $($(1)_built): | $($(1)_configured) - $(AT)echo Building $(1)... - $(AT)mkdir -p $$(@D) - $(AT)+cd $$(@D); $($(1)_build_env) $(call $(1)_build_cmds, $(1)) - $(AT)touch $$@ + echo Building $(1)... + mkdir -p $$(@D) + +{ cd $$(@D); export $($(1)_build_env); $($(1)_build_cmds); } $$($(1)_logging) + touch $$@ $($(1)_staged): | $($(1)_built) - $(AT)echo Staging $(1)... - $(AT)mkdir -p $($(1)_staging_dir)/$(host_prefix) - $(AT)cd $($(1)_build_dir); $($(1)_stage_env) $(call $(1)_stage_cmds, $(1)) - $(AT)rm -rf $($(1)_extract_dir) - $(AT)touch $$@ + echo Staging $(1)... + mkdir -p $($(1)_staging_dir)/$(host_prefix) + +{ cd $($(1)_build_dir); export $($(1)_stage_env); $($(1)_stage_cmds); } $$($(1)_logging) + rm -rf $($(1)_extract_dir) + touch $$@ $($(1)_postprocessed): | $($(1)_staged) - $(AT)echo Postprocessing $(1)... - $(AT)cd $($(1)_staging_prefix_dir); $(call $(1)_postprocess_cmds) - $(AT)touch $$@ + echo Postprocessing $(1)... + cd $($(1)_staging_prefix_dir); $($(1)_postprocess_cmds) + touch $$@ $($(1)_cached): | $($(1)_dependencies) $($(1)_postprocessed) - $(AT)echo Caching $(1)... - $(AT)cd $$($(1)_staging_dir)/$(host_prefix); find . | sort | tar --no-recursion -czf $$($(1)_staging_dir)/$$(@F) -T - - $(AT)mkdir -p $$(@D) - $(AT)rm -rf $$(@D) && mkdir -p $$(@D) - $(AT)mv $$($(1)_staging_dir)/$$(@F) $$(@) - $(AT)rm -rf $($(1)_staging_dir) + echo Caching $(1)... + cd $$($(1)_staging_dir)/$(host_prefix); \ + find . ! -name '.stamp_postprocessed' -print0 | TZ=UTC xargs -0r touch -h -m -t 200001011200; \ + find . ! -name '.stamp_postprocessed' | LC_ALL=C sort | $(build_TAR) --numeric-owner --no-recursion -czf $$($(1)_staging_dir)/$$(@F) -T - + mkdir -p $$(@D) + rm -rf $$(@D) && mkdir -p $$(@D) + mv $$($(1)_staging_dir)/$$(@F) $$(@) + rm -rf $($(1)_staging_dir) + if test -f $($(1)_build_log); then mv $($(1)_build_log) $$(@D); fi $($(1)_cached_checksum): $($(1)_cached) - $(AT)cd $$(@D); $(build_SHA256SUM) $$( $$(@) + cd $$(@D); $(build_SHA256SUM) $$( $$(@) .PHONY: $(1) $(1): | $($(1)_cached_checksum) diff --git a/depends/gen_id b/depends/gen_id new file mode 100755 index 0000000000..a0cd586461 --- /dev/null +++ b/depends/gen_id @@ -0,0 +1,78 @@ +#!/usr/bin/env bash + +# Usage: env [ CC=... ] [ CXX=... ] [ AR=... ] [ RANLIB=... ] [ STRIP=... ] \ +# [ DEBUG=... ] [ LTO=... ] ./build-id [ID_SALT]... +# +# Prints to stdout a SHA256 hash representing the current toolset, used by +# depends/Makefile as a build id for caching purposes (detecting when the +# toolset has changed and the cache needs to be invalidated). +# +# If the DEBUG environment variable is non-empty and the system has `tee` +# available in its $PATH, the pre-image to the SHA256 hash will be printed to +# stderr. This is to help developers debug caching issues in depends. + +# This script explicitly does not `set -e` because id determination is mostly +# opportunistic: it is fine that things fail, as long as they fail consistently. + +# Command variables (CC/CXX/AR) which can be blank are invoked with `bash -c`, +# because the "command not found" error message printed by shells often include +# the line number, like so: +# +# ./depends/gen_id: line 43: --version: command not found +# +# By invoking with `bash -c`, we ensure that the line number is always 1 + +( + # Redirect stderr to stdout + exec 2>&1 + + echo "BEGIN ALL" + + # Include any ID salts supplied via command line + echo "BEGIN ID SALT" + echo "$@" + echo "END ID SALT" + + # GCC only prints COLLECT_LTO_WRAPPER when invoked with just "-v", but we want + # the information from "-v -E -" as well, so just include both. + echo "BEGIN CC" + bash -c "${CC} -v" + bash -c "${CC} -v -E -xc -o /dev/null - < /dev/null" + bash -c "${CC} -v -E -xobjective-c -o /dev/null - < /dev/null" + echo "END CC" + + echo "BEGIN CXX" + bash -c "${CXX} -v" + bash -c "${CXX} -v -E -xc++ -o /dev/null - < /dev/null" + bash -c "${CXX} -v -E -xobjective-c++ -o /dev/null - < /dev/null" + echo "END CXX" + + echo "BEGIN AR" + bash -c "${AR} --version" + env | grep '^AR_' + echo "ZERO_AR_DATE=${ZERO_AR_DATE}" + echo "END AR" + + echo "BEGIN RANLIB" + bash -c "${RANLIB} --version" + env | grep '^RANLIB_' + echo "END RANLIB" + + echo "BEGIN STRIP" + bash -c "${STRIP} --version" + env | grep '^STRIP_' + echo "END STRIP" + + echo "BEGIN LTO" + echo "LTO=${LTO}" + echo "END LTO" + + echo "END ALL" +) | if [ -n "$DEBUG" ] && command -v tee > /dev/null 2>&1; then + # When debugging and `tee` is available, output the preimage to stderr + # in addition to passing through stdin to stdout + tee >(cat 1>&2) + else + # Otherwise, passthrough stdin to stdout + cat + fi | ${SHA256SUM} - | cut -d' ' -f1 diff --git a/depends/hosts/android.mk b/depends/hosts/android.mk index 4784f77a72..df70ef10ec 100644 --- a/depends/hosts/android.mk +++ b/depends/hosts/android.mk @@ -8,4 +8,9 @@ android_AR=$(ANDROID_TOOLCHAIN_BIN)/$(HOST)-ar android_CXX=$(ANDROID_TOOLCHAIN_BIN)/$(HOST)$(ANDROID_API_LEVEL)-clang++ android_CC=$(ANDROID_TOOLCHAIN_BIN)/$(HOST)$(ANDROID_API_LEVEL)-clang android_RANLIB=$(ANDROID_TOOLCHAIN_BIN)/$(HOST)-ranlib +endif + +ifneq ($(LTO),) +android_CFLAGS += -flto +android_LDFLAGS += -flto endif \ No newline at end of file diff --git a/depends/hosts/darwin.mk b/depends/hosts/darwin.mk index 3e16780cca..62ddb02b43 100644 --- a/depends/hosts/darwin.mk +++ b/depends/hosts/darwin.mk @@ -1,11 +1,53 @@ -OSX_MIN_VERSION=10.12 -OSX_SDK_VERSION=10.15.1 -XCODE_VERSION=11.3.1 -XCODE_BUILD_ID=11C505 -LD64_VERSION=530 +OSX_MIN_VERSION=10.14 +OSX_SDK_VERSION=10.15.6 +XCODE_VERSION=12.1 +XCODE_BUILD_ID=12A7403 +LD64_VERSION=609 OSX_SDK=$(SDK_PATH)/Xcode-$(XCODE_VERSION)-$(XCODE_BUILD_ID)-extracted-SDK-with-libcxx-headers +darwin_native_binutils=native_cctools + +ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) +# FORCE_USE_SYSTEM_CLANG is empty, so we use our depends-managed, pinned clang +# from llvm.org + +# Clang is a dependency of native_cctools when FORCE_USE_SYSTEM_CLANG is empty +darwin_native_toolchain=native_cctools + +clang_prog=$(build_prefix)/bin/clang +clangxx_prog=$(clang_prog)++ + +clang_resource_dir=$(build_prefix)/lib/clang/$(native_clang_version) +else +# FORCE_USE_SYSTEM_CLANG is non-empty, so we use the clang from the user's +# system + +darwin_native_toolchain= + +# We can't just use $(shell command -v clang) because GNU Make handles builtins +# in a special way and doesn't know that `command` is a POSIX-standard builtin +# prior to 1af314465e5dfe3e8baa839a32a72e83c04f26ef, first released in v4.2.90. +# At the time of writing, GNU Make v4.2.1 is still being used in supported +# distro releases. +# +# Source: https://lists.gnu.org/archive/html/bug-make/2017-11/msg00017.html +clang_prog=$(shell $(SHELL) $(.SHELLFLAGS) "command -v clang") +clangxx_prog=$(shell $(SHELL) $(.SHELLFLAGS) "command -v clang++") + +clang_resource_dir=$(shell clang -print-resource-dir) +endif + +cctools_TOOLS=AR RANLIB STRIP NM LIBTOOL OTOOL INSTALL_NAME_TOOL DSYMUTIL + +# Make-only lowercase function +lc = $(subst A,a,$(subst B,b,$(subst C,c,$(subst D,d,$(subst E,e,$(subst F,f,$(subst G,g,$(subst H,h,$(subst I,i,$(subst J,j,$(subst K,k,$(subst L,l,$(subst M,m,$(subst N,n,$(subst O,o,$(subst P,p,$(subst Q,q,$(subst R,r,$(subst S,s,$(subst T,t,$(subst U,u,$(subst V,v,$(subst W,w,$(subst X,x,$(subst Y,y,$(subst Z,z,$1)))))))))))))))))))))))))) + +# For well-known tools provided by cctools, make sure that their well-known +# variable is set to the full path of the tool, just like how AC_PATH_{TOO,PROG} +# would. +$(foreach TOOL,$(cctools_TOOLS),$(eval darwin_$(TOOL) = $$(build_prefix)/bin/$$(host)-$(call lc,$(TOOL)))) + # Flag explanations: # # -mlinker-version @@ -18,20 +60,62 @@ OSX_SDK=$(SDK_PATH)/Xcode-$(XCODE_VERSION)-$(XCODE_BUILD_ID)-extracted-SDK-with- # Explicitly point to our binaries (e.g. cctools) so that they are # ensured to be found and preferred over other possibilities. # -# -nostdinc++ -isystem $(OSX_SDK)/usr/include/c++/v1 +# -stdlib=libc++ -stdlib++-isystem$(OSX_SDK)/usr/include/c++/v1 # # Forces clang to use the libc++ headers from our SDK and completely # forget about the libc++ headers from the standard directories # -# TODO: Once we start requiring a clang version that has the -# -stdlib++-isystem flag first introduced here: -# https://reviews.llvm.org/D64089, we should use that instead. Read the -# differential summary there for more details. +# -Xclang -*system \ +# -Xclang -*system \ +# -Xclang -*system ... +# +# Adds path_a, path_b, and path_c to the bottom of clang's list of +# include search paths. This is used to explicitly specify the list of +# system include search paths and its ordering, rather than rely on +# clang's autodetection routine. This routine has been shown to: +# 1. Fail to pickup libc++ headers in $SYSROOT/usr/include/c++/v1 +# when clang was built manually (see: https://github.com/bitcoin/bitcoin/pull/17919#issuecomment-656785034) +# 2. Fail to pickup C headers in $SYSROOT/usr/include when +# C_INCLUDE_DIRS was specified at configure time (see: https://gist.github.com/dongcarl/5cdc6990b7599e8a5bf6d2a9c70e82f9) +# +# Talking directly to cc1 with -Xclang here grants us access to specify +# more granular categories for these system include search paths, and we +# can use the correct categories that these search paths would have been +# placed in if the autodetection routine had worked correctly. (see: +# https://gist.github.com/dongcarl/5cdc6990b7599e8a5bf6d2a9c70e82f9#the-treatment) # -darwin_CC=clang -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION) -B$(build_prefix)/bin -darwin_CXX=clang++ -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(OSX_SDK) -stdlib=libc++ -mlinker-version=$(LD64_VERSION) -B$(build_prefix)/bin -nostdinc++ -isystem $(OSX_SDK)/usr/include/c++/v1 +# Furthermore, it places these search paths after any "non-Xclang" +# specified search paths. This prevents any additional clang options or +# environment variables from coming after or in between these system +# include search paths, as that would be wrong in general but would also +# break #include_next's. +# +darwin_CC=env -u C_INCLUDE_PATH -u CPLUS_INCLUDE_PATH \ + -u OBJC_INCLUDE_PATH -u OBJCPLUS_INCLUDE_PATH -u CPATH \ + -u LIBRARY_PATH \ + $(clang_prog) --target=$(host) -mmacosx-version-min=$(OSX_MIN_VERSION) \ + -B$(build_prefix)/bin -mlinker-version=$(LD64_VERSION) \ + --sysroot=$(OSX_SDK) \ + -Xclang -internal-externc-isystem$(clang_resource_dir)/include \ + -Xclang -internal-externc-isystem$(OSX_SDK)/usr/include +darwin_CXX=env -u C_INCLUDE_PATH -u CPLUS_INCLUDE_PATH \ + -u OBJC_INCLUDE_PATH -u OBJCPLUS_INCLUDE_PATH -u CPATH \ + -u LIBRARY_PATH \ + $(clangxx_prog) --target=$(host) -mmacosx-version-min=$(OSX_MIN_VERSION) \ + -B$(build_prefix)/bin -mlinker-version=$(LD64_VERSION) \ + --sysroot=$(OSX_SDK) \ + -stdlib=libc++ \ + -stdlib++-isystem$(OSX_SDK)/usr/include/c++/v1 \ + -Xclang -internal-externc-isystem$(clang_resource_dir)/include \ + -Xclang -internal-externc-isystem$(OSX_SDK)/usr/include darwin_CFLAGS=-pipe + +ifneq ($(LTO),) +darwin_CFLAGS += -flto +darwin_LDFLAGS += -flto +endif + darwin_CXXFLAGS=$(darwin_CFLAGS) darwin_release_CFLAGS=-O2 @@ -39,10 +123,3 @@ darwin_release_CXXFLAGS=$(darwin_release_CFLAGS) darwin_debug_CFLAGS=-O1 darwin_debug_CXXFLAGS=$(darwin_debug_CFLAGS) - -darwin_native_binutils=native_cctools -ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) -darwin_native_toolchain=native_cctools -else -darwin_native_toolchain= -endif diff --git a/depends/hosts/default.mk b/depends/hosts/default.mk index 258619a9d0..ea60f025de 100644 --- a/depends/hosts/default.mk +++ b/depends/hosts/default.mk @@ -8,8 +8,6 @@ default_host_AR = $(host_toolchain)ar default_host_RANLIB = $(host_toolchain)ranlib default_host_STRIP = $(host_toolchain)strip default_host_LIBTOOL = $(host_toolchain)libtool -default_host_INSTALL_NAME_TOOL = $(host_toolchain)install_name_tool -default_host_OTOOL = $(host_toolchain)otool default_host_NM = $(host_toolchain)nm define add_host_tool_func @@ -35,5 +33,5 @@ host_$1 = $$($(host_arch)_$(host_os)_$1) host_$(release_type)_$1 = $$($(host_arch)_$(host_os)_$(release_type)_$1) endef -$(foreach tool,CC CXX AR RANLIB STRIP NM LIBTOOL OTOOL INSTALL_NAME_TOOL,$(eval $(call add_host_tool_func,$(tool)))) +$(foreach tool,CC CXX AR RANLIB STRIP NM LIBTOOL OTOOL INSTALL_NAME_TOOL DSYMUTIL,$(eval $(call add_host_tool_func,$(tool)))) $(foreach flags,CFLAGS CXXFLAGS CPPFLAGS LDFLAGS, $(eval $(call add_host_flags_func,$(flags)))) diff --git a/depends/hosts/freebsd.mk b/depends/hosts/freebsd.mk new file mode 100644 index 0000000000..853fa0f457 --- /dev/null +++ b/depends/hosts/freebsd.mk @@ -0,0 +1,37 @@ +freebsd_CFLAGS=-pipe + +ifneq ($(LTO),) +freebsd_CFLAGS += -flto +freebsd_LDFLAGS += -flto +endif + +freebsd_CXXFLAGS=$(freebsd_CFLAGS) + +freebsd_release_CFLAGS=-O2 +freebsd_release_CXXFLAGS=$(freebsd_release_CFLAGS) + +freebsd_debug_CFLAGS=-O1 +freebsd_debug_CXXFLAGS=$(freebsd_debug_CFLAGS) + +ifeq (86,$(findstring 86,$(build_arch))) +i686_freebsd_CC=clang -m32 +i686_freebsd_CXX=clang++ -m32 +i686_freebsd_AR=ar +i686_freebsd_RANLIB=ranlib +i686_freebsd_NM=nm +i686_freebsd_STRIP=strip + +x86_64_freebsd_CC=clang -m64 +x86_64_freebsd_CXX=clang++ -m64 +x86_64_freebsd_AR=ar +x86_64_freebsd_RANLIB=ranlib +x86_64_freebsd_NM=nm +x86_64_freebsd_STRIP=strip +else +i686_freebsd_CC=$(default_host_CC) -m32 +i686_freebsd_CXX=$(default_host_CXX) -m32 +x86_64_freebsd_CC=$(default_host_CC) -m64 +x86_64_freebsd_CXX=$(default_host_CXX) -m64 +endif + +freebsd_cmake_system=FreeBSD diff --git a/depends/hosts/linux.mk b/depends/hosts/linux.mk index b13a0f1ad7..9786db0038 100644 --- a/depends/hosts/linux.mk +++ b/depends/hosts/linux.mk @@ -1,4 +1,14 @@ linux_CFLAGS=-pipe + +ifneq ($(LTO),) +linux_CFLAGS += -flto +linux_LDFLAGS += -flto + +linux_AR = $(host_toolchain)gcc-ar +linux_NM = $(host_toolchain)gcc-nm +linux_RANLIB = $(host_toolchain)gcc-ranlib +endif + linux_CXXFLAGS=$(linux_CFLAGS) linux_release_CFLAGS=-O2 diff --git a/depends/hosts/mingw32.mk b/depends/hosts/mingw32.mk index dbfb62fdcf..910cb21e9f 100644 --- a/depends/hosts/mingw32.mk +++ b/depends/hosts/mingw32.mk @@ -1,4 +1,18 @@ +ifneq ($(shell $(SHELL) $(.SHELLFLAGS) "command -v $(host)-g++-posix"),) +mingw32_CXX := $(host)-g++-posix +endif + mingw32_CFLAGS=-pipe + +ifneq ($(LTO),) +mingw32_CFLAGS += -flto +mingw32_LDFLAGS += -flto + +mingw32_AR = $(host_toolchain)gcc-ar +mingw32_NM = $(host_toolchain)gcc-nm +mingw32_RANLIB = $(host_toolchain)gcc-ranlib +endif + mingw32_CXXFLAGS=$(mingw32_CFLAGS) mingw32_release_CFLAGS=-O2 diff --git a/depends/hosts/netbsd.mk b/depends/hosts/netbsd.mk new file mode 100644 index 0000000000..9586283cad --- /dev/null +++ b/depends/hosts/netbsd.mk @@ -0,0 +1,41 @@ +netbsd_CFLAGS=-pipe + +ifneq ($(LTO),) +netbsd_CFLAGS += -flto +netbsd_LDFLAGS += -flto + +netbsd_AR = $(host_toolchain)gcc-ar +netbsd_NM = $(host_toolchain)gcc-nm +netbsd_RANLIB = $(host_toolchain)gcc-ranlib +endif + +netbsd_CXXFLAGS=$(netbsd_CFLAGS) + +netbsd_release_CFLAGS=-O2 +netbsd_release_CXXFLAGS=$(netbsd_release_CFLAGS) + +netbsd_debug_CFLAGS=-O1 +netbsd_debug_CXXFLAGS=$(netbsd_debug_CFLAGS) + +ifeq (86,$(findstring 86,$(build_arch))) +i686_netbsd_CC=gcc -m32 +i686_netbsd_CXX=g++ -m32 +i686_netbsd_AR=ar +i686_netbsd_RANLIB=ranlib +i686_netbsd_NM=nm +i686_netbsd_STRIP=strip + +x86_64_netbsd_CC=gcc -m64 +x86_64_netbsd_CXX=g++ -m64 +x86_64_netbsd_AR=ar +x86_64_netbsd_RANLIB=ranlib +x86_64_netbsd_NM=nm +x86_64_netbsd_STRIP=strip +else +i686_netbsd_CC=$(default_host_CC) -m32 +i686_netbsd_CXX=$(default_host_CXX) -m32 +x86_64_netbsd_CC=$(default_host_CC) -m64 +x86_64_netbsd_CXX=$(default_host_CXX) -m64 +endif + +netbsd_cmake_system=NetBSD diff --git a/depends/hosts/openbsd.mk b/depends/hosts/openbsd.mk new file mode 100644 index 0000000000..c4a629e021 --- /dev/null +++ b/depends/hosts/openbsd.mk @@ -0,0 +1,36 @@ +openbsd_CFLAGS=-pipe +openbsd_CXXFLAGS=$(openbsd_CFLAGS) + +ifneq ($(LTO),) +openbsd_CFLAGS += -flto +openbsd_LDFLAGS += -flto +endif + +openbsd_release_CFLAGS=-O2 +openbsd_release_CXXFLAGS=$(openbsd_release_CFLAGS) + +openbsd_debug_CFLAGS=-O1 +openbsd_debug_CXXFLAGS=$(openbsd_debug_CFLAGS) + +ifeq (86,$(findstring 86,$(build_arch))) +i686_openbsd_CC=clang -m32 +i686_openbsd_CXX=clang++ -m32 +i686_openbsd_AR=ar +i686_openbsd_RANLIB=ranlib +i686_openbsd_NM=nm +i686_openbsd_STRIP=strip + +x86_64_openbsd_CC=clang -m64 +x86_64_openbsd_CXX=clang++ -m64 +x86_64_openbsd_AR=ar +x86_64_openbsd_RANLIB=ranlib +x86_64_openbsd_NM=nm +x86_64_openbsd_STRIP=strip +else +i686_openbsd_CC=$(default_host_CC) -m32 +i686_openbsd_CXX=$(default_host_CXX) -m32 +x86_64_openbsd_CC=$(default_host_CC) -m64 +x86_64_openbsd_CXX=$(default_host_CXX) -m64 +endif + +openbsd_cmake_system=OpenBSD diff --git a/depends/packages.md b/depends/packages.md index 51ce968355..a6c368c653 100644 --- a/depends/packages.md +++ b/depends/packages.md @@ -151,6 +151,18 @@ Most autotools projects can be properly staged using: $(MAKE) DESTDIR=$($(package)_staging_dir) install +## Build outputs: + +In general, the output of a depends package should not contain any libtool +archives. Instead, the package should output `.pc` (`pkg-config`) files where +possible. + +From the [Gentoo Wiki entry](https://wiki.gentoo.org/wiki/Project:Quality_Assurance/Handling_Libtool_Archives): + +> Libtool pulls in all direct and indirect dependencies into the .la files it +> creates. This leads to massive overlinking, which is toxic to the Gentoo +> ecosystem, as it leads to a massive number of unnecessary rebuilds. + ## Secondary dependencies: Secondary dependency packages relative to the bitcoin binaries/libraries (i.e. @@ -168,4 +180,19 @@ For us, it's much easier to just link a static `libsecondary` into a shared `libprimary` anyway that we'll throw away. We don't care if the end-user has a static or dynamic `libseconday`, that's not our concern. With a static `libseconday`, when we need to link `libprimary` into our executable, there's no -dependency chain to worry about as `libprimary` has all the symbols. \ No newline at end of file +dependency chain to worry about as `libprimary` has all the symbols. + +## Build targets: + +To build an individual package (useful for debugging), following build targets are available. + + make ${package} + make ${package}_fetched + make ${package}_extracted + make ${package}_preprocessed + make ${package}_configured + make ${package}_built + make ${package}_staged + make ${package}_postprocessed + make ${package}_cached + make ${package}_cached_checksum \ No newline at end of file diff --git a/depends/packages/bdb.mk b/depends/packages/bdb.mk index abd67d106c..0e00daf251 100644 --- a/depends/packages/bdb.mk +++ b/depends/packages/bdb.mk @@ -7,10 +7,14 @@ $(package)_build_subdir=build_unix $(package)_patches=clang_cxx_11.patch define $(package)_set_vars -$(package)_config_opts=--disable-shared --enable-cxx --disable-replication +$(package)_config_opts=--disable-shared --enable-cxx --disable-replication --enable-option-checking $(package)_config_opts_mingw32=--enable-mingw $(package)_config_opts_linux=--with-pic -$(package)_cxxflags=-std=c++17 +$(package)_config_opts_freebsd=--with-pic +$(package)_config_opts_netbsd=--with-pic +$(package)_config_opts_openbsd=--with-pic +$(package)_cflags+=-Wno-error=implicit-function-declaration +$(package)_cxxflags+=-std=c++17 $(package)_cppflags_mingw32=-DUNICODE -D_UNICODE endef diff --git a/depends/packages/boost.mk b/depends/packages/boost.mk index 33074f39bd..497bd2e987 100644 --- a/depends/packages/boost.mk +++ b/depends/packages/boost.mk @@ -1,8 +1,8 @@ package=boost -$(package)_version=1_71_0 -$(package)_download_path=https://boostorg.jfrog.io/artifactory/main/release/$(subst _,.,$($(package)_version))/source/ -$(package)_file_name=boost_$($(package)_version).tar.bz2 -$(package)_sha256_hash=d73a8da01e8bf8c7eda40b4c84915071a8c8a0df4a6734537ddde4a8580524ee +$(package)_version=1.72.0 +$(package)_download_path=https://boostorg.jfrog.io/artifactory/main/release/$($(package)_version)/source/ +$(package)_file_name=boost_$(subst .,_,$($(package)_version)).tar.bz2 +$(package)_sha256_hash=59c9b274bc451cf91a9ba1dd2c7fdcaf5d60b1b3aa83f2c9fa143417cc660722 $(package)_dependencies=native_b2 define $(package)_set_vars @@ -31,8 +31,10 @@ else $(package)_toolset_$(host_os)=gcc endif $(package)_config_libraries=chrono,filesystem,program_options,system,thread,test -$(package)_cxxflags=-std=c++17 -fvisibility=hidden +$(package)_cxxflags+=-std=c++17 $(package)_cxxflags_linux=-fPIC +$(package)_cxxflags_freebsd=-fPIC +$(package)_cxxflags_openbsd=-fPIC $(package)_cxxflags_android=-fPIC endef @@ -49,5 +51,5 @@ define $(package)_build_cmds endef define $(package)_stage_cmds - b2 -d0 -j4 --prefix=$($(package)_staging_prefix_dir) $($(package)_config_opts) toolset=$($(package)_toolset_$(host_os)) install + b2 -d0 -j4 --prefix=$($(package)_staging_prefix_dir) $($(package)_config_opts) toolset=$($(package)_toolset_$(host_os)) --no-cmake-config install endef diff --git a/depends/packages/expat.mk b/depends/packages/expat.mk index a0c1e2d766..f2e16da315 100644 --- a/depends/packages/expat.mk +++ b/depends/packages/expat.mk @@ -1,11 +1,18 @@ package=expat -$(package)_version=2.2.6 -$(package)_download_path=https://github.com/libexpat/libexpat/releases/download/R_2_2_6/ -$(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=17b43c2716d521369f82fc2dc70f359860e90fa440bea65b3b85f0b246ea81f2 +$(package)_version=2.5.0 +$(package)_download_path=https://github.com/libexpat/libexpat/releases/download/R_$(subst .,_,$($(package)_version))/ +$(package)_file_name=$(package)-$($(package)_version).tar.xz +$(package)_sha256_hash=ef2420f0232c087801abf705e89ae65f6257df6b7931d37846a193ef2e8cdcbe +# -D_DEFAULT_SOURCE defines __USE_MISC, which exposes additional +# definitions in endian.h, which are required for a working +# endianess check in configure when building with -flto. define $(package)_set_vars - $(package)_config_opts=--disable-static --without-docbook + $(package)_config_opts=--disable-shared --without-docbook --without-tests --without-examples + $(package)_config_opts += --disable-dependency-tracking --enable-option-checking + $(package)_config_opts += --without-xmlwf + $(package)_config_opts_linux=--with-pic + $(package)_cppflags += -D_DEFAULT_SOURCE endef define $(package)_config_cmds @@ -19,3 +26,7 @@ endef define $(package)_stage_cmds $(MAKE) DESTDIR=$($(package)_staging_dir) install endef + +define $(package)_postprocess_cmds + rm -rf share lib/cmake lib/*.la +endef diff --git a/depends/packages/fontconfig.mk b/depends/packages/fontconfig.mk index 416e5c0a75..c8b2fc33d5 100644 --- a/depends/packages/fontconfig.mk +++ b/depends/packages/fontconfig.mk @@ -1,17 +1,17 @@ package=fontconfig -$(package)_version=2.12.1 +$(package)_version=2.12.6 $(package)_download_path=https://www.freedesktop.org/software/fontconfig/release/ $(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=b449a3e10c47e1d1c7a6ec6e2016cca73d3bd68fbbd4f0ae5cc6b573f7d6c7f3 +$(package)_sha256_hash=cf0c30807d08f6a28ab46c61b8dbd55c97d2f292cf88f3a07d3384687f31f017 $(package)_dependencies=freetype expat -$(package)_patches=remove_char_width_usage.patch gperf_header_regen.patch +$(package)_patches=gperf_header_regen.patch define $(package)_set_vars - $(package)_config_opts=--disable-docs --disable-static + $(package)_config_opts=--disable-docs --disable-static --disable-libxml2 --disable-iconv + $(package)_config_opts += --disable-dependency-tracking --enable-option-checking endef define $(package)_preprocess_cmds - patch -p1 < $($(package)_patch_dir)/remove_char_width_usage.patch && \ patch -p1 < $($(package)_patch_dir)/gperf_header_regen.patch endef @@ -26,3 +26,7 @@ endef define $(package)_stage_cmds $(MAKE) DESTDIR=$($(package)_staging_dir) install endef + +define $(package)_postprocess_cmds + rm -rf var lib/*.la +endef diff --git a/depends/packages/freetype.mk b/depends/packages/freetype.mk index a98e82ed16..6f5dbe0f01 100644 --- a/depends/packages/freetype.mk +++ b/depends/packages/freetype.mk @@ -1,11 +1,12 @@ package=freetype -$(package)_version=2.7.1 +$(package)_version=2.11.0 $(package)_download_path=https://download.savannah.gnu.org/releases/$(package) -$(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=3a3bb2c4e15ffb433f2032f50a5b5a92558206822e22bfe8cbe339af4aa82f88 +$(package)_file_name=$(package)-$($(package)_version).tar.xz +$(package)_sha256_hash=8bee39bd3968c4804b70614a0a3ad597299ad0e824bc8aad5ce8aaf48067bde7 define $(package)_set_vars $(package)_config_opts=--without-zlib --without-png --without-harfbuzz --without-bzip2 --disable-static + $(package)_config_opts += --enable-option-checking --without-brotli $(package)_config_opts_linux=--with-pic endef @@ -20,3 +21,7 @@ endef define $(package)_stage_cmds $(MAKE) DESTDIR=$($(package)_staging_dir) install endef + +define $(package)_postprocess_cmds + rm -rf share/man lib/*.la +endef diff --git a/depends/packages/libXau.mk b/depends/packages/libXau.mk index ce42140689..b7e032c0b2 100644 --- a/depends/packages/libXau.mk +++ b/depends/packages/libXau.mk @@ -1,12 +1,15 @@ package=libXau -$(package)_version=1.0.8 +$(package)_version=1.0.9 $(package)_download_path=https://xorg.freedesktop.org/releases/individual/lib/ $(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=fdd477320aeb5cdd67272838722d6b7d544887dfe7de46e1e7cc0c27c2bea4f2 +$(package)_sha256_hash=ccf8cbf0dbf676faa2ea0a6d64bcc3b6746064722b606c8c52917ed00dcb73ec $(package)_dependencies=xproto +# When updating this package, check the default value of +# --disable-xthreads. It is currently enabled. define $(package)_set_vars - $(package)_config_opts=--disable-shared + $(package)_config_opts=--disable-shared --disable-lint-library --without-lint + $(package)_config_opts += --disable-dependency-tracking --enable-option-checking $(package)_config_opts_linux=--with-pic endef @@ -25,3 +28,7 @@ endef define $(package)_stage_cmds $(MAKE) DESTDIR=$($(package)_staging_dir) install endef + +define $(package)_postprocess_cmds + rm -rf share lib/*.la +endef diff --git a/depends/packages/libcurl.mk b/depends/packages/libcurl.mk new file mode 100644 index 0000000000..95fb6e7adf --- /dev/null +++ b/depends/packages/libcurl.mk @@ -0,0 +1,36 @@ +package=libcurl +$(package)_version=8.5.0 +$(package)_dependencies=openssl +$(package)_download_path=https://curl.haxx.se/download +$(package)_file_name=curl-$($(package)_version).tar.xz +$(package)_sha256_hash=42ab8db9e20d8290a3b633e7fbb3cec15db34df65fd1015ef8ac1e4723750eeb +$(package)_config_opts=--disable-shared --enable-static --prefix=$(host_prefix) --host=$(HOST) --with-openssl +$(package)_config_opts+=--disable-manual --disable-ntlm-wb --with-random=/dev/urandom +$(package)_config_opts+=--disable-curldebug --disable-libcurl-option --disable-ldap --disable-ldaps +$(package)_config_opts+=--disable-dependency-tracking --enable-option-checking +$(package)_config_opts+=CFLAGS="$($(package)_cflags) -fPIC" +$(package)_conf_tool=./configure + +define $(package)_set_vars + $(package)_config_env=AR="$($(package)_ar)" RANLIB="$($(package)_ranlib)" CC="$($(package)_cc)" +endef + +define $(package)_config_cmds + echo '=== config for $(package):' && \ + echo '$($(package)_config_env) $($(package)_conf_tool) $($(package)_config_opts)' && \ + echo '=== ' && \ + $($(package)_config_env) $($(package)_conf_tool) $($(package)_config_opts) +endef + +define $(package)_build_cmds + $(MAKE) +endef + +define $(package)_stage_cmds + echo 'Staging dir: $($(package)_staging_dir)$(host_prefix)' && \ + $(MAKE) DESTDIR=$($(package)_staging_dir) install +endef + +define $(package)_postprocess_cmds + rm -rf share/man lib/*.la +endef diff --git a/depends/packages/libevent.mk b/depends/packages/libevent.mk index ae1a0b4478..0b2ef01223 100644 --- a/depends/packages/libevent.mk +++ b/depends/packages/libevent.mk @@ -1,14 +1,8 @@ package=libevent -$(package)_version=2.1.11-stable -$(package)_download_path=https://github.com/libevent/libevent/archive/ -$(package)_file_name=release-$($(package)_version).tar.gz -$(package)_sha256_hash=229393ab2bf0dc94694f21836846b424f3532585bac3468738b7bf752c03901e -$(package)_patches=0001-fix-windows-getaddrinfo.patch - -define $(package)_preprocess_cmds - patch -p1 < $($(package)_patch_dir)/0001-fix-windows-getaddrinfo.patch && \ - ./autogen.sh -endef +$(package)_version=2.1.12-stable +$(package)_download_path=https://github.com/libevent/libevent/releases/download/release-$($(package)_version)/ +$(package)_file_name=$(package)-$($(package)_version).tar.gz +$(package)_sha256_hash=92e6de1be9ec176428fd2367677e61ceffc2ee1cb119035037a27d346b0403bb # When building for Windows, we set _WIN32_WINNT to target the same Windows # version as we do in configure. Due to quirks in libevents build system, this @@ -18,6 +12,9 @@ define $(package)_set_vars $(package)_config_opts += --disable-dependency-tracking --enable-option-checking $(package)_config_opts_release=--disable-debug-mode $(package)_config_opts_linux=--with-pic + $(package)_config_opts_freebsd=--with-pic + $(package)_config_opts_netbsd=--with-pic + $(package)_config_opts_openbsd=--with-pic $(package)_config_opts_android=--with-pic $(package)_cppflags_mingw32=-D_WIN32_WINNT=0x0601 endef @@ -35,4 +32,5 @@ define $(package)_stage_cmds endef define $(package)_postprocess_cmds + rm lib/*.la endef diff --git a/depends/packages/libxcb.mk b/depends/packages/libxcb.mk index 961cb86c95..99a7ee2fbd 100644 --- a/depends/packages/libxcb.mk +++ b/depends/packages/libxcb.mk @@ -1,38 +1,30 @@ package=libxcb -$(package)_version=1.10 +$(package)_version=1.14 $(package)_download_path=https://xcb.freedesktop.org/dist -$(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=98d9ab05b636dd088603b64229dd1ab2d2cc02ab807892e107d674f9c3f2d5b5 +$(package)_file_name=$(package)-$($(package)_version).tar.xz +$(package)_sha256_hash=a55ed6db98d43469801262d81dc2572ed124edc3db31059d4e9916eb9f844c34 $(package)_dependencies=xcb_proto libXau define $(package)_set_vars -$(package)_config_opts=--disable-static -# Because we pass -qt-xcb to Qt, it will compile in a set of xcb helper libraries and extensions, -# so we skip building all of the extensions here. -# More info is available from: https://doc.qt.io/qt-5.9/linux-requirements.html +$(package)_config_opts=--disable-static --disable-devel-docs --without-doxygen --without-launchd +$(package)_config_opts += --disable-dependency-tracking --enable-option-checking +# Disable uneeded extensions. +# More info is available from: https://doc.qt.io/qt-5.15/linux-requirements.html $(package)_config_opts += --disable-composite --disable-damage --disable-dpms $(package)_config_opts += --disable-dri2 --disable-dri3 --disable-glx -$(package)_config_opts += --disable-present --disable-randr --disable-record -$(package)_config_opts += --disable-render --disable-resource --disable-screensaver -$(package)_config_opts += --disable-shape --disable-shm --disable-sync -$(package)_config_opts += --disable-xevie --disable-xfixes --disable-xfree86-dri -$(package)_config_opts += --disable-xinerama --disable-xinput --disable-xkb -$(package)_config_opts += --disable-xprint --disable-selinux --disable-xtest -$(package)_config_opts += --disable-xv --disable-xvmc +$(package)_config_opts += --disable-present --disable-record --disable-resource +$(package)_config_opts += --disable-screensaver --disable-xevie --disable-xfree86-dri +$(package)_config_opts += --disable-xinput --disable-xprint --disable-selinux +$(package)_config_opts += --disable-xtest --disable-xv --disable-xvmc endef define $(package)_preprocess_cmds - cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub build-aux &&\ + cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub build-aux && \ sed "s/pthread-stubs//" -i configure endef -# Don't install xcb headers to the default path in order to work around a qt -# build issue: https://bugreports.qt.io/browse/QTBUG-34748 -# When using qt's internal libxcb, it may end up finding the real headers in -# depends staging. Use a non-default path to avoid that. - define $(package)_config_cmds - $($(package)_autoconf) --includedir=$(host_prefix)/include/xcb-shared + $($(package)_autoconf) endef define $(package)_build_cmds @@ -44,5 +36,5 @@ define $(package)_stage_cmds endef define $(package)_postprocess_cmds - rm -rf share/man share/doc + rm -rf share lib/*.la endef diff --git a/depends/packages/libxkbcommon.mk b/depends/packages/libxkbcommon.mk new file mode 100644 index 0000000000..8c6c56545f --- /dev/null +++ b/depends/packages/libxkbcommon.mk @@ -0,0 +1,32 @@ +package=libxkbcommon +$(package)_version=0.8.4 +$(package)_download_path=https://xkbcommon.org/download/ +$(package)_file_name=$(package)-$($(package)_version).tar.xz +$(package)_sha256_hash=60ddcff932b7fd352752d51a5c4f04f3d0403230a584df9a2e0d5ed87c486c8b +$(package)_dependencies=libxcb + +define $(package)_set_vars +$(package)_config_opts = --enable-option-checking --disable-dependency-tracking +$(package)_config_opts += --disable-static --disable-docs +endef + +define $(package)_preprocess_cmds + cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub build-aux +endef + +define $(package)_config_cmds + $($(package)_autoconf) +endef + +define $(package)_build_cmds + $(MAKE) +endef + +define $(package)_stage_cmds + $(MAKE) DESTDIR=$($(package)_staging_dir) install +endef + +define $(package)_postprocess_cmds + rm lib/*.la +endef + diff --git a/depends/packages/miniupnpc.mk b/depends/packages/miniupnpc.mk index 99f5b0a8db..7ad2529e47 100644 --- a/depends/packages/miniupnpc.mk +++ b/depends/packages/miniupnpc.mk @@ -3,17 +3,20 @@ $(package)_version=2.2.2 $(package)_download_path=https://miniupnp.tuxfamily.org/files/ $(package)_file_name=$(package)-$($(package)_version).tar.gz $(package)_sha256_hash=888fb0976ba61518276fe1eda988589c700a3f2a69d71089260d75562afd3687 -$(package)_patches=dont_leak_info.patch +$(package)_patches=dont_leak_info.patch respect_mingw_cflags.patch +# Next time this package is updated, ensure that _WIN32_WINNT is still properly set. +# See discussion in https://github.com/bitcoin/bitcoin/pull/25964. define $(package)_set_vars $(package)_build_opts=CC="$($(package)_cc)" $(package)_build_opts_darwin=LIBTOOL="$($(package)_libtool)" -$(package)_build_opts_mingw32=-f Makefile.mingw +$(package)_build_opts_mingw32=-f Makefile.mingw CFLAGS="$($(package)_cflags) -D_WIN32_WINNT=0x0601" $(package)_build_env+=CFLAGS="$($(package)_cflags) $($(package)_cppflags)" AR="$($(package)_ar)" endef define $(package)_preprocess_cmds - patch -p1 < $($(package)_patch_dir)/dont_leak_info.patch + patch -p1 < $($(package)_patch_dir)/dont_leak_info.patch && \ + patch -p1 < $($(package)_patch_dir)/respect_mingw_cflags.patch endef define $(package)_build_cmds diff --git a/depends/packages/native_cctools.mk b/depends/packages/native_cctools.mk index d56b636695..885207fce9 100644 --- a/depends/packages/native_cctools.mk +++ b/depends/packages/native_cctools.mk @@ -1,86 +1,19 @@ package=native_cctools -$(package)_version=55562e4073dea0fbfd0b20e0bf69ffe6390c7f97 +$(package)_version=2ef2e931cf641547eb8a68cfebde61003587c9fd $(package)_download_path=https://github.com/tpoechtrager/cctools-port/archive $(package)_file_name=$($(package)_version).tar.gz -$(package)_sha256_hash=e51995a843533a3dac155dd0c71362dd471597a2d23f13dff194c6285362f875 +$(package)_sha256_hash=6b73269efdf5c58a070e7357b66ee760501388549d6a12b423723f45888b074b $(package)_build_subdir=cctools -$(package)_patches=ld64_disable_threading.patch - -ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) -$(package)_clang_version=8.0.0 -$(package)_clang_download_path=https://releases.llvm.org/$($(package)_clang_version) -$(package)_clang_download_file=clang+llvm-$($(package)_clang_version)-x86_64-linux-gnu-ubuntu-14.04.tar.xz -$(package)_clang_file_name=clang-llvm-$($(package)_clang_version)-x86_64-linux-gnu-ubuntu-14.04.tar.xz -$(package)_clang_sha256_hash=9ef854b71949f825362a119bf2597f744836cb571131ae6b721cd102ffea8cd0 -endif - -$(package)_libtapi_version=3efb201881e7a76a21e0554906cf306432539cef -$(package)_libtapi_download_path=https://github.com/tpoechtrager/apple-libtapi/archive -$(package)_libtapi_download_file=$($(package)_libtapi_version).tar.gz -$(package)_libtapi_file_name=$($(package)_libtapi_version).tar.gz -$(package)_libtapi_sha256_hash=380c1ca37cfa04a8699d0887a8d3ee1ad27f3d08baba78887c73b09485c0fbd3 - -$(package)_extra_sources=$($(package)_libtapi_file_name) -ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) -$(package)_extra_sources += $($(package)_clang_file_name) -endif - -ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) -define $(package)_fetch_cmds -$(call fetch_file,$(package),$($(package)_download_path),$($(package)_download_file),$($(package)_file_name),$($(package)_sha256_hash)) && \ -$(call fetch_file,$(package),$($(package)_clang_download_path),$($(package)_clang_download_file),$($(package)_clang_file_name),$($(package)_clang_sha256_hash)) && \ -$(call fetch_file,$(package),$($(package)_libtapi_download_path),$($(package)_libtapi_download_file),$($(package)_libtapi_file_name),$($(package)_libtapi_sha256_hash)) -endef -else -define $(package)_fetch_cmds -$(call fetch_file,$(package),$($(package)_download_path),$($(package)_download_file),$($(package)_file_name),$($(package)_sha256_hash)) && \ -$(call fetch_file,$(package),$($(package)_libtapi_download_path),$($(package)_libtapi_download_file),$($(package)_libtapi_file_name),$($(package)_libtapi_sha256_hash)) -endef -endif - -ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) -define $(package)_extract_cmds - mkdir -p $($(package)_extract_dir) && \ - echo "$($(package)_sha256_hash) $($(package)_source)" > $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - echo "$($(package)_clang_sha256_hash) $($(package)_source_dir)/$($(package)_clang_file_name)" >> $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - echo "$($(package)_libtapi_sha256_hash) $($(package)_source_dir)/$($(package)_libtapi_file_name)" >> $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - $(build_SHA256SUM) -c $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - mkdir -p toolchain/bin toolchain/lib/clang/$($(package)_clang_version)/include && \ - mkdir -p libtapi && \ - tar --no-same-owner --strip-components=1 -C libtapi -xf $($(package)_source_dir)/$($(package)_libtapi_file_name) && \ - tar --no-same-owner --strip-components=1 -C toolchain -xf $($(package)_source_dir)/$($(package)_clang_file_name) && \ - rm -f toolchain/lib/libc++abi.so* && \ - tar --no-same-owner --strip-components=1 -xf $($(package)_source) -endef -else -define $(package)_extract_cmds - mkdir -p $($(package)_extract_dir) && \ - echo "$($(package)_sha256_hash) $($(package)_source)" > $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - echo "$($(package)_libtapi_sha256_hash) $($(package)_source_dir)/$($(package)_libtapi_file_name)" >> $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - $(build_SHA256SUM) -c $($(package)_extract_dir)/.$($(package)_file_name).hash && \ - mkdir -p libtapi && \ - tar --no-same-owner --strip-components=1 -C libtapi -xf $($(package)_source_dir)/$($(package)_libtapi_file_name) && \ - tar --no-same-owner --strip-components=1 -xf $($(package)_source) -endef -endif +$(package)_dependencies=native_libtapi define $(package)_set_vars - $(package)_config_opts=--target=$(host) --with-libtapi=$($(package)_extract_dir) + $(package)_config_opts=--target=$(host) $(package)_ldflags+=-Wl,-rpath=\\$$$$$$$$\$$$$$$$$ORIGIN/../lib ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) - $(package)_config_opts+=--enable-lto-support --with-llvm-config=$($(package)_extract_dir)/toolchain/bin/llvm-config - $(package)_cc=$($(package)_extract_dir)/toolchain/bin/clang - $(package)_cxx=$($(package)_extract_dir)/toolchain/bin/clang++ - else - $(package)_cc=clang - $(package)_cxx=clang++ + $(package)_config_opts+=--enable-lto-support --with-llvm-config=$(build_prefix)/bin/llvm-config endif -endef - -define $(package)_preprocess_cmds - CC=$($(package)_cc) CXX=$($(package)_cxx) INSTALLPREFIX=$($(package)_extract_dir) ./libtapi/build.sh && \ - CC=$($(package)_cc) CXX=$($(package)_cxx) INSTALLPREFIX=$($(package)_extract_dir) ./libtapi/install.sh && \ - patch -p1 < $($(package)_patch_dir)/ld64_disable_threading.patch + $(package)_cc=$(clang_prog) + $(package)_cxx=$(clangxx_prog) endef define $(package)_config_cmds @@ -91,26 +24,10 @@ define $(package)_build_cmds $(MAKE) endef -ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) define $(package)_stage_cmds - $(MAKE) DESTDIR=$($(package)_staging_dir) install && \ - mkdir -p $($(package)_staging_prefix_dir)/lib/ && \ - cd $($(package)_extract_dir) && \ - cp lib/libtapi.so.6 $($(package)_staging_prefix_dir)/lib/ && \ - cd $($(package)_extract_dir)/toolchain && \ - mkdir -p $($(package)_staging_prefix_dir)/lib/clang/$($(package)_clang_version)/include && \ - mkdir -p $($(package)_staging_prefix_dir)/bin $($(package)_staging_prefix_dir)/include && \ - cp bin/clang $($(package)_staging_prefix_dir)/bin/ &&\ - cp -P bin/clang++ $($(package)_staging_prefix_dir)/bin/ &&\ - cp lib/libLTO.so $($(package)_staging_prefix_dir)/lib/ && \ - cp -rf lib/clang/$($(package)_clang_version)/include/* $($(package)_staging_prefix_dir)/lib/clang/$($(package)_clang_version)/include/ && \ - cp bin/dsymutil $($(package)_staging_prefix_dir)/bin/$(host)-dsymutil + $(MAKE) DESTDIR=$($(package)_staging_dir) install endef -else -define $(package)_stage_cmds - $(MAKE) DESTDIR=$($(package)_staging_dir) install && \ - mkdir -p $($(package)_staging_prefix_dir)/lib/ && \ - cd $($(package)_extract_dir) && \ - cp lib/libtapi.so.6 $($(package)_staging_prefix_dir)/lib/ + +define $(package)_postprocess_cmds + rm -rf share endef -endif diff --git a/depends/packages/native_cdrkit.mk b/depends/packages/native_cdrkit.mk deleted file mode 100644 index 8243458ec8..0000000000 --- a/depends/packages/native_cdrkit.mk +++ /dev/null @@ -1,26 +0,0 @@ -package=native_cdrkit -$(package)_version=1.1.11 -$(package)_download_path=https://distro.ibiblio.org/fatdog/source/600/c -$(package)_file_name=cdrkit-$($(package)_version).tar.bz2 -$(package)_sha256_hash=b50d64c214a65b1a79afe3a964c691931a4233e2ba605d793eb85d0ac3652564 -$(package)_patches=cdrkit-deterministic.patch - -define $(package)_preprocess_cmds - patch -p1 < $($(package)_patch_dir)/cdrkit-deterministic.patch -endef - -define $(package)_config_cmds - cmake -DCMAKE_INSTALL_PREFIX=$(build_prefix) -endef - -define $(package)_build_cmds - $(MAKE) genisoimage -endef - -define $(package)_stage_cmds - $(MAKE) DESTDIR=$($(package)_staging_dir) -C genisoimage install -endef - -define $(package)_postprocess_cmds - rm bin/isovfy bin/isoinfo bin/isodump bin/isodebug bin/devdump -endef diff --git a/depends/packages/native_clang.mk b/depends/packages/native_clang.mk new file mode 100644 index 0000000000..1131593ac7 --- /dev/null +++ b/depends/packages/native_clang.mk @@ -0,0 +1,25 @@ +$(package)_version=10.0.1 +$(package)_download_path=https://github.com/llvm/llvm-project/releases/download/llvmorg-$($(package)_version) +$(package)_download_file=clang+llvm-$($(package)_version)-x86_64-linux-gnu-ubuntu-16.04.tar.xz +$(package)_file_name=clang+llvm-$($(package)_version)-x86_64-linux-gnu-ubuntu-16.04.tar.xz +$(package)_sha256_hash=48b83ef827ac2c213d5b64f5ad7ed082c8bcb712b46644e0dc5045c6f462c231 + +define $(package)_preprocess_cmds + rm -f $($(package)_extract_dir)/lib/libc++abi.so* +endef + +define $(package)_stage_cmds + mkdir -p $($(package)_staging_prefix_dir)/lib/clang/$($(package)_version)/include && \ + mkdir -p $($(package)_staging_prefix_dir)/bin && \ + mkdir -p $($(package)_staging_prefix_dir)/include && \ + cp bin/clang $($(package)_staging_prefix_dir)/bin/ && \ + cp -P bin/clang++ $($(package)_staging_prefix_dir)/bin/ && \ + cp bin/dsymutil $($(package)_staging_prefix_dir)/bin/$(host)-dsymutil && \ + cp bin/llvm-config $($(package)_staging_prefix_dir)/bin/ && \ + cp lib/libLTO.so $($(package)_staging_prefix_dir)/lib/ && \ + cp -rf lib/clang/$($(package)_version)/include/* $($(package)_staging_prefix_dir)/lib/clang/$($(package)_version)/include/ +endef + +define $(package)_postprocess_cmds + rmdir include +endef diff --git a/depends/packages/native_libdmg-hfsplus.mk b/depends/packages/native_libdmg-hfsplus.mk deleted file mode 100644 index 8493f1d979..0000000000 --- a/depends/packages/native_libdmg-hfsplus.mk +++ /dev/null @@ -1,24 +0,0 @@ -package=native_libdmg-hfsplus -$(package)_version=7ac55ec64c96f7800d9818ce64c79670e7f02b67 -$(package)_download_path=https://github.com/planetbeing/libdmg-hfsplus/archive -$(package)_file_name=$($(package)_version).tar.gz -$(package)_sha256_hash=56fbdc48ec110966342f0ecddd6f8f89202f4143ed2a3336e42bbf88f940850c -$(package)_build_subdir=build -$(package)_patches=remove-libcrypto-dependency.patch - -define $(package)_preprocess_cmds - patch -p1 < $($(package)_patch_dir)/remove-libcrypto-dependency.patch && \ - mkdir build -endef - -define $(package)_config_cmds - cmake -DCMAKE_INSTALL_PREFIX:PATH=$(build_prefix) .. -endef - -define $(package)_build_cmds - $(MAKE) -C dmg -endef - -define $(package)_stage_cmds - $(MAKE) DESTDIR=$($(package)_staging_dir) -C dmg install -endef diff --git a/depends/packages/native_libtapi.mk b/depends/packages/native_libtapi.mk new file mode 100644 index 0000000000..60b898da5f --- /dev/null +++ b/depends/packages/native_libtapi.mk @@ -0,0 +1,20 @@ +package=native_libtapi +$(package)_version=664b8414f89612f2dfd35a9b679c345aa5389026 +$(package)_download_path=https://github.com/tpoechtrager/apple-libtapi/archive +$(package)_download_file=$($(package)_version).tar.gz +$(package)_file_name=$($(package)_version).tar.gz +$(package)_sha256_hash=62e419c12d1c9fad67cc1cd523132bc00db050998337c734c15bc8d73cc02b61 + +ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) +$(package)_dependencies=native_clang +endif + +define $(package)_build_cmds + CC=$(clang_prog) CXX=$(clangxx_prog) INSTALLPREFIX=$($(package)_staging_prefix_dir) ./build.sh +endef + +define $(package)_stage_cmds + ./install.sh && \ + mkdir -p $($(package)_staging_prefix_dir)/include/llvm-c && \ + cp src/llvm/include/llvm-c/lto.h $($(package)_staging_prefix_dir)/include/llvm-c +endef diff --git a/depends/packages/native_protobuf.mk b/depends/packages/native_protobuf.mk deleted file mode 100644 index 1de8c37d36..0000000000 --- a/depends/packages/native_protobuf.mk +++ /dev/null @@ -1,25 +0,0 @@ -package=native_protobuf -$(package)_version=2.6.1 -$(package)_download_path=https://github.com/google/protobuf/releases/download/v$($(package)_version) -$(package)_file_name=protobuf-$($(package)_version).tar.bz2 -$(package)_sha256_hash=ee445612d544d885ae240ffbcbf9267faa9f593b7b101f21d58beceb92661910 - -define $(package)_set_vars -$(package)_config_opts=--disable-shared --without-zlib -endef - -define $(package)_config_cmds - $($(package)_autoconf) -endef - -define $(package)_build_cmds - $(MAKE) -C src protoc -endef - -define $(package)_stage_cmds - $(MAKE) -C src DESTDIR=$($(package)_staging_dir) install-strip -endef - -define $(package)_postprocess_cmds - rm -rf lib include -endef diff --git a/depends/packages/openssl.mk b/depends/packages/openssl.mk index c909416798..f85dfe2e76 100644 --- a/depends/packages/openssl.mk +++ b/depends/packages/openssl.mk @@ -1,35 +1,28 @@ package=openssl -$(package)_version=1.0.1k -$(package)_download_path=https://www.openssl.org/source/old +$(package)_version=1.0.2u +$(package)_download_path=https://www.openssl.org/source/old/1.0.2 $(package)_file_name=$(package)-$($(package)_version).tar.gz -$(package)_sha256_hash=8f9faeaebad088e772f4ef5e38252d472be4d878c6b3a2718c10a4fcebe7a41c +$(package)_sha256_hash=ecd0c6ffb493dd06707d38b14bb4d8c2288bb7033735606569d8f90f89669d16 define $(package)_set_vars $(package)_config_env=AR="$($(package)_ar)" RANLIB="$($(package)_ranlib)" CC="$($(package)_cc)" $(package)_config_opts=--prefix=$(host_prefix) --openssldir=$(host_prefix)/etc/openssl -$(package)_config_opts+=no-camellia $(package)_config_opts+=no-capieng -$(package)_config_opts+=no-cast -$(package)_config_opts+=no-comp $(package)_config_opts+=no-dso $(package)_config_opts+=no-dtls1 $(package)_config_opts+=no-ec_nistp_64_gcc_128 $(package)_config_opts+=no-gost $(package)_config_opts+=no-gmp $(package)_config_opts+=no-heartbeats -$(package)_config_opts+=no-idea $(package)_config_opts+=no-jpake $(package)_config_opts+=no-krb5 $(package)_config_opts+=no-libunbound $(package)_config_opts+=no-md2 -$(package)_config_opts+=no-mdc2 -$(package)_config_opts+=no-rc4 $(package)_config_opts+=no-rc5 $(package)_config_opts+=no-rdrand $(package)_config_opts+=no-rfc3779 $(package)_config_opts+=no-rsax $(package)_config_opts+=no-sctp -$(package)_config_opts+=no-seed $(package)_config_opts+=no-sha0 $(package)_config_opts+=no-shared $(package)_config_opts+=no-ssl-trace @@ -39,7 +32,6 @@ $(package)_config_opts+=no-static_engine $(package)_config_opts+=no-store $(package)_config_opts+=no-unit-test $(package)_config_opts+=no-weak-ssl-ciphers -$(package)_config_opts+=no-whirlpool $(package)_config_opts+=no-zlib $(package)_config_opts+=no-zlib-dynamic $(package)_config_opts+=$($(package)_cflags) $($(package)_cppflags) diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk index 5a7e426748..aaf9faee98 100644 --- a/depends/packages/packages.mk +++ b/depends/packages/packages.mk @@ -1,11 +1,8 @@ -packages:=boost openssl libevent +packages:=boost openssl libevent libcurl -qt_native_packages = native_protobuf -qt_packages = protobuf zlib +qt_packages = qrencode zlib -qrencode_packages = qrencode - -qt_linux_packages:=qt expat libxcb xcb_proto libXau xproto freetype fontconfig +qt_linux_packages:=qt expat libxcb xcb_proto libXau xproto freetype fontconfig libxkbcommon qt_android_packages=qt qt_darwin_packages=qt @@ -22,5 +19,10 @@ darwin_native_packages = native_ds_store native_mac_alias $(host_arch)_$(host_os)_native_packages += native_b2 ifneq ($(build_os),darwin) -darwin_native_packages += native_cctools native_cdrkit native_libdmg-hfsplus +darwin_native_packages += native_cctools native_libtapi + +ifeq ($(strip $(FORCE_USE_SYSTEM_CLANG)),) +darwin_native_packages+= native_clang +endif + endif diff --git a/depends/packages/protobuf.mk b/depends/packages/protobuf.mk deleted file mode 100644 index 4bd9447c67..0000000000 --- a/depends/packages/protobuf.mk +++ /dev/null @@ -1,34 +0,0 @@ -package=protobuf -$(package)_version=$(native_$(package)_version) -$(package)_download_path=$(native_$(package)_download_path) -$(package)_file_name=$(native_$(package)_file_name) -$(package)_sha256_hash=$(native_$(package)_sha256_hash) -$(package)_dependencies=native_$(package) -$(package)_cxxflags=-std=c++17 - -define $(package)_set_vars - $(package)_config_opts=--disable-shared --with-protoc=$(build_prefix)/bin/protoc - $(package)_config_opts_linux=--with-pic -endef - -define $(package)_preprocess_cmds - cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub . &&\ - cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub gtest/build-aux -endef - -define $(package)_config_cmds - $($(package)_autoconf) -endef - -define $(package)_build_cmds - $(MAKE) -C src libprotobuf.la -endef - -define $(package)_stage_cmds - $(MAKE) DESTDIR=$($(package)_staging_dir) -C src install-libLTLIBRARIES install-nobase_includeHEADERS &&\ - $(MAKE) DESTDIR=$($(package)_staging_dir) install-pkgconfigDATA -endef - -define $(package)_postprocess_cmds - rm lib/libprotoc.a -endef diff --git a/depends/packages/qrencode.mk b/depends/packages/qrencode.mk index f81fb100be..2afd95d7c4 100644 --- a/depends/packages/qrencode.mk +++ b/depends/packages/qrencode.mk @@ -1,13 +1,16 @@ package=qrencode -$(package)_version=3.4.4 +$(package)_version=4.1.1 $(package)_download_path=https://fukuchi.org/works/qrencode/ $(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=efe5188b1ddbcbf98763b819b146be6a90481aac30cfc8d858ab78a19cde1fa5 +$(package)_sha256_hash=e455d9732f8041cf5b9c388e345a641fd15707860f928e94507b1961256a6923 define $(package)_set_vars -$(package)_config_opts=--disable-shared -without-tools --disable-sdltest +$(package)_config_opts=--disable-shared --without-tools --without-tests --without-png +$(package)_config_opts += --disable-gprof --disable-gcov --disable-mudflap +$(package)_config_opts += --disable-dependency-tracking --enable-option-checking $(package)_config_opts_linux=--with-pic $(package)_config_opts_android=--with-pic +$(package)_cflags += -Wno-int-conversion -Wno-implicit-function-declaration endef define $(package)_preprocess_cmds @@ -25,3 +28,7 @@ endef define $(package)_stage_cmds $(MAKE) DESTDIR=$($(package)_staging_dir) install endef + +define $(package)_postprocess_cmds + rm lib/*.la +endef diff --git a/depends/packages/qt.mk b/depends/packages/qt.mk index dab7172721..7e7d50552a 100644 --- a/depends/packages/qt.mk +++ b/depends/packages/qt.mk @@ -1,33 +1,38 @@ PACKAGE=qt -$(package)_version=5.9.9 -$(package)_download_path=https://download.qt.io/archive/qt/5.9/$($(package)_version)/submodules -$(package)_suffix=opensource-src-$($(package)_version).tar.xz +$(package)_version=5.12.11 +$(package)_download_path=https://download.qt.io/archive/qt/5.12/$($(package)_version)/submodules +$(package)_suffix=everywhere-src-$($(package)_version).tar.xz $(package)_file_name=qtbase-$($(package)_suffix) -$(package)_sha256_hash=d5a97381b9339c0fbaf13f0c05d599a5c999dcf94145044058198987183fed65 +$(package)_sha256_hash=1c1b4e33137ca77881074c140d54c3c9747e845a31338cfe8680f171f0bc3a39 $(package)_dependencies=openssl zlib -$(package)_linux_dependencies=freetype fontconfig libxcb -$(package)_build_subdir=qtbase +$(package)_linux_dependencies=freetype fontconfig libxcb libxkbcommon $(package)_qt_libs=corelib network widgets gui plugins testlib concurrent -$(package)_patches=fix_qt_pkgconfig.patch mac-qmake.conf fix_configure_mac.patch fix_no_printer.patch -$(package)_patches+= fix_rcc_determinism.patch fix_riscv64_arch.patch xkb-default.patch no-xlib.patch -$(package)_patches+= fix_android_qmake_conf.patch fix_android_jni_static.patch dont_hardcode_pwd.patch -$(package)_patches+= freetype_back_compat.patch drop_lrelease_dependency.patch -$(package)_patches+= fix_mingw_cross_compile.patch +$(package)_linguist_tools = lrelease lupdate lconvert +$(package)_patches = qt.pro qttools_src.pro +$(package)_patches += fix_qt_pkgconfig.patch mac-qmake.conf fix_no_printer.patch no-xlib.patch +$(package)_patches += support_new_android_ndks.patch fix_android_jni_static.patch dont_hardcode_pwd.patch +$(package)_patches += dont_hardcode_x86_64.patch +$(package)_patches+= fix_qpainter_non_determinism.patch fix_lib_paths.patch fix_android_pch.patch +$(package)_patches+= fix_limits_header.patch +$(package)_patches+= fix_montery_include.patch # Update OSX_QT_TRANSLATIONS when this is updated $(package)_qttranslations_file_name=qttranslations-$($(package)_suffix) -$(package)_qttranslations_sha256_hash=f7474f260a1382549720081bf2359a3d425ec3bf7d31976c512834303d30d73b +$(package)_qttranslations_sha256_hash=577b0668a777eb2b451c61e8d026d79285371597ce9df06b6dee6c814164b7c3 $(package)_qttools_file_name=qttools-$($(package)_suffix) -$(package)_qttools_sha256_hash=fce6e0fd39a40bcef880c669080087dba94af1ec442296222210472e0852bf98 +$(package)_qttools_sha256_hash=98b2aaca230458f65996f3534fd471d2ffd038dd58ac997c0589c06dc2385b4f $(package)_extra_sources = $($(package)_qttranslations_file_name) $(package)_extra_sources += $($(package)_qttools_file_name) define $(package)_set_vars +$(package)_config_env = QT_MAC_SDK_NO_VERSION_CHECK=1 +$(package)_config_env += OPENSSL_LIBS="-lssl -lcrypto -lpthread -lws2_32 -lgdi32" $(package)_config_opts_release = -release $(package)_config_opts_release += -silent $(package)_config_opts_debug = -debug +$(package)_config_opts_debug += -optimized-tools $(package)_config_opts += -bindir $(build_prefix)/bin $(package)_config_opts += -c++std c++1z $(package)_config_opts += -confirm-license @@ -47,7 +52,6 @@ $(package)_config_opts += -no-libudev $(package)_config_opts += -no-mtdev $(package)_config_opts += -no-openvg $(package)_config_opts += -no-reduce-relocations -$(package)_config_opts += -no-qml-debug $(package)_config_opts += -no-sql-db2 $(package)_config_opts += -no-sql-ibase $(package)_config_opts += -no-sql-oci @@ -58,13 +62,12 @@ $(package)_config_opts += -no-sql-psql $(package)_config_opts += -no-sql-sqlite $(package)_config_opts += -no-sql-sqlite2 $(package)_config_opts += -no-use-gold-linker -$(package)_config_opts += -no-xinput2 $(package)_config_opts += -nomake examples $(package)_config_opts += -nomake tests +$(package)_config_opts += -nomake tools $(package)_config_opts += -opensource $(package)_config_opts += -openssl-linked $(package)_config_opts += -optimized-qmake -$(package)_config_opts += -pch $(package)_config_opts += -pkg-config $(package)_config_opts += -prefix $(host_prefix) $(package)_config_opts += -qt-libpng @@ -75,13 +78,16 @@ $(package)_config_opts += -system-zlib $(package)_config_opts += -static $(package)_config_opts += -v $(package)_config_opts += -no-feature-dial +$(package)_config_opts += -no-feature-dtls $(package)_config_opts += -no-feature-ftp $(package)_config_opts += -no-feature-lcdnumber $(package)_config_opts += -no-feature-pdf $(package)_config_opts += -no-feature-printer $(package)_config_opts += -no-feature-printdialog $(package)_config_opts += -feature-concurrent +$(package)_config_opts += -no-feature-securetransport $(package)_config_opts += -no-feature-sql +$(package)_config_opts += -no-feature-sqlmodel $(package)_config_opts += -no-feature-statemachine $(package)_config_opts += -no-feature-syntaxhighlighter $(package)_config_opts += -no-feature-textbrowser @@ -91,32 +97,44 @@ $(package)_config_opts += -no-feature-wizard $(package)_config_opts += -no-feature-xml $(package)_config_opts_darwin = -no-dbus +$(package)_config_opts_darwin += -no-opengl +$(package)_config_opts_darwin += -pch +$(package)_config_opts_darwin += -no-feature-corewlan +$(package)_config_opts_darwin += QMAKE_MACOSX_DEPLOYMENT_TARGET=$(OSX_MIN_VERSION) ifneq ($(build_os),darwin) $(package)_config_opts_darwin += -xplatform macx-clang-linux $(package)_config_opts_darwin += -device-option MAC_SDK_PATH=$(OSX_SDK) $(package)_config_opts_darwin += -device-option MAC_SDK_VERSION=$(OSX_SDK_VERSION) $(package)_config_opts_darwin += -device-option CROSS_COMPILE="$(host)-" -$(package)_config_opts_darwin += -device-option MAC_MIN_VERSION=$(OSX_MIN_VERSION) $(package)_config_opts_darwin += -device-option MAC_TARGET=$(host) $(package)_config_opts_darwin += -device-option XCODE_VERSION=$(XCODE_VERSION) endif -# for macOS on Apple Silicon (ARM) see https://bugreports.qt.io/browse/QTBUG-85279 +ifneq ($(build_arch),$(host_arch)) $(package)_config_opts_aarch64_darwin += -device-option QMAKE_APPLE_DEVICE_ARCHS=arm64 +$(package)_config_opts_x86_64_darwin += -device-option QMAKE_APPLE_DEVICE_ARCHS=x86_64 +endif -$(package)_config_opts_linux = -qt-xkbcommon-x11 -$(package)_config_opts_linux += -qt-xcb +$(package)_config_opts_linux = -qt-xcb $(package)_config_opts_linux += -no-xcb-xlib $(package)_config_opts_linux += -no-feature-xlib $(package)_config_opts_linux += -system-freetype $(package)_config_opts_linux += -no-feature-sessionmanager $(package)_config_opts_linux += -fontconfig $(package)_config_opts_linux += -no-opengl +$(package)_config_opts_linux += -no-feature-vulkan $(package)_config_opts_linux += -dbus-runtime +ifneq ($(LTO),) +$(package)_config_opts_linux += -ltcg +endif $(package)_config_opts_arm_linux += -platform linux-g++ -xplatform bitcoin-linux-g++ $(package)_config_opts_i686_linux = -xplatform linux-g++-32 +ifneq (,$(findstring -stdlib=libc++,$($(1)_cxx))) +$(package)_config_opts_x86_64_linux = -xplatform linux-clang-libc++ +else $(package)_config_opts_x86_64_linux = -xplatform linux-g++-64 +endif $(package)_config_opts_aarch64_linux = -xplatform linux-aarch64-gnu-g++ $(package)_config_opts_riscv64_linux = -platform linux-g++ -xplatform bitcoin-linux-g++ $(package)_config_opts_s390x_linux += -platform linux-g++ -xplatform linux-g++-64 @@ -129,7 +147,11 @@ $(package)_config_opts_m68k_linux += -platform linux-g++ -xplatform linux-g++-32 $(package)_config_opts_mingw32 = -no-opengl $(package)_config_opts_mingw32 += -no-dbus $(package)_config_opts_mingw32 += -xplatform win32-g++ +$(package)_config_opts_mingw32 += "QMAKE_CFLAGS = '$($(package)_cflags) $($(package)_cppflags)'" +$(package)_config_opts_mingw32 += "QMAKE_CXXFLAGS = '$($(package)_cflags) $($(package)_cppflags)'" +$(package)_config_opts_mingw32 += "QMAKE_LFLAGS = '$($(package)_ldflags)'" $(package)_config_opts_mingw32 += -device-option CROSS_COMPILE="$(host)-" +$(package)_config_opts_mingw32 += -pch $(package)_config_opts_android = -xplatform android-clang $(package)_config_opts_android += -android-sdk $(ANDROID_SDK) @@ -145,14 +167,13 @@ $(package)_config_opts_android += -qt-freetype $(package)_config_opts_android += -no-fontconfig $(package)_config_opts_android += -L $(host_prefix)/lib $(package)_config_opts_android += -I $(host_prefix)/include +$(package)_config_opts_android += -pch +$(package)_config_opts_android += -no-feature-vulkan $(package)_config_opts_aarch64_android += -android-arch arm64-v8a $(package)_config_opts_armv7a_android += -android-arch armeabi-v7a $(package)_config_opts_x86_64_android += -android-arch x86_64 $(package)_config_opts_i686_android += -android-arch i686 - -$(package)_build_env = QT_RCC_TEST=1 -$(package)_build_env += QT_RCC_SOURCE_DATE_OVERRIDE=1 endef define $(package)_fetch_cmds @@ -168,50 +189,47 @@ define $(package)_extract_cmds echo "$($(package)_qttools_sha256_hash) $($(package)_source_dir)/$($(package)_qttools_file_name)" >> $($(package)_extract_dir)/.$($(package)_file_name).hash && \ $(build_SHA256SUM) -c $($(package)_extract_dir)/.$($(package)_file_name).hash && \ mkdir qtbase && \ - tar --no-same-owner --strip-components=1 -xf $($(package)_source) -C qtbase && \ + $(build_TAR) --no-same-owner --strip-components=1 -xf $($(package)_source) -C qtbase && \ mkdir qttranslations && \ - tar --no-same-owner --strip-components=1 -xf $($(package)_source_dir)/$($(package)_qttranslations_file_name) -C qttranslations && \ + $(build_TAR) --no-same-owner --strip-components=1 -xf $($(package)_source_dir)/$($(package)_qttranslations_file_name) -C qttranslations && \ mkdir qttools && \ - tar --no-same-owner --strip-components=1 -xf $($(package)_source_dir)/$($(package)_qttools_file_name) -C qttools + $(build_TAR) --no-same-owner --strip-components=1 -xf $($(package)_source_dir)/$($(package)_qttools_file_name) -C qttools endef # Preprocessing steps work as follows: # # 1. Apply our patches to the extracted source. See each patch for more info. # -# 2. Point to lrelease in qttools/bin/lrelease; otherwise Qt will look for it in -# $(host)/native/bin/lrelease and not find it. -# -# 3. Create a macOS-Clang-Linux mkspec using our mac-qmake.conf. +# 2. Create a macOS-Clang-Linux mkspec using our mac-qmake.conf. # -# 4. After making a copy of the mkspec for the linux-arm-gnueabi host, named +# 3. After making a copy of the mkspec for the linux-arm-gnueabi host, named # bitcoin-linux-g++, replace instances of linux-arm-gnueabi with $(host). This # way we can generically support hosts like riscv64-linux-gnu, which Qt doesn't # ship a mkspec for. See it's usage in config_opts_* above. # -# 5. Put our C, CXX and LD FLAGS into gcc-base.conf. Only used for non-host builds. +# 4. Put our C, CXX and LD FLAGS into gcc-base.conf. Only used for non-host builds. # -# 6. Do similar for the win32-g++ mkspec. +# 5. Do similar for the win32-g++ mkspec. # -# 7. In clang.conf, swap out clang & clang++, for our compiler + flags. See #17466. +# 6. In clang.conf, swap out clang & clang++, for our compiler + flags. See #17466. # -# 8. Adjust a regex in toolchain.prf, to accomodate Guix's usage of +# 7. Adjust a regex in toolchain.prf, to accommodate Guix's usage of # CROSS_LIBRARY_PATH. See #15277. define $(package)_preprocess_cmds - patch -p1 -i $($(package)_patch_dir)/freetype_back_compat.patch && \ - patch -p1 -i $($(package)_patch_dir)/drop_lrelease_dependency.patch && \ + cp $($(package)_patch_dir)/qt.pro qt.pro && \ + cp $($(package)_patch_dir)/qttools_src.pro qttools/src/src.pro && \ patch -p1 -i $($(package)_patch_dir)/dont_hardcode_pwd.patch && \ patch -p1 -i $($(package)_patch_dir)/fix_qt_pkgconfig.patch && \ - patch -p1 -i $($(package)_patch_dir)/fix_configure_mac.patch && \ patch -p1 -i $($(package)_patch_dir)/fix_no_printer.patch && \ - patch -p1 -i $($(package)_patch_dir)/fix_rcc_determinism.patch && \ - patch -p1 -i $($(package)_patch_dir)/xkb-default.patch && \ - patch -p1 -i $($(package)_patch_dir)/fix_android_qmake_conf.patch && \ + patch -p1 -i $($(package)_patch_dir)/support_new_android_ndks.patch && \ patch -p1 -i $($(package)_patch_dir)/fix_android_jni_static.patch && \ - patch -p1 -i $($(package)_patch_dir)/fix_riscv64_arch.patch && \ - patch -p1 -i $($(package)_patch_dir)/no-xlib.patch && \ - patch -p1 -i $($(package)_patch_dir)/fix_mingw_cross_compile.patch && \ - sed -i.old "s|updateqm.commands = \$$$$\$$$$LRELEASE|updateqm.commands = $($(package)_extract_dir)/qttools/bin/lrelease|" qttranslations/translations/translations.pro && \ + patch -p1 -i $($(package)_patch_dir)/fix_android_pch.patch && \ + patch -p1 -i $($(package)_patch_dir)/no-xlib.patch && \ + patch -p1 -i $($(package)_patch_dir)/dont_hardcode_x86_64.patch && \ + patch -p1 -i $($(package)_patch_dir)/fix_qpainter_non_determinism.patch && \ + patch -p1 -i $($(package)_patch_dir)/fix_lib_paths.patch && \ + patch -p1 -i $($(package)_patch_dir)/fix_limits_header.patch && \ + patch -p1 -i $($(package)_patch_dir)/fix_montery_include.patch && \ mkdir -p qtbase/mkspecs/macx-clang-linux &&\ cp -f qtbase/mkspecs/macx-clang/qplatformdefs.h qtbase/mkspecs/macx-clang-linux/ &&\ cp -f $($(package)_patch_dir)/mac-qmake.conf qtbase/mkspecs/macx-clang-linux/qmake.conf && \ @@ -225,46 +243,29 @@ define $(package)_preprocess_cmds echo "!host_build: QMAKE_CFLAGS += $($(package)_cflags) $($(package)_cppflags)" >> qtbase/mkspecs/common/gcc-base.conf && \ echo "!host_build: QMAKE_CXXFLAGS += $($(package)_cxxflags) $($(package)_cppflags)" >> qtbase/mkspecs/common/gcc-base.conf && \ echo "!host_build: QMAKE_LFLAGS += $($(package)_ldflags)" >> qtbase/mkspecs/common/gcc-base.conf && \ - sed -i.old "s|QMAKE_CFLAGS += |!host_build: QMAKE_CFLAGS = $($(package)_cflags) $($(package)_cppflags) |" qtbase/mkspecs/win32-g++/qmake.conf && \ - sed -i.old "s|QMAKE_CXXFLAGS += |!host_build: QMAKE_CXXFLAGS = $($(package)_cxxflags) $($(package)_cppflags) |" qtbase/mkspecs/win32-g++/qmake.conf && \ - sed -i.old "0,/^QMAKE_LFLAGS_/s|^QMAKE_LFLAGS_|!host_build: QMAKE_LFLAGS = $($(package)_ldflags)\n&|" qtbase/mkspecs/win32-g++/qmake.conf && \ - sed -i.old "s|QMAKE_CC = clang|QMAKE_CC = $($(package)_cc)|" qtbase/mkspecs/common/clang.conf && \ - sed -i.old "s|QMAKE_CXX = clang++|QMAKE_CXX = $($(package)_cxx)|" qtbase/mkspecs/common/clang.conf + sed -i.old "s|QMAKE_CC = \$$$$\$$$${CROSS_COMPILE}clang|QMAKE_CC = $($(package)_cc)|" qtbase/mkspecs/common/clang.conf && \ + sed -i.old "s|QMAKE_CXX = \$$$$\$$$${CROSS_COMPILE}clang++|QMAKE_CXX = $($(package)_cxx)|" qtbase/mkspecs/common/clang.conf && \ + sed -i.old "s/LIBRARY_PATH/(CROSS_)?\0/g" qtbase/mkspecs/features/toolchain.prf endef define $(package)_config_cmds - export PKG_CONFIG_SYSROOT_DIR=/ && \ - export PKG_CONFIG_LIBDIR=$(host_prefix)/lib/pkgconfig && \ - export PKG_CONFIG_PATH=$(host_prefix)/share/pkgconfig && \ - ./configure $($(package)_config_opts) && \ - echo "host_build: QT_CONFIG ~= s/system-zlib/zlib" >> mkspecs/qconfig.pri && \ - echo "CONFIG += force_bootstrap" >> mkspecs/qconfig.pri && \ - $(MAKE) sub-src-clean && \ - cd ../qttranslations && ../qtbase/bin/qmake qttranslations.pro -o Makefile && \ - cd translations && ../../qtbase/bin/qmake translations.pro -o Makefile && cd ../.. && \ - cd qttools/src/linguist/lrelease/ && ../../../../qtbase/bin/qmake lrelease.pro -o Makefile && \ - cd ../lupdate/ && ../../../../qtbase/bin/qmake lupdate.pro -o Makefile && cd ../../../.. + export QT_MAC_SDK_NO_VERSION_CHECK=1 && \ + cd qtbase && \ + ./configure -top-level $($(package)_config_opts) endef define $(package)_build_cmds export PATH=$(build_prefix)/bin:$(PATH) && \ - $(MAKE) -C src $(addprefix sub-,$($(package)_qt_libs)) && \ - $(MAKE) -C ../qttools/src/linguist/lrelease && \ - $(MAKE) -C ../qttools/src/linguist/lupdate && \ - $(MAKE) -C ../qttranslations + $(MAKE) endef define $(package)_stage_cmds - $(MAKE) -C src INSTALL_ROOT=$($(package)_staging_dir) $(addsuffix -install_subtargets,$(addprefix sub-,$($(package)_qt_libs))) && cd .. && \ - $(MAKE) -C qttools/src/linguist/lrelease INSTALL_ROOT=$($(package)_staging_dir) install_target && \ - $(MAKE) -C qttools/src/linguist/lupdate INSTALL_ROOT=$($(package)_staging_dir) install_target && \ - $(MAKE) -C qttranslations INSTALL_ROOT=$($(package)_staging_dir) install_subtargets && \ - if `test -f qtbase/src/plugins/platforms/xcb/xcb-static/libxcb-static.a`; then \ - cp qtbase/src/plugins/platforms/xcb/xcb-static/libxcb-static.a $($(package)_staging_prefix_dir)/lib; \ - fi + $(MAKE) -C qtbase/src INSTALL_ROOT=$($(package)_staging_dir) $(addsuffix -install_subtargets,$(addprefix sub-,$($(package)_qt_libs))) && \ + $(MAKE) -C qttools/src/linguist INSTALL_ROOT=$($(package)_staging_dir) $(addsuffix -install_subtargets,$(addprefix sub-,$($(package)_linguist_tools))) && \ + $(MAKE) -C qttranslations INSTALL_ROOT=$($(package)_staging_dir) install_subtargets endef define $(package)_postprocess_cmds rm -rf native/mkspecs/ native/lib/ lib/cmake/ && \ - rm -f lib/lib*.la lib/*.prl plugins/*/*.prl + rm -f lib/lib*.la endef diff --git a/depends/packages/xcb_proto.mk b/depends/packages/xcb_proto.mk index 01203a0718..6e1c5a10a8 100644 --- a/depends/packages/xcb_proto.mk +++ b/depends/packages/xcb_proto.mk @@ -1,8 +1,8 @@ package=xcb_proto -$(package)_version=1.10 -$(package)_download_path=https://xcb.freedesktop.org/dist -$(package)_file_name=xcb-proto-$($(package)_version).tar.bz2 -$(package)_sha256_hash=7ef40ddd855b750bc597d2a435da21e55e502a0fefa85b274f2c922800baaf05 +$(package)_version=1.15.2 +$(package)_download_path=https://xorg.freedesktop.org/archive/individual/proto +$(package)_file_name=xcb-proto-$($(package)_version).tar.xz +$(package)_sha256_hash=7072beb1f680a2fe3f9e535b797c146d22528990c72f63ddb49d2f350a3653ed define $(package)_config_cmds $($(package)_autoconf) @@ -17,6 +17,5 @@ define $(package)_stage_cmds endef define $(package)_postprocess_cmds - find -name "*.pyc" -delete && \ - find -name "*.pyo" -delete + rm -rf lib/python*/site-packages/xcbgen/__pycache__ endef diff --git a/depends/packages/xproto.mk b/depends/packages/xproto.mk index 23ad5ffa10..7a43c52faf 100644 --- a/depends/packages/xproto.mk +++ b/depends/packages/xproto.mk @@ -1,11 +1,12 @@ package=xproto -$(package)_version=7.0.26 +$(package)_version=7.0.31 $(package)_download_path=https://xorg.freedesktop.org/releases/individual/proto $(package)_file_name=$(package)-$($(package)_version).tar.bz2 -$(package)_sha256_hash=636162c1759805a5a0114a369dffdeccb8af8c859ef6e1445f26a4e6e046514f +$(package)_sha256_hash=c6f9747da0bd3a95f86b17fb8dd5e717c8f3ab7f0ece3ba1b247899ec1ef7747 define $(package)_set_vars -$(package)_config_opts=--disable-shared +$(package)_config_opts=--without-fop --without-xmlto --without-xsltproc --disable-specs +$(package)_config_opts += --disable-dependency-tracking --enable-option-checking endef define $(package)_preprocess_cmds diff --git a/depends/packages/zeromq.mk b/depends/packages/zeromq.mk index 9eae1a816e..a090493b3f 100644 --- a/depends/packages/zeromq.mk +++ b/depends/packages/zeromq.mk @@ -1,23 +1,31 @@ package=zeromq -$(package)_version=4.3.1 +$(package)_version=4.3.5 $(package)_download_path=https://github.com/zeromq/libzmq/releases/download/v$($(package)_version)/ $(package)_file_name=$(package)-$($(package)_version).tar.gz -$(package)_sha256_hash=bcbabe1e2c7d0eec4ed612e10b94b112dd5f06fcefa994a0c79a45d835cd21eb +$(package)_sha256_hash=6653ef5910f17954861fe72332e68b03ca6e4d9c7160eb3a8de5a5a913bfab43 $(package)_patches=remove_libstd_link.patch define $(package)_set_vars - $(package)_config_opts=--without-docs --disable-shared --without-libsodium --disable-curve --disable-curve-keygen --disable-perf --disable-Werror + $(package)_config_opts = --without-docs --disable-shared --disable-valgrind + $(package)_config_opts += --disable-perf --disable-curve-keygen --disable-curve --disable-libbsd + $(package)_config_opts += --without-libsodium --without-libgssapi_krb5 --without-pgm --without-norm --without-vmci + $(package)_config_opts += --disable-libunwind --disable-radix-tree --without-gcov --disable-dependency-tracking + $(package)_config_opts += --disable-Werror --disable-drafts --enable-option-checking $(package)_config_opts_linux=--with-pic + $(package)_config_opts_freebsd=--with-pic + $(package)_config_opts_netbsd=--with-pic + $(package)_config_opts_openbsd=--with-pic $(package)_config_opts_android=--with-pic - $(package)_cxxflags=-std=c++17 + $(package)_cxxflags+=-std=c++17 endef define $(package)_preprocess_cmds - patch -p1 < $($(package)_patch_dir)/remove_libstd_link.patch && \ - cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub config + patch -p1 < $($(package)_patch_dir)/remove_libstd_link.patch endef define $(package)_config_cmds + ./autogen.sh && \ + cp -f $(BASEDIR)/config.guess $(BASEDIR)/config.sub config && \ $($(package)_autoconf) endef @@ -30,5 +38,5 @@ define $(package)_stage_cmds endef define $(package)_postprocess_cmds - rm -rf bin share + rm -rf bin share lib/*.la endef diff --git a/depends/packages/zlib.mk b/depends/packages/zlib.mk index 12675691b9..c5361e3463 100644 --- a/depends/packages/zlib.mk +++ b/depends/packages/zlib.mk @@ -1,8 +1,8 @@ package=zlib -$(package)_version=1.2.11 +$(package)_version=1.3.1 $(package)_download_path=https://www.zlib.net -$(package)_file_name=$(package)-$($(package)_version).tar.gz -$(package)_sha256_hash=c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1 +$(package)_file_name=$(package)-$($(package)_version).tar.xz +$(package)_sha256_hash=38ef96b8dfe510d42707d9c781877914792541133e1870841463bfa73f883e32 define $(package)_set_vars $(package)_config_opts= CC="$($(package)_cc)" diff --git a/depends/patches/fontconfig/gperf_header_regen.patch b/depends/patches/fontconfig/gperf_header_regen.patch index 7401b83d84..b1a70d5fb1 100755 --- a/depends/patches/fontconfig/gperf_header_regen.patch +++ b/depends/patches/fontconfig/gperf_header_regen.patch @@ -2,7 +2,7 @@ commit 7b6eb33ecd88768b28c67ce5d2d68a7eed5936b6 Author: fanquake Date: Tue Aug 25 14:34:53 2020 +0800 - Remove rule that causes inadvertant header regeneration + Remove rule that causes inadvertent header regeneration Otherwise the makefile will needlessly attempt to re-generate the headers with gperf. This can be dropped once the upstream build is fixed. @@ -13,12 +13,12 @@ diff --git a/src/Makefile.in b/src/Makefile.in index f4626ad..4ae1b00 100644 --- a/src/Makefile.in +++ b/src/Makefile.in -@@ -903,7 +903,7 @@ fcobjshash.gperf: fcobjshash.gperf.h fcobjs.h +@@ -912,7 +912,7 @@ ' - > $@.tmp && \ - mv -f $@.tmp $@ || ( $(RM) $@.tmp && false ) + mv -f $@.tmp fcobjshash.gperf && touch $@ || ( $(RM) $@.tmp && false ) --fcobjshash.h: fcobjshash.gperf +-fcobjshash.h: Makefile fcobjshash.gperf +fcobjshash.h: - $(AM_V_GEN) $(GPERF) -m 100 $< > $@.tmp && \ + $(AM_V_GEN) $(GPERF) --pic -m 100 fcobjshash.gperf > $@.tmp && \ mv -f $@.tmp $@ || ( $(RM) $@.tmp && false ) diff --git a/depends/patches/fontconfig/remove_char_width_usage.patch b/depends/patches/fontconfig/remove_char_width_usage.patch deleted file mode 100755 index 9f69081890..0000000000 --- a/depends/patches/fontconfig/remove_char_width_usage.patch +++ /dev/null @@ -1,62 +0,0 @@ -commit 28165a9b078583dc8e9e5c344510e37582284cef -Author: fanquake -Date: Mon Aug 17 20:35:42 2020 +0800 - - Remove usage of CHAR_WIDTH - - CHAR_WIDTH which is reserved and clashes with glibc 2.25+ - - See #10851. - -diff --git a/fontconfig/fontconfig.h b/fontconfig/fontconfig.h -index 5c72b22..843c532 100644 ---- a/fontconfig/fontconfig.h -+++ b/fontconfig/fontconfig.h -@@ -128,7 +128,7 @@ typedef int FcBool; - #define FC_USER_CACHE_FILE ".fonts.cache-" FC_CACHE_VERSION - - /* Adjust outline rasterizer */ --#define FC_CHAR_WIDTH "charwidth" /* Int */ -+#define FC_CHARWIDTH "charwidth" /* Int */ - #define FC_CHAR_HEIGHT "charheight"/* Int */ - #define FC_MATRIX "matrix" /* FcMatrix */ - -diff --git a/src/fcobjs.h b/src/fcobjs.h -index 1fc4f65..d27864b 100644 ---- a/src/fcobjs.h -+++ b/src/fcobjs.h -@@ -51,7 +51,7 @@ FC_OBJECT (DPI, FcTypeDouble, NULL) - FC_OBJECT (RGBA, FcTypeInteger, NULL) - FC_OBJECT (SCALE, FcTypeDouble, NULL) - FC_OBJECT (MINSPACE, FcTypeBool, NULL) --FC_OBJECT (CHAR_WIDTH, FcTypeInteger, NULL) -+FC_OBJECT (CHARWIDTH, FcTypeInteger, NULL) - FC_OBJECT (CHAR_HEIGHT, FcTypeInteger, NULL) - FC_OBJECT (MATRIX, FcTypeMatrix, NULL) - FC_OBJECT (CHARSET, FcTypeCharSet, FcCompareCharSet) -diff --git a/src/fcobjshash.gperf b/src/fcobjshash.gperf -index 80a0237..eb4ad84 100644 ---- a/src/fcobjshash.gperf -+++ b/src/fcobjshash.gperf -@@ -44,7 +44,7 @@ int id; - "rgba",FC_RGBA_OBJECT - "scale",FC_SCALE_OBJECT - "minspace",FC_MINSPACE_OBJECT --"charwidth",FC_CHAR_WIDTH_OBJECT -+"charwidth",FC_CHARWIDTH_OBJECT - "charheight",FC_CHAR_HEIGHT_OBJECT - "matrix",FC_MATRIX_OBJECT - "charset",FC_CHARSET_OBJECT -diff --git a/src/fcobjshash.h b/src/fcobjshash.h -index 5a4d1ea..4e66bb0 100644 ---- a/src/fcobjshash.h -+++ b/src/fcobjshash.h -@@ -284,7 +284,7 @@ FcObjectTypeLookup (register const char *str, register unsigned int len) - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str43,FC_CHARSET_OBJECT}, - {-1}, - #line 47 "fcobjshash.gperf" -- {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str45,FC_CHAR_WIDTH_OBJECT}, -+ {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str45,FC_CHARWIDTH_OBJECT}, - #line 48 "fcobjshash.gperf" - {(int)(long)&((struct FcObjectTypeNamePool_t *)0)->FcObjectTypeNamePool_str46,FC_CHAR_HEIGHT_OBJECT}, - #line 55 "fcobjshash.gperf" diff --git a/depends/patches/libevent/0001-fix-windows-getaddrinfo.patch b/depends/patches/libevent/0001-fix-windows-getaddrinfo.patch deleted file mode 100644 index a98cd90bd5..0000000000 --- a/depends/patches/libevent/0001-fix-windows-getaddrinfo.patch +++ /dev/null @@ -1,15 +0,0 @@ -diff -ur libevent-2.1.8-stable.orig/configure.ac libevent-2.1.8-stable/configure.ac ---- libevent-2.1.8-stable.orig/configure.ac 2017-01-29 17:51:00.000000000 +0000 -+++ libevent-2.1.8-stable/configure.ac 2020-03-07 01:11:16.311335005 +0000 -@@ -389,6 +389,10 @@ - #ifdef HAVE_NETDB_H - #include - #endif -+#ifdef _WIN32 -+#include -+#include -+#endif - ]], - [[ - getaddrinfo; -Only in libevent-2.1.8-stable: configure.ac~ diff --git a/depends/patches/miniupnpc/respect_mingw_cflags.patch b/depends/patches/miniupnpc/respect_mingw_cflags.patch new file mode 100644 index 0000000000..a44580ddab --- /dev/null +++ b/depends/patches/miniupnpc/respect_mingw_cflags.patch @@ -0,0 +1,23 @@ +commit fec515a7ac9991a0ee91068fda046b54b191155e +Author: fanquake +Date: Wed Jul 27 15:52:37 2022 +0100 + + build: respect CFLAGS in makefile.mingw + + Similar to the other Makefile. + + Cherry-pick of https://github.com/miniupnp/miniupnp/pull/619. + +diff --git a/Makefile.mingw b/Makefile.mingw +index 2bff7bd..88430d2 100644 +--- a/Makefile.mingw ++++ b/Makefile.mingw +@@ -19,7 +19,7 @@ else + RM = rm -f + endif + #CFLAGS = -Wall -g -DDEBUG -D_WIN32_WINNT=0X501 +-CFLAGS = -Wall -W -Wstrict-prototypes -Os -DNDEBUG -D_WIN32_WINNT=0X501 ++CFLAGS ?= -Wall -W -Wstrict-prototypes -Os -DNDEBUG -D_WIN32_WINNT=0X501 + LDLIBS = -lws2_32 -liphlpapi + # -lwsock32 + # -liphlpapi is needed for GetBestRoute() and GetIpAddrTable() diff --git a/depends/patches/native_cctools/ld64_disable_threading.patch b/depends/patches/native_cctools/ld64_disable_threading.patch deleted file mode 100755 index d6c58c102f..0000000000 --- a/depends/patches/native_cctools/ld64_disable_threading.patch +++ /dev/null @@ -1,26 +0,0 @@ -commit 584668415039adeed073decee7e04de28248afd3 -Author: fanquake -Date: Tue Aug 18 01:20:24 2020 +0000 - - Disable threading to fix non-determinism - - A bug in the file parser can cause dependencies to be calculated - differently based on which files have already been parsed. This is more - likely to occur on systems with more CPUs. - - Just disable threading for now. There is no noticable slowdown. - - See #9891. - -diff --git a/cctools/ld64/src/ld/InputFiles.h b/cctools/ld64/src/ld/InputFiles.h -index ef9c756..90a70b6 100644 ---- a/cctools/ld64/src/ld/InputFiles.h -+++ b/cctools/ld64/src/ld/InputFiles.h -@@ -25,7 +25,6 @@ - #ifndef __INPUT_FILES_H__ - #define __INPUT_FILES_H__ - --#define HAVE_PTHREADS 1 - - #include - #include diff --git a/depends/patches/native_cdrkit/cdrkit-deterministic.patch b/depends/patches/native_cdrkit/cdrkit-deterministic.patch deleted file mode 100644 index 8ab0993dc4..0000000000 --- a/depends/patches/native_cdrkit/cdrkit-deterministic.patch +++ /dev/null @@ -1,86 +0,0 @@ ---- cdrkit-1.1.11.old/genisoimage/tree.c 2008-10-21 19:57:47.000000000 -0400 -+++ cdrkit-1.1.11/genisoimage/tree.c 2013-12-06 00:23:18.489622668 -0500 -@@ -1139,8 +1139,9 @@ - scan_directory_tree(struct directory *this_dir, char *path, - struct directory_entry *de) - { -- DIR *current_dir; -+ int current_file; - char whole_path[PATH_MAX]; -+ struct dirent **d_list; - struct dirent *d_entry; - struct directory *parent; - int dflag; -@@ -1164,7 +1165,8 @@ - this_dir->dir_flags |= DIR_WAS_SCANNED; - - errno = 0; /* Paranoia */ -- current_dir = opendir(path); -+ //current_dir = opendir(path); -+ current_file = scandir(path, &d_list, NULL, alphasort); - d_entry = NULL; - - /* -@@ -1173,12 +1175,12 @@ - */ - old_path = path; - -- if (current_dir) { -+ if (current_file >= 0) { - errno = 0; -- d_entry = readdir(current_dir); -+ d_entry = d_list[0]; - } - -- if (!current_dir || !d_entry) { -+ if (current_file < 0 || !d_entry) { - int ret = 1; - - #ifdef USE_LIBSCHILY -@@ -1191,8 +1193,8 @@ - de->isorec.flags[0] &= ~ISO_DIRECTORY; - ret = 0; - } -- if (current_dir) -- closedir(current_dir); -+ if(d_list) -+ free(d_list); - return (ret); - } - #ifdef ABORT_DEEP_ISO_ONLY -@@ -1208,7 +1210,7 @@ - errmsgno(EX_BAD, "use Rock Ridge extensions via -R or -r,\n"); - errmsgno(EX_BAD, "or allow deep ISO9660 directory nesting via -D.\n"); - } -- closedir(current_dir); -+ free(d_list); - return (1); - } - #endif -@@ -1250,13 +1252,13 @@ - * The first time through, skip this, since we already asked - * for the first entry when we opened the directory. - */ -- if (dflag) -- d_entry = readdir(current_dir); -+ if (dflag && current_file >= 0) -+ d_entry = d_list[current_file]; - dflag++; - -- if (!d_entry) -+ if (current_file < 0) - break; -- -+ current_file--; - /* OK, got a valid entry */ - - /* If we do not want all files, then pitch the backups. */ -@@ -1348,7 +1350,7 @@ - insert_file_entry(this_dir, whole_path, d_entry->d_name); - #endif /* APPLE_HYB */ - } -- closedir(current_dir); -+ free(d_list); - - #ifdef APPLE_HYB - /* diff --git a/depends/patches/native_libdmg-hfsplus/remove-libcrypto-dependency.patch b/depends/patches/native_libdmg-hfsplus/remove-libcrypto-dependency.patch deleted file mode 100644 index f346c8f2cf..0000000000 --- a/depends/patches/native_libdmg-hfsplus/remove-libcrypto-dependency.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 3e5fd3fb56bc9ff03beb535979e33dcf83fe1f70 Mon Sep 17 00:00:00 2001 -From: Cory Fields -Date: Thu, 8 May 2014 12:39:42 -0400 -Subject: [PATCH] dmg: remove libcrypto dependency - ---- - dmg/CMakeLists.txt | 16 ---------------- - 1 file changed, 16 deletions(-) - -diff --git a/dmg/CMakeLists.txt b/dmg/CMakeLists.txt -index eec62d6..3969f64 100644 ---- a/dmg/CMakeLists.txt -+++ b/dmg/CMakeLists.txt -@@ -1,12 +1,5 @@ --INCLUDE(FindOpenSSL) - INCLUDE(FindZLIB) - --FIND_LIBRARY(CRYPTO_LIBRARIES crypto -- PATHS -- /usr/lib -- /usr/local/lib -- ) -- - IF(NOT ZLIB_FOUND) - message(FATAL_ERROR "zlib is required for dmg!") - ENDIF(NOT ZLIB_FOUND) -@@ -18,15 +11,6 @@ link_directories(${PROJECT_BINARY_DIR}/common ${PROJECT_BINARY_DIR}/hfs) - - add_library(dmg adc.c base64.c checksum.c dmgfile.c dmglib.c filevault.c io.c partition.c resources.c udif.c) - --IF(OPENSSL_FOUND) -- add_definitions(-DHAVE_CRYPT) -- include_directories(${OPENSSL_INCLUDE_DIR}) -- target_link_libraries(dmg ${CRYPTO_LIBRARIES}) -- IF(WIN32) -- TARGET_LINK_LIBRARIES(dmg gdi32) -- ENDIF(WIN32) --ENDIF(OPENSSL_FOUND) -- - target_link_libraries(dmg common hfs z) - - add_executable(dmg-bin dmg.c) --- -2.22.0 - diff --git a/depends/patches/qt/dont_hardcode_x86_64.patch b/depends/patches/qt/dont_hardcode_x86_64.patch new file mode 100644 index 0000000000..0e1ca6acda --- /dev/null +++ b/depends/patches/qt/dont_hardcode_x86_64.patch @@ -0,0 +1,123 @@ +macOS: Don't hard-code x86_64 as the architecture when using qmake + +Upstream commit: + - Qt 6.1: 9082cc8e8d5a6441dabe5e7a95bc0cd9085b95fe + +For other Qt branches see +https://codereview.qt-project.org/q/I70db7e4c27f0d3da5d0af33cb491d72c312d3fa8 + + +--- old/qtbase/configure.json ++++ new/qtbase/configure.json +@@ -208,11 +208,18 @@ + + "testTypeDependencies": { + "linkerSupportsFlag": [ "use_gold_linker" ], +- "verifySpec": [ "shared", "use_gold_linker", "compiler-flags", "qmakeargs", "commit" ], ++ "verifySpec": [ ++ "shared", ++ "use_gold_linker", ++ "compiler-flags", "qmakeargs", ++ "simulator_and_device", ++ "thread", ++ "commit" ], + "compile": [ "verifyspec" ], + "detectPkgConfig": [ "cross_compile", "machineTuple" ], + "library": [ "pkg-config", "compiler-flags" ], +- "getPkgConfigVariable": [ "pkg-config" ] ++ "getPkgConfigVariable": [ "pkg-config" ], ++ "architecture" : [ "verifyspec" ] + }, + + "testTypeAliases": { +@@ -653,7 +660,7 @@ + }, + "architecture": { + "label": "Architecture", +- "output": [ "architecture" ] ++ "output": [ "architecture", "commitConfig" ] + }, + "pkg-config": { + "label": "Using pkg-config", +diff --git a/configure.pri b/configure.pri +index 33c90a8c2f..71767e29d6 100644 + +--- old/qtbase/configure.pri ++++ new/qtbase/configure.pri +@@ -642,6 +642,13 @@ defineTest(qtConfOutput_commitOptions) { + write_file($$QT_BUILD_TREE/mkspecs/qdevice.pri, $${currentConfig}.output.devicePro)|error() + } + ++# Output is written after configuring each Qt module, ++# but some tests within a module might depend on the ++# configuration output of previous tests. ++defineTest(qtConfOutput_commitConfig) { ++ qtConfProcessOutput() ++} ++ + # type (empty or 'host'), option name, default value + defineTest(processQtPath) { + out_var = config.rel_input.$${2} +diff --git a/mkspecs/common/macx.conf b/mkspecs/common/macx.conf +index 7d4a406134..de96c12fc9 100644 + +--- old/qtbase/mkspecs/common/macx.conf ++++ new/qtbase/mkspecs/common/macx.conf +@@ -6,7 +6,6 @@ QMAKE_PLATFORM += macos osx macx + QMAKE_MAC_SDK = macosx + + QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.12 +-QMAKE_APPLE_DEVICE_ARCHS = x86_64 + + QT_MAC_SDK_VERSION_MIN = 10.13 + QT_MAC_SDK_VERSION_MAX = 11.0 +diff --git a/mkspecs/features/mac/default_post.prf b/mkspecs/features/mac/default_post.prf +index d052808c14..0a89effe87 100644 + +--- old/qtbase/mkspecs/features/mac/default_post.prf ++++ new/qtbase/mkspecs/features/mac/default_post.prf +@@ -89,6 +89,11 @@ app_extension_api_only { + QMAKE_LFLAGS += $$QMAKE_CFLAGS_APPLICATION_EXTENSION + } + ++# Non-universal builds do not set QMAKE_APPLE_DEVICE_ARCHS, ++# so we pick it up from what the arch test resolved instead. ++isEmpty(QMAKE_APPLE_DEVICE_ARCHS): \ ++ QMAKE_APPLE_DEVICE_ARCHS = $$QT_ARCH ++ + macx-xcode { + qmake_pkginfo_typeinfo.name = QMAKE_PKGINFO_TYPEINFO + !isEmpty(QMAKE_PKGINFO_TYPEINFO): \ +@@ -144,9 +149,6 @@ macx-xcode { + simulator: VALID_SIMULATOR_ARCHS = $$QMAKE_APPLE_SIMULATOR_ARCHS + VALID_ARCHS = $$VALID_DEVICE_ARCHS $$VALID_SIMULATOR_ARCHS + +- isEmpty(VALID_ARCHS): \ +- error("QMAKE_APPLE_DEVICE_ARCHS or QMAKE_APPLE_SIMULATOR_ARCHS must contain at least one architecture") +- + single_arch: VALID_ARCHS = $$first(VALID_ARCHS) + + ACTIVE_ARCHS = $(filter $(EXPORT_VALID_ARCHS), $(ARCHS)) +diff --git a/mkspecs/features/toolchain.prf b/mkspecs/features/toolchain.prf +index 5003679bd0..c7c080cb07 100644 + +--- old/qtbase/mkspecs/features/toolchain.prf ++++ new/qtbase/mkspecs/features/toolchain.prf +@@ -182,9 +182,14 @@ isEmpty($${target_prefix}.INCDIRS) { + # UIKit simulator platforms will see the device SDK's sysroot in + # QMAKE_DEFAULT_*DIRS, because they're handled in a single build pass. + darwin { +- # Clang doesn't pick up the architecture from the sysroot, and will +- # default to the host architecture, so we need to manually set it. +- cxx_flags += -arch $$QMAKE_APPLE_DEVICE_ARCHS ++ uikit { ++ # Clang doesn't automatically pick up the architecture, just because ++ # we're passing the iOS sysroot below, and we will end up building the ++ # test for the host architecture, resulting in linker errors when ++ # linking against the iOS libraries. We work around this by passing ++ # the architecture explicitly. ++ cxx_flags += -arch $$first(QMAKE_APPLE_DEVICE_ARCHS) ++ } + + uikit:macx-xcode: \ + cxx_flags += -isysroot $$sdk_path_device.value diff --git a/depends/patches/qt/drop_lrelease_dependency.patch b/depends/patches/qt/drop_lrelease_dependency.patch deleted file mode 100644 index f6b2c9fc80..0000000000 --- a/depends/patches/qt/drop_lrelease_dependency.patch +++ /dev/null @@ -1,20 +0,0 @@ -commit 67b3ed7406e1d0762188dbad2c44a06824ba0778 -Author: fanquake -Date: Tue Aug 18 15:24:01 2020 +0800 - - Drop dependency on lrelease - - Qts buildsystem insists on using the installed lrelease, but gets - confused about how to find it. Since we manually control the build - order, just drop the dependency. - - See #9469 - -diff --git a/qttranslations/translations/translations.pro b/qttranslations/translations/translations.pro -index 694544c..eff339d 100644 ---- a/qttranslations/translations/translations.pro -+++ b/qttranslations/translations/translations.pro -@@ -109,3 +109,2 @@ updateqm.commands = $$LRELEASE ${QMAKE_FILE_IN} -qm ${QMAKE_FILE_OUT} - silent:updateqm.commands = @echo lrelease ${QMAKE_FILE_IN} && $$updateqm.commands --updateqm.depends = $$LRELEASE_EXE - updateqm.name = LRELEASE ${QMAKE_FILE_IN} diff --git a/depends/patches/qt/fix_android_jni_static.patch b/depends/patches/qt/fix_android_jni_static.patch index 2f6ff00f40..a186aeb8f6 100644 --- a/depends/patches/qt/fix_android_jni_static.patch +++ b/depends/patches/qt/fix_android_jni_static.patch @@ -1,6 +1,6 @@ --- old/qtbase/src/plugins/platforms/android/androidjnimain.cpp +++ new/qtbase/src/plugins/platforms/android/androidjnimain.cpp -@@ -890,6 +890,14 @@ +@@ -898,6 +898,14 @@ __android_log_print(ANDROID_LOG_FATAL, "Qt", "registerNatives failed"); return -1; } diff --git a/depends/patches/qt/fix_android_pch.patch b/depends/patches/qt/fix_android_pch.patch new file mode 100644 index 0000000000..195e1c5e59 --- /dev/null +++ b/depends/patches/qt/fix_android_pch.patch @@ -0,0 +1,10 @@ +--- old/qtbase/mkspecs/common/android-base-head.conf ++++ new/qtbase/mkspecs/common/android-base-head.conf +@@ -72,6 +72,6 @@ CROSS_COMPILE = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX- + QMAKE_PCH_OUTPUT_EXT = .gch + + QMAKE_CFLAGS_PRECOMPILE = -x c-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT} +-QMAKE_CFLAGS_USE_PRECOMPILE = -include ${QMAKE_PCH_OUTPUT_BASE} ++QMAKE_CFLAGS_USE_PRECOMPILE = -include-pch ${QMAKE_PCH_OUTPUT} + QMAKE_CXXFLAGS_PRECOMPILE = -x c++-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT} + QMAKE_CXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE diff --git a/depends/patches/qt/fix_android_qmake_conf.patch b/depends/patches/qt/fix_android_qmake_conf.patch deleted file mode 100644 index 13bfff9776..0000000000 --- a/depends/patches/qt/fix_android_qmake_conf.patch +++ /dev/null @@ -1,20 +0,0 @@ ---- old/qtbase/mkspecs/android-clang/qmake.conf -+++ new/qtbase/mkspecs/android-clang/qmake.conf -@@ -30,7 +30,7 @@ - QMAKE_CFLAGS += -target mips64el-none-linux-android - - QMAKE_CFLAGS += -gcc-toolchain $$NDK_TOOLCHAIN_PATH --QMAKE_LINK = $$QMAKE_CXX $$QMAKE_CFLAGS -Wl,--exclude-libs,libgcc.a -+QMAKE_LINK = $$QMAKE_CXX $$QMAKE_CFLAGS -Wl,--exclude-libs,libgcc.a -nostdlib++ - QMAKE_CFLAGS += -DANDROID_HAS_WSTRING --sysroot=$$NDK_ROOT/sysroot \ - -isystem $$NDK_ROOT/sysroot/usr/include/$$NDK_TOOLS_PREFIX \ - -isystem $$NDK_ROOT/sources/cxx-stl/llvm-libc++/include \ -@@ -40,7 +40,7 @@ - ANDROID_SOURCES_CXX_STL_LIBDIR = $$NDK_ROOT/sources/cxx-stl/llvm-libc++/libs/$$ANDROID_TARGET_ARCH - - ANDROID_STDCPP_PATH = $$ANDROID_SOURCES_CXX_STL_LIBDIR/libc++_shared.so --ANDROID_CXX_STL_LIBS = -lc++ -+ANDROID_CXX_STL_LIBS = -lc++_shared - - QMAKE_ARM_CFLAGS_RELEASE = -Oz - QMAKE_ARM_CFLAGS_RELEASE_WITH_DEBUGINFO = -g -Oz diff --git a/depends/patches/qt/fix_configure_mac.patch b/depends/patches/qt/fix_configure_mac.patch deleted file mode 100644 index 0d7dd647de..0000000000 --- a/depends/patches/qt/fix_configure_mac.patch +++ /dev/null @@ -1,50 +0,0 @@ ---- old/qtbase/mkspecs/features/mac/sdk.prf 2018-02-08 10:24:48.000000000 -0800 -+++ new/qtbase/mkspecs/features/mac/sdk.prf 2018-03-23 10:38:56.000000000 -0700 -@@ -8,21 +8,21 @@ - defineReplace(xcodeSDKInfo) { - info = $$1 - equals(info, "Path"): \ -- info = --show-sdk-path -+ infoarg = --show-sdk-path - equals(info, "PlatformPath"): \ -- info = --show-sdk-platform-path -+ infoarg = --show-sdk-platform-path - equals(info, "SDKVersion"): \ -- info = --show-sdk-version -+ infoarg = --show-sdk-version - sdk = $$2 - isEmpty(sdk): \ - sdk = $$QMAKE_MAC_SDK - - isEmpty(QMAKE_MAC_SDK.$${sdk}.$${info}) { -- QMAKE_MAC_SDK.$${sdk}.$${info} = $$system("/usr/bin/xcrun --sdk $$sdk $$info 2>/dev/null") -+ QMAKE_MAC_SDK.$${sdk}.$${info} = $$system("/usr/bin/xcrun --sdk $$sdk $$infoarg 2>/dev/null") - # --show-sdk-platform-path won't work for Command Line Tools; this is fine - # only used by the XCTest backend to testlib -- isEmpty(QMAKE_MAC_SDK.$${sdk}.$${info}):if(!isEmpty(QMAKE_XCODEBUILD_PATH)|!equals(info, "--show-sdk-platform-path")): \ -- error("Could not resolve SDK $$info for \'$$sdk\'") -+ isEmpty(QMAKE_MAC_SDK.$${sdk}.$${info}):if(!isEmpty(QMAKE_XCODEBUILD_PATH)|!equals(infoarg, "--show-sdk-platform-path")): \ -+ error("Could not resolve SDK $$info for \'$$sdk\' using $$infoarg") - cache(QMAKE_MAC_SDK.$${sdk}.$${info}, set stash, QMAKE_MAC_SDK.$${sdk}.$${info}) - } - ---- old/qtbase/configure 2018-02-08 10:24:48.000000000 -0800 -+++ new/qtbase/configure 2018-03-23 05:42:29.000000000 -0700 -@@ -232,8 +232,13 @@ - - sdk=$(getSingleQMakeVariable "QMAKE_MAC_SDK" "$1") - if [ -z "$sdk" ]; then echo "QMAKE_MAC_SDK must be set when building on Mac" >&2; exit 1; fi -- sysroot=$(/usr/bin/xcrun --sdk $sdk --show-sdk-path 2>/dev/null) -- if [ -z "$sysroot" ]; then echo "Failed to resolve SDK path for '$sdk'" >&2; exit 1; fi -+ sysroot=$(getSingleQMakeVariable "QMAKE_MAC_SDK_PATH" "$1") -+ -+ echo "sysroot pre-configured as $sysroot"; -+ if [ -z "$sysroot" ]; then -+ sysroot=$(/usr/bin/xcrun --sdk $sdk --show-sdk-path 2>/dev/null) -+ if [ -z "$sysroot" ]; then echo "Failed to resolve SDK path for '$sdk'" >&2; exit 1; fi -+ fi - - case "$sdk" in - macosx*) - - diff --git a/depends/patches/qt/fix_lib_paths.patch b/depends/patches/qt/fix_lib_paths.patch new file mode 100644 index 0000000000..d1a15373f4 --- /dev/null +++ b/depends/patches/qt/fix_lib_paths.patch @@ -0,0 +1,193 @@ +--- old/qtbase/mkspecs/common/mac.conf ++++ new/qtbase/mkspecs/common/mac.conf +@@ -14,7 +14,6 @@ + + QMAKE_RESOURCE = /Developer/Tools/Rez + QMAKE_EXTENSION_SHLIB = dylib +-QMAKE_EXTENSIONS_AUX_SHLIB = tbd + QMAKE_LIBDIR = + + # sdk.prf will prefix the proper SDK sysroot + +--- old/qtbase/mkspecs/features/qmake_use.prf ++++ new/qtbase/mkspecs/features/qmake_use.prf +@@ -22,6 +22,8 @@ + !defined(QMAKE_LIBS_$$nu, var): \ + error("Library '$$lower($$replace(nu, _, -))' is not defined.") + ++ QMAKE_LIBDIR += $$eval(QMAKE_LIBDIR_$$nu) ++ + debug: \ + LIBS$${suffix} += $$eval(QMAKE_LIBS_$${nu}_DEBUG) $$eval(QMAKE_LIBS_$$nu) + else: \ + +--- old/qtbase/mkspecs/features/qt_configure.prf ++++ new/qtbase/mkspecs/features/qt_configure.prf +@@ -526,98 +526,23 @@ + return($$sysrootified) + } + +-# libs-var, libs, in-paths, out-paths-var ++# libs-var, libs, in-paths + defineTest(qtConfResolveLibs) { +- ret = true +- paths = $$3 +- out = +- copy = false +- for (l, 2) { +- $$copy { +- copy = false +- out += $$l +- } else: equals(l, "-s") { +- # em++ flag to link libraries from emscripten-ports; passed on literally. +- copy = true +- out += $$l +- } else: contains(l, "^-L.*") { +- lp = $$replace(l, "^-L", ) +- gcc: lp = $$qtGccSysrootifiedPath($$lp) +- !exists($$lp/.) { +- qtLog("Library path $$val_escape(lp) is invalid.") +- ret = false +- } else { +- paths += $$lp +- } +- } else: contains(l, "^-l.*") { +- lib = $$replace(l, "^-l", ) +- lcan = +- integrity:contains(lib, "^.*\\.a") { +- # INTEGRITY compiler searches for exact filename +- # if -l argument has .a suffix +- lcan += $${lib} +- } else: contains(lib, "^:.*") { +- # Use exact filename when -l:filename syntax is used. +- lib ~= s/^:// +- lcan += $${lib} +- } else: unix { +- # Under UNIX, we look for actual shared libraries, in addition +- # to static ones. +- shexts = $$QMAKE_EXTENSION_SHLIB $$QMAKE_EXTENSIONS_AUX_SHLIB +- for (ext, shexts) { +- lcan += $${QMAKE_PREFIX_SHLIB}$${lib}.$${ext} +- } +- lcan += \ +- $${QMAKE_PREFIX_STATICLIB}$${lib}.$${QMAKE_EXTENSION_STATICLIB} +- } else { +- # Under Windows, we look only for static libraries, as even for DLLs +- # one actually links against a static import library. +- mingw { +- lcan += \ +- # MinGW supports UNIX-style library naming in addition to +- # the MSVC style. +- lib$${lib}.dll.a lib$${lib}.a \ +- # Fun fact: prefix-less libraries are also supported. +- $${lib}.dll.a $${lib}.a +- } +- lcan += $${lib}.lib +- } +- l = $$qtConfFindInPathList($$lcan, $$paths $$EXTRA_LIBDIR $$QMAKE_DEFAULT_LIBDIRS) +- isEmpty(l) { +- qtLog("None of [$$val_escape(lcan)] found in [$$val_escape(paths)] and global paths.") +- ret = false +- } else { +- out += $$l +- } +- } else { +- out += $$l +- } +- } +- $$1 = $$out ++ for (path, 3): \ ++ pre_lflags += -L$$path ++ $$1 = $$pre_lflags $$2 + export($$1) +- !isEmpty(4) { +- $$4 = $$paths +- export($$4) +- } +- return($$ret) +-} +- +-# source-var +-defineTest(qtConfResolveAllLibs) { +- ret = true +- !qtConfResolveLibs($${1}.libs, $$eval($${1}.libs), , $${1}.libdirs): \ +- ret = false +- for (b, $${1}.builds._KEYS_): \ +- !qtConfResolveLibs($${1}.builds.$${b}, $$eval($${1}.builds.$${b}), $$eval($${1}.libdirs), ): \ +- ret = false +- return($$ret) ++ return(true) + } + + # libs-var, in-paths, libs + defineTest(qtConfResolvePathLibs) { + ret = true +- gcc: 2 = $$qtGccSysrootifiedPaths($$2) +- for (libdir, 2) { ++ gcc: \ ++ local_paths = $$qtGccSysrootifiedPaths($$2) ++ else: \ ++ local_paths = $$2 ++ for (libdir, local_paths) { + !exists($$libdir/.) { + qtLog("Library path $$val_escape(libdir) is invalid.") + ret = false +@@ -667,8 +592,11 @@ + # includes-var, in-paths, test-object-var + defineTest(qtConfResolvePathIncs) { + ret = true +- gcc: 2 = $$qtGccSysrootifiedPaths($$2) +- for (incdir, 2) { ++ gcc: \ ++ local_paths = $$qtGccSysrootifiedPaths($$2) ++ else: \ ++ local_paths = $$2 ++ for (incdir, local_paths) { + !exists($$incdir/.) { + qtLog("Include path $$val_escape(incdir) is invalid.") + ret = false +@@ -727,6 +655,7 @@ + vars += $$eval(config.commandline.rev_assignments.$${iv}) + defined(config.input.$${iv}, var) { + eval($${1}.builds.$${b} = $$eval(config.input.$${iv})) ++ export($${1}.builds.$${b}) + $${1}.builds._KEYS_ *= $${b} + any = true + } else { +@@ -741,11 +670,14 @@ + export($${1}.builds._KEYS_) + # we also reset the generic libs, to avoid surprises. + $${1}.libs = ++ export($${1}.libs) + } + + # direct libs. overwrites inline libs. +- defined(config.input.$${input}.libs, var): \ ++ defined(config.input.$${input}.libs, var) { + eval($${1}.libs = $$eval(config.input.$${input}.libs)) ++ export($${1}.libs) ++ } + + includes = $$eval(config.input.$${input}.incdir) + +@@ -754,6 +686,7 @@ + !isEmpty(prefix) { + includes += $$prefix/include + $${1}.libs = -L$$prefix/lib $$eval($${1}.libs) ++ export($${1}.libs) + } + + libdir = $$eval(config.input.$${input}.libdir) +@@ -762,11 +695,9 @@ + for (ld, libdir): \ + libs += -L$$ld + $${1}.libs = $$libs $$eval($${1}.libs) ++ export($${1}.libs) + } + +- !qtConfResolveAllLibs($$1): \ +- return(false) +- + !qtConfResolvePathIncs($${1}.includedir, $$includes, $$2): \ + return(false) + diff --git a/depends/patches/qt/fix_limits_header.patch b/depends/patches/qt/fix_limits_header.patch new file mode 100644 index 0000000000..e4313770e5 --- /dev/null +++ b/depends/patches/qt/fix_limits_header.patch @@ -0,0 +1,44 @@ +Fix compiling with GCC 11 + +See: https://bugreports.qt.io/browse/QTBUG-90395. + +Upstream commits: + - Qt 5.15 -- unavailable as open source + - Qt 6.0: b2af6332ea37e45ab230a7a5d2d278f86d961b83 + - Qt 6.1: 9c56d4da2ff631a8c1c30475bd792f6c86bda53c + +--- old/qtbase/src/corelib/global/qendian.h ++++ new/qtbase/src/corelib/global/qendian.h +@@ -44,6 +44,8 @@ + #include + #include + ++#include ++ + // include stdlib.h and hope that it defines __GLIBC__ for glibc-based systems + #include + #include + +--- old/qtbase/src/corelib/tools/qbytearraymatcher.h ++++ new/qtbase/src/corelib/tools/qbytearraymatcher.h +@@ -42,6 +42,8 @@ + + #include + ++#include ++ + QT_BEGIN_NAMESPACE + + + +--- old/qtbase/src/tools/moc/generator.cpp ++++ new/qtbase/src/tools/moc/generator.cpp +@@ -40,6 +40,8 @@ + #include + #include + ++#include ++ + #include + #include + diff --git a/depends/patches/qt/fix_mingw_cross_compile.patch b/depends/patches/qt/fix_mingw_cross_compile.patch deleted file mode 100644 index 67f76f1d85..0000000000 --- a/depends/patches/qt/fix_mingw_cross_compile.patch +++ /dev/null @@ -1,25 +0,0 @@ -commit 5a992a549adfe5a587bbcd6cd2b2cee47d236e27 -Author: fanquake -Date: Fri Sep 4 08:13:44 2020 +0800 - - Work around broken mingw cross-compilation - - See upstream issues: - https://bugreports.qt.io/browse/QTBUG-63637 - https://bugreports.qt.io/browse/QTBUG-63659 - https://codereview.qt-project.org/q/8bebded9 - - We should be able to drop this once we are building qt 5.10.1 or later. - - Added in #12971. - -diff --git a/qtbase/mkspecs/win32-g++/qmake.conf b/qtbase/mkspecs/win32-g++/qmake.conf -index e071a0d1..ad229b10 100644 ---- a/qtbase/mkspecs/win32-g++/qmake.conf -+++ b/qtbase/mkspecs/win32-g++/qmake.conf -@@ -87,3 +87,5 @@ QMAKE_NM = $${CROSS_COMPILE}nm -P - include(../common/angle.conf) - - load(qt_config) -+QMAKE_LINK_OBJECT_MAX = 10 -+QMAKE_LINK_OBJECT_SCRIPT = object_script diff --git a/depends/patches/qt/fix_montery_include.patch b/depends/patches/qt/fix_montery_include.patch new file mode 100644 index 0000000000..38b700addf --- /dev/null +++ b/depends/patches/qt/fix_montery_include.patch @@ -0,0 +1,21 @@ +From dece6f5840463ae2ddf927d65eb1b3680e34a547 +From: Øystein Heskestad +Date: Wed, 27 Oct 2021 13:07:46 +0200 +Subject: [PATCH] Add missing macOS header file that was indirectly included before + +See: https://bugreports.qt.io/browse/QTBUG-97855 + +Upstream Commits: + - Qt 6.2: c884bf138a21dd7320e35cef34d24e22e74d7ce0 + +diff --git a/qtbase/src/plugins/platforms/cocoa/qiosurfacegraphicsbuffer.h b/qtbase/src/plugins/platforms/cocoa/qiosurfacegraphicsbuffer.h +index e070ba97..07c75b04 100644 +--- a/qtbase/src/plugins/platforms/cocoa/qiosurfacegraphicsbuffer.h ++++ b/qtbase/src/plugins/platforms/cocoa/qiosurfacegraphicsbuffer.h +@@ -40,6 +40,7 @@ + #ifndef QIOSURFACEGRAPHICSBUFFER_H + #define QIOSURFACEGRAPHICSBUFFER_H + ++#include + #include + #include diff --git a/depends/patches/qt/fix_no_printer.patch b/depends/patches/qt/fix_no_printer.patch index f868ca2577..1372356138 100644 --- a/depends/patches/qt/fix_no_printer.patch +++ b/depends/patches/qt/fix_no_printer.patch @@ -10,10 +10,10 @@ --- x/qtbase/src/plugins/plugins.pro +++ y/qtbase/src/plugins/plugins.pro -@@ -8,6 +8,3 @@ qtHaveModule(gui) { - qtConfig(imageformatplugin): SUBDIRS *= imageformats +@@ -9,6 +9,3 @@ qtHaveModule(gui) { !android:qtConfig(library): SUBDIRS *= generic } + qtHaveModule(widgets): SUBDIRS += styles - -!winrt:qtHaveModule(printsupport): \ - SUBDIRS += printsupport diff --git a/depends/patches/qt/fix_qpainter_non_determinism.patch b/depends/patches/qt/fix_qpainter_non_determinism.patch new file mode 100644 index 0000000000..44c45187c5 --- /dev/null +++ b/depends/patches/qt/fix_qpainter_non_determinism.patch @@ -0,0 +1,63 @@ +commit 2a8f7dc6ddfc414a66491522501c1574a1343ee1 +Author: Andrew Chow +Date: Sat Nov 21 01:11:04 2020 -0500 + + build: Fix determinism issue when building with Clang 8 + + When building Qt with LLVM/Clang 8 under -O3 (the default), we run into + a determinism issue in `qt_interset_spans`. The issue has been fixed for + LLVM/Clang 9, see + https://github.com/llvm/llvm-project/commit/db101864bdc938deb1d63fe4f7da761bd38e5cae + and https://reviews.llvm.org/D64601, however this fix was not backported + to 8.x. Once LLVM/Clang 9 is used, this patch can be dropped. + + The particular issue appears to be an optimization done by -O3 which + adds a temporary variable for `spans->y` in `qt_intersect_spans`. When + it does this, sometimes it chooses to use a 32-bit movs instruction + (movswl), and other times it chooses a 64-bit movs instruction (movswq). + By patching `qt_intersect_spans` to always make a temporary variable for + `spans->y`, we are able to sidestep this problem. + +diff --git a/qtbase/src/gui/painting/qpaintengine_raster.cpp b/qtbase/src/gui/painting/qpaintengine_raster.cpp +index 92ab6e8375..f018009e0b 100644 +--- a/qtbase/src/gui/painting/qpaintengine_raster.cpp ++++ b/qtbase/src/gui/painting/qpaintengine_raster.cpp +@@ -4128,22 +4128,23 @@ static const QSpan *qt_intersect_spans(const QClipData *clip, int *currentClip, + const QSpan *clipEnd = clip->m_spans + clip->count; + + while (available && spans < end ) { ++ const short spans_y = spans->y; + if (clipSpans >= clipEnd) { + spans = end; + break; + } +- if (clipSpans->y > spans->y) { ++ if (clipSpans->y > spans_y) { + ++spans; + continue; + } +- if (spans->y != clipSpans->y) { +- if (spans->y < clip->count && clip->m_clipLines[spans->y].spans) +- clipSpans = clip->m_clipLines[spans->y].spans; ++ if (spans_y != clipSpans->y) { ++ if (spans_y < clip->count && clip->m_clipLines[spans_y].spans) ++ clipSpans = clip->m_clipLines[spans_y].spans; + else + ++clipSpans; + continue; + } +- Q_ASSERT(spans->y == clipSpans->y); ++ Q_ASSERT(spans_y == clipSpans->y); + + int sx1 = spans->x; + int sx2 = sx1 + spans->len; +@@ -4162,7 +4163,7 @@ static const QSpan *qt_intersect_spans(const QClipData *clip, int *currentClip, + if (len) { + out->x = qMax(sx1, cx1); + out->len = qMin(sx2, cx2) - out->x; +- out->y = spans->y; ++ out->y = spans_y; + out->coverage = qt_div_255(spans->coverage * clipSpans->coverage); + ++out; + --available; + diff --git a/depends/patches/qt/fix_qt_pkgconfig.patch b/depends/patches/qt/fix_qt_pkgconfig.patch index 8c722ffb46..a5de2b4b9e 100644 --- a/depends/patches/qt/fix_qt_pkgconfig.patch +++ b/depends/patches/qt/fix_qt_pkgconfig.patch @@ -1,17 +1,17 @@ --- old/qtbase/mkspecs/features/qt_module.prf +++ new/qtbase/mkspecs/features/qt_module.prf -@@ -264,7 +264,7 @@ +@@ -269,7 +269,7 @@ load(qt_installs) load(qt_targets) # this builds on top of qt_common --!internal_module:!lib_bundle:if(unix|mingw) { +-!internal_module:if(unix|mingw) { +if(unix|mingw):!if(darwin:debug_and_release:CONFIG(debug, debug|release)) { CONFIG += create_pc QMAKE_PKGCONFIG_DESTDIR = pkgconfig host_build: \ -@@ -274,9 +274,9 @@ - QMAKE_PKGCONFIG_INCDIR = $$[QT_INSTALL_HEADERS/raw] - QMAKE_PKGCONFIG_CFLAGS = -I${includedir}/$$MODULE_INCNAME +@@ -284,9 +284,9 @@ load(qt_targets) + QMAKE_PKGCONFIG_CFLAGS = -D$$MODULE_DEFINE -I${includedir}/$$MODULE_INCNAME + } QMAKE_PKGCONFIG_NAME = $$replace(TARGET, ^Qt, "Qt$$QT_MAJOR_VERSION ") - QMAKE_PKGCONFIG_FILE = $$replace(TARGET, ^Qt, Qt$$QT_MAJOR_VERSION) + QMAKE_PKGCONFIG_FILE = $$replace(TARGET, ^Qt, Qt$$QT_MAJOR_VERSION)$$qtPlatformTargetSuffix() @@ -20,4 +20,4 @@ + QMAKE_PKGCONFIG_REQUIRES += $$replace(QT.$${i}.name, ^Qt, Qt$$section(QT.$${i}.VERSION, ., 0, 0))$$qtPlatformTargetSuffix() isEmpty(QMAKE_PKGCONFIG_DESCRIPTION): \ QMAKE_PKGCONFIG_DESCRIPTION = $$replace(TARGET, ^Qt, "Qt ") module - pclib_replace.match = $$lib_replace.match + !isEmpty(lib_replace0.match) { diff --git a/depends/patches/qt/fix_rcc_determinism.patch b/depends/patches/qt/fix_rcc_determinism.patch deleted file mode 100644 index c1b07fe23a..0000000000 --- a/depends/patches/qt/fix_rcc_determinism.patch +++ /dev/null @@ -1,15 +0,0 @@ ---- old/qtbase/src/tools/rcc/rcc.cpp -+++ new/qtbase/src/tools/rcc/rcc.cpp -@@ -207,7 +207,11 @@ void RCCFileInfo::writeDataInfo(RCCResourceLibrary &lib) - if (lib.formatVersion() >= 2) { - // last modified time stamp - const QDateTime lastModified = m_fileInfo.lastModified(); -- lib.writeNumber8(quint64(lastModified.isValid() ? lastModified.toMSecsSinceEpoch() : 0)); -+ quint64 lastmod = quint64(lastModified.isValid() ? lastModified.toMSecsSinceEpoch() : 0); -+ static const quint64 sourceDate = 1000 * qgetenv("QT_RCC_SOURCE_DATE_OVERRIDE").toULongLong(); -+ if (sourceDate != 0) -+ lastmod = sourceDate; -+ lib.writeNumber8(lastmod); - if (text || pass1) - lib.writeChar('\n'); - } diff --git a/depends/patches/qt/fix_riscv64_arch.patch b/depends/patches/qt/fix_riscv64_arch.patch deleted file mode 100644 index e7f29f01f9..0000000000 --- a/depends/patches/qt/fix_riscv64_arch.patch +++ /dev/null @@ -1,14 +0,0 @@ -diff --git a/qtbase/src/3rdparty/double-conversion/include/double-conversion/utils.h b/qtbase/src/3rdparty/double-conversion/include/double-conversion/utils.h -index 20bfd36..93729fa 100644 ---- a/qtbase/src/3rdparty/double-conversion/include/double-conversion/utils.h -+++ b/qtbase/src/3rdparty/double-conversion/include/double-conversion/utils.h -@@ -65,7 +65,8 @@ - defined(__sparc__) || defined(__sparc) || defined(__s390__) || \ - defined(__SH4__) || defined(__alpha__) || \ - defined(_MIPS_ARCH_MIPS32R2) || \ -- defined(__AARCH64EL__) -+ defined(__AARCH64EL__) || defined(__aarch64__) || \ -+ defined(__riscv) - #define DOUBLE_CONVERSION_CORRECT_DOUBLE_OPERATIONS 1 - #elif defined(_M_IX86) || defined(__i386__) || defined(__i386) - #if defined(_WIN32) diff --git a/depends/patches/qt/freetype_back_compat.patch b/depends/patches/qt/freetype_back_compat.patch deleted file mode 100644 index b0f1c98aa6..0000000000 --- a/depends/patches/qt/freetype_back_compat.patch +++ /dev/null @@ -1,28 +0,0 @@ -commit 14bc77db61bf9d56f9b6c8b84aa02573605c19c6 -Author: fanquake -Date: Tue Aug 18 15:15:08 2020 +0800 - - Fix backwards compatibility with older Freetype versions at runtime - - A few years ago, libfreetype introduced FT_Get_Font_Format() as an alias - for FT_Get_X11_Font_Format(), but FT_Get_X11_Font_Format() was kept for abi - backwards-compatibility. - - Qt 5.9 introduced a call to FT_Get_Font_Format(). Replace it with FT_Get_X11_Font_Format() - in order to remain compatibile with older freetype, which is still used by e.g. Ubuntu Trusty. - - See #14348. - -diff --git a/qtbase/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp b/qtbase/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp -index 3f543755..8ecc1c8c 100644 ---- a/qtbase/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp -+++ b/qtbase/src/platformsupport/fontdatabases/freetype/qfontengine_ft.cpp -@@ -898,7 +898,7 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format, - } - } - #if defined(FT_FONT_FORMATS_H) -- const char *fmt = FT_Get_Font_Format(face); -+ const char *fmt = FT_Get_X11_Font_Format(face); - if (fmt && qstrncmp(fmt, "CFF", 4) == 0) { - FT_Bool no_stem_darkening = true; - FT_Error err = FT_Property_Get(qt_getFreetype(), "cff", "no-stem-darkening", &no_stem_darkening); diff --git a/depends/patches/qt/mac-qmake.conf b/depends/patches/qt/mac-qmake.conf index 0142667547..e4bfaa1463 100644 --- a/depends/patches/qt/mac-qmake.conf +++ b/depends/patches/qt/mac-qmake.conf @@ -8,13 +8,11 @@ include(../common/clang-mac.conf) QMAKE_MAC_SDK_PATH=$${MAC_SDK_PATH} QMAKE_XCODE_VERSION = $${XCODE_VERSION} QMAKE_XCODE_DEVELOPER_PATH=/Developer -QMAKE_MACOSX_DEPLOYMENT_TARGET = $${MAC_MIN_VERSION} QMAKE_MAC_SDK=macosx QMAKE_MAC_SDK.macosx.Path = $${MAC_SDK_PATH} QMAKE_MAC_SDK.macosx.platform_name = macosx QMAKE_MAC_SDK.macosx.SDKVersion = $${MAC_SDK_VERSION} QMAKE_MAC_SDK.macosx.PlatformPath = /phony -QMAKE_APPLE_DEVICE_ARCHS=x86_64 !host_build: QMAKE_CFLAGS += -target $${MAC_TARGET} !host_build: QMAKE_OBJECTIVE_CFLAGS += $$QMAKE_CFLAGS !host_build: QMAKE_CXXFLAGS += $$QMAKE_CFLAGS diff --git a/depends/patches/qt/no-xlib.patch b/depends/patches/qt/no-xlib.patch index fe82c2c73c..f4a6f09ee4 100644 --- a/depends/patches/qt/no-xlib.patch +++ b/depends/patches/qt/no-xlib.patch @@ -22,15 +22,15 @@ index 7c62c2e2b3..c05c6c0a07 100644 #include #include -@@ -384,6 +386,7 @@ void QXcbCursor::changeCursor(QCursor *cursor, QWindow *widget) - w->setCursor(c, isBitmapCursor); +@@ -391,6 +393,7 @@ void QXcbCursor::changeCursor(QCursor *cursor, QWindow *window) + xcb_flush(xcb_connection()); } +#if QT_CONFIG(xcb_xlib) && QT_CONFIG(library) static int cursorIdForShape(int cshape) { int cursorId = 0; -@@ -437,6 +440,7 @@ static int cursorIdForShape(int cshape) +@@ -444,6 +447,7 @@ static int cursorIdForShape(int cshape) } return cursorId; } @@ -38,7 +38,7 @@ index 7c62c2e2b3..c05c6c0a07 100644 xcb_cursor_t QXcbCursor::createNonStandardCursor(int cshape) { -@@ -558,7 +562,9 @@ static xcb_cursor_t loadCursor(void *dpy, int cshape) +@@ -556,7 +560,9 @@ static xcb_cursor_t loadCursor(void *dpy, int cshape) xcb_cursor_t QXcbCursor::createFontCursor(int cshape) { xcb_connection_t *conn = xcb_connection(); @@ -48,22 +48,23 @@ index 7c62c2e2b3..c05c6c0a07 100644 xcb_cursor_t cursor = XCB_NONE; // Try Xcursor first -@@ -589,6 +595,7 @@ xcb_cursor_t QXcbCursor::createFontCursor(int cshape) +@@ -585,7 +591,7 @@ xcb_cursor_t QXcbCursor::createFontCursor(int cshape) + // Non-standard X11 cursors are created from bitmaps cursor = createNonStandardCursor(cshape); - +- +#if QT_CONFIG(xcb_xlib) && QT_CONFIG(library) // Create a glpyh cursor if everything else failed if (!cursor && cursorId) { cursor = xcb_generate_id(conn); -@@ -596,6 +603,7 @@ xcb_cursor_t QXcbCursor::createFontCursor(int cshape) +@@ -593,6 +599,7 @@ xcb_cursor_t QXcbCursor::createFontCursor(int cshape) cursorId, cursorId + 1, 0xFFFF, 0xFFFF, 0xFFFF, 0, 0, 0); } +#endif if (cursor && cshape >= 0 && cshape < Qt::LastCursor && connection()->hasXFixes()) { - const char *name = cursorNames[cshape]; + const char *name = cursorNames[cshape].front(); -- 2.22.0 diff --git a/depends/patches/qt/qt.pro b/depends/patches/qt/qt.pro new file mode 100644 index 0000000000..8f2e900a84 --- /dev/null +++ b/depends/patches/qt/qt.pro @@ -0,0 +1,16 @@ +# Create the super cache so modules will add themselves to it. +cache(, super) + +!QTDIR_build: cache(CONFIG, add, $$list(QTDIR_build)) + +prl = no_install_prl +CONFIG += $$prl +cache(CONFIG, add stash, prl) + +TEMPLATE = subdirs +SUBDIRS = qtbase qttools qttranslations + +qttools.depends = qtbase +qttranslations.depends = qttools + +load(qt_configure) diff --git a/depends/patches/qt/qttools_src.pro b/depends/patches/qt/qttools_src.pro new file mode 100644 index 0000000000..6ef71a0942 --- /dev/null +++ b/depends/patches/qt/qttools_src.pro @@ -0,0 +1,6 @@ +TEMPLATE = subdirs +SUBDIRS = linguist + +fb = force_bootstrap +CONFIG += $$fb +cache(CONFIG, add, fb) diff --git a/depends/patches/qt/support_new_android_ndks.patch b/depends/patches/qt/support_new_android_ndks.patch new file mode 100644 index 0000000000..85c8ae2132 --- /dev/null +++ b/depends/patches/qt/support_new_android_ndks.patch @@ -0,0 +1,122 @@ +Follow Google's BuildSystemMaintainers doc to support future NDK releases. + +Upstream commit: + - Qt 5.14: 9b14950ff600a4ce5a8698b67ab38907c50417f1 + +--- old/qtbase/mkspecs/android-clang/qmake.conf ++++ new/qtbase/mkspecs/android-clang/qmake.conf +@@ -14,43 +14,29 @@ + QMAKE_CC = $$NDK_LLVM_PATH/bin/clang + QMAKE_CXX = $$NDK_LLVM_PATH/bin/clang++ + ++# Follow https://android.googlesource.com/platform/ndk/+/ndk-release-r20/docs/BuildSystemMaintainers.md ++ + equals(ANDROID_TARGET_ARCH, armeabi-v7a): \ +- QMAKE_CFLAGS += -target armv7-none-linux-androideabi +-else: equals(ANDROID_TARGET_ARCH, armeabi): \ +- QMAKE_CFLAGS += -target armv5te-none-linux-androideabi ++ QMAKE_CFLAGS = -target armv7a-linux-androideabi$$replace(ANDROID_PLATFORM, "android-", "") + else: equals(ANDROID_TARGET_ARCH, arm64-v8a): \ +- QMAKE_CFLAGS += -target aarch64-none-linux-android ++ QMAKE_CFLAGS = -target aarch64-linux-android$$replace(ANDROID_PLATFORM, "android-", "") + else: equals(ANDROID_TARGET_ARCH, x86): \ +- QMAKE_CFLAGS += -target i686-none-linux-android -mstackrealign ++ QMAKE_CFLAGS = -target i686-linux-android$$replace(ANDROID_PLATFORM, "android-", "") -mstackrealign + else: equals(ANDROID_TARGET_ARCH, x86_64): \ +- QMAKE_CFLAGS += -target x86_64-none-linux-android +-else: equals(ANDROID_TARGET_ARCH, mips): \ +- QMAKE_CFLAGS += -target mipsel-none-linux-android +-else: equals(ANDROID_TARGET_ARCH, mips64): \ +- QMAKE_CFLAGS += -target mips64el-none-linux-android +- +-QMAKE_CFLAGS += -gcc-toolchain $$NDK_TOOLCHAIN_PATH -fno-limit-debug-info +- +-QMAKE_LINK = $$QMAKE_CXX $$QMAKE_CFLAGS -Wl,--exclude-libs,libgcc.a -Wl,--exclude-libs,libatomic.a -nostdlib++ +-equals(ANDROID_TARGET_ARCH, armeabi-v7a): QMAKE_LINK += -Wl,--exclude-libs,libunwind.a +- +-QMAKE_CFLAGS += -DANDROID_HAS_WSTRING --sysroot=$$NDK_ROOT/sysroot \ +- -isystem $$NDK_ROOT/sysroot/usr/include/$$NDK_TOOLS_PREFIX \ +- -isystem $$NDK_ROOT/sources/cxx-stl/llvm-libc++/include \ +- -isystem $$NDK_ROOT/sources/android/support/include \ +- -isystem $$NDK_ROOT/sources/cxx-stl/llvm-libc++abi/include ++ QMAKE_CFLAGS = -target x86_64-linux-android$$replace(ANDROID_PLATFORM, "android-", "") + +-ANDROID_SOURCES_CXX_STL_LIBDIR = $$NDK_ROOT/sources/cxx-stl/llvm-libc++/libs/$$ANDROID_TARGET_ARCH ++QMAKE_CFLAGS += -fno-limit-debug-info + +-ANDROID_STDCPP_PATH = $$ANDROID_SOURCES_CXX_STL_LIBDIR/libc++_shared.so ++QMAKE_LINK = $$QMAKE_CXX $$QMAKE_CFLAGS + +-ANDROID_USE_LLVM = true ++ANDROID_STDCPP_PATH = $$NDK_LLVM_PATH/sysroot/usr/lib/$$NDK_TOOLS_PREFIX/libc++_shared.so + +-exists($$ANDROID_SOURCES_CXX_STL_LIBDIR/libc++.so): \ +- ANDROID_CXX_STL_LIBS = -lc++ +-else: \ +- ANDROID_CXX_STL_LIBS = $$ANDROID_SOURCES_CXX_STL_LIBDIR/libc++.so.$$replace(ANDROID_PLATFORM, "android-", "") ++ANDROID_USE_LLVM = true + +-QMAKE_CFLAGS_OPTIMIZE_SIZE = -Oz ++QMAKE_CFLAGS_OPTIMIZE_SIZE = -Oz ++QMAKE_LIBDIR_POST = ++QMAKE_LFLAGS = ++QMAKE_LIBS_PRIVATE = ++ANDROID_CXX_STL_LIBS = + + include(../common/android-base-tail.conf) + +--- old/qtbase/mkspecs/common/android-base-head.conf ++++ new/qtbase/mkspecs/common/android-base-head.conf +@@ -64,7 +58,6 @@ + } + + CONFIG += $$ANDROID_PLATFORM +-QMAKE_CFLAGS = -D__ANDROID_API__=$$replace(ANDROID_PLATFORM, "android-", "") + + ANDROID_PLATFORM_ROOT_PATH = $$NDK_ROOT/platforms/$$ANDROID_PLATFORM/arch-$$ANDROID_ARCHITECTURE/ + +--- old/qtbase/mkspecs/common/android-base-tail.conf ++++ new/qtbase/mkspecs/common/android-base-tail.conf +@@ -6,22 +6,17 @@ + QMAKE_CFLAGS += -fstack-protector-strong -DANDROID + + equals(ANDROID_TARGET_ARCH, armeabi-v7a): \ +- QMAKE_CFLAGS += -march=armv7-a -mfloat-abi=softfp -mfpu=vfp -fno-builtin-memmove ++ QMAKE_CFLAGS += -march=armv7-a -mfloat-abi=softfp -mfpu=vfp + else: equals(ANDROID_TARGET_ARCH, armeabi): \ +- QMAKE_CFLAGS += -march=armv5te -mtune=xscale -msoft-float -fno-builtin-memmove +-# -fno-builtin-memmove is used to workaround https://code.google.com/p/android/issues/detail?id=81692 ++ QMAKE_CFLAGS += -march=armv5te -mtune=xscale -msoft-float + + QMAKE_CFLAGS_WARN_ON = -Wall -W + QMAKE_CFLAGS_WARN_OFF = + equals(ANDROID_TARGET_ARCH, armeabi-v7a) | equals(ANDROID_TARGET_ARCH, armeabi) { + CONFIG += optimize_size + QMAKE_CFLAGS_DEBUG = -g -marm -O0 +- equals(ANDROID_TARGET_ARCH, armeabi):if(equals(NDK_TOOLCHAIN_VERSION, 4.8)|equals(NDK_TOOLCHAIN_VERSION, 4.9)) { +- DEFINES += QT_OS_ANDROID_GCC_48_WORKAROUND +- } else { +- QMAKE_CFLAGS_RELEASE += -mthumb +- QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -mthumb +- } ++ QMAKE_CFLAGS_RELEASE += -mthumb ++ QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -mthumb + } + + QMAKE_CFLAGS_SHLIB = -fPIC +@@ -61,15 +56,12 @@ + QMAKE_RANLIB = $${CROSS_COMPILE}ranlib + + QMAKE_INCDIR_POST = +-QMAKE_LIBDIR_POST = $$ANDROID_SOURCES_CXX_STL_LIBDIR + QMAKE_INCDIR_X11 = + QMAKE_LIBDIR_X11 = + QMAKE_INCDIR_OPENGL = + QMAKE_LIBDIR_OPENGL = + + QMAKE_LINK_SHLIB = $$QMAKE_LINK +-QMAKE_LFLAGS = --sysroot=$$ANDROID_PLATFORM_ROOT_PATH +-equals(ANDROID_TARGET_ARCH, x86_64) QMAKE_LFLAGS += -L$$ANDROID_PLATFORM_ROOT_PATH/usr/lib64 + QMAKE_LFLAGS_APP = -Wl,--no-undefined -Wl,-z,noexecstack -shared + QMAKE_LFLAGS_SHLIB = -Wl,--no-undefined -Wl,-z,noexecstack -shared + QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB diff --git a/depends/patches/qt/xkb-default.patch b/depends/patches/qt/xkb-default.patch deleted file mode 100644 index 165abf3e2e..0000000000 --- a/depends/patches/qt/xkb-default.patch +++ /dev/null @@ -1,26 +0,0 @@ ---- old/qtbase/src/gui/configure.pri 2018-06-06 17:28:10.000000000 -0400 -+++ new/qtbase/src/gui/configure.pri 2018-08-17 18:43:01.589384567 -0400 -@@ -43,18 +43,11 @@ - } - - defineTest(qtConfTest_xkbConfigRoot) { -- qtConfTest_getPkgConfigVariable($${1}): return(true) -- -- for (dir, $$list("/usr/share/X11/xkb", "/usr/local/share/X11/xkb")) { -- exists($$dir) { -- $${1}.value = $$dir -- export($${1}.value) -- $${1}.cache += value -- export($${1}.cache) -- return(true) -- } -- } -- return(false) -+ $${1}.value = "/usr/share/X11/xkb" -+ export($${1}.value) -+ $${1}.cache += value -+ export($${1}.cache) -+ return(true) - } - - defineTest(qtConfTest_qpaDefaultPlatform) { diff --git a/doc/README.md b/doc/README.md index 58d8db63c6..00305941e6 100644 --- a/doc/README.md +++ b/doc/README.md @@ -39,6 +39,10 @@ The following are developer notes on how to build PRCYCoin on your native platfo - [macOS Build Notes](build-osx.md) - [Unix Build Notes](build-unix.md) - [Windows Build Notes](build-windows.md) +- [FreeBSD Build Notes](build-freebsd.md) +- [OpenBSD Build Notes](build-openbsd.md) +- [NetBSD Build Notes](build-netbsd.md) +- [Android Build Notes](build-android.md) - [Gitian Building Guide](gitian-building.md) Development diff --git a/doc/REST-interface.md b/doc/REST-interface.md index ddb3cbe37b..418fcf9f5e 100644 --- a/doc/REST-interface.md +++ b/doc/REST-interface.md @@ -33,7 +33,7 @@ Given a block hash: returns amount of blockheaders in upward direction. Returns various state info regarding block chain processing. Only supports JSON as output format. -* chain : (string) current network name as defined in BIP70 (main, test, regtest) +* chain : (string) current network name (main, test, regtest) * blocks : (numeric) the current number of blocks processed in the server * headers : (numeric) the current number of headers we have validated * bestblockhash : (string) the hash of the currently best block diff --git a/doc/build-android.md b/doc/build-android.md new file mode 100644 index 0000000000..9f8717a459 --- /dev/null +++ b/doc/build-android.md @@ -0,0 +1,12 @@ +ANDROID BUILD NOTES +====================== + +This guide describes how to build and package the `prcycoin-qt` GUI for Android on Linux and macOS. + +## Preparation + +You will need to get the Android NDK and build dependencies for Android as described in [depends/README.md](../depends/README.md). + +## Building and packaging + +After the depends are built configure with one of the resulting prefixes and run `make && make apk` in `src/qt`. \ No newline at end of file diff --git a/doc/build-freebsd.md b/doc/build-freebsd.md new file mode 100644 index 0000000000..f48855a344 --- /dev/null +++ b/doc/build-freebsd.md @@ -0,0 +1,61 @@ +FreeBSD build guide +====================== +(updated for FreeBSD 12.0) + +This guide describes how to build bitcoind and command-line utilities on FreeBSD. + +This guide does not contain instructions for building the GUI. + +## Preparation + +You will need the following dependencies, which can be installed as root via pkg: + +```bash +pkg install autoconf automake boost-libs git gmake libevent libtool pkgconf + +git clone https://github.com/bitcoin/bitcoin.git +``` + +In order to run the test suite (recommended), you will need to have Python 3 installed: + +```bash +pkg install python3 +``` + +See [dependencies.md](dependencies.md) for a complete overview. + +### Building BerkeleyDB + +BerkeleyDB is only necessary for the wallet functionality. To skip this, pass +`--disable-wallet` to `./configure` and skip to the next section. + +```bash +./contrib/install_db4.sh `pwd` +export BDB_PREFIX="$PWD/db4" +``` + +## Building Bitcoin Core + +**Important**: Use `gmake` (the non-GNU `make` will exit with an error). + +With wallet: +```bash +./autogen.sh +./configure --with-gui=no \ + BDB_LIBS="-L${BDB_PREFIX}/lib -ldb_cxx-4.8" \ + BDB_CFLAGS="-I${BDB_PREFIX}/include" \ + MAKE=gmake +``` + +Without wallet: +```bash +./autogen.sh +./configure --with-gui=no --disable-wallet MAKE=gmake +``` + +followed by: + +```bash +gmake # use -jX here for parallelism +gmake check # Run tests if Python 3 is available +``` diff --git a/doc/build-netbsd.md b/doc/build-netbsd.md new file mode 100644 index 0000000000..47049a780e --- /dev/null +++ b/doc/build-netbsd.md @@ -0,0 +1,81 @@ +NetBSD build guide +====================== +(updated for NetBSD 8.0) + +This guide describes how to build bitcoind and command-line utilities on NetBSD. + +This guide does not contain instructions for building the GUI. + +Preparation +------------- + +You will need the following modules, which can be installed via pkgsrc or pkgin: + +``` +autoconf +automake +boost +git +gmake +libevent +libtool +pkg-config +python37 + +git clone https://github.com/bitcoin/bitcoin.git +``` + +See [dependencies.md](dependencies.md) for a complete overview. + +### Building BerkeleyDB + +BerkeleyDB is only necessary for the wallet functionality. To skip this, pass +`--disable-wallet` to `./configure` and skip to the next section. + +It is recommended to use Berkeley DB 4.8. You cannot use the BerkeleyDB library +from ports, for the same reason as boost above (g++/libstd++ incompatibility). +If you have to build it yourself, you can use [the installation script included +in contrib/](/contrib/install_db4.sh) like so: + +```bash +./contrib/install_db4.sh `pwd` +``` + +from the root of the repository. Then set `BDB_PREFIX` for the next section: + +```bash +export BDB_PREFIX="$PWD/db4" +``` + +### Building Bitcoin Core + +**Important**: Use `gmake` (the non-GNU `make` will exit with an error). + +With wallet: +```bash +./autogen.sh +./configure --with-gui=no CPPFLAGS="-I/usr/pkg/include" \ + LDFLAGS="-L/usr/pkg/lib" \ + BOOST_CPPFLAGS="-I/usr/pkg/include" \ + BOOST_LDFLAGS="-L/usr/pkg/lib" \ + BDB_LIBS="-L${BDB_PREFIX}/lib -ldb_cxx-4.8" \ + BDB_CFLAGS="-I${BDB_PREFIX}/include" \ + MAKE=gmake +``` + +Without wallet: +```bash +./autogen.sh +./configure --with-gui=no --disable-wallet \ + CPPFLAGS="-I/usr/pkg/include" \ + LDFLAGS="-L/usr/pkg/lib" \ + BOOST_CPPFLAGS="-I/usr/pkg/include" \ + BOOST_LDFLAGS="-L/usr/pkg/lib" \ + MAKE=gmake +``` + +Build and run the tests: +```bash +gmake # use -jX here for parallelism +gmake check +``` diff --git a/doc/build-openbsd.md b/doc/build-openbsd.md new file mode 100644 index 0000000000..85777b5b97 --- /dev/null +++ b/doc/build-openbsd.md @@ -0,0 +1,130 @@ +OpenBSD build guide +====================== +(updated for OpenBSD 6.7) + +This guide describes how to build bitcoind and command-line utilities on OpenBSD. + +OpenBSD is most commonly used as a server OS, so this guide does not contain instructions for building the GUI. + +Preparation +------------- + +Run the following as root to install the base dependencies for building: + +```bash +pkg_add git gmake libevent libtool boost +pkg_add autoconf # (select highest version, e.g. 2.69) +pkg_add automake # (select highest version, e.g. 1.16) +pkg_add python # (select highest version, e.g. 3.8) + +git clone https://github.com/bitcoin/bitcoin.git +``` + +See [dependencies.md](dependencies.md) for a complete overview. + +**Important**: From OpenBSD 6.2 onwards a C++11-supporting clang compiler is +part of the base image, and while building it is necessary to make sure that +this compiler is used and not ancient g++ 4.2.1. This is done by appending +`CC=cc CC_FOR_BUILD=cc CXX=c++` to configuration commands. Mixing different +compilers within the same executable will result in errors. + +### OpenSSL + +OpenBSD uses a replacement of OpenSSL: LibreSSL. This can cause compatibility issues, hence `./configure` will bark if you try to compile with this library: + + Detected LibreSSL: This is NOT supported, and may break consensus compatibility! + +To install a 'real' OpenSSL use: + + pkg_add openssl + +Any program linked against this library can only be used after setting the dynamic library path: + + export LD_LIBRARY_PATH="/usr/local/lib/eopenssl" + +(otherwise there will be an error about not being able to find `libcrypto.so.1.0`) + +Alternatively, pass `--with-libressl` to `./configure`, however as the warning says, this is NOT supported, and may cause problems syncing the chain, or the node to fork off the network in unexpected circumstances. + +### Building BerkeleyDB + +BerkeleyDB is only necessary for the wallet functionality. To skip this, pass +`--disable-wallet` to `./configure` and skip to the next section. + +It is recommended to use Berkeley DB 4.8. You cannot use the BerkeleyDB library +from ports, for the same reason as boost above (g++/libstd++ incompatibility). +If you have to build it yourself, you can use [the installation script included +in contrib/](/contrib/install_db4.sh) like so: + +```bash +./contrib/install_db4.sh `pwd` CC=cc CXX=c++ +``` + +from the root of the repository. Then set `BDB_PREFIX` for the next section: + +```bash +export BDB_PREFIX="$PWD/db4" +``` + +### Building Bitcoin Core + +**Important**: Use `gmake` (the non-GNU `make` will exit with an error). + +Preparation: +```bash + +# Replace this with the autoconf version that you installed. Include only +# the major and minor parts of the version: use "2.69" for "autoconf-2.69p2". +export AUTOCONF_VERSION=2.69 + +# Replace this with the automake version that you installed. Include only +# the major and minor parts of the version: use "1.16" for "automake-1.16.1". +export AUTOMAKE_VERSION=1.16 + +./autogen.sh +``` +Make sure `BDB_PREFIX` is set to the appropriate path from the above steps. + +To configure with wallet: +```bash +./configure --with-gui=no CC=cc CXX=c++ \ + SSL_CFLAGS="-I/usr/local/include/eopenssl" SSL_LIBS="-L/usr/local/lib/eopenssl -lssl" \ + CRYPTO_CFLAGS="-I/usr/local/include/eopenssl" CRYPTO_LIBS="-L/usr/local/lib/eopenssl -lcrypto" \ + BDB_LIBS="-L${BDB_PREFIX}/lib -ldb_cxx-4.8" \ + BDB_CFLAGS="-I${BDB_PREFIX}/include" \ + MAKE=gmake +``` + +To configure without wallet: +```bash +./configure --disable-wallet --with-gui=no CC=cc CC_FOR_BUILD=cc CXX=c++ \ + SSL_CFLAGS="-I/usr/local/include/eopenssl" SSL_LIBS="-L/usr/local/lib/eopenssl -lssl" \ + CRYPTO_CFLAGS="-I/usr/local/include/eopenssl" CRYPTO_LIBS="-L/usr/local/lib/eopenssl -lcrypto" \ + MAKE=gmake +``` + +Build and run the tests: +```bash +gmake # use -jX here for parallelism +gmake check +``` + +Resource limits +------------------- + +If the build runs into out-of-memory errors, the instructions in this section +might help. + +The standard ulimit restrictions in OpenBSD are very strict: + + data(kbytes) 1572864 + +This is, unfortunately, in some cases not enough to compile some `.cpp` files in the project, +(see issue [#6658](https://github.com/bitcoin/bitcoin/issues/6658)). +If your user is in the `staff` group the limit can be raised with: + + ulimit -d 3000000 + +The change will only affect the current shell and processes spawned by it. To +make the change system-wide, change `datasize-cur` and `datasize-max` in +`/etc/login.conf`, and reboot. diff --git a/doc/build-osx.md b/doc/build-osx.md index 20ba4118cb..7db04dd99c 100644 --- a/doc/build-osx.md +++ b/doc/build-osx.md @@ -16,15 +16,11 @@ Then install [Homebrew](https://brew.sh). Dependencies ---------------------- - brew install autoconf automake berkeley-db4 libtool boost miniupnpc openssl pkg-config protobuf python3 qt5 zmq libevent qrencode + brew install autoconf automake berkeley-db4 libtool boost miniupnpc openssl pkg-config python3 qt5 zmq libevent qrencode See [dependencies.md](dependencies.md) for a complete overview. -If you want to build the disk image with `make deploy` (.dmg / optional), you need RSVG: - - brew install librsvg - -and [`macdeployqtplus`](../contrib/macdeploy/README.md) dependencies: +[`macdeployqtplus`](../contrib/macdeploy/README.md) dependencies: ```shell pip3 install ds_store mac_alias ``` @@ -110,7 +106,7 @@ Other commands: Notes ----- -* Tested on OS X 10.12 Sierra through macOS 10.15 Catalina on 64-bit Intel processors only. +* Tested on OS X 10.14 Mojave through macOS 11 Big Sur on 64-bit Intel * Building with downloaded Qt binaries is not officially supported. See the notes in [#7714](https://github.com/bitcoin/bitcoin/issues/7714) diff --git a/doc/build-unix.md b/doc/build-unix.md index 98ef67c71e..4ee3a25bcc 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -2,6 +2,8 @@ UNIX BUILD NOTES ==================== Some notes on how to build PRCYCoin in Unix. +(For BSD specific instructions, see `build-*bsd.md` in this directory.) + Note --------------------- Always use absolute paths to configure and compile PRCYCoin and the dependencies, @@ -42,7 +44,6 @@ Optional dependencies: miniupnpc | UPnP Support | Firewall-jumping support libdb4.8 | Berkeley DB | Wallet storage (only needed when wallet enabled) qt | GUI | GUI toolkit (only needed when GUI enabled) - protobuf | Payments in GUI | Data interchange format used for payment protocol (only needed when GUI enabled) libqrencode | QR codes in GUI | Optional for generating QR codes (only needed when GUI enabled) univalue | Utility | JSON parsing and encoding (bundled version will be used unless --with-system-univalue passed to configure) libzmq3 | ZMQ notification | Optional, allows generating ZMQ notifications (requires ZMQ version >= 4.0.0) @@ -114,7 +115,7 @@ To build without GUI pass `--without-gui`. To build with Qt 5 you need the following: - sudo apt-get install libqt5gui5 libqt5core5a libqt5dbus5 qttools5-dev qttools5-dev-tools libprotobuf-dev protobuf-compiler + sudo apt-get install libqt5gui5 libqt5core5a libqt5dbus5 qttools5-dev qttools5-dev-tools libqrencode (optional) can be installed with: @@ -138,7 +139,7 @@ Optional: To build with Qt 5 you need the following: - sudo dnf install qt5-qttools-devel qt5-qtbase-devel protobuf-devel + sudo dnf install qt5-qttools-devel qt5-qtbase-devel libqrencode (optional) can be installed with: @@ -277,7 +278,7 @@ To build executables for ARM: make HOST=arm-linux-gnueabihf NO_QT=1 cd .. ./autogen.sh - ./configure --prefix=$PWD/depends/arm-linux-gnueabihf --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++ + CONFIG_SITE=$PWD/depends/arm-linux-gnueabihf/share/config.site ./configure --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++ make diff --git a/doc/build-windows.md b/doc/build-windows.md index 29d2983b0a..e1a887c282 100644 --- a/doc/build-windows.md +++ b/doc/build-windows.md @@ -62,8 +62,7 @@ First, install the general dependencies: sudo apt install build-essential libtool autotools-dev automake pkg-config bsdmainutils curl git A host toolchain (`build-essential`) is necessary because some dependency -packages (such as `protobuf`) need to build host utilities that are used in the -build process. +packages need to build host utilities that are used in the build process. See [dependencies.md](dependencies.md) for a complete overview. @@ -82,10 +81,6 @@ The first step is to install the mingw-w64 cross-compilation tool chain: sudo apt install g++-mingw-w64-x86-64 -Ubuntu Bionic 18.04 [1](#footnote1): - - sudo update-alternatives --config x86_64-w64-mingw32-g++ # Set the default mingw32 g++ compiler option to posix. - Once the toolchain is installed the build steps are common: Note that for WSL the PRCYCoin source path MUST be somewhere in the default mount file system, for @@ -118,14 +113,4 @@ way. This will install to `c:\workspace\prcycoin`, for example: You can also create an installer using: - make deploy - -Footnotes ---------- - -1: Starting from Ubuntu Xenial 16.04, both the 32 and 64 bit Mingw-w64 packages install two different -compiler options to allow a choice between either posix or win32 threads. The default option is win32 threads which is the more -efficient since it will result in binary code that links directly with the Windows kernel32.lib. Unfortunately, the headers -required to support win32 threads conflict with some of the classes in the C++11 standard library, in particular std::mutex. -It's not possible to build the PRCYCoin code using the win32 version of the Mingw-w64 cross compilers (at least not without -modifying headers in the PRCYCoin source code). + make deploy \ No newline at end of file diff --git a/doc/dependencies.md b/doc/dependencies.md index c124bd5324..b31c0c95ee 100644 --- a/doc/dependencies.md +++ b/doc/dependencies.md @@ -6,25 +6,22 @@ These are the dependencies currently used by PRCYCoin. You can find instructions | Dependency | Version used | Minimum required | CVEs | Shared | [Bundled Qt library](https://doc.qt.io/qt-5/configure-options.html#third-party-libraries) | | --- | --- | --- | --- | --- | --- | | Berkeley DB | [4.8.30](https://www.oracle.com/technetwork/database/database-technologies/berkeleydb/downloads/index.html) | 4.8.x | No | | | -| Boost | [1.71.0](https://www.boost.org/users/download/) | [1.57.0](https://github.com/PRCYCoin/PRCYCoin/pull/286) | No | | | +| Boost | [1.71.0](https://www.boost.org/users/download/) | [1.64.0](https://github.com/PRCYCoin/PRCYCoin/pull/286) | No | | | | Clang | | [3.3+](https://llvm.org/releases/download.html) (C++11 support) | | | | | D-Bus | [1.10.18](https://cgit.freedesktop.org/dbus/dbus/tree/NEWS?h=dbus-1.10) | | No | Yes | | -| Expat | [2.2.6](https://libexpat.github.io/) | | No | Yes | | -| fontconfig | [2.12.1](https://www.freedesktop.org/software/fontconfig/release/) | | No | Yes | | -| FreeType | [2.7.1](https://download.savannah.gnu.org/releases/freetype) | | No | | | +| Fontconfig | [2.12.6](https://www.freedesktop.org/software/fontconfig/release/) | | No | Yes | | +| FreeType | [2.11.0](https://download.savannah.gnu.org/releases/freetype) | | No | | [Yes](https://github.com/bitcoin/bitcoin/blob/master/depends/packages/qt.mk) (Android only) | | GCC | | [4.8+](https://gcc.gnu.org/) (C++11 support) | | | | | HarfBuzz-NG | | | | | | -| libevent | [2.1.11-stable](https://github.com/libevent/libevent/releases) | 2.0.22 | No | | | +| libevent | [2.1.12-stable](https://github.com/libevent/libevent/releases) | [2.0.21](https://github.com/PRCYCoin/PRCYCoin/pull/385) | No | | | | libjpeg | | | | | [Yes](https://github.com/prcycoin/prcycoin/blob/master/depends/packages/qt.mk#L65) | | libpng | | | | | [Yes](https://github.com/prcycoin/prcycoin/blob/master/depends/packages/qt.mk#L64) | -| librsvg | | | | | | | MiniUPnPc | [2.2.2](https://miniupnp.tuxfamily.org/files) | | No | | | | OpenSSL | [1.0.1k](https://www.openssl.org/source) | | Yes | | | | PCRE | | | | | [Yes](https://github.com/prcycoin/prcycoin/blob/master/depends/packages/qt.mk#L66) | -| protobuf | [2.6.1](https://github.com/google/protobuf/releases) | | No | | | -| Python (tests) | | [3.5](https://www.python.org/downloads) | | | | +| Python (tests) | | [3.6](https://www.python.org/downloads) | | | | | qrencode | [3.4.4](https://fukuchi.org/works/qrencode) | | No | | | -| Qt | [5.9.9](https://download.qt.io/official_releases/qt/) | [5.5.1](https://github.com/bitcoin/bitcoin/issues/13478) | No | | | +| Qt | [5.12.11](https://download.qt.io/official_releases/qt/) | [5.5.1](https://github.com/bitcoin/bitcoin/issues/13478) | No | | | | XCB | | | | | [Yes](https://github.com/prcycoin/prcycoin/blob/master/depends/packages/qt.mk#L87) (Linux only) | | xkbcommon | | | | | [Yes](https://github.com/prcycoin/prcycoin/blob/master/depends/packages/qt.mk#L86) (Linux only) | | ZeroMQ | [4.3.1](https://github.com/zeromq/libzmq/releases) | 4.0.0 | No | | | @@ -41,5 +38,4 @@ Some dependencies are not needed in all configurations. The following are some f * If the qrencode dependency is absent, QR support won't be added. To force an error when that happens, pass `--with-qrencode`. * ZeroMQ is needed only with the `--with-zmq` option. -#### Other -* librsvg is only needed if you need to run `make deploy` on (cross-compilation to) macOS. +#### Other \ No newline at end of file diff --git a/doc/release-notes.md b/doc/release-notes.md index dfd904d06e..5972ff3257 100644 --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -20,7 +20,7 @@ Compatibility ============== PRCY is extensively tested on multiple operating systems using -the Linux kernel, macOS 10.8+, and Windows Vista and later. +the Linux kernel, macOS 10.14+, and Windows Vista and later. Microsoft ended support for Windows XP on [April 8th, 2014](https://www.microsoft.com/en-us/WindowsForBusiness/end-of-xp-support), No attempt is made to prevent installing or running the software on Windows XP, you diff --git a/doc/release-process.md b/doc/release-process.md index 53cef8bdf5..e155fad166 100644 --- a/doc/release-process.md +++ b/doc/release-process.md @@ -251,7 +251,6 @@ The list of files should be: ``` prcycoin-${VERSION}-aarch64-linux-gnu.tar.gz prcycoin-${VERSION}-arm-linux-gnueabihf.tar.gz -prcycoin-${VERSION}-i686-pc-linux-gnu.tar.gz prcycoin-${VERSION}-riscv64-linux-gnu.tar.gz prcycoin-${VERSION}-x86_64-linux-gnu.tar.gz prcycoin-${VERSION}-osx64.tar.gz diff --git a/share/genbuild.sh b/share/genbuild.sh index fb5daeb145..6753934904 100755 --- a/share/genbuild.sh +++ b/share/genbuild.sh @@ -24,7 +24,6 @@ git_check_in_repo() { DESC="" SUFFIX="" -LAST_COMMIT_DATE="" if [ "${BITCOIN_GENBUILD_NO_GIT}" != "1" -a -e "$(which git 2>/dev/null)" -a "$(git rev-parse --is-inside-work-tree 2>/dev/null)" = "true" ] && git_check_in_repo share/genbuild.sh; then # clean 'dirty' status of touched files that haven't been modified git diff >/dev/null 2>/dev/null @@ -38,9 +37,6 @@ if [ "${BITCOIN_GENBUILD_NO_GIT}" != "1" -a -e "$(which git 2>/dev/null)" -a "$( # otherwise generate suffix from git, i.e. string like "59887e8-dirty" SUFFIX=$(git rev-parse --short HEAD) git diff-index --quiet HEAD -- || SUFFIX="$SUFFIX" - - # get a string like "2012-04-10 16:27:19 +0200" - LAST_COMMIT_DATE="$(git log -n 1 --format="%ci")" fi if [ -n "$DESC" ]; then @@ -54,7 +50,4 @@ fi # only update build.h if necessary if [ "$INFO" != "$NEWINFO" ]; then echo "$NEWINFO" >"$FILE" - if [ -n "$LAST_COMMIT_DATE" ]; then - echo "#define BUILD_DATE \"$LAST_COMMIT_DATE\"" >> "$FILE" - fi fi \ No newline at end of file diff --git a/share/pixmaps/addressbook16.bmp b/share/pixmaps/addressbook16.bmp deleted file mode 100644 index c5576910b1..0000000000 Binary files a/share/pixmaps/addressbook16.bmp and /dev/null differ diff --git a/share/pixmaps/addressbook16mask.bmp b/share/pixmaps/addressbook16mask.bmp deleted file mode 100644 index d3a478d1ad..0000000000 Binary files a/share/pixmaps/addressbook16mask.bmp and /dev/null differ diff --git a/share/pixmaps/addressbook20.bmp b/share/pixmaps/addressbook20.bmp deleted file mode 100644 index 2b33b228aa..0000000000 Binary files a/share/pixmaps/addressbook20.bmp and /dev/null differ diff --git a/share/pixmaps/addressbook20mask.bmp b/share/pixmaps/addressbook20mask.bmp deleted file mode 100644 index 56ce6125db..0000000000 Binary files a/share/pixmaps/addressbook20mask.bmp and /dev/null differ diff --git a/share/pixmaps/check.ico b/share/pixmaps/check.ico deleted file mode 100644 index 0c4e6e8147..0000000000 Binary files a/share/pixmaps/check.ico and /dev/null differ diff --git a/share/pixmaps/favicon.ico b/share/pixmaps/favicon.ico deleted file mode 100644 index 9e18e1a0b6..0000000000 Binary files a/share/pixmaps/favicon.ico and /dev/null differ diff --git a/share/pixmaps/prcycoin-bc.ico b/share/pixmaps/prcycoin-bc.ico deleted file mode 100644 index f3522f1953..0000000000 Binary files a/share/pixmaps/prcycoin-bc.ico and /dev/null differ diff --git a/share/pixmaps/send16.bmp b/share/pixmaps/send16.bmp deleted file mode 100644 index 676b5c4b49..0000000000 Binary files a/share/pixmaps/send16.bmp and /dev/null differ diff --git a/share/pixmaps/send16mask.bmp b/share/pixmaps/send16mask.bmp deleted file mode 100644 index 06c747f934..0000000000 Binary files a/share/pixmaps/send16mask.bmp and /dev/null differ diff --git a/share/pixmaps/send16masknoshadow.bmp b/share/pixmaps/send16masknoshadow.bmp deleted file mode 100644 index faf24e0d8a..0000000000 Binary files a/share/pixmaps/send16masknoshadow.bmp and /dev/null differ diff --git a/share/pixmaps/send20.bmp b/share/pixmaps/send20.bmp deleted file mode 100644 index 2b90422b38..0000000000 Binary files a/share/pixmaps/send20.bmp and /dev/null differ diff --git a/share/pixmaps/send20mask.bmp b/share/pixmaps/send20mask.bmp deleted file mode 100644 index f124d0da08..0000000000 Binary files a/share/pixmaps/send20mask.bmp and /dev/null differ diff --git a/share/qt/Info.plist.in b/share/qt/Info.plist.in index 22e6ed6095..ed45e41514 100644 --- a/share/qt/Info.plist.in +++ b/share/qt/Info.plist.in @@ -3,7 +3,7 @@ LSMinimumSystemVersion - 10.12.0 + 10.14.0 LSArchitecturePriority @@ -54,43 +54,6 @@ - UTExportedTypeDeclarations - - - UTTypeIdentifier - io.prcycoin.paymentrequest - UTTypeDescription - Prcycoin payment request - UTTypeConformsTo - - public.data - - UTTypeTagSpecification - - public.mime-type - application/x-prcycoin-payment-request - public.filename-extension - - prcycoinpaymentrequest - - - - - - CFBundleDocumentTypes - - - CFBundleTypeRole - Editor - LSItemContentTypes - - io.prcycoin.paymentrequest - - LSHandlerRank - Owner - - - NSPrincipalClass NSApplication diff --git a/share/qt/img/reload.png b/share/qt/img/reload.png deleted file mode 100644 index 735d9f165b..0000000000 Binary files a/share/qt/img/reload.png and /dev/null differ diff --git a/share/qt/img/reload.xcf b/share/qt/img/reload.xcf deleted file mode 100644 index dc8be62831..0000000000 Binary files a/share/qt/img/reload.xcf and /dev/null differ diff --git a/share/qt/make_spinner.py b/share/qt/make_spinner.py deleted file mode 100644 index bb19e91508..0000000000 --- a/share/qt/make_spinner.py +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env python -# W.J. van der Laan, 2011 -# Make spinning animation from a .png -# Requires imagemagick 6.7+ -from __future__ import division -from os import path -from PIL import Image -from subprocess import Popen - -SRC='img/reload.png' -TMPDIR='../../src/qt/res/movies/' -TMPNAME='spinner-%03i.png' -NUMFRAMES=35 -FRAMERATE=10.0 -CONVERT='convert' -CLOCKWISE=True -DSIZE=(16,16) - -im_src = Image.open(SRC) - -if CLOCKWISE: - im_src = im_src.transpose(Image.FLIP_LEFT_RIGHT) - -def frame_to_filename(frame): - return path.join(TMPDIR, TMPNAME % frame) - -frame_files = [] -for frame in xrange(NUMFRAMES): - rotation = (frame + 0.5) / NUMFRAMES * 360.0 - if CLOCKWISE: - rotation = -rotation - im_new = im_src.rotate(rotation, Image.BICUBIC) - im_new.thumbnail(DSIZE, Image.ANTIALIAS) - outfile = frame_to_filename(frame) - im_new.save(outfile, 'png') - frame_files.append(outfile) - - diff --git a/share/rpcuser/README.md b/share/rpcuser/README.md new file mode 100644 index 0000000000..12a8e6fb0c --- /dev/null +++ b/share/rpcuser/README.md @@ -0,0 +1,10 @@ +RPC Tools +--------------------- + +### [RPCUser](/share/rpcuser) ### + +Create an RPC user login credential. + +Usage: + + ./rpcuser.py diff --git a/share/rpcuser/rpcuser.py b/share/rpcuser/rpcuser.py new file mode 100644 index 0000000000..9fd176908b --- /dev/null +++ b/share/rpcuser/rpcuser.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python2 +# Copyright (c) 2015 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +import hashlib +import sys +import os +from random import SystemRandom +import base64 +import hmac + +if len(sys.argv) < 2: + sys.stderr.write('Please include username as an argument.\n') + sys.exit(0) + +username = sys.argv[1] + +#This uses os.urandom() underneath +cryptogen = SystemRandom() + +#Create 16 byte hex salt +salt_sequence = [cryptogen.randrange(256) for i in range(16)] +hexseq = list(map(hex, salt_sequence)) +salt = "".join([x[2:] for x in hexseq]) + +#Create 32 byte b64 password +password = base64.urlsafe_b64encode(os.urandom(32)) + +digestmod = hashlib.sha256 + +if sys.version_info.major >= 3: + password = password.decode('utf-8') + digestmod = 'SHA256' + +m = hmac.new(bytearray(salt, 'utf-8'), bytearray(password, 'utf-8'), digestmod) +result = m.hexdigest() + +print("String to be appended to bitcoin.conf:") +print("rpcauth="+username+":"+salt+"$"+result) +print("Your password:\n"+password) diff --git a/share/setup.nsi.in b/share/setup.nsi.in index 86cafef46f..7668dea8b9 100644 --- a/share/setup.nsi.in +++ b/share/setup.nsi.in @@ -2,6 +2,12 @@ Name "@PACKAGE_NAME@ (64-bit)" RequestExecutionLevel highest SetCompressor /SOLID lzma +SetDateSave off +Unicode true + +# Uncomment these lines when investigating reproducibility errors +#SetCompress off +#SetDatablockOptimize off # General Symbol Definitions !define REGKEY "SOFTWARE\$(^Name)" @@ -19,7 +25,8 @@ SetCompressor /SOLID lzma !define MUI_STARTMENUPAGE_REGISTRY_KEY ${REGKEY} !define MUI_STARTMENUPAGE_REGISTRY_VALUENAME StartMenuGroup !define MUI_STARTMENUPAGE_DEFAULTFOLDER "@PACKAGE_NAME@" -!define MUI_FINISHPAGE_RUN $INSTDIR\@BITCOIN_GUI_NAME@@EXEEXT@ +!define MUI_FINISHPAGE_RUN "$WINDIR\explorer.exe" +!define MUI_FINISHPAGE_RUN_PARAMETERS $INSTDIR\@BITCOIN_GUI_NAME@@EXEEXT@ !define MUI_UNICON "${NSISDIR}\Contrib\Graphics\Icons\modern-uninstall.ico" !define MUI_UNWELCOMEFINISHPAGE_BITMAP "@abs_top_srcdir@/share/pixmaps/nsis-wizard.bmp" !define MUI_UNFINISHPAGE_NOAUTOCLOSE @@ -47,7 +54,7 @@ Var StartMenuGroup # Installer attributes OutFile @abs_top_srcdir@/@PACKAGE_TARNAME@-@PACKAGE_VERSION@-win64-setup-unsigned.exe InstallDir $PROGRAMFILES64\PRCYcoin -CRCCheck on +CRCCheck force XPStyle on BrandingText " " ShowInstDetails show @@ -66,13 +73,13 @@ ShowUninstDetails show Section -Main SEC0000 SetOutPath $INSTDIR SetOverwrite on - File @abs_top_srcdir@/release/@BITCOIN_GUI_NAME@@EXEEXT@ + File @abs_top_builddir@/release/@BITCOIN_GUI_NAME@@EXEEXT@ File /oname=COPYING.txt @abs_top_srcdir@/COPYING File /oname=readme.txt @abs_top_srcdir@/doc/README_windows.txt SetOutPath $INSTDIR\daemon - File @abs_top_srcdir@/release/@BITCOIN_DAEMON_NAME@@EXEEXT@ - File @abs_top_srcdir@/release/@BITCOIN_CLI_NAME@@EXEEXT@ - File @abs_top_srcdir@/release/@BITCOIN_TX_NAME@@EXEEXT@ + File @abs_top_builddir@/release/@BITCOIN_DAEMON_NAME@@EXEEXT@ + File @abs_top_builddir@/release/@BITCOIN_CLI_NAME@@EXEEXT@ + File @abs_top_builddir@/release/@BITCOIN_TX_NAME@@EXEEXT@ SetOutPath $INSTDIR\doc File /r /x Makefile* @abs_top_srcdir@/doc\*.* SetOutPath $INSTDIR diff --git a/share/ui.rc b/share/ui.rc deleted file mode 100644 index e81b81bc13..0000000000 --- a/share/ui.rc +++ /dev/null @@ -1,15 +0,0 @@ -bitcoin ICON "pixmaps/prcycoin.ico" - -#include "wx/msw/wx.rc" - -check ICON "pixmaps/check.ico" -send16 BITMAP "pixmaps/send16.bmp" -send16mask BITMAP "pixmaps/send16mask.bmp" -send16masknoshadow BITMAP "pixmaps/send16masknoshadow.bmp" -send20 BITMAP "pixmaps/send20.bmp" -send20mask BITMAP "pixmaps/send20mask.bmp" -addressbook16 BITMAP "pixmaps/addressbook16.bmp" -addressbook16mask BITMAP "pixmaps/addressbook16mask.bmp" -addressbook20 BITMAP "pixmaps/addressbook20.bmp" -addressbook20mask BITMAP "pixmaps/addressbook20mask.bmp" -favicon ICON "pixmaps/favicon.ico" diff --git a/src/Makefile.am b/src/Makefile.am index 5b7c4335f3..7b5a0815f9 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,9 +2,13 @@ # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. +# Pattern rule to print variables, e.g. make print-top_srcdir +print-%: + @echo '$*' = '$($*)' + DIST_SUBDIRS = secp256k1 secp256k1-mw univalue -AM_LDFLAGS = $(PTHREAD_CFLAGS) $(LIBTOOL_LDFLAGS) $(HARDENED_LDFLAGS) $(GPROF_LDFLAGS) $(SANITIZER_LDFLAGS) -AM_CXXFLAGS = $(DEBUG_CXXFLAGS) $(HARDENED_CXXFLAGS) $(WARN_CXXFLAGS) $(NOWARN_CXXFLAGS) $(ERROR_CXXFLAGS) $(GPROF_CXXFLAGS) $(SANITIZER_CXXFLAGS) +AM_LDFLAGS = $(PTHREAD_CFLAGS) $(LIBTOOL_LDFLAGS) $(HARDENED_LDFLAGS) $(GPROF_LDFLAGS) $(SANITIZER_LDFLAGS) $(LTO_LDFLAGS) +AM_CXXFLAGS = $(DEBUG_CXXFLAGS) $(HARDENED_CXXFLAGS) $(WARN_CXXFLAGS) $(NOWARN_CXXFLAGS) $(ERROR_CXXFLAGS) $(GPROF_CXXFLAGS) $(SANITIZER_CXXFLAGS) $(LTO_CXXFLAGS) AM_CPPFLAGS = $(DEBUG_CPPFLAGS) $(HARDENED_CPPFLAGS) AM_LIBTOOLFLAGS = --preserve-dup-deps EXTRA_LIBRARIES = @@ -18,7 +22,7 @@ else LIBUNIVALUE = $(UNIVALUE_LIBS) endif -BITCOIN_INCLUDES=-I$(builddir) $(BDB_CPPFLAGS) $(BOOST_CPPFLAGS) $(LEVELDB_CPPFLAGS) $(CRYPTO_CFLAGS) $(SSL_CFLAGS) +BITCOIN_INCLUDES=-I$(builddir) $(BDB_CPPFLAGS) $(BOOST_CPPFLAGS) $(LEVELDB_CPPFLAGS) $(CRYPTO_CFLAGS) $(SSL_CFLAGS) $(CURL_CFLAGS) BITCOIN_INCLUDES += -I$(srcdir)/secp256k1/include BITCOIN_INCLUDES += -I$(srcdir)/secp256k1-mw/include @@ -117,6 +121,7 @@ BITCOIN_CORE_H = \ core_io.h \ cuckoocache.h \ crypter.h \ + curl_json.h \ wallet/db.h \ fs.h \ eccryptoverify.h \ @@ -157,6 +162,7 @@ BITCOIN_CORE_H = \ random.h \ reverselock.h \ reverse_iterate.h \ + rpc/blockchain.h \ rpc/client.h \ rpc/protocol.h \ rpc/server.h \ @@ -171,6 +177,7 @@ BITCOIN_CORE_H = \ stakeinput.h \ streams.h \ support/cleanse.h \ + support/events.h \ sync.h \ threadsafety.h \ timedata.h \ @@ -207,7 +214,7 @@ obj/build.h: FORCE libbitcoin_util_a-clientversion.$(OBJEXT): obj/build.h # server: shared between prcycoind and prcycoin-qt -libbitcoin_server_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(MINIUPNPC_CPPFLAGS) $(EVENT_CFLAGS) $(EVENT_PTHREADS_CFLAGS) +libbitcoin_server_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(MINIUPNPC_CPPFLAGS) $(EVENT_CFLAGS) $(EVENT_PTHREADS_CFLAGS) $(CURL_CFLAGS) libbitcoin_server_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libbitcoin_server_a_SOURCES = \ addrman.cpp \ @@ -216,6 +223,7 @@ libbitcoin_server_a_SOURCES = \ chain.cpp \ checkpoints.cpp \ consensus/tx_verify.cpp \ + curl_json.cpp \ httprpc.cpp \ httpserver.cpp \ init.cpp \ @@ -448,7 +456,7 @@ prcycoind_LDADD = \ $(LIBSECP256K1) \ $(LIBSECP256K1_2) -prcycoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(ZMQ_LIBS) +prcycoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(ZMQ_LIBS) $(CURL_LIBS) # prcycoin-cli binary # prcycoin_cli_SOURCES = prcycoin-cli.cpp @@ -583,14 +591,8 @@ if HARDEN $(AM_V_at) READELF=$(READELF) OBJDUMP=$(OBJDUMP) $(top_srcdir)/contrib/devtools/security-check.py < $(bin_PROGRAMS) endif -%.pb.cc %.pb.h: %.proto - @test -f $(PROTOC) - $(AM_V_GEN) $(PROTOC) --cpp_out=$(@D) --proto_path=$( forms/ui_foo.h QT_FORMS_H=$(join $(dir $(QT_FORMS_UI)),$(addprefix ui_, $(notdir $(QT_FORMS_UI:.ui=.h)))) @@ -413,14 +406,9 @@ QT_FORMS_H=$(join $(dir $(QT_FORMS_UI)),$(addprefix ui_, $(notdir $(QT_FORMS_UI: $(QT_MOC): $(QT_FORMS_H) $(qt_libbitcoinqt_a_OBJECTS) $(qt_prcycoin_qt_OBJECTS) : | $(QT_MOC) -#Generating these with a half-written protobuf header leads to wacky results. -#This makes sure it's done. -$(QT_MOC): $(PROTOBUF_H) -$(QT_MOC_CPP): $(PROTOBUF_H) - # prcycoin-qt binary # qt_prcycoin_qt_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(BITCOIN_QT_INCLUDES) \ - $(QT_INCLUDES) $(PROTOBUF_CFLAGS) $(QR_CFLAGS) + $(QT_INCLUDES) $(QR_CFLAGS) $(CURL_CFLAGS) qt_prcycoin_qt_CXXFLAGS = $(AM_CXXFLAGS) $(QT_PIE_FLAGS) qt_prcycoin_qt_SOURCES = qt/prcycoin.cpp @@ -430,7 +418,7 @@ endif if TARGET_WINDOWS qt_prcycoin_qt_SOURCES += $(BITCOIN_RC) endif -qt_prcycoin_qt_LDADD = qt/libbitcoinqt.a $(LIBBITCOIN_SERVER) $(LIBSECP256K1) $(LIBSECP256K1_2) +qt_prcycoin_qt_LDADD = qt/libbitcoinqt.a $(LIBBITCOIN_SERVER) $(LIBSECP256K1) $(LIBSECP256K1_2) $(CURL_LIBS) if ENABLE_WALLET qt_prcycoin_qt_LDADD += $(LIBBITCOIN_UTIL) $(LIBBITCOIN_WALLET) $(LIBBITCOIN_ZXCVBN) endif @@ -439,8 +427,8 @@ qt_prcycoin_qt_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS) endif qt_prcycoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) $(LIBLEVELDB_SSE42) $(LIBMEMENV) \ - $(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \ - $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) -lqrencode + $(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \ + $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) -lqrencode $(CURL_LIBS) qt_prcycoin_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) qt_prcycoin_qt_LIBTOOLFLAGS = $(AM_LIBTOOLFLAGS) --tag CXX @@ -456,17 +444,19 @@ $(srcdir)/qt/prcycoinstrings.cpp: $(libbitcoin_server_a_SOURCES) $(libbitcoin_wa translate: $(srcdir)/qt/prcycoinstrings.cpp $(QT_FORMS_UI) $(QT_FORMS_UI) $(BITCOIN_QT_BASE_CPP) qt/prcycoin.cpp $(BITCOIN_QT_WINDOWS_CPP) $(BITCOIN_QT_WALLET_CPP) $(BITCOIN_QT_H) $(BITCOIN_MM) @test -n $(LUPDATE) || echo "lupdate is required for updating translations" $(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(LUPDATE) $^ -locations relative -no-obsolete -ts $(srcdir)/qt/locale/prcycoin_en.ts + @test -n $(LCONVERT) || echo "lconvert is required for updating translations" + $(AM_V_GEN) QT_SELECT=$(QT_SELECT) $(LCONVERT) -o $(srcdir)/qt/locale/prcycoin_en.xlf -i $(srcdir)/qt/locale/prcycoin_en.ts $(QT_QRC_LOCALE_CPP): $(QT_QRC_LOCALE) $(QT_QM) @test -f $(RCC) @cp -f $< $(@D)/temp_$( $@ @rm $(@D)/temp_$( $@ CLEAN_QT = $(nodist_qt_libbitcoinqt_a_SOURCES) $(QT_QM) $(QT_FORMS_H) qt/*.gcda qt/*.gcno qt/temp_prcycoin_locale.qrc @@ -478,6 +468,20 @@ prcycoin_qt_clean: FORCE prcycoin_qt : qt/prcycoin-qt$(EXEEXT) +APK_LIB_DIR = qt/android/libs/$(ANDROID_ARCH) +QT_BASE_PATH = $(shell find ../depends/sources/ -maxdepth 1 -type f -regex ".*qtbase.*\.tar.xz") +QT_BASE_TLD = $(shell tar tf $(QT_BASE_PATH) --exclude='*/*') + +prcycoin_qt_apk: FORCE + mkdir -p $(APK_LIB_DIR) + cp $(dir $(CC))../sysroot/usr/lib/$(host_alias)/libc++_shared.so $(APK_LIB_DIR) + tar xf $(QT_BASE_PATH) -C qt/android/src/ $(QT_BASE_TLD)src/android/jar/src --strip-components=5 + tar xf $(QT_BASE_PATH) -C qt/android/src/ $(QT_BASE_TLD)src/android/java/src --strip-components=5 + tar xf $(QT_BASE_PATH) -C qt/android/res/ $(QT_BASE_TLD)src/android/java/res --strip-components=5 + cp qt/prcycoin-qt $(APK_LIB_DIR)/libprcycoin-qt.so + cd qt/android && gradle wrapper --gradle-version=6.6.1 + cd qt/android && ./gradlew build + ui_%.h: %.ui @test -f $(UIC) @$(MKDIR_P) $(@D) diff --git a/src/Makefile.qttest.include b/src/Makefile.qttest.include index cf3b86c202..da1890ef62 100644 --- a/src/Makefile.qttest.include +++ b/src/Makefile.qttest.include @@ -6,26 +6,16 @@ TESTS += qt/test/test_prcycoin-qt TEST_QT_MOC_CPP = qt/test/moc_uritests.cpp -if ENABLE_WALLET -TEST_QT_MOC_CPP += qt/test/moc_paymentservertests.cpp -endif - TEST_QT_H = \ - qt/test/uritests.h \ - qt/test/paymentrequestdata.h \ - qt/test/paymentservertests.h + qt/test/uritests.h qt_test_test_prcycoin_qt_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(BITCOIN_QT_INCLUDES) \ - $(QT_INCLUDES) $(QT_TEST_INCLUDES) $(PROTOBUF_CFLAGS) + $(QT_INCLUDES) $(QT_TEST_INCLUDES) qt_test_test_prcycoin_qt_SOURCES = \ qt/test/test_main.cpp \ qt/test/uritests.cpp \ $(TEST_QT_H) -if ENABLE_WALLET -qt_test_test_prcycoin_qt_SOURCES += \ - qt/test/paymentservertests.cpp -endif nodist_qt_test_test_prcycoin_qt_SOURCES = $(TEST_QT_MOC_CPP) @@ -38,7 +28,7 @@ qt_test_test_prcycoin_qt_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS) endif qt_test_test_prcycoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) \ $(LIBLEVELDB_SSE42) $(LIBMEMENV) $(BOOST_LIBS) $(QT_DBUS_LIBS) $(QT_TEST_LIBS) $(QT_LIBS) \ - $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \ + $(QR_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \ $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) qt_test_test_prcycoin_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) qt_test_test_prcycoin_qt_CXXFLAGS = $(AM_CXXFLAGS) $(QT_PIE_FLAGS) diff --git a/src/Makefile.test.include b/src/Makefile.test.include index b419bcf67f..f9ef118420 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -51,6 +51,7 @@ BITCOIN_TESTS =\ test/netbase_tests.cpp \ test/pmt_tests.cpp \ test/prevector_tests.cpp \ + test/raii_event_tests.cpp \ test/reverselock_tests.cpp \ test/rpc_tests.cpp \ test/sanity_tests.cpp \ @@ -78,7 +79,7 @@ BITCOIN_TESTS += \ endif test_test_prcycoin_SOURCES = $(BITCOIN_TEST_SUITE) $(BITCOIN_TESTS) $(JSON_TEST_FILES) $(RAW_TEST_FILES) -test_test_prcycoin_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -I$(builddir)/test/ $(TESTDEFS) $(EVENT_FLAGS) +test_test_prcycoin_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -I$(builddir)/test/ $(TESTDEFS) $(EVENT_CFLAGS) test_test_prcycoin_LDADD = $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) \ $(LIBLEVELDB) $(LIBLEVELDB_SSE42) $(LIBMEMENV) $(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1) $(LIBSECP256K1_2) $(EVENT_LIBS) $(EVENT_PTHREADS_LIBS) if ENABLE_WALLET diff --git a/src/allocators.cpp b/src/allocators.cpp index df498f7eae..15b72f1447 100644 --- a/src/allocators.cpp +++ b/src/allocators.cpp @@ -5,11 +5,6 @@ #include "allocators.h" #ifdef WIN32 -#ifdef _WIN32_WINNT -#undef _WIN32_WINNT -#endif -#define _WIN32_WINNT 0x0501 -#define WIN32_LEAN_AND_MEAN 1 #ifndef NOMINMAX #define NOMINMAX #endif diff --git a/src/chainparams.h b/src/chainparams.h index f983ed9dd1..4451258962 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -91,7 +91,7 @@ class CChainParams bool MineBlocksOnDemand() const { return fMineBlocksOnDemand; } /** In the future use NetworkIDString() for RPC fields */ bool TestnetToBeDeprecatedFieldRPC() const { return fTestnetToBeDeprecatedFieldRPC; } - /** Return the BIP70 network string (main, test or regtest) */ + /** Return the network string */ std::string NetworkIDString() const { return strNetworkID; } const std::vector& DNSSeeds() const { return vSeeds; } const std::vector& Base58Prefix(Base58Type type) const { return base58Prefixes[type]; } diff --git a/src/clientversion.cpp b/src/clientversion.cpp index 14f8fd3505..b62210c39a 100644 --- a/src/clientversion.cpp +++ b/src/clientversion.cpp @@ -67,16 +67,7 @@ const std::string CLIENT_NAME("PRCY"); #endif #endif -#ifndef BUILD_DATE -#ifdef GIT_COMMIT_DATE -#define BUILD_DATE GIT_COMMIT_DATE -#else -#define BUILD_DATE __DATE__ ", " __TIME__ -#endif -#endif - const std::string CLIENT_BUILD(BUILD_DESC CLIENT_VERSION_SUFFIX); -const std::string CLIENT_DATE(BUILD_DATE); static std::string FormatVersion(int nVersion) { diff --git a/src/clientversion.h b/src/clientversion.h index 1df409cc42..d0a5820254 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -43,7 +43,6 @@ static const int CLIENT_VERSION = extern const std::string CLIENT_NAME; extern const std::string CLIENT_BUILD; -extern const std::string CLIENT_DATE; std::string FormatFullVersion(); diff --git a/src/compat.h b/src/compat.h index 6fbefd772b..54c4f980a8 100644 --- a/src/compat.h +++ b/src/compat.h @@ -11,13 +11,6 @@ #endif #ifdef WIN32 -#ifdef _WIN32_WINNT -#undef _WIN32_WINNT -#endif -#define _WIN32_WINNT 0x0501 -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN 1 -#endif #ifndef NOMINMAX #define NOMINMAX #endif diff --git a/src/compat/byteswap.h b/src/compat/byteswap.h index 92a4f91ed1..c09778a99f 100644 --- a/src/compat/byteswap.h +++ b/src/compat/byteswap.h @@ -17,20 +17,13 @@ #if defined(MAC_OSX) -#if !defined(bswap_16) - -// Mac OS X / Darwin features; we include a check for bswap_16 because if it is already defined, protobuf has -// defined these macros for us already; if it isn't, we do it ourselves. In either case, we get the exact same -// result regardless which path was taken #include #define bswap_16(x) OSSwapInt16(x) #define bswap_32(x) OSSwapInt32(x) #define bswap_64(x) OSSwapInt64(x) -#endif // !defined(bswap_16) - #else -// Non-Mac OS X / non-Darwin +// Non-MacOS / non-Darwin #if HAVE_DECL_BSWAP_16 == 0 inline uint16_t bswap_16(uint16_t x) diff --git a/src/compat/glibc_compat.cpp b/src/compat/glibc_compat.cpp index 0d457e93f3..dc95ae3722 100644 --- a/src/compat/glibc_compat.cpp +++ b/src/compat/glibc_compat.cpp @@ -17,6 +17,8 @@ extern "C" void* memcpy(void* a, const void* b, size_t c) return memmove(a, b, c); } +extern "C" void __chk_fail(void) __attribute__((__noreturn__)); + #if defined(__i386__) || defined(__arm__) extern "C" int64_t __udivmoddi4(uint64_t u, uint64_t v, uint64_t* rp); diff --git a/src/curl_json.cpp b/src/curl_json.cpp new file mode 100644 index 0000000000..0bff43737b --- /dev/null +++ b/src/curl_json.cpp @@ -0,0 +1,75 @@ +// Copyright (c) 2009-2014 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "curl_json.h" +#include "util.h" + +#include + +static size_t writer(char *in, size_t size, size_t nmemb, std::string *out) +{ + out->append((char*)in, size * nmemb); + return size * nmemb; +} + +void getHttpsJson(std::string url, JsonDownload* reply, int headerType) +{ + reply->failed = false; + reply->complete = false; + reply->URL = url; + std::string response_string; + + curl_global_init(CURL_GLOBAL_ALL); + CURL *curl; + CURLcode res; + + struct curl_slist *headers=NULL; // init to NULL is important + switch(headerType) { + case STANDARD_HEADERS: + headers = curl_slist_append(headers, "Accept: application/json"); + break; + case CG_HEADERS: + headers = curl_slist_append(headers, "Accept: application/json"); + break; + case GITHUB_HEADERS: + headers = curl_slist_append(headers, "Accept: application/vnd.github+json"); + headers = curl_slist_append(headers, "User-Agent: PRCYcoin"); + break; + } + + headers = curl_slist_append(headers, "Content-Type: application/json"); + headers = curl_slist_append(headers, "charset: utf-8"); + + curl = curl_easy_init(); + if(curl) { + + curl_easy_setopt(curl, CURLOPT_URL, reply->URL.c_str()); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + curl_easy_setopt(curl, CURLOPT_HTTPGET, 1); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writer); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_string); + res = curl_easy_perform(curl); + + if(CURLE_OK == res) { + char *ct; + /* ask for the content-type */ + res = curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &ct); + if((CURLE_OK == res) && ct) { + reply->response = std::move(response_string); + reply->failed = false; + reply->complete = true; + } + } else { + reply->response = ""; + reply->failed = false; + reply->complete = false; + } + } + /* always cleanup */ + curl_easy_cleanup(curl); + curl_slist_free_all(headers); + curl_global_cleanup(); +} diff --git a/src/curl_json.h b/src/curl_json.h new file mode 100644 index 0000000000..d8f9b9c442 --- /dev/null +++ b/src/curl_json.h @@ -0,0 +1,40 @@ +// Copyright (c) 2009-2014 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef PRCYCOIN_CURLJSON_H +#define PRCYCOIN_CURLJSON_H + +#include + +#include + +#define TIME_IN_US 1 +#define TIMETYPE curl_off_t +#define TIMEOPT CURLINFO_TOTAL_TIME_T +#define MINIMAL_PROGRESS_FUNCTIONALITY_INTERVAL 3000000 + +struct CurlProgress { + TIMETYPE lastruntime; /* type depends on version, see above */ + CURL *curl; +}; + +enum JsonDownloadHeaders { + STANDARD_HEADERS, + CG_HEADERS, + GITHUB_HEADERS +}; + +struct JsonDownload { + std::string URL = ""; + std::string response = ""; + bool failed = false; + bool complete = false; + CURL *curl; + CurlProgress prog; +}; + +static size_t writer(char *in, size_t size, size_t nmemb, std::string *out); +extern void getHttpsJson(std::string url, JsonDownload* reply, int headerType); + +#endif diff --git a/src/dbwrapper.cpp b/src/dbwrapper.cpp index c180be3890..119657f3b2 100644 --- a/src/dbwrapper.cpp +++ b/src/dbwrapper.cpp @@ -6,8 +6,6 @@ #include "util.h" -#include - #include #include #include @@ -102,7 +100,7 @@ bool CDBWrapper::WriteBatch(CDBBatch& batch, bool fSync) bool CDBWrapper::IsEmpty() { - boost::scoped_ptr it(NewIterator()); + std::unique_ptr it(NewIterator()); it->SeekToFirst(); return !(it->Valid()); } diff --git a/src/httprpc.cpp b/src/httprpc.cpp index 9aea450dba..d8c6cb5a8a 100644 --- a/src/httprpc.cpp +++ b/src/httprpc.cpp @@ -16,16 +16,21 @@ #include "util.h" #include "utilstrencodings.h" #include "guiinterface.h" +#include "crypto/hmac_sha256.h" +#include #include // boost::trim +/** WWW-Authenticate to present with 401 Unauthorized response */ +static const char* WWW_AUTH_HEADER_DATA = "Basic realm=\"jsonrpc\""; + /** Simple one-shot callback timer to be used by the RPC mechanism to e.g. * re-lock the wellet. */ class HTTPRPCTimer : public RPCTimerBase { public: - HTTPRPCTimer(struct event_base* eventBase, boost::function& func, int64_t millis) : + HTTPRPCTimer(struct event_base* eventBase, std::function& func, int64_t millis) : ev(eventBase, false, func) { struct timeval tv; @@ -40,14 +45,14 @@ class HTTPRPCTimer : public RPCTimerBase class HTTPRPCTimerInterface : public RPCTimerInterface { public: - HTTPRPCTimerInterface(struct event_base* base) : base(base) + HTTPRPCTimerInterface(struct event_base* _base) : base(_base) { } const char* Name() { return "HTTP"; } - RPCTimerBase* NewTimer(boost::function& func, int64_t millis) + RPCTimerBase* NewTimer(std::function& func, int64_t millis) { return new HTTPRPCTimer(base, func, millis); } @@ -78,6 +83,50 @@ static void JSONErrorReply(HTTPRequest* req, const UniValue& objError, const Uni req->WriteReply(nStatus, strReply); } +//This function checks username and password against -rpcauth +//entries from config file. +static bool multiUserAuthorized(std::string strUserPass) +{ + if (strUserPass.find(":") == std::string::npos) { + return false; + } + std::string strUser = strUserPass.substr(0, strUserPass.find(":")); + std::string strPass = strUserPass.substr(strUserPass.find(":") + 1); + + if (mapMultiArgs.count("-rpcauth") > 0) { + //Search for multi-user login/pass "rpcauth" from config + for (std::string strRPCAuth : mapMultiArgs["-rpcauth"]) + { + std::vector vFields; + boost::split(vFields, strRPCAuth, boost::is_any_of(":$")); + if (vFields.size() != 3) { + //Incorrect formatting in config file + continue; + } + + std::string strName = vFields[0]; + if (!TimingResistantEqual(strName, strUser)) { + continue; + } + + std::string strSalt = vFields[1]; + std::string strHash = vFields[2]; + + unsigned int KEY_SIZE = 32; + unsigned char out[KEY_SIZE]; + + CHMAC_SHA256(reinterpret_cast(strSalt.c_str()), strSalt.size()).Write(reinterpret_cast(strPass.c_str()), strPass.size()).Finalize(out); + std::vector hexvec(out, out+KEY_SIZE); + std::string strHashFromPass = HexStr(hexvec); + + if (TimingResistantEqual(strHashFromPass, strHash)) { + return true; + } + } + } + return false; +} + static bool RPCAuthorized(const std::string& strAuth) { if (strRPCUserColonPass.empty()) // Belt-and-suspenders measure if InitRPCAuthentication was not called @@ -87,7 +136,12 @@ static bool RPCAuthorized(const std::string& strAuth) std::string strUserPass64 = strAuth.substr(6); boost::trim(strUserPass64); std::string strUserPass = DecodeBase64(strUserPass64); - return TimingResistantEqual(strUserPass, strRPCUserColonPass); + + //Check if authorized under single-user field + if (TimingResistantEqual(strUserPass, strRPCUserColonPass)) { + return true; + } + return multiUserAuthorized(strUserPass); } static bool HTTPReq_JSONRPC(HTTPRequest* req, const std::string &) @@ -100,6 +154,7 @@ static bool HTTPReq_JSONRPC(HTTPRequest* req, const std::string &) // Check authorization std::pair authHeader = req->GetHeader("authorization"); if (!authHeader.first) { + req->WriteHeader("WWW-Authenticate", WWW_AUTH_HEADER_DATA); req->WriteReply(HTTP_UNAUTHORIZED); return false; } @@ -112,6 +167,7 @@ static bool HTTPReq_JSONRPC(HTTPRequest* req, const std::string &) shouldn't have their RPC port exposed. */ MilliSleep(250); + req->WriteHeader("WWW-Authenticate", WWW_AUTH_HEADER_DATA); req->WriteReply(HTTP_UNAUTHORIZED); return false; } @@ -163,6 +219,7 @@ static bool InitRPCAuthentication() return false; } } else { + LogPrintf("Config options rpcuser and rpcpassword will soon be deprecated. Locally-run instances may remove rpcuser to use cookie-based auth, or may be replaced with rpcauth. Please see share/rpcuser for rpcauth auth generation.\n"); strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]; } return true; diff --git a/src/httpserver.cpp b/src/httpserver.cpp index 08f612cec1..3eda8cd890 100644 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -14,6 +14,7 @@ #include "sync.h" #include "guiinterface.h" +#include #include #include #include @@ -23,13 +24,14 @@ #include #include -#include -#include #include #include +#include #include #include +#include "support/events.h" + #ifdef EVENT__HAVE_NETINET_IN_H #include #ifdef _XOPEN_SOURCE_EXTENDED @@ -44,8 +46,8 @@ static const size_t MAX_HEADERS_SIZE = 8192; class HTTPWorkItem : public HTTPClosure { public: - HTTPWorkItem(HTTPRequest* req, const std::string &path, const HTTPRequestHandler& func): - req(req), path(path), func(func) + HTTPWorkItem(std::unique_ptr _req, const std::string &_path, const HTTPRequestHandler& _func): + req(std::move(_req)), path(_path), func(_func) { } void operator()() @@ -70,45 +72,19 @@ class WorkQueue /** Mutex protects entire object */ std::mutex cs; std::condition_variable cond; - /* XXX in C++11 we can use std::unique_ptr here and avoid manual cleanup */ - std::deque queue; + std::deque> queue; bool running; size_t maxDepth; - int numThreads; - - /** RAII object to keep track of number of running worker threads */ - class ThreadCounter - { - public: - WorkQueue &wq; - ThreadCounter(WorkQueue &w): wq(w) - { - std::lock_guard lock(wq.cs); - wq.numThreads += 1; - } - ~ThreadCounter() - { - std::lock_guard lock(wq.cs); - wq.numThreads -= 1; - wq.cond.notify_all(); - } - }; public: - WorkQueue(size_t maxDepth) : running(true), - maxDepth(maxDepth), - numThreads(0) + WorkQueue(size_t _maxDepth) : running(true), + maxDepth(_maxDepth) { } - /*( Precondition: worker threads have all stopped - * (call WaitExit) + /** Precondition: worker threads have all stopped (they have been joined). */ ~WorkQueue() { - while (!queue.empty()) { - delete queue.front(); - queue.pop_front(); - } } /** Enqueue a work item */ bool Enqueue(WorkItem* item) @@ -117,27 +93,25 @@ class WorkQueue if (queue.size() >= maxDepth) { return false; } - queue.push_back(item); + queue.emplace_back(std::unique_ptr(item)); cond.notify_one(); return true; } /** Thread function */ void Run() { - ThreadCounter count(*this); - while (running) { - WorkItem* i = 0; + while (true) { + std::unique_ptr i; { std::unique_lock lock(cs); while (running && queue.empty()) cond.wait(lock); if (!running) break; - i = queue.front(); + i = std::move(queue.front()); queue.pop_front(); } (*i)(); - delete i; } } /** Interrupt and exit loops */ @@ -147,14 +121,6 @@ class WorkQueue running = false; cond.notify_all(); } - /** Wait for worker threads to exit */ - void WaitExit() - { - std::unique_lock lock(cs); - while (numThreads > 0) - cond.wait(lock); - } - /** Return current depth of queue */ size_t Depth() { @@ -166,8 +132,8 @@ class WorkQueue struct HTTPPathHandler { HTTPPathHandler() {} - HTTPPathHandler(std::string prefix, bool exactMatch, HTTPRequestHandler handler): - prefix(prefix), exactMatch(exactMatch), handler(handler) + HTTPPathHandler(std::string _prefix, bool _exactMatch, HTTPRequestHandler _handler): + prefix(_prefix), exactMatch(_exactMatch), handler(_handler) { } std::string prefix; @@ -187,6 +153,7 @@ static std::vector rpc_allow_subnets; static WorkQueue* workQueue = 0; //! Handlers for (sub)paths std::vector pathHandlers; +//! Bound listening sockets std::vector boundSockets; /** Check if a network address is allowed to access the HTTP server */ @@ -255,6 +222,16 @@ static std::string RequestMethodString(HTTPRequest::RequestMethod m) /** HTTP request callback */ static void http_request_cb(struct evhttp_request* req, void* arg) { + // Disable reading to work around a libevent bug, fixed in 2.2.0. + if (event_get_version_number() >= 0x02010600 && event_get_version_number() < 0x02020001) { + evhttp_connection* conn = evhttp_request_get_connection(req); + if (conn) { + bufferevent* bev = evhttp_connection_get_bufferevent(conn); + if (bev) { + bufferevent_disable(bev, EV_READ); + } + } + } std::unique_ptr hreq(new HTTPRequest(req)); LogPrint(BCLog::HTTP, "Received a %s request for %s from %s\n", @@ -291,12 +268,14 @@ static void http_request_cb(struct evhttp_request* req, void* arg) // Dispatch to worker thread if (i != iend) { - std::unique_ptr item(new HTTPWorkItem(hreq.release(), path, i->handler)); + std::unique_ptr item(new HTTPWorkItem(std::move(hreq), path, i->handler)); assert(workQueue); if (workQueue->Enqueue(item.get())) item.release(); /* if true, queue took ownership */ - else + else { + LogPrintf("WARNING: request rejected because http work queue depth exceeded, it can be increased with the -rpcworkqueue= setting\n"); item->req->WriteReply(HTTP_INTERNAL, "Work queue depth exceeded"); + } } else { hreq->WriteReply(HTTP_NOTFOUND); } @@ -308,6 +287,7 @@ static void http_reject_request_cb(struct evhttp_request* req, void*) LogPrint(BCLog::HTTP, "Rejecting request while shutting down\n"); evhttp_send_error(req, HTTP_SERVUNAVAIL, NULL); } + /** Event dispatcher thread */ static bool ThreadHTTP(struct event_base* base, struct evhttp* http) { @@ -380,9 +360,6 @@ static void libevent_log_cb(int severity, const char *msg) bool InitHTTPServer() { - struct evhttp* http = 0; - struct event_base* base = 0; - if (!InitHTTPAllowList()) return false; @@ -408,17 +385,13 @@ bool InitHTTPServer() evthread_use_pthreads(); #endif - base = event_base_new(); // XXX RAII - if (!base) { - LogPrintf("Couldn't create an event_base: exiting\n"); - return false; - } + raii_event_base base_ctr = obtain_event_base(); /* Create a new evhttp object to handle requests. */ - http = evhttp_new(base); // XXX RAII + raii_evhttp http_ctr = obtain_evhttp(base_ctr.get()); + struct evhttp* http = http_ctr.get(); if (!http) { LogPrintf("couldn't create evhttp. Exiting.\n"); - event_base_free(base); return false; } @@ -429,8 +402,6 @@ bool InitHTTPServer() if (!HTTPBindAddresses(http)) { LogPrintf("Unable to bind any endpoint for RPC server\n"); - evhttp_free(http); - event_base_free(base); return false; } @@ -439,8 +410,9 @@ bool InitHTTPServer() LogPrintf("HTTP: creating work queue of depth %d\n", workQueueDepth); workQueue = new WorkQueue(workQueueDepth); - eventBase = base; - eventHTTP = http; + // tranfer ownership to eventBase/HTTP via .release() + eventBase = base_ctr.release(); + eventHTTP = http_ctr.release(); return true; } @@ -460,6 +432,7 @@ bool UpdateHTTPServerLogging(bool enable) { std::thread threadHTTP; std::future threadResult; +static std::vector g_thread_http_workers; bool StartHTTPServer() { @@ -471,8 +444,7 @@ bool StartHTTPServer() threadHTTP = std::thread(std::move(task), eventBase, eventHTTP); for (int i = 0; i < rpcThreads; i++) { - std::thread rpc_worker(HTTPWorkQueueRun, workQueue); - rpc_worker.detach(); + g_thread_http_workers.emplace_back(HTTPWorkQueueRun, workQueue); } return true; } @@ -481,9 +453,11 @@ void InterruptHTTPServer() { LogPrint(BCLog::HTTP, "Interrupting HTTP server\n"); if (eventHTTP) { + // Unlisten sockets for (evhttp_bound_socket *socket : boundSockets) { evhttp_del_accept_socket(eventHTTP, socket); } + // Reject requests on current connections evhttp_set_gencb(eventHTTP, http_reject_request_cb, NULL); } if (workQueue) @@ -495,12 +469,18 @@ void StopHTTPServer() LogPrint(BCLog::HTTP, "Stopping HTTP server\n"); if (workQueue) { LogPrint(BCLog::HTTP, "Waiting for HTTP worker threads to exit\n"); - workQueue->WaitExit(); + for (auto& thread: g_thread_http_workers) { + thread.join(); + } + g_thread_http_workers.clear(); delete workQueue; + workQueue = nullptr; } MilliSleep(500); // Avoid race condition while the last HTTP-thread is exiting if (eventBase) { LogPrint(BCLog::HTTP, "Waiting for HTTP event thread to exit\n"); + // Exit the event loop as soon as there are no active events. + event_base_loopexit(eventBase, nullptr); // Give event loop a few seconds to exit (to send back last RPC responses), then break it // Before this was solved with event_base_loopexit, but that didn't work as expected in // at least libevent 2.0.21 and always introduced a delay. In libevent @@ -510,7 +490,6 @@ void StopHTTPServer() if (threadResult.valid() && threadResult.wait_for(std::chrono::milliseconds(2000)) == std::future_status::timeout) { LogPrintf("HTTP event loop did not exit within allotted time, sending loopbreak\n"); event_base_loopbreak(eventBase); - } threadHTTP.join(); } @@ -539,8 +518,8 @@ static void httpevent_callback_fn(evutil_socket_t, short, void* data) delete self; } -HTTPEvent::HTTPEvent(struct event_base* base, bool deleteWhenTriggered, const std::function& handler): - deleteWhenTriggered(deleteWhenTriggered), handler(handler) +HTTPEvent::HTTPEvent(struct event_base* base, bool _deleteWhenTriggered, const std::function& _handler): + deleteWhenTriggered(_deleteWhenTriggered), handler(_handler) { ev = event_new(base, -1, 0, httpevent_callback_fn, this); assert(ev); @@ -556,7 +535,7 @@ void HTTPEvent::trigger(struct timeval* tv) else evtimer_add(ev, tv); // trigger after timeval passed } -HTTPRequest::HTTPRequest(struct evhttp_request* req) : req(req), +HTTPRequest::HTTPRequest(struct evhttp_request* _req) : req(_req), replySent(false) { } @@ -620,8 +599,21 @@ void HTTPRequest::WriteReply(int nStatus, const std::string& strReply) struct evbuffer* evb = evhttp_request_get_output_buffer(req); assert(evb); evbuffer_add(evb, strReply.data(), strReply.size()); - HTTPEvent* ev = new HTTPEvent(eventBase, true, - std::bind(evhttp_send_reply, req, nStatus, (const char*)NULL, (struct evbuffer *)NULL)); + auto req_copy = req; + HTTPEvent* ev = new HTTPEvent(eventBase, true, [req_copy, nStatus]{ + evhttp_send_reply(req_copy, nStatus, nullptr, nullptr); + // Re-enable reading from the socket. This is the second part of the libevent + // workaround above. + if (event_get_version_number() >= 0x02010600 && event_get_version_number() < 0x02020001) { + evhttp_connection* conn = evhttp_request_get_connection(req_copy); + if (conn) { + bufferevent* bev = evhttp_connection_get_bufferevent(conn); + if (bev) { + bufferevent_enable(bev, EV_READ | EV_WRITE); + } + } + } + }); ev->trigger(0); replySent = true; req = 0; // transferred back to main thread diff --git a/src/init.cpp b/src/init.cpp index 408adad708..adb33edc32 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -31,6 +31,7 @@ #include "miner.h" #include "netbase.h" #include "net.h" +#include "rpc/blockchain.h" #include "rpc/server.h" #include "script/standard.h" #include "script/sigcache.h" @@ -442,6 +443,7 @@ std::string HelpMessage(HelpMessageMode mode) CURRENCY_UNIT, FormatMoney(CWallet::minTxFee.GetFeePerK()))); strUsage += HelpMessageOpt("-paytxfee=", strprintf(_("Fee (in %s/kB) to add to transactions you send (default: %s)"), CURRENCY_UNIT, FormatMoney(payTxFee.GetFeePerK()))); strUsage += HelpMessageOpt("-rescan", _("Rescan the block chain for missing wallet transactions") + " " + _("on startup")); + strUsage += HelpMessageOpt("-rescanheight", _("Rescan the block chain from the specified height when rescan=1 on startup")); strUsage += HelpMessageOpt("-salvagewallet", _("Attempt to recover private keys from a corrupt wallet.dat") + " " + _("on startup")); strUsage += HelpMessageOpt("-sendfreetransactions", strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), 0)); strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), 1)); @@ -554,6 +556,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-rpcbind=", _("Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces)")); strUsage += HelpMessageOpt("-rpcuser=", _("Username for JSON-RPC connections")); strUsage += HelpMessageOpt("-rpcpassword=", _("Password for JSON-RPC connections")); + strUsage += HelpMessageOpt("-rpcauth=", _("Username and hashed password for JSON-RPC connections. The field comes in the format: :$. A canonical python script is included in share/rpcuser. This option can be specified multiple times")); strUsage += HelpMessageOpt("-rpcport=", strprintf(_("Listen for JSON-RPC connections on (default: %u or testnet: %u)"), 59683, 59685)); strUsage += HelpMessageOpt("-rpcallowip=", _("Allow JSON-RPC connections from specified source. Valid for are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times")); strUsage += HelpMessageOpt("-rpcthreads=", strprintf(_("Set the number of threads to service RPC calls (default: %d)"), DEFAULT_HTTP_THREADS)); @@ -774,16 +777,7 @@ bool AppInitBasicSetup() #endif #ifdef WIN32 // Enable Data Execution Prevention (DEP) -// Minimum supported OS versions: WinXP SP3, WinVista >= SP1, Win Server 2008 -// A failure is non-critical and needs no further attention! -#ifndef PROCESS_DEP_ENABLE -// We define this here, because GCCs winbase.h limits this to _WIN32_WINNT >= 0x0601 (Windows 7), -// which is not correct. Can be removed, when GCCs winbase.h is fixed! -#define PROCESS_DEP_ENABLE 0x00000001 -#endif - typedef BOOL(WINAPI * PSETPROCDEPPOL)(DWORD); - PSETPROCDEPPOL setProcDEPPol = (PSETPROCDEPPOL)GetProcAddress(GetModuleHandleA("Kernel32.dll"), "SetProcessDEPPolicy"); - if (setProcDEPPol != NULL) setProcDEPPol(PROCESS_DEP_ENABLE); + SetProcessDEPPolicy(PROCESS_DEP_ENABLE); #endif if (!SetupNetworking()) @@ -908,7 +902,7 @@ void InitLogging() #else version_string += " (release build)"; #endif - LogPrintf("PRCY version %s (%s)\n", version_string, CLIENT_DATE); + LogPrintf("PRCY version %s\n", version_string); } /** Initialize prcy. @@ -1492,7 +1486,7 @@ bool AppInit2(bool isDaemon) } //Must check at level 4 - if (!CVerifyDB().VerifyDB(pcoinsdbview, 4, GetArg("-checkblocks", 100))) { + if (!CVerifyDB().VerifyDB(pcoinsdbview, 4, GetArg("-checkblocks", 10))) { strLoadError = _("Corrupted block database detected"); fVerifyingBlocks = false; break; @@ -1682,7 +1676,7 @@ bool AppInit2(bool isDaemon) //Sort Transactions by block and block index, then reorder LOCK2(cs_main, pwalletMain->cs_wallet); if (chainActive.Tip()) { - LogPrintf("Runnning transaction reorder\n"); + LogPrintf("Running transaction reorder\n"); int64_t maxOrderPos = 0; std::map, CWalletTx*> mapSorted; pwalletMain->ReorderWalletTransactions(mapSorted, maxOrderPos); @@ -1692,6 +1686,15 @@ bool AppInit2(bool isDaemon) if (GetBoolArg("-rescan", false)) { pindexRescan = chainActive.Genesis(); + + int rescanHeight = GetArg("-rescanheight", 0); + if (rescanHeight > 0) { + if (rescanHeight > chainActive.Tip()->nHeight) { + pindexRescan = chainActive.Tip(); + } else { + pindexRescan = chainActive[rescanHeight]; + } + } } else { CWalletDB walletdb(strWalletFile); CBlockLocator locator; diff --git a/src/limitedmap.h b/src/limitedmap.h index dda9287f16..7688edf3c5 100644 --- a/src/limitedmap.h +++ b/src/limitedmap.h @@ -63,8 +63,10 @@ class limitedmap } void update(const_iterator itIn, const mapped_type& v) { - // TODO: When we switch to C++11, use map.erase(itIn, itIn) to get the non-const iterator. - iterator itTarget = map.find(itIn->first); + // Using map::erase() with empty range instead of map::find() to get a non-const iterator, + // since it is a constant time operation in C++11. For more details, see + // https://stackoverflow.com/questions/765148/how-to-remove-constness-of-const-iterator + iterator itTarget = map.erase(itIn, itIn); if (itTarget == map.end()) return; std::pair itPair = rmap.equal_range(itTarget->second); diff --git a/src/main.cpp b/src/main.cpp index 6c702f2b18..a43e3cf14e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -192,7 +192,7 @@ std::map mapBlockSource; * * Memory used: 1.7MB */ -boost::scoped_ptr recentRejects; +std::unique_ptr recentRejects; uint256 hashRecentRejectsChainTip; /** Blocks that are in flight, and that are in the queue to be downloaded. Protected by cs_main. */ @@ -4716,7 +4716,7 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex, CTransaction &stakeTxIn = block.vtx[1]; // Only one input is allowed - if (stakeTxIn.vin.size() > 1) + if (stakeTxIn.vin.size() > 1 && nHeight > Params().FixChecks()) return state.DoS(100, error("%s : multiple stake inputs not allowed", __func__), REJECT_INVALID, "bad-txns-stake"); // Inputs diff --git a/src/net.cpp b/src/net.cpp index 23b4f72a6a..135c7ef774 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -50,18 +50,6 @@ #define MSG_NOSIGNAL 0 #endif -// Fix for ancient MinGW versions, that don't have defined these in ws2tcpip.h. -// Todo: Can be removed when our pull-tester is upgraded to a modern MinGW version. -#ifdef WIN32 -#ifndef PROTECTION_LEVEL_UNRESTRICTED -#define PROTECTION_LEVEL_UNRESTRICTED 10 -#endif -#ifndef IPV6_PROTECTION_LEVEL -#define IPV6_PROTECTION_LEVEL 23 -#endif -#endif - - namespace { const int MAX_OUTBOUND_CONNECTIONS = 16; const int MAX_FEELER_CONNECTIONS = 1; diff --git a/src/netbase.cpp b/src/netbase.cpp index 24319659ae..53f5df6965 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -130,11 +130,7 @@ bool static LookupIntern(const char* pszName, std::vector& vIP, unsign aiHint.ai_socktype = SOCK_STREAM; aiHint.ai_protocol = IPPROTO_TCP; aiHint.ai_family = AF_UNSPEC; -#ifdef WIN32 - aiHint.ai_flags = fAllowLookup ? 0 : AI_NUMERICHOST; -#else aiHint.ai_flags = fAllowLookup ? AI_ADDRCONFIG : AI_NUMERICHOST; -#endif struct addrinfo* aiRes = NULL; #ifdef HAVE_GETADDRINFO_A diff --git a/src/obj/.gitignore b/src/obj/.gitignore deleted file mode 100644 index d6b7ef32c8..0000000000 --- a/src/obj/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -* -!.gitignore diff --git a/src/prcycoin-cli.cpp b/src/prcycoin-cli.cpp index 6ca05fd89d..485b6aa688 100644 --- a/src/prcycoin-cli.cpp +++ b/src/prcycoin-cli.cpp @@ -17,11 +17,9 @@ #include #include -#include -#include #include #include - +#include "support/events.h" #define _(x) std::string(x) /* Keep the _() around in case gettext or such will be used later to translate non-UI */ @@ -145,19 +143,15 @@ UniValue CallRPC(const std::string& strMethod, const UniValue& params) std::string host = GetArg("-rpcconnect", "127.0.0.1"); int port = GetArg("-rpcport", BaseParams().RPCPort()); - // Create event base - struct event_base *base = event_base_new(); // TODO RAII - if (!base) - throw std::runtime_error("cannot create event_base"); + // Obtain event base + raii_event_base base = obtain_event_base(); // Synchronously look up hostname - struct evhttp_connection *evcon = evhttp_connection_base_new(base, NULL, host.c_str(), port); // TODO RAII - if (evcon == NULL) - throw std::runtime_error("create connection failed"); - evhttp_connection_set_timeout(evcon, GetArg("-rpcclienttimeout", DEFAULT_HTTP_CLIENT_TIMEOUT)); + raii_evhttp_connection evcon = obtain_evhttp_connection_base(base.get(), host, port); + evhttp_connection_set_timeout(evcon.get(), GetArg("-rpcclienttimeout", DEFAULT_HTTP_CLIENT_TIMEOUT)); HTTPReply response; - struct evhttp_request *req = evhttp_request_new(http_request_done, (void*)&response); // TODO RAII + raii_evhttp_request req = obtain_evhttp_request(http_request_done, (void*)&response); if (req == NULL) throw std::runtime_error("create http request failed"); @@ -175,28 +169,26 @@ UniValue CallRPC(const std::string& strMethod, const UniValue& params) strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]; } - struct evkeyvalq *output_headers = evhttp_request_get_output_headers(req); + struct evkeyvalq* output_headers = evhttp_request_get_output_headers(req.get()); assert(output_headers); evhttp_add_header(output_headers, "Host", host.c_str()); evhttp_add_header(output_headers, "Connection", "close"); + evhttp_add_header(output_headers, "Content-Type", "application/json"); evhttp_add_header(output_headers, "Authorization", (std::string("Basic ") + EncodeBase64(strRPCUserColonPass)).c_str()); // Attach request data std::string strRequest = JSONRPCRequest(strMethod, params, 1); - struct evbuffer * output_buffer = evhttp_request_get_output_buffer(req); + struct evbuffer* output_buffer = evhttp_request_get_output_buffer(req.get()); assert(output_buffer); evbuffer_add(output_buffer, strRequest.data(), strRequest.size()); - int r = evhttp_make_request(evcon, req, EVHTTP_REQ_POST, "/"); + int r = evhttp_make_request(evcon.get(), req.get(), EVHTTP_REQ_POST, "/"); + req.release(); // ownership moved to evcon in above call if (r != 0) { - evhttp_connection_free(evcon); - event_base_free(base); throw CConnectionFailed("send http request failed"); } - event_base_dispatch(base); - evhttp_connection_free(evcon); - event_base_free(base); + event_base_dispatch(base.get()); if (response.status == 0) throw CConnectionFailed("couldn't connect to server"); diff --git a/src/qt/addressbookpage.cpp b/src/qt/addressbookpage.cpp index d72cdcfdb6..3d333b0739 100644 --- a/src/qt/addressbookpage.cpp +++ b/src/qt/addressbookpage.cpp @@ -275,7 +275,8 @@ void AddressBookPage::on_exportButton_clicked() if (!writer.write()) { QMessageBox::critical(this, tr("Exporting Failed"), - tr("There was an error trying to save the address list to %1. Please try again.").arg(filename)); + //: %1 is a name of the file (e.g., "addrbook.csv") that the bitcoin addresses were exported to. + tr("There was an error trying to save the address list to %1. Please try again.", "An error message.").arg(filename)); } } diff --git a/src/qt/android/AndroidManifest.xml b/src/qt/android/AndroidManifest.xml new file mode 100644 index 0000000000..82ac5877bc --- /dev/null +++ b/src/qt/android/AndroidManifest.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/qt/android/build.gradle b/src/qt/android/build.gradle new file mode 100644 index 0000000000..4c36e79db8 --- /dev/null +++ b/src/qt/android/build.gradle @@ -0,0 +1,52 @@ +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.1.0' + } +} + +repositories { + google() + jcenter() +} + +apply plugin: 'com.android.application' + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) +} + +android { + compileSdkVersion androidCompileSdkVersion.toInteger() + + buildToolsVersion androidBuildToolsVersion + + sourceSets { + main { + manifest.srcFile 'AndroidManifest.xml' + java.srcDirs = [qt5AndroidDir + '/src', 'src', 'java'] + aidl.srcDirs = [qt5AndroidDir + '/src', 'src', 'aidl'] + res.srcDirs = [qt5AndroidDir + '/res', 'res'] + resources.srcDirs = ['src'] + renderscript.srcDirs = ['src'] + assets.srcDirs = ['assets'] + jniLibs.srcDirs = ['libs'] + } + } + + lintOptions { + abortOnError false + } + + dexOptions { + javaMaxHeapSize '4g' + } + + defaultConfig { + minSdkVersion 24 + } +} diff --git a/src/qt/android/gradle.properties b/src/qt/android/gradle.properties new file mode 100644 index 0000000000..838870f62d --- /dev/null +++ b/src/qt/android/gradle.properties @@ -0,0 +1,4 @@ +androidBuildToolsVersion=28.0.3 +androidCompileSdkVersion=28 +qt5AndroidDir=new File(".").absolutePath +org.gradle.jvmargs=-Xmx4608M diff --git a/src/qt/android/res/drawable-hdpi/prcycoin.png b/src/qt/android/res/drawable-hdpi/prcycoin.png new file mode 100644 index 0000000000..d0cc260448 Binary files /dev/null and b/src/qt/android/res/drawable-hdpi/prcycoin.png differ diff --git a/src/qt/android/res/drawable-ldpi/prcycoin.png b/src/qt/android/res/drawable-ldpi/prcycoin.png new file mode 100644 index 0000000000..e60b04c554 Binary files /dev/null and b/src/qt/android/res/drawable-ldpi/prcycoin.png differ diff --git a/src/qt/android/res/drawable-mdpi/prcycoin.png b/src/qt/android/res/drawable-mdpi/prcycoin.png new file mode 100644 index 0000000000..7791a12f67 Binary files /dev/null and b/src/qt/android/res/drawable-mdpi/prcycoin.png differ diff --git a/src/qt/android/res/drawable-xhdpi/prcycoin.png b/src/qt/android/res/drawable-xhdpi/prcycoin.png new file mode 100644 index 0000000000..ec1b374ac2 Binary files /dev/null and b/src/qt/android/res/drawable-xhdpi/prcycoin.png differ diff --git a/src/qt/android/res/drawable-xxhdpi/prcycoin.png b/src/qt/android/res/drawable-xxhdpi/prcycoin.png new file mode 100644 index 0000000000..dd7dfd5334 Binary files /dev/null and b/src/qt/android/res/drawable-xxhdpi/prcycoin.png differ diff --git a/src/qt/android/res/drawable-xxxhdpi/prcycoin.png b/src/qt/android/res/drawable-xxxhdpi/prcycoin.png new file mode 100644 index 0000000000..fcdeb9301b Binary files /dev/null and b/src/qt/android/res/drawable-xxxhdpi/prcycoin.png differ diff --git a/src/qt/android/src/org/prcycoincore/qt/PrcycoinQtActivity.java b/src/qt/android/src/org/prcycoincore/qt/PrcycoinQtActivity.java new file mode 100644 index 0000000000..33dceb30e1 --- /dev/null +++ b/src/qt/android/src/org/prcycoincore/qt/PrcycoinQtActivity.java @@ -0,0 +1,29 @@ +package org.prcycoin.qt; + +import android.os.Bundle; +import android.system.ErrnoException; +import android.system.Os; + +import org.qtproject.qt5.android.bindings.QtActivity; + +import java.io.File; + +public class PrcycoinQtActivity extends QtActivity +{ + @Override + public void onCreate(Bundle savedInstanceState) + { + final File prcycoinDir = new File(getFilesDir().getAbsolutePath() + "/.prcycoin"); + if (!prcycoinDir.exists()) { + prcycoinDir.mkdir(); + } + + try { + Os.setenv("QT_QPA_PLATFORM", "android", true); + } catch (ErrnoException e) { + e.printStackTrace(); + } + + super.onCreate(savedInstanceState); + } +} diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp index 2fcbc3c309..360baeb40e 100644 --- a/src/qt/askpassphrasedialog.cpp +++ b/src/qt/askpassphrasedialog.cpp @@ -143,21 +143,17 @@ void AskPassphraseDialog::accept() ""); QApplication::quit(); } else { - QMessageBox msgBox; - msgBox.setWindowTitle("Wallet Encryption Failed"); - msgBox.setText("Wallet encryption failed due to an internal error. Your wallet was not encrypted. Please try again."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); + GUIUtil::showMessageBox( + tr("Wallet Encryption Failed"), + tr("Wallet encryption failed due to an internal error. Your wallet was not encrypted. Please try again."), + QMessageBox::Critical); } QDialog::accept(); // Success } else { - QMessageBox msgBox; - msgBox.setWindowTitle("Wallet Encryption Failed"); - msgBox.setText("The supplied passphrases do not match. Please try again."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); + GUIUtil::showMessageBox( + tr("Wallet Encryption Failed"), + tr("The supplied passphrases do not match. Please try again."), + QMessageBox::Critical); } } else { QDialog::reject(); // Cancelled @@ -166,24 +162,20 @@ void AskPassphraseDialog::accept() case Mode::UnlockStaking: case Mode::Unlock: if (!model->setWalletLocked(false, oldpass, ui->stakingCheckBox->isChecked())) { - QMessageBox msgBox; - msgBox.setWindowTitle("Wallet Unlock Failed"); - msgBox.setText("The passphrase entered for the wallet unlock was incorrect. Please try again."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); + GUIUtil::showMessageBox( + tr("Wallet Unlock Failed"), + tr("The passphrase entered for the wallet unlock was incorrect. Please try again."), + QMessageBox::Critical); } else { QDialog::accept(); // Success } break; case Mode::Decrypt: if (!model->setWalletEncrypted(false, oldpass)) { - QMessageBox msgBox; - msgBox.setWindowTitle("Wallet Decryption Failed"); - msgBox.setText("The passphrase entered for the wallet decryption was incorrect. Please try again."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); + GUIUtil::showMessageBox( + tr("Wallet Decryption Failed"), + tr("The passphrase entered for the wallet decryption was incorrect. Please try again."), + QMessageBox::Critical); } else { QDialog::accept(); // Success } @@ -191,28 +183,22 @@ void AskPassphraseDialog::accept() case Mode::ChangePass: if (newpass1 == newpass2) { if (model->changePassphrase(oldpass, newpass1)) { - QMessageBox msgBox; - msgBox.setWindowTitle("Passphrase Change Successful"); - msgBox.setText("Wallet passphrase was successfully changed.\nPlease remember your passphrase as there is no way to recover it."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Information); - msgBox.exec(); + GUIUtil::showMessageBox( + tr("Passphrase Change Successful"), + tr("Wallet passphrase was successfully changed.\nPlease remember your passphrase as there is no way to recover it."), + QMessageBox::Information); QDialog::accept(); // Success } else { - QMessageBox msgBox; - msgBox.setWindowTitle("Wallet Encryption Failed"); - msgBox.setText("The passphrase entered for the wallet decryption was incorrect. Please try again."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); + GUIUtil::showMessageBox( + tr("Wallet Encryption Failed"), + tr("The passphrase entered for the wallet decryption was incorrect. Please try again."), + QMessageBox::Critical); } } else { - QMessageBox msgBox; - msgBox.setWindowTitle("Wallet Encryption Failed"); - msgBox.setText("The supplied passphrases do not match. Please try again."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); + GUIUtil::showMessageBox( + tr("Wallet Encryption Failed"), + tr("The supplied passphrases do not match. Please try again."), + QMessageBox::Critical); } break; } diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 7e6c8e1a2e..78a9cebe57 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -60,8 +60,9 @@ #include #include #include -#include -#include +#include +#include +#include #define BASE_WINDOW_WIDTH 800 #define BASE_WINDOW_HEIGHT 768 @@ -254,7 +255,9 @@ BitcoinGUI::BitcoinGUI(const NetworkStyle* networkStyle, QWidget* parent) : QMai timerStakingIcon->start(10000); setStakingStatus(); } - checkForUpdatesClicked(); + + gitReply = new JsonDownload; + checkForUpdates(); } BitcoinGUI::~BitcoinGUI() @@ -981,57 +984,71 @@ void BitcoinGUI::openToolkitClicked() } void BitcoinGUI::checkForUpdatesClicked() +{ + checkForUpdates(true); +} + +void BitcoinGUI::checkForUpdates(bool isClicked) { LogPrintf("Check For Updates: Checking...\n"); - QUrl serviceUrl = QUrl("https://raw.githubusercontent.com/PRCYCoin/PRCYCoin/master/version.txt"); - QNetworkAccessManager *manager = new QNetworkAccessManager(this); - connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(serviceRequestFinished(QNetworkReply*))); - QNetworkRequest request; - request.setUrl(serviceUrl); - QNetworkReply* reply = manager->get(request); -} - -void BitcoinGUI::serviceRequestFinished(QNetworkReply* reply) -{ - QString currentVersion = QString::number(CLIENT_VERSION_MAJOR) + "." + QString::number(CLIENT_VERSION_MINOR)+ "." + QString::number(CLIENT_VERSION_REVISION)+ "." + QString::number(CLIENT_VERSION_BUILD); - QString currentVersionStripped = currentVersion.remove(QChar('.'), Qt::CaseInsensitive); - reply->deleteLater(); - if(reply->error() == QNetworkReply::NoError) { - QByteArray data = reply->readAll(); - QString dataStream = data.trimmed(); - QString availableVersionStripped = dataStream.remove(QChar('.'), Qt::CaseInsensitive); - if (availableVersionStripped > currentVersionStripped) { - LogPrintf("Check For Updates: Update Available!\n"); - QMessageBox::StandardButton msgReply; - msgReply = QMessageBox::question(this, "Wallet Update Available!", "Wallet update available.\n\nWould you like to go to the GitHub Releases page to download v" + data.trimmed() + "?", QMessageBox::Yes|QMessageBox::No); - if (msgReply == QMessageBox::Yes) { - QDesktopServices::openUrl(QUrl("https://github.com/PRCYCoin/PRCYCoin/releases/latest")); + getHttpsJson("https://api.github.com/repos/prcycoin/prcycoin/releases/latest", gitReply, GITHUB_HEADERS); + checkForUpdatesFinished(isClicked); +} + +void BitcoinGUI::checkForUpdatesFinished(bool isClicked) +{ + if (!gitReply->failed && gitReply->complete) { + try { + QString currentVersion = QString("%1.%2.%3.%4").arg(CLIENT_VERSION_MAJOR).arg(CLIENT_VERSION_MINOR).arg(CLIENT_VERSION_REVISION).arg(CLIENT_VERSION_BUILD); + QString currentVersionStripped = currentVersion.replace(".", ""); + + QJsonDocument response = QJsonDocument::fromJson(gitReply->response.c_str()); + const QJsonObject jsonObject = response.object(); + QString gitStrVersion = jsonObject["tag_name"].toString(); + QString gitStrVersionStripped = gitStrVersion.replace(".", ""); + + QString gitStrName = jsonObject["name"].toString(); + bool isMandatory = gitStrName.contains("Mandatory", Qt::CaseInsensitive); + + if (gitStrVersionStripped > currentVersionStripped) { + LogPrintf("Check For Updates: Update Available!\n"); + + QString updateMessage = tr("Wallet update available.\n\nWould you like to go to the GitHub Releases page to download v") + gitStrVersion + "?"; + if (isMandatory) { + updateMessage.prepend(tr("Mandatory ")); + } + + QMessageBox::StandardButton msgReply = QMessageBox::question(this, + tr("Wallet Update Available!"), + updateMessage, + QMessageBox::Yes | QMessageBox::No); + + if (msgReply == QMessageBox::Yes) { + QDesktopServices::openUrl(QUrl("https://github.com/PRCYCoin/PRCYCoin/releases/latest")); + } else { + LogPrintf("Check For Updates: Update Available, but declined by user.\n"); + return; + } } else { - LogPrintf("Check For Updates: Update Available, but declined by user.\n"); - return; - } - } else { - LogPrintf("Check For Updates: No update available.\n"); - if (!isStartup) { - QMessageBox msgBox; - msgBox.setWindowTitle("No Update Available"); - msgBox.setText("No update available.\n\nYour wallet is up to date."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Information); - msgBox.exec(); + LogPrintf("Check For Updates: No update available.\n"); + if (isClicked) { + GUIUtil::showMessageBox(tr("No Update Available"), + tr("No update available.\n\nYour wallet is up to date."), + QMessageBox::Information); + } } + } catch (const std::exception& e) { + LogPrintf("Github Releases JSON Parsing error: %s\n", e.what()); } } else { LogPrintf("Check For Updates: Error!\n"); - QByteArray error = reply->readAll(); - QMessageBox msgBox; - msgBox.setWindowTitle("Error"); - msgBox.setText("Error checking for updates.\n\n" + error); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); + if (isClicked) { + QString error = gitReply->response.c_str(); + GUIUtil::showMessageBox(tr("Error"), + tr("Error checking for updates.\n\n") + error, + QMessageBox::Critical); + } } - isStartup = false; } #ifdef ENABLE_WALLET diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 98c686f2ff..357f939c2f 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -10,6 +10,7 @@ #endif #include "amount.h" +#include "curl_json.h" #include #include @@ -19,7 +20,6 @@ #include #include #include -#include class ClientModel; class NetworkStyle; @@ -71,7 +71,6 @@ class BitcoinGUI : public QMainWindow #endif // ENABLE_WALLET bool enableWallet; bool fMultiSend = false; - bool isStartup = true; protected: void changeEvent(QEvent* e); @@ -186,6 +185,8 @@ class BitcoinGUI : public QMainWindow /** Disconnect core signals from GUI client */ void unsubscribeFromCoreSignals(); + JsonDownload* gitReply; + Q_SIGNALS: /** Signal raised when a URI was entered or dragged to the GUI */ void receivedURI(const QString& uri); @@ -282,7 +283,8 @@ private Q_SLOTS: void openDexClicked(); void openToolkitClicked(); void checkForUpdatesClicked(); - void serviceRequestFinished(QNetworkReply* reply); + void checkForUpdates(bool isClicked = false); + void checkForUpdatesFinished(bool isClicked); #ifndef Q_OS_MAC /** Handle tray icon clicked */ void trayIconActivated(QSystemTrayIcon::ActivationReason reason); diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index 0e153196d4..c62ab1c13c 100644 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -215,11 +215,6 @@ QString ClientModel::formatFullVersion() const return QString::fromStdString(FormatFullVersion()); } -QString ClientModel::formatBuildDate() const -{ - return QString::fromStdString(CLIENT_DATE); -} - bool ClientModel::isReleaseVersion() const { return CLIENT_VERSION_IS_RELEASE; diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h index 3251cc2442..3bd6490de9 100644 --- a/src/qt/clientmodel.h +++ b/src/qt/clientmodel.h @@ -75,7 +75,6 @@ class ClientModel : public QObject QString getStatusBarWarnings() const; QString formatFullVersion() const; - QString formatBuildDate() const; bool isReleaseVersion() const; QString clientName() const; QString formatClientStartupTime() const; diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 096a332c55..3dc53985aa 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -231,11 +231,11 @@ void CoinControlDialog::buttonToggleLockClicked() CoinControlDialog::updateLabels(model, this); updateDialogLabels(); } else { - QMessageBox msgBox; - msgBox.setObjectName("lockMessageBox"); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setText(tr("Please switch to \"List mode\" to use this function.")); - msgBox.exec(); + GUIUtil::showMessageBox( + "lockMessageBox", + "", + tr("Please switch to \"List mode\" to use this function."), + QMessageBox::Warning); } } diff --git a/src/qt/encryptdialog.cpp b/src/qt/encryptdialog.cpp index 947e5f9e1d..cf8972f725 100644 --- a/src/qt/encryptdialog.cpp +++ b/src/qt/encryptdialog.cpp @@ -34,7 +34,7 @@ void EncryptDialog::setModel(WalletModel* model) void EncryptDialog::closeEvent (QCloseEvent *event) { QMessageBox::StandardButton reply; - reply = QMessageBox::warning(this, "Wallet Encryption Required", "There was no passphrase entered for the wallet.\n\nWallet encryption is required for the security of your funds.\n\nWhat would you like to do?", QMessageBox::Retry|QMessageBox::Close); + reply = QMessageBox::warning(this, tr("Wallet Encryption Required"), tr("There was no passphrase entered for the wallet.\n\nWallet encryption is required for the security of your funds.\n\nWhat would you like to do?"), QMessageBox::Retry|QMessageBox::Close); if (reply == QMessageBox::Retry) { event->ignore(); } else { @@ -45,7 +45,7 @@ void EncryptDialog::closeEvent (QCloseEvent *event) void EncryptDialog::on_btnCancel() { QMessageBox::StandardButton reply; - reply = QMessageBox::warning(this, "Wallet Encryption Required", "There was no passphrase entered for the wallet.\n\nWallet encryption is required for the security of your funds.\n\nWhat would you like to do?", QMessageBox::Retry|QMessageBox::Close); + reply = QMessageBox::warning(this, tr("Wallet Encryption Required"), tr("There was no passphrase entered for the wallet.\n\nWallet encryption is required for the security of your funds.\n\nWhat would you like to do?"), QMessageBox::Retry|QMessageBox::Close); if (reply == QMessageBox::Retry) { return; } else { @@ -63,66 +63,54 @@ void EncryptDialog::on_acceptPassphrase() { newPass2.assign(ui->linePwdConfirm->text().toStdString().c_str() ); if ( (!ui->linePwd->text().length()) || (!ui->linePwdConfirm->text().length()) ) { - QMessageBox msgBox; - msgBox.setWindowTitle("Wallet Encryption Failed"); - msgBox.setText("The passphrase entered for wallet encryption was empty. Please try again."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); - return; + GUIUtil::showMessageBox( + tr("Wallet Encryption Failed"), + tr("The passphrase entered for wallet encryption was empty. Please try again."), + QMessageBox::Critical); + return; } if (newPass == newPass2) { if (newPass.length() < 10) { - QMessageBox msgBox; - msgBox.setWindowTitle("Wallet Encryption Failed"); - msgBox.setText("The passphrase's length has to be more than 10. Please try again."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); + GUIUtil::showMessageBox( + tr("Wallet Encryption Failed"), + tr("The passphrase's length has to be more than 10. Please try again."), + QMessageBox::Critical); return; } if (!pwalletMain->checkPassPhraseRule(newPass.c_str())) { - QMessageBox msgBox; - msgBox.setWindowTitle("Wallet Encryption Failed"); - msgBox.setText("The passphrase must contain lower, upper, digit, symbol. Please try again."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); + GUIUtil::showMessageBox( + tr("Wallet Encryption Failed"), + tr("The passphrase must contain lower, upper, digit, symbol. Please try again."), + QMessageBox::Critical); return; } double guesses; int ret = zxcvbn_password_strength(newPass.c_str(), NULL, &guesses, NULL); if (ret < 0 || guesses < 10000) { - QMessageBox msgBox; - msgBox.setWindowTitle("Wallet Encryption Failed"); - msgBox.setText("The passphrases entered for wallet encryption is too weak. Please try again."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); + GUIUtil::showMessageBox( + tr("Wallet Encryption Failed"), + tr("The passphrases entered for wallet encryption is too weak. Please try again."), + QMessageBox::Critical); return; } if (model->setWalletEncrypted(true, newPass)) { pwalletMain->nTimeFirstKey = 1; model->setWalletLocked(false, newPass); - QMessageBox msgBox; - msgBox.setWindowTitle("Wallet Encryption Successful"); - msgBox.setText("Wallet passphrase was successfully set.\nPlease remember your passphrase as there is no way to recover it."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Information); - msgBox.exec(); + GUIUtil::showMessageBox( + tr("Wallet Encryption Successful"), + tr("Wallet passphrase was successfully set.\nPlease remember your passphrase as there is no way to recover it."), + QMessageBox::Information); accept(); } } else { - QMessageBox msgBox; - msgBox.setWindowTitle("Wallet Encryption Failed"); - msgBox.setText("The passphrases entered for wallet encryption do not match. Please try again."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); + GUIUtil::showMessageBox( + tr("Wallet Encryption Failed"), + tr("The passphrases entered for wallet encryption do not match. Please try again."), + QMessageBox::Critical); return; } } diff --git a/src/qt/entermnemonics.cpp b/src/qt/entermnemonics.cpp index fc921665c0..11ca7a0442 100644 --- a/src/qt/entermnemonics.cpp +++ b/src/qt/entermnemonics.cpp @@ -26,12 +26,12 @@ void EnterMnemonics::on_next() std::string phrase = ui->mnemonics->toPlainText().trimmed().toStdString(); try { pwalletMain->GenerateNewHDChain(&phrase); - QMessageBox::information(this, "Recovery Phrase Import Successful", "Your mnemonics have been successfully imported into the wallet. Rescanning will be scheduled to recover all your funds.", QMessageBox::Ok); + QMessageBox::information(this, tr("Recovery Phrase Import Successful"), tr("Your mnemonics have been successfully imported into the wallet. Rescanning will be scheduled to recover all your funds."), QMessageBox::Ok); CBlockLocator loc = chainActive.GetLocator(chainActive[0]); pwalletMain->SetBestChain(loc); CWalletDB(pwalletMain->strWalletFile).WriteScannedBlockHeight(0); //reschedule to rescan entire chain to recover all funds and history accept(); } catch (const std::exception& ex) { - QMessageBox::warning(this, "Recovery Phrase Invalid", "Recovery phrase is invalid. Please try again and double check all words.", QMessageBox::Ok); + QMessageBox::warning(this, tr("Recovery Phrase Invalid"), tr("Recovery phrase is invalid. Please try again and double check all words."), QMessageBox::Ok); } } diff --git a/src/qt/forms/openuridialog.ui b/src/qt/forms/openuridialog.ui index 114a363943..b202df6f6b 100644 --- a/src/qt/forms/openuridialog.ui +++ b/src/qt/forms/openuridialog.ui @@ -17,7 +17,7 @@ - Open payment request from URI or file + Open PRCYcoin URI @@ -33,19 +33,6 @@ - - - - Select payment request file - - - ... - - - false - - - diff --git a/src/qt/forms/revealtxdialog.ui b/src/qt/forms/revealtxdialog.ui index 51ae940796..620739e389 100644 --- a/src/qt/forms/revealtxdialog.ui +++ b/src/qt/forms/revealtxdialog.ui @@ -7,7 +7,7 @@ 0 0 750 - 290 + 402 @@ -15,333 +15,470 @@ - - - - - Copy transaction ID to clipboard - - - - - - - - - - - 83 - 0 - - - - TxId - - - - - - - - 0 - 0 - - - - - 415 - 0 - - - - - - - - - - - - - - - - - - - - - - Copy address to clipboard - - - - - - - - - - - 83 - 0 - - - - Address - - - - - - - - 0 - 0 - - - - - 415 - 0 - - - - - - - - - - - - - - - Copy transaction private key to clipboard - - - - - - - - - - - 83 - 0 - - - - PrivKey - - - - - - - - 0 - 0 - - - - - 415 - 0 - - - - - - - - - - - - - - - Copy Transaction Amount to clipboard - - - - - - - - - - - 83 - 0 - - - - Amount - - - - - - - - 0 - 0 - - - - - 415 - 0 - - - - - - - - - - - - - - - Copy Transaction Fee to clipboard - - - - - - - - - - - 83 - 0 - - - - Fee - - - - - - - - 0 - 0 - - - - - 415 - 0 - - - - - - - - + + + Transaction Details + + + + + + + + + 83 + 0 + + + + TXID: + + + + + + + + 0 + 0 + + + + + 415 + 0 + + + + + + + + + + + + + + + + + + Copy transaction ID to clipboard + + + + + + + + + + + + + + + 83 + 0 + + + + Address: + + + + + + + + 0 + 0 + + + + + 415 + 0 + + + + + + + + + + + Copy address to clipboard + + + + + + + + + + + + + + + 83 + 0 + + + + Private Key: + + + + + + + + 0 + 0 + + + + + 415 + 0 + + + + + + + + + + + Copy transaction private key to clipboard + + + + + + + + + + + + + + + 83 + 0 + + + + Amount: + + + + + + + + 0 + 0 + + + + + 415 + 0 + + + + + + + + + + + Copy Transaction Amount to clipboard + + + + + + + + + + + + + + + 83 + 0 + + + + Fee: + + + + + + + + 0 + 0 + + + + + 415 + 0 + + + + + + + + + + + Copy Transaction Fee to clipboard + + + + + + + + + + + + + + + 83 + 0 + + + + Ring Size: + + + + + + + + 0 + 0 + + + + + 415 + 0 + + + + + + + + + + + Copy Payment ID to clipboard + + + + + + + + + + + + + + + 83 + 0 + + + + Payment ID: + + + + + + + + 0 + 0 + + + + + 415 + 0 + + + + + + + + + + + Copy Payment ID to clipboard + + + + + + + + + + - - - - - Copy Payment ID to clipboard - - - - - - - - - - - 83 - 0 - - - - Ring Size - - - - - - - - 0 - 0 - - - - - 415 - 0 - - - - - - - - + + + In Block: + + + + + + + + + 83 + 0 + + + + Height: + + + + + + + + 0 + 0 + + + + + 415 + 0 + + + + + + + + + + + + + + + + + + Copy address to clipboard + + + + + + + + + + + + + + + 83 + 0 + + + + Hash: + + + + + + + + 0 + 0 + + + + + 415 + 0 + + + + + + + + + + + + + + + + + + Copy address to clipboard + + + + + + + + + + - - - - - Copy Payment ID to clipboard - - - - - - - - - - - 83 - 0 - - - - Payment ID - - - - - - - - 0 - 0 - - - - - 415 - 0 - - - - - - - - + + + Qt::Horizontal + + + + 40 + 20 + + + diff --git a/src/qt/forms/rpcconsole.ui b/src/qt/forms/rpcconsole.ui index 62bf34328f..41b24ed9aa 100644 --- a/src/qt/forms/rpcconsole.ui +++ b/src/qt/forms/rpcconsole.ui @@ -17,7 +17,7 @@ - 4 + 0 @@ -145,29 +145,6 @@ - - - - Build date - - - - - - - IBeamCursor - - - N/A - - - Qt::PlainText - - - Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse - - - diff --git a/src/qt/guiconstants.h b/src/qt/guiconstants.h index 5f26aead49..dd9183705b 100644 --- a/src/qt/guiconstants.h +++ b/src/qt/guiconstants.h @@ -52,7 +52,7 @@ static const int MAX_URI_LENGTH = 255; #define EXPORT_IMAGE_SIZE 256 /* Number of frames in spinner animation */ -#define SPINNER_FRAMES 35 +#define SPINNER_FRAMES 36 #define QAPP_ORG_NAME "PRCY" #define QAPP_ORG_DOMAIN "prcycoin.com" diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index ba5aaf1463..4c1c421c99 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -21,15 +21,6 @@ #include "util.h" #ifdef WIN32 -#ifdef _WIN32_WINNT -#undef _WIN32_WINNT -#endif -#define _WIN32_WINNT 0x0501 -#ifdef _WIN32_IE -#undef _WIN32_IE -#endif -#define _WIN32_IE 0x0501 -#define WIN32_LEAN_AND_MEAN 1 #ifndef NOMINMAX #define NOMINMAX #endif @@ -50,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -88,9 +80,7 @@ QString dateTimeStr(qint64 nTime) QFont bitcoinAddressFont() { - QFont font("Monospace"); - font.setStyleHint(QFont::Monospace); - return font; + return QFontDatabase::systemFont(QFontDatabase::FixedFont); } void setupAddressWidget(QValidatedLineEdit* widget, QWidget* parent) @@ -768,13 +758,22 @@ void setWindowless(QWidget* widget){ void disableTooltips(QWidget* widget){ } -void prompt(QString message){ - QMessageBox* errorPrompt = new QMessageBox(); - GUIUtil::setWindowless(errorPrompt); - errorPrompt->setStyleSheet(GUIUtil::loadStyleSheet()); - errorPrompt->setText(message); - errorPrompt->exec(); - errorPrompt->deleteLater(); +void showMessageBox(const QString& title, const QString& message, QMessageBox::Icon icon) { + showMessageBox("", title, message, icon); +} + +void showMessageBox(const QString& objectName, const QString& title, const QString& message, QMessageBox::Icon icon) { + QMessageBox* messageBox = new QMessageBox(); + if (!objectName.isEmpty()) { + messageBox->setObjectName(objectName); + } + //GUIUtil::setWindowless(messageBox); + messageBox->setStyleSheet(GUIUtil::loadStyleSheet()); + messageBox->setText(message); + messageBox->setIcon(icon); + messageBox->setWindowTitle(title); + messageBox->exec(); + messageBox->deleteLater(); } void colorCalendarWidgetWeekends(QCalendarWidget* widget, QColor color) diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h index b095bda3f3..a44e25ffe3 100644 --- a/src/qt/guiutil.h +++ b/src/qt/guiutil.h @@ -242,8 +242,9 @@ void disableTooltips(QWidget* widget); /** Check whether a theme is not build-in */ bool isExternal(QString theme); -//display a windowless prompt -void prompt(QString message); +/** Display styled MessageBox **/ +void showMessageBox(const QString& title, const QString& message, QMessageBox::Icon icon); +void showMessageBox(const QString& objectName, const QString& title, const QString& message, QMessageBox::Icon icon); /* Convert QString to OS specific boost path through UTF-8 */ fs::path qstringToBoostPath(const QString& path); diff --git a/src/qt/historypage.cpp b/src/qt/historypage.cpp index 2662aaee78..08c259f2c4 100644 --- a/src/qt/historypage.cpp +++ b/src/qt/historypage.cpp @@ -94,79 +94,101 @@ void HistoryPage::connectWidgets() //add functions to widget signals void HistoryPage::on_cellClicked(int row, int column) { if (pwalletMain->IsLocked()) return; - //1 is column index for type - QTableWidgetItem* cell = ui->tableView->item(row, 1); - QString type = cell->data(0).toString(); - std::string stdType = type.trimmed().toStdString(); - //2 is column index for address - cell = ui->tableView->item(row, 2); - QString address = cell->data(0).toString(); - //3 is column index for amount - cell = ui->tableView->item(row, 3); - QString amount = cell->data(0).toString(); - std::string stdAddress = address.trimmed().toStdString(); - if (pwalletMain->addrToTxHashMap.count(stdAddress) == 1) { - RevealTxDialog txdlg; - txdlg.setStyleSheet(GUIUtil::loadStyleSheet()); - - txdlg.setTxID(pwalletMain->addrToTxHashMap[stdAddress].c_str()); - - txdlg.setTxAddress(stdAddress.c_str()); - bool privkeyFound = false; - std::string txHash = pwalletMain->addrToTxHashMap[stdAddress]; - if (IsHex(txHash)) { - uint256 hash; - hash.SetHex(txHash); - - if (pwalletMain && pwalletMain->mapWallet.count(hash) == 1) { - CWalletTx tx = pwalletMain->mapWallet[hash]; - for (size_t i = 0; i < tx.vout.size(); i++) { - txnouttype type; - std::vector addresses; - int nRequired; - - if (ExtractDestinations(tx.vout[i].scriptPubKey, type, addresses, nRequired)) { - std::string parseddAddress = CBitcoinAddress(addresses[0]).ToString(); - if (stdAddress == parseddAddress) { - if (tx.IsCoinStake() && !tx.vout[i].txPriv.empty()) { - CKey txPriv; - txPriv.Set(tx.vout[i].txPriv.begin(), tx.vout[i].txPriv.end(), true); - txdlg.setTxPrivKey(CBitcoinSecret(txPriv).ToString().c_str()); + + // Get cell data and convert QString to std::string + std::string type = ui->tableView->item(row, 1)->data(0).toString().trimmed().toStdString(); + std::string address = ui->tableView->item(row, 2)->data(0).toString().trimmed().toStdString(); + + QTableWidgetItem* cell = ui->tableView->item(row, 3); //3 is column index for amount + QString amountQString = cell->data(0).toString(); + + // Remove any sequence of whitespace with a single space and remove spaces + amountQString = amountQString.simplified(); + amountQString.remove(' '); + + double amountDouble = amountQString.toDouble(); + CAmount amount = static_cast(amountDouble * COIN); + + // Check if address exists in the hash map + auto it = pwalletMain->addrToTxHashMap.find(address); + if (it == pwalletMain->addrToTxHashMap.end()) return; + + // Create transaction dialog + RevealTxDialog txdlg; + txdlg.setStyleSheet(GUIUtil::loadStyleSheet()); + txdlg.setTxID(it->second.c_str()); + txdlg.setTxAddress(address.c_str()); + + // Retrieve transaction details + bool privkeyFound = false; + std::string txHash = it->second; + if (IsHex(txHash)) { + uint256 hash; + hash.SetHex(txHash); + + if (pwalletMain && pwalletMain->mapWallet.count(hash) == 1) { + CWalletTx tx = pwalletMain->mapWallet[hash]; + for (size_t i = 0; i < tx.vout.size(); i++) { + txnouttype type; + std::vector addresses; + int nRequired; + + if (ExtractDestinations(tx.vout[i].scriptPubKey, type, addresses, nRequired)) { + std::string parsedAddress = CBitcoinAddress(addresses[0]).ToString(); + if (address == parsedAddress) { + if (tx.IsCoinStake() && !tx.vout[i].txPriv.empty()) { + CKey txPriv; + txPriv.Set(tx.vout[i].txPriv.begin(), tx.vout[i].txPriv.end(), true); + txdlg.setTxPrivKey(CBitcoinSecret(txPriv).ToString().c_str()); + privkeyFound = true; + } else { + std::string key = txHash + std::to_string(i); + std::string secret; + if (CWalletDB(pwalletMain->strWalletFile).ReadTxPrivateKey(key, secret)) { + txdlg.setTxPrivKey(secret.c_str()); privkeyFound = true; - } else { - std::string key = txHash + std::to_string(i); - std::string secret; - if (CWalletDB(pwalletMain->strWalletFile).ReadTxPrivateKey(key, secret)) { - txdlg.setTxPrivKey(secret.c_str()); - privkeyFound = true; - } } } } } - txdlg.setTxAmount(amount); - txdlg.setTxFee(tx.nTxFee); - if (tx.hasPaymentID) { - txdlg.setTxPaymentID(tx.paymentID); - } else { - txdlg.setTxPaymentID(0); - } - txdlg.setTxRingSize(tx.vin[0].decoys.size() + 1); } - } - std::string txdlgMsg = "Request from Sender (if applicable)"; - if (stdType == "Minted") { - privkeyFound = false; - txdlgMsg = "Minted transactions do not have a PrivKey"; - } - if (pwalletMain->IsLocked()) { - privkeyFound = false; - txdlgMsg = "Wallet must be unlocked to view PrivKey"; - } - if (!privkeyFound) txdlg.setTxPrivKey(std::string(txdlgMsg).c_str()); + txdlg.setTxAmount(amount); + txdlg.setTxFee(tx.nTxFee); + if (tx.hasPaymentID) { + txdlg.setTxPaymentID(tx.paymentID); + } else { + txdlg.setTxPaymentID(0); + } + txdlg.setTxRingSize(tx.vin[0].decoys.size() + 1); + + // Get block index object using block hash + BlockMap::iterator it = mapBlockIndex.find(tx.hashBlock); + if (it != mapBlockIndex.end()) { + CBlockIndex* pindex = it->second; - txdlg.exec(); + // Get block height + int blockHeight = pindex->nHeight; + txdlg.setBlockHeight(blockHeight); + + // Get block hash + uint256 blockHash = *pindex->phashBlock; + txdlg.setBlockHash(blockHash.ToString().c_str()); + } else { + txdlg.setBlockHeight(-1); + txdlg.setBlockHash("Not in block"); + } + } } + // Determine message to display in case private key is not found + std::string txdlgMsg = "Request from Sender (if applicable)"; + if (type == "Minted") { + privkeyFound = false; + txdlgMsg = "Minted transactions do not have a Private Key"; + } + if (!privkeyFound) txdlg.setTxPrivKey(std::string(txdlgMsg).c_str()); + + // Show dialog + txdlg.exec(); } void HistoryPage::resizeEvent(QResizeEvent* event) diff --git a/src/qt/locale/prcycoin_en.ts b/src/qt/locale/prcycoin_en.ts index 24998a3199..8baebf37df 100644 --- a/src/qt/locale/prcycoin_en.ts +++ b/src/qt/locale/prcycoin_en.ts @@ -119,9 +119,11 @@ Exporting Failed - + There was an error trying to save the address list to %1. Please try again. - There was an error trying to save the address list to %1. Please try again. + An error message. + %1 is a name of the file (e.g., "addrbook.csv") that the bitcoin addresses were exported to. + There was an error trying to save the address list to %1. Please try again. @@ -250,7 +252,58 @@ IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. - + + + + + Wallet Encryption Failed + + + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. Please try again. + + + + + + The supplied passphrases do not match. Please try again. + + + + + Wallet Unlock Failed + + + + + The passphrase entered for the wallet unlock was incorrect. Please try again. + + + + + Wallet Decryption Failed + + + + + + The passphrase entered for the wallet decryption was incorrect. Please try again. + + + + + Passphrase Change Successful + + + + + Wallet passphrase was successfully changed. +Please remember your passphrase as there is no way to recover it. + + + + Warning: The Caps Lock key is on! Warning: The Caps Lock key is on! @@ -519,7 +572,7 @@ Show information about Qt - + &Show / Hide &Show / Hide @@ -549,7 +602,7 @@ Backup wallet to another location - + &Change Passphrase... &Change Passphrase... @@ -723,18 +776,8 @@ PRivaCY Dex Link - - - &PRCY Checker - - - - - PRCY Checker Link - - - + %n Active Connections @@ -742,7 +785,7 @@ - + Processed %n blocks of transaction history. Processed %n block of transaction history. @@ -750,7 +793,7 @@ - + Date: %1 Amount: %2 Type: %3 @@ -760,18 +803,17 @@ Confirmations: %5 - + Staking Disabled - + Staking Enabled - Enabling Staking... @@ -781,12 +823,12 @@ Confirmations: %5 - + &File &File - + &Settings &Settings @@ -816,7 +858,7 @@ Confirmations: %5 - + &Staking @@ -826,12 +868,12 @@ Confirmations: %5 - + &Network &Network - + &Debug Console @@ -846,7 +888,7 @@ Confirmations: %5 - + &Tools &Tools @@ -856,12 +898,12 @@ Confirmations: %5 &Help - + PRCY - + &Masternodes @@ -881,7 +923,17 @@ Confirmations: %5 - + + &Show Seed Phrase + + + + + Show 24 word wallet seed phrase + + + + &MultiSend @@ -1026,7 +1078,17 @@ Confirmations: %5 - + + &PRCY Toolkit + + + + + PRCY Toolkit Link + + + + &Telegram Tech Support @@ -1066,17 +1128,36 @@ Confirmations: %5 - + Social - + PRCY client - + + No Update Available + + + + + No update available. + +Your wallet is up to date. + + + + + Error checking for updates. + + + + + + Up to date Up to date @@ -1134,18 +1215,18 @@ Confirmations: %5 Transactions after this will not yet be visible. - + Loading Blocks... - + Syncing Blocks... - + %n Blocks @@ -1153,7 +1234,8 @@ Confirmations: %5 - + + Error Error @@ -1183,7 +1265,7 @@ Confirmations: %5 - + No Active Peers @@ -1193,7 +1275,7 @@ Confirmations: %5 - + Wallet is <b>encrypted</b> and currently <b>unlocked</b> for staking only @@ -1213,7 +1295,7 @@ Confirmations: %5 Wallet is <b>encrypted</b> and currently <b>locked</b> - + A fatal error occurred. PRCY can no longer continue safely and will quit. @@ -1259,7 +1341,7 @@ Confirmations: %5 ClientModel - + Total: %1 (IPv4: %2 / IPv6: %3 / Tor: %4 / Unknown: %5) @@ -1377,7 +1459,7 @@ Confirmations: %5 Priority - + Copy address Copy address @@ -1699,6 +1781,67 @@ lowercase letters, numbers, symbols) Esc + + + + Wallet Encryption Required + + + + + + There was no passphrase entered for the wallet. + +Wallet encryption is required for the security of your funds. + +What would you like to do? + + + + + + + + + Wallet Encryption Failed + + + + + The passphrase entered for wallet encryption was empty. Please try again. + + + + + The passphrase's length has to be more than 10. Please try again. + + + + + The passphrase must contain lower, upper, digit, symbol. Please try again. + + + + + The passphrases entered for wallet encryption is too weak. Please try again. + + + + + Wallet Encryption Successful + + + + + Wallet passphrase was successfully set. +Please remember your passphrase as there is no way to recover it. + + + + + The passphrases entered for wallet encryption do not match. Please try again. + + EnterMnemonics @@ -1717,6 +1860,26 @@ lowercase letters, numbers, symbols) Next + + + Recovery Phrase Import Successful + + + + + Your mnemonics have been successfully imported into the wallet. Rescanning will be scheduled to recover all your funds. + + + + + Recovery Phrase Invalid + + + + + Recovery phrase is invalid. Please try again and double check all words. + + FreespaceChecker @@ -1795,12 +1958,12 @@ lowercase letters, numbers, symbols) - + Show splash screen on startup (default: %u) - + Set language, for example "de_DE" (default: system locale) Set language, for example "de_DE" (default: system locale) @@ -1809,11 +1972,6 @@ lowercase letters, numbers, symbols) Start minimized Start minimized - - - Set SSL root certificates for payment request (default: -system-) - Set SSL root certificates for payment request (default: -system-) - HistoryPage @@ -1824,7 +1982,7 @@ lowercase letters, numbers, symbols) - + All Types @@ -1832,50 +1990,59 @@ lowercase letters, numbers, symbols) - + Sent Sent - + - + Received Received - + - + + Mined Mined - + - + + Minted - + - + + Masternode - + - + Payment to yourself Payment to yourself + + + + Rewards + + Min Amount @@ -2275,25 +2442,10 @@ Please check the address and try again. Open URI - - Open payment request from URI or file - Open payment request from URI or file - - - + URI: URI: - - - Select payment request file - Select payment request file - - - - Select payment request file to open - Select payment request file to open - OptionsDialog @@ -2561,7 +2713,7 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translations&Cancel - + default default @@ -2633,7 +2785,7 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translations - + Backup Wallet Backup Wallet @@ -2682,6 +2834,11 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translationsRequest authentication code before sending any transactions + + + Request passphrase before sending any transactions + + Change current passphrase @@ -2724,7 +2881,7 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translations - Enabling this will incur a minimum 1 PRCY fee each time you receive a new deposit that needs to be consolidated for staking. + Enabling this will incur a maximum 0.1 PRCY fee each time you receive a new deposit that needs to be consolidated for staking. @@ -2843,12 +3000,12 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translations - + Two Factor Authentication - + Remember my authentication code for @@ -2873,215 +3030,379 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translations - - Wallet Data (*.dat) - Wallet Data (*.dat) + + Reserve Balance Empty + - - Copy + + PRCY reserve amount is empty and must be a minimum of 1. +Please click Disable if you would like to turn it off. + + + + + Invalid Reserve Amount - OK + The amount you have attempted to keep as spendable is greater than the %1 (%2M) limit. Please try a smaller amount. - - - OverviewPage - - Form - Form + + Reserve Balance Set + - - Blocks + + Reserve balance of %1 PRCY is successfully set. - - - ??? + + Reserve Balance Disabled - - of + + Reserve balance disabled. - - (loading) + + + + + + + Wallet Encryption Failed - - Balance + + The passphrase entered for wallet encryption was empty or contained spaces. Please try again. - - Your current balance + + The passphrase you have entered is the same as your old passphrase. Please use a different passphrase if you would like to change it. - - Your current spendable balance - Your current spendable balance + + The passphrase's length has to be more than 10. Please try again. + - - Pending: - Pending: + + The passphrase must contain lower, upper, digit, symbol. Please try again. + - - Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance - Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance + + The passphrase is too weak. You must use a minimum passphrase length of 10 characters and use uppercase letters, lowercase letters, numbers, and symbols. Please try again. + - - (syncing) + + Passphrase Change Successful - - - Recent Transactions + + Wallet passphrase was successfully changed. +Please remember your passphrase as there is no way to recover it. - - It is advised not to send or receive coins until your current sync is complete. + + The passphrases entered for wallet encryption do not match. Please try again. - - Spendable: - Spendable: + + Wallet Data (*.dat) + Wallet Data (*.dat) - - - + + Wallet has been successfully backed up to + - - - PaymentServer - - - - - - - Payment request error - Payment request error + + Wallet Backup Successful + - - - URI handling - URI handling + + Wallet Backup Failed + - - Payment request file handling - Payment request file handling + + Wallet backup failed. Please try again. + - - Invalid payment address %1 - Invalid payment address %1 + + Staking Disabled - Syncing Masternode list + - - Cannot start prcycoin: click-to-pay handler + + Enable Staking is disabled when you are still syncing the Masternode list as this is required. Please allow the wallet to fully sync this list before attempting to Enable Staking. - - URI cannot be parsed! This can be caused by an invalid PRCY address or malformed URI parameters. + + Staking Setting - - Payment request file cannot be read! This can be caused by an invalid payment request file. - Payment request file cannot be read! This can be caused by an invalid payment request file. + + + + Please unlock the wallet with your passphrase before changing this setting. + - - - - Payment request rejected - Payment request rejected + + PoW blocks are still being mined. +Please wait until Block %1. + - - Payment request network doesn't match client network. - Payment request network doesn't match client network. + + + Information + Information - - Payment request has expired. - Payment request has expired. + + Your stakeable balance is under the threshold of %1 PRCY. Please deposit more PRCY into your account in order to enable staking. + + + + + Your balance requires a consolidation transaction which incurs a fee of between %1 to %2 PRCY. However after that transaction fee, your balance will be below the staking threshold of %3 PRCY. Please deposit more PRCY into your account or reduce your reserved amount in order to enable staking. + + + + + Your stakeable balance is under the threshold of %1 PRCY. This is due to your reserve balance being too high. Please deposit more PRCY into your account or reduce your reserved amount in order to enable staking. + + + + + Your stakeable balance is under the threshold of %1 PRCY. This is due to your reserve balance of %2 PRCY being too high. The wallet software has tried to consolidate your funds with the reserve balance but without success because of a consolidation fee of %3 PRCY. Please wait around 10 minutes for the wallet to resolve the reserve to enable staking. + - Payment request is not initialized. - Payment request is not initialized. + Warning: Staking Issue + - - Unverified payment requests to custom payment scripts are unsupported. - Unverified payment requests to custom payment scripts are unsupported. + + In order to enable staking with 100%% of your current balance, your previous PRCY deposits must be consolidated and reorganized. This will incur a fee of between %1 to %2 PRCY. + +Would you like to do this? + - - Requested payment amount of %1 is too small (considered dust). - Requested payment amount of %1 is too small (considered dust). + + In order to enable staking with 100%% of your current balance except the reserve balance, your previous PRCY deposits must be consolidated and reorganized. This will incur a fee of between %1 to %2 PRCY. + +Would you like to do this? + + + + + Staking Needs Consolidation + + + + + Consolidation transaction created! + + + + + 2FA Setting + - Refund from %1 - Refund from %1 + SUCCESS! + - - Payment request %1 is too large (%2 bytes, allowed %3 bytes). - Payment request %1 is too large (%2 bytes, allowed %3 bytes). + + Two-factor authentication has been successfully enabled. + + + + + UPNP Settings + + + + + UPNP Settings successfully changed. Please restart the wallet for changes to take effect. + + + + + + 2FA Digit Settings + + + + + 2FA Digit Settings have been changed successfully. + - Payment request DoS protection - Payment request DoS protection + 2FA Digit Settings have not been changed. + - - Error communicating with %1: %2 - Error communicating with %1: %2 + + Hide Balance When Unlocked + - - Payment request cannot be parsed! - Payment request cannot be parsed! + + Attempt to Disable 'Hide Balance when unlocked' failed or canceled. Wallet Locked for security. + - - Bad response from server %1 - Bad response from server %1 + + Lock Send Tab When Unlocked + - - Network request error - Network request error + + Attempt to Disable 'Lock Send Tab when unlocked' failed or canceled. Wallet Locked for security. + - - Payment acknowledged - Payment acknowledged + + Password Locked Setting + + + + + OverviewPage + + + Form + Form + + + + Blocks + + + + + + ??? + + + + + of + + + + + (loading) + + + + + Balance + + + + + Your current balance + + + + + Your current spendable balance + Your current spendable balance + + + + Pending: + Pending: + + + + Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance + Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance + + + + (syncing) + + + + + + Recent Transactions + + + + + It is advised not to send or receive coins until your current sync is complete. + + + + + Spendable: + Spendable: + + + + + + + + + PaymentServer + + + Payment request error + Payment request error + + + + + URI handling + URI handling + + + + Invalid payment address %1 + Invalid payment address %1 + + + + Cannot start prcycoin: click-to-pay handler + + + + + URI cannot be parsed! This can be caused by an invalid PRCY address or malformed URI parameters. + @@ -3125,7 +3446,7 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translationsAmount - + %1 d %1 d @@ -3196,7 +3517,7 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translations%1 GB - + @@ -3265,35 +3586,34 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translations&Information - + General General - + Name Name - + Client name Client name - - + + - - + @@ -3310,12 +3630,14 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translations - + + + N/A N/A - + Number of connections Number of connections @@ -3350,22 +3672,17 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translationsDebug log file - + Using OpenSSL version Using OpenSSL version - - Build date - Build date - - - + Current number of blocks Current number of blocks - + Client version Client version @@ -3375,7 +3692,7 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translationsUsing BerkeleyDB version - + Open the PRCY debug log file from the current data directory. This can take a few seconds for large log files. @@ -3385,7 +3702,7 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translationsNumber of Masternodes - + &Console &Console @@ -3410,12 +3727,12 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translationsTotals - + Received Received - + Sent Sent @@ -3431,8 +3748,8 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translations - - + + Select a peer to view detailed information. Select a peer to view detailed information. @@ -3517,47 +3834,57 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translations&Wallet Repair - - Rebuild block chain index from current blk000??.dat files. + + The buttons below will restart the wallet with command-line options to repair the wallet, fix issues with corrupt blockhain files or missing/obsolete transactions. - - The buttons below will restart the wallet with command-line options to repair the wallet, fix issues with corrupt blockchain files or missing/obsolete transactions. + + Custom Backup Path: - + + Custom Backups Threshold: + + + + + Rebuild block chain index from current blk000??.dat files. + + + + Wallet In Use: - + Salvage wallet Salvage wallet - + Attempt to recover private keys from a corrupt wallet.dat. - + Rescan blockchain files Rescan blockchain files - + Recover transactions 1 Recover transactions 1 - + Recover transactions from blockchain (keep meta-data, e.g. account owner). - + Data Directory @@ -3567,42 +3894,42 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translations - + Recover transactions 2 Recover transactions 2 - + Rescan the block chain for missing wallet transactions. - + Recover transactions from blockchain (drop meta-data). - + Upgrade wallet format Upgrade wallet format - + -resync: - + Delete local Blockchain Folders - + Deletes all local blockchain folders so the wallet synchronizes from scratch. - + Starting Block @@ -3617,22 +3944,22 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translations - + Wallet repair options. Wallet repair options. - + Upgrade wallet to latest format on startup. (Note: this is NOT an update of the wallet itself!) - + Rebuild index Rebuild index - + In: In: @@ -3647,7 +3974,7 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translations - + &Disconnect Node @@ -3685,7 +4012,7 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translations - + This will delete your local blockchain folders and the wallet will synchronize the complete Blockchain from scratch.<br /><br /> @@ -3863,7 +4190,17 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translationsCopy address - + + Invalid Amount + + + + + Invalid amount entered. Please enter an amount less than %1 (%2M) PRCY. + + + + Enter Label @@ -3945,73 +4282,156 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translationsRevealTxDialog + Transaction Details - + + TXID: + + + + Copy transaction ID to clipboard - - TxId + + Address: - + + Private Key: + + + + + Amount: + Amount: + + + + Fee: + Fee: + + + + Ring Size: + + + + + Payment ID: + + + + + In Block: + + + + + Height: + + + + + Hash: + + + + + + Copy address to clipboard - - Address - Address + + Copy transaction private key to clipboard + + + + + Copy Transaction Amount to clipboard + + + + + Copy Transaction Fee to clipboard + + + + + + Copy Payment ID to clipboard + + + + + Are You Sure? + + + + + Are you sure you would like to delete this transaction from the local wallet? + +Note: They can only be restored from backup or rescan. + + + + + Potential Masternode Collateral Detected! + - - Copy transaction private key to clipboard + + Potential Masternode Collateral Detected! +Are you sure? + +Note: They can only be restored from backup or rescan. - - PrivKey + + Invalid or non-wallet transaction id - - Copy Transaction Amount to clipboard + + Invalid or non-wallet transaction id. - - Amount - Amount + + Unable to delete transaction id + - - Copy Transaction Fee to clipboard + + Unable to delete transaction id. - - Fee + + Do not show successful confirmation again - - - Copy Payment ID to clipboard + + OK - - Ring Size + + Success! - - Payment ID + + Transaction ID successfully deleted. @@ -4188,7 +4608,37 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translationsCopy change - + + Send Disabled - Syncing + + + + + Sending PRCY is disabled when you are still syncing the wallet. Please allow the wallet to fully sync before attempting to send a transaction. + + + + + Invalid Address + + + + + Invalid address entered. Please make sure you are sending to a Stealth Address. + + + + + Invalid Amount + + + + + Invalid amount entered. Please enter an amount less than your Spendable Balance. + + + + Destination @@ -4213,7 +4663,59 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translations - + + Insufficient Spendable Funds! + + + + + Insufficient spendable funds. Send with smaller amount or wait for your coins become mature + + + + + Insufficient Reserve Funds! + + + + + Insufficient reserve funds. Send with smaller amount or turn off staking mode. + + + + + Information + Information + + + + Consolidation transaction created! + + + + + + Sweeping Transaction Creation Error + + + + + + Sweeping transaction creation failed due to an internal error. Please try again later. + + + + + Unable to create transaction. Please try again later. + + + + + Transaction Creation Error + + + + View on Explorer @@ -4228,7 +4730,7 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translations - + Warning: Invalid PIVX address @@ -4310,6 +4812,16 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translationsMemo: Memo: + + + Invalid Amount + + + + + Invalid amount entered. Please enter an amount less than %1 (%2M) PRCY. + + ShutdownWindow @@ -4557,7 +5069,7 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translations TrafficGraphWidget - + KB/s KB/s @@ -4714,12 +5226,12 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translations - + Credit Credit - + matures in %n more block(s) matures in %n more block @@ -4734,12 +5246,12 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translations - + Debit Debit - + Total debit Total debit @@ -4780,12 +5292,7 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translations - - Merchant - Merchant - - - + Generated coins must mature %1 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to "not accepted" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours. Generated coins must mature %1 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to "not accepted" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours. @@ -4921,12 +5428,12 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translationsReceived from - + Confirmed Count. - + Sent to Sent to @@ -4951,7 +5458,7 @@ https://www.transifex.com/prcycoin-project/prcycoin-project-translationsMined - + watch-only watch-only @@ -5393,10 +5900,49 @@ Please try again. WalletModel - + Send Coins Send Coins + + + + + Mnemonic Recovery Phrase + + + + + + Attempt to view Mnemonic Phrase failed or canceled. Wallet locked for security. + + + + + Are You Sure? + + + + + Are you sure you would like to view your Mnemonic Phrase? +You will be required to enter your passphrase. Failed or canceled attempts will be logged. + + + + + Copy + + + + + OK + + + + + Below is your Mnemonic Recovery Phrase, consisting of 24 seed words. Please copy/write these words down in order. We strongly recommend keeping multiple copies in different locations. + + WalletView @@ -5479,12 +6025,12 @@ Please try again. Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup - + Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. - + Enter regression test mode, which uses a special chain in which blocks can be solved instantly. Enter regression test mode, which uses a special chain in which blocks can be solved instantly. @@ -5559,12 +6105,12 @@ Please try again. Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u) - + Maximum size of data in data carrier transactions we relay and mine (default: %u) Maximum size of data in data carrier transactions we relay and mine (default: %u) - + Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s) Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s) @@ -5645,16 +6191,16 @@ Please try again. - Unable to locate enough funds for this transaction that are not equal 10000 PRCY. - - - - Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) + Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times + + + + Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction. Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction. @@ -5843,6 +6389,11 @@ Please try again. Done loading Done loading + + + Enable Old Transaction Deletion + + Enable publish hash transaction (locked via SwiftX) in <address> @@ -5893,11 +6444,6 @@ Please try again. Error reading from database, shutting down. Error reading from database, shutting down. - - - Error recovering public key. - Error recovering public key. - Error @@ -5919,17 +6465,17 @@ Please try again. Error: Unsupported argument -tor found, use -onion. - - Failed to listen on any port. Use -listen=0 if you want this. - Failed to listen on any port. Use -listen=0 if you want this. + + Failed to generate RingCT + - Failed to read block - Failed to read block + Failed to listen on any port. Use -listen=0 if you want this. + Failed to listen on any port. Use -listen=0 if you want this. - + Force safe mode (default: %u) Force safe mode (default: %u) @@ -6009,27 +6555,22 @@ Please try again. Invalid netmask specified in -whitelist: '%s' - - Invalid private key. - Invalid private key. - - - + Reindex the %s money supply statistics - + SwiftX options: - + This is a pre-release test build - use at your own risk - do not use for staking or merchant applications! - + Accept connections from outside (default: 1 if no -proxy or -connect/-noconnect) @@ -6039,10 +6580,20 @@ Please try again. - + + Delete transaction every <n> blocks during inital block download (default: %i) + + + + Enable SwiftX, show confirmations for locked transactions (bool, default: %s) + + + Enable or disable staking functionality for PRCY inputs (0-1, default: %u) + + Error: The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. @@ -6064,7 +6615,17 @@ Please try again. - + + Maximum average size of an index occurrence in the block spam filter (default: %u) + + + + + Maximum size of the list of indexes in the block spam filter (default: %u) + + + + Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect/-noconnect) @@ -6084,7 +6645,7 @@ Please try again. - + You have attempted to send more than 50 UTXOs in a single transaction. To work around this limitation, please either lower the total amount of the transaction or send two separate transactions with 50% of your total desired amount. @@ -6189,7 +6750,7 @@ Please try again. - + Enable publish hash block in <address> @@ -6229,7 +6790,7 @@ Please try again. - + Error: -listen must be true if -masternode is set. @@ -6244,17 +6805,7 @@ Please try again. - - Failed to generate RingCT for Sweeping transaction - - - - - Failed to generate bulletproof for Sweeping transaction - - - - + Failed to generate bulletproof @@ -6264,7 +6815,7 @@ Please try again. - + Fee (in %s/kB) to add to transactions you send (default: %s) @@ -6294,17 +6845,12 @@ Please try again. - + Keep at most <n> unconnectable transactions in memory (default: %u) Keep at most <n> unconnectable transactions in memory (default: %u) - - Limit size of signature cache to <n> entries (default: %u) - Limit size of signature cache to <n> entries (default: %u) - - - + Line: %d Line: %d @@ -6404,7 +6950,7 @@ Please try again. Number of automatic wallet backups (default: 10) - + Only accept block chain matching built-in checkpoints (default: %u) Only accept block chain matching built-in checkpoints (default: %u) @@ -6498,11 +7044,6 @@ Please try again. Send transactions as zero-fee transactions if possible (default: %u) Send transactions as zero-fee transactions if possible (default: %u) - - - Session timed out. - Session timed out. - Set database cache size in megabytes (%d to %d, default: %d) @@ -6559,17 +7100,27 @@ Please try again. Shrink debug.log file on client startup (default: 1 when no -debug) - - Signing failed. - Signing failed. + + Keep the last <n> transactions (default: %i) + - Signing timed out. - Signing timed out. + Keep transactions for at least <n> blocks (default: %i) + + Limit size of signature cache to <n> MiB (default: %u) + + + + + Number of custom location backups to retain (default: %d) + + + + Signing transaction failed Signing transaction failed @@ -6748,6 +7299,11 @@ Please try again. Use a custom max chain reorganization depth (default: %u) + + + Use block spam filter (default: %u) + + Use the test network diff --git a/src/qt/locale/prcycoin_en.xlf b/src/qt/locale/prcycoin_en.xlf new file mode 100644 index 0000000000..5fd34b9152 --- /dev/null +++ b/src/qt/locale/prcycoin_en.xlf @@ -0,0 +1,7591 @@ + + + + + + Right-click to edit address or label + Right-click to edit address or label + 67 + + + Create a new address + Create a new address + 94 + + + &New + &New + 97 + + + Copy the currently selected address to the system clipboard + Copy the currently selected address to the system clipboard + 111 + + + &Copy + &Copy + 114 + + + Delete the currently selected address from the list + Delete the currently selected address from the list + 128 + + + &Delete + &Delete + 131 + + + Export the data in the current tab to a file + Export the data in the current tab to a file + 158 + + + &Export + &Export + 161 + + + C&lose + C&lose + 181 + + + + + + + Choose the address to send coins to + Choose the address to send coins to + 44 + + + Choose the address to receive coins with + Choose the address to receive coins with + 47 + + + C&hoose + C&hoose + 53 + + + Sending addresses + Sending addresses + 59 + + + Receiving addresses + Receiving addresses + 62 + + + These are your PRCY addresses for sending payments. Always check the amount and the receiving address before sending coins. + + 69 + + + These are your PRCY addresses for receiving payments. It is recommended to use a new receiving address for each transaction. + + 73 + + + &Copy Address + &Copy Address + 79 + + + Copy &Label + Copy &Label + 80 + + + &Edit + &Edit + 81 + + + Export Address List + Export Address List + 263 + + + Comma separated file (*.csv) + Comma separated file (*.csv) + 264 + + + Exporting Failed + Exporting Failed + 277 + + + There was an error trying to save the address list to %1. Please try again. + There was an error trying to save the address list to %1. Please try again. + 279 + An error message. + %1 is a name of the file (e.g., "addrbook.csv") that the bitcoin addresses were exported to. + + + + + + + Label + Label + 169 + + + Address + Address + 169 + + + (no label) + (no label) + 202 + + + + + + + Passphrase Dialog + Passphrase Dialog + 26 + + + Enter passphrase + Enter passphrase + 56 + + + New passphrase + New passphrase + 70 + + + Repeat new passphrase + Repeat new passphrase + 84 + + + Serves to disable the trivial sendmoney when OS account compromised. Provides no real security. + Serves to disable the trivial sendmoney when OS account compromised. Provides no real security. + 120 + + + For staking only + + 123 + + + Show passphrase + + 130 + + + + + + + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. + Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>. + 46 + + + This operation needs your wallet passphrase to decrypt the wallet. + This operation needs your wallet passphrase to decrypt the wallet. + 64 + + + Enter the old and new passphrase to the wallet. + Enter the old and new passphrase to the wallet. + 73 + + + Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR COINS</b>! + + 127 + + + PRCY will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your PRCYs from being stolen by malware infecting your computer. + + 135 + + + Are you sure you wish to encrypt your wallet? + Are you sure you wish to encrypt your wallet? + 127 + + + Encrypt Wallet + + 49 + + + This operation needs your wallet passphrase to unlock the wallet.<br/><br/>(Wallet may appear not responding as it rescans for all transactions)<br/><br/> + + 55 + + + Unlock Wallet + + 61 + + + Decrypt Wallet + + 69 + + + Change Passphrase + + 72 + + + Confirm Wallet Encryption + + 126 + + + Wallet Encrypted + + 133 + + + IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. + IMPORTANT: Any previous backups you have made of your wallet file should be replaced with the newly generated, encrypted wallet file. For security reasons, previous backups of the unencrypted wallet file will become useless as soon as you start using the new, encrypted wallet. + 139 + + + Wallet Encryption Failed + + 147 + 154 + 193 + 199 + + + Wallet encryption failed due to an internal error. Your wallet was not encrypted. Please try again. + + 148 + + + The supplied passphrases do not match. Please try again. + + 155 + 200 + + + Wallet Unlock Failed + + 166 + + + The passphrase entered for the wallet unlock was incorrect. Please try again. + + 167 + + + Wallet Decryption Failed + + 176 + + + The passphrase entered for the wallet decryption was incorrect. Please try again. + + 177 + 194 + + + Passphrase Change Successful + + 187 + + + Wallet passphrase was successfully changed. +Please remember your passphrase as there is no way to recover it. + + 188 + + + Warning: The Caps Lock key is on! + Warning: The Caps Lock key is on! + 236 + 260 + + + + + + + IP/Netmask + + 90 + + + Banned Until + + 90 + + + + + + + BIP 38 Tool + + 14 + + + &BIP 38 Encrypt + + 27 + + + Address: + + 57 + 457 + + + Enter a PRCY Address that you would like to encrypt using BIP 38. Enter a passphrase in the middle box. Press encrypt to compute the encrypted private key. + + 33 + + + The PRCY address to encrypt + + 64 + + + Choose previously used address + Choose previously used address + 71 + + + Alt+A + Alt+A + 81 + + + Paste address from clipboard + Paste address from clipboard + 88 + 308 + + + Alt+P + Alt+P + 98 + 318 + + + Passphrase: + + 118 + 338 + + + Encrypted Key: + + 145 + 294 + + + Copy the current signature to the system clipboard + Copy the current signature to the system clipboard + 167 + + + Encrypt the private key for this PRCY address + + 185 + + + Reset all fields + + 202 + 373 + + + The encrypted private key + + 301 + + + Decrypt the entered key using the passphrase + + 356 + + + Encrypt &Key + + 188 + + + Clear &All + Clear &All + 205 + 376 + + + &BIP 38 Decrypt + + 264 + + + Enter the BIP 38 encrypted private key. Enter the passphrase in the middle box. Click Decrypt Key to compute the private key. After the key is decrypted, clicking 'Import Address' will add this private key to the wallet. + + 270 + + + Decrypt &Key + + 359 + + + Decrypted Key: + + 436 + + + Import Address + + 450 + + + + + + + Click "Decrypt Key" to compute key + + 32 + + + The entered passphrase is invalid. + + 121 + + + Allowed: 0-9,a-z,A-Z, + + 121 + + + The entered address is invalid. + The entered address is invalid. + 128 + + + Please check the address and try again. + Please check the address and try again. + 128 + 136 + + + The entered address does not refer to a key. + The entered address does not refer to a key. + 136 + + + Wallet unlock was cancelled. + Wallet unlock was cancelled. + 143 + 206 + + + Private key for the entered address is not available. + Private key for the entered address is not available. + 150 + + + Failed to decrypt. + + 189 + + + Please check the key and passphrase and try again. + + 189 + + + Data Not Valid. + + 215 + + + Please try again. + + 215 + + + Please wait while key is imported + + 222 + + + Key Already Held By Wallet + + 230 + + + Error Adding Key To Wallet + + 238 + + + Successfully Added Private Key To Wallet + + 248 + + + + + + + Node + Node + 137 + + + &Overview + &Overview + 281 + + + &Send + &Send + 293 + + + &Receive + &Receive + 304 + + + E&xit + E&xit + 355 + + + Quit application + Quit application + 356 + + + About &Qt + About &Qt + 362 + + + Show information about Qt + Show information about Qt + 363 + + + &Show / Hide + &Show / Hide + 396 + + + Show or hide the main Window + Show or hide the main Window + 397 + + + &Encrypt Wallet... + &Encrypt Wallet... + 399 + + + Encrypt the private keys that belong to your wallet + Encrypt the private keys that belong to your wallet + 400 + + + &Backup Wallet... + &Backup Wallet... + 402 + + + Backup wallet to another location + Backup wallet to another location + 403 + + + &Change Passphrase... + &Change Passphrase... + 406 + + + Change the passphrase used for wallet encryption + Change the passphrase used for wallet encryption + 407 + + + &Unlock Wallet... + &Unlock Wallet... + 408 + + + Unlock wallet + Unlock wallet + 409 + + + &Lock Wallet + &Lock Wallet + 410 + + + &Information + &Information + 415 + + + Show diagnostic information + Show diagnostic information + 416 + + + Open debugging console + Open debugging console + 418 + + + &Network Monitor + &Network Monitor + 420 + + + Show network monitor + Show network monitor + 421 + + + Show peers info + Show peers info + 423 + + + Wallet &Repair + Wallet &Repair + 424 + + + Show wallet repair options + Show wallet repair options + 425 + + + Open configuration file + Open configuration file + 427 + + + Show &PRCYcoin Folder + + 432 + + + Show the PRCYcoin folder + + 433 + + + Show &Qt Folder + + 435 + + + Show the Qt folder + + 436 + + + Show Automatic &Backups + Show Automatic &Backups + 438 + + + Show automatically created wallet backups + Show automatically created wallet backups + 439 + + + &Sending addresses... + &Sending addresses... + 441 + + + Show the list of used sending addresses and labels + Show the list of used sending addresses and labels + 442 + + + &Receiving addresses... + &Receiving addresses... + 443 + + + Show the list of used receiving addresses and labels + Show the list of used receiving addresses and labels + 444 + + + Open &URI... + Open &URI... + 446 + + + &Knowledge Base + + 475 + + + Knowledge Base + + 476 + + + &GitHub Wiki + + 477 + + + GitHub Wiki + + 478 + + + &Blockchain Explorer API + + 479 + + + Blockchain Explorer API + + 480 + + + &Bridge + + 483 + + + Bridge Link + + 484 + + + &PRivaCY DEX + + 485 + + + PRivaCY Dex Link + + 486 + + + 1130 + + %n Active Connections + + + + %n Active Connections + + + + + 1149 + + Processed %n blocks of transaction history. + Processed %n block of transaction history. + + + Processed %n blocks of transaction history. + Processed %n blocks of transaction history. + + + + Date: %1 +Amount: %2 +Type: %3 +Address: %4 +Confirmations: %5 + + + 1321 + + + Staking Disabled + + 1370 + + + Staking Enabled + + 1397 + + + Enabling Staking... + + 1407 + + + Disabling Staking... + + 1411 + + + &File + &File + 551 + + + &Settings + &Settings + 365 + + + PRivaCY Coin + + 126 + + + Wallet + + 135 + + + &History + + 315 + + + Masternodes + + 329 + + + Modify settings + + 367 + + + &Staking + + 379 + + + Staking Status + + 380 + + + &Network + &Network + 386 + + + &Debug Console + + 417 + + + &Peers List + + 422 + + + &Blockchain Explorer + + 448 + + + &Tools + &Tools + 579 + + + &Help + &Help + 605 + + + PRCY + + 1230 + + + &Masternodes + + 327 + + + - Lite Mode + + 140 + + + &About PRCY + + 359 + + + Show information about PRCY + + 360 + + + &Show Seed Phrase + + 404 + + + Show 24 word wallet seed phrase + + 405 + + + &MultiSend + + 411 + + + MultiSend Settings + + 412 + + + Open Wallet &Configuration File + + 426 + + + Open &Masternode Configuration File + + 429 + + + Open Masternode configuration file + + 430 + + + Open a PRCY: URI or payment request + + 447 + + + Block explorer window + + 449 + + + Facebook + + 451 + + + PRCY Facebook + + 452 + + + Twitter + + 453 + + + PRCY Twitter + + 454 + + + Discord + + 455 + + + PRCY Discord + + 456 + + + Telegram - Main + + 457 + + + PRCY Telegram - Main + + 458 + + + Telegram - Lounge + + 459 + + + PRCY Telegram - Lounge + + 460 + + + Medium + + 461 + + + PRCY Medium + + 462 + + + Steemit + + 463 + + + PRCY Steemit + + 464 + + + Instagram + + 465 + + + PRCY Instagram + + 466 + + + Reddit + + 467 + + + PRCY Reddit + + 468 + + + &Command-line Options + + 470 + + + Show the PRCY help message to get a list with possible PRCY command-line options + + 472 + + + &BootStrap + + 481 + + + BootStrap Link + + 482 + + + &PRCY Toolkit + + 487 + + + PRCY Toolkit Link + + 488 + + + &Telegram Tech Support + + 489 + + + Telegram Tech Support + + 490 + + + &Telegram Masternode Support + + 491 + + + Telegram Masternode Support + + 492 + + + &Discord Tech Support + + 493 + + + Discord Tech Support + + 494 + + + &Check For Updates + + 495 + + + Check For Updates + + 496 + + + Social + + 594 + + + PRCY client + + 794 + + + No Update Available + + 1017 + + + No update available. + +Your wallet is up to date. + + 1018 + + + Error checking for updates. + + + + 1027 + + + Up to date + Up to date + 1155 + + + 1185 + + %n hour(s) + %n hour + + + %n hour(s) + %n hours + + + + 1187 + + %n day(s) + %n day + + + %n day(s) + %n days + + + + 1189 + 1193 + + %n week(s) + %n week + + + %n week(s) + %n weeks + + + + %1 and %2 + %1 and %2 + 1193 + + + 1193 + + %n year(s) + %n year + + + %n year(s) + %n years + + + + Catching up... + Catching up... + 1196 + + + Last received block was generated %1 ago. + Last received block was generated %1 ago. + 1212 + + + Transactions after this will not yet be visible. + Transactions after this will not yet be visible. + 1214 + + + Loading Blocks... + + 1218 + + + Syncing Blocks... + + 1220 + 1384 + + + 1222 + + %n Blocks + + + + %n Blocks + + + + + Error + Error + 1026 + 1243 + + + Warning + Warning + 1246 + + + Information + Information + 1249 + + + Sent transaction + Sent transaction + 1320 + + + Incoming transaction + Incoming transaction + 1320 + + + Sent MultiSend transaction + + 1320 + + + No Active Peers + + 1377 + + + Syncing MN List... + + 1391 + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> for staking only + + 1444 + + + Tor is <b>enabled</b>: %1 + + 1474 + + + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + Wallet is <b>encrypted</b> and currently <b>unlocked</b> + 1434 + + + Wallet is <b>encrypted</b> and currently <b>locked</b> + Wallet is <b>encrypted</b> and currently <b>locked</b> + 1454 + + + + + Unit to show amounts in. Click to select another unit. + Unit to show amounts in. Click to select another unit. + 1552 + + + + + + + A fatal error occurred. PRCY can no longer continue safely and will quit. + + 539 + + + + + PRCY + + 634 + 641 + 654 + 673 + + + Error: Specified data directory "%1" does not exist. + + 635 + + + Error: Cannot parse configuration file: %1. Only use key=value syntax. + + 642 + + + Error: Invalid combination of -regtest and -testnet. + + 654 + + + Error reading masternode configuration file: %1 + + 674 + + + PRCY didn't yet exit safely... + + 717 + + + + + + + Blockchain Explorer + + 14 + + + Back + + 32 + + + Forward + + 46 + + + Address / Block / Transaction + + 75 + + + Search + + 100 + + + TextLabel + + 139 + + + + + + + Not all transactions will be shown. To view all transactions you need to set txindex=1 in the configuration file (prcycoin.conf). + + 422 + + + + + + + Total: %1 (IPv4: %2 / IPv6: %3 / Tor: %4 / Unknown: %5) + + 81 + + + + + + + Quantity: + Quantity: + 48 + + + Bytes: + Bytes: + 77 + + + Amount: + Amount: + 122 + + + Priority: + Priority: + 151 + + + Fee: + Fee: + 196 + + + Coin Selection + Coin Selection + 14 + + + Dust: + Dust: + 228 + + + After Fee: + After Fee: + 276 + + + Change: + Change: + 308 + + + (un)select all + (un)select all + 364 + + + toggle lock state + + 380 + + + Tree mode + Tree mode + 396 + + + List mode + List mode + 409 + + + (1 locked) + (1 locked) + 419 + + + Amount + Amount + 465 + + + Received with label + Received with label + 470 + + + Received with address + Received with address + 475 + + + Type + Type + 480 + + + Date + Date + 485 + + + Confirmations + Confirmations + 490 + + + Confirmed + Confirmed + 493 + + + Priority + Priority + 498 + + + medium + medium + 164 + ../coincontroldialog.cpp461 + + + no + no + 244 + ../coincontroldialog.cpp663 + + + + + + + Copy address + Copy address + 55 + + + Copy label + Copy label + 56 + + + Copy amount + Copy amount + 57 + 83 + + + Copy transaction ID + Copy transaction ID + 58 + + + Lock unspent + Lock unspent + 59 + + + Unlock unspent + Unlock unspent + 60 + + + Copy quantity + Copy quantity + 82 + + + Copy fee + Copy fee + 84 + + + Copy after fee + Copy after fee + 85 + + + Copy bytes + Copy bytes + 86 + + + Copy priority + Copy priority + 87 + + + Copy dust + Copy dust + 88 + + + Copy change + Copy change + 89 + + + Select all + + 196 + + + Unselect all + + 198 + + + Please switch to "List mode" to use this function. + + 237 + + + highest + highest + 453 + + + higher + higher + 455 + + + high + high + 457 + + + medium-high + medium-high + 459 + + + Can vary +/- %1 duff(s) per input. + Can vary +/- %1 duff(s) per input. + 694 + + + low-medium + low-medium + 463 + + + low + low + 465 + + + lower + lower + 467 + + + lowest + lowest + 469 + + + (%1 locked) + (%1 locked) + 478 + + + none + none + 537 + + + yes + yes + 663 + + + This label turns red, if the transaction size is greater than 1000 bytes. + This label turns red, if the transaction size is greater than 1000 bytes. + 678 + + + This means a fee of at least %1 per kB is required. + This means a fee of at least %1 per kB is required. + 679 + 684 + + + Can vary +/- 1 byte per input. + Can vary +/- 1 byte per input. + 680 + + + Transactions with higher priority are more likely to get included into a block. + Transactions with higher priority are more likely to get included into a block. + 682 + + + This label turns red, if the priority is smaller than "medium". + This label turns red, if the priority is smaller than "medium". + 683 + + + This label turns red, if any recipient receives an amount smaller than %1. + This label turns red, if any recipient receives an amount smaller than %1. + 686 + + + (no label) + (no label) + 740 + 803 + + + change from %1 (%2) + change from %1 (%2) + 798 + + + (change) + (change) + 799 + + + + + + + Edit Address + Edit Address + 14 + + + &Label + &Label + 25 + + + The label associated with this address list entry + The label associated with this address list entry + 35 + + + &Address + &Address + 42 + + + The address associated with this address list entry. This can only be modified for sending addresses. + The address associated with this address list entry. This can only be modified for sending addresses. + 52 + + + + + + + New receiving address + New receiving address + 29 + + + New sending address + New sending address + 33 + + + Edit receiving address + Edit receiving address + 36 + + + Edit sending address + Edit sending address + 40 + + + The entered address "%1" is not a valid PRCY address. + + 107 + + + The entered address "%1" is already in the address book. + The entered address "%1" is already in the address book. + 112 + + + Could not unlock wallet. + Could not unlock wallet. + 117 + + + New key generation failed. + New key generation failed. + 122 + + + + + + + Transaction Details + + 20 + + + Encrypt Wallet + + 31 + + + Please enter a passphrase to encrypt your wallet. This is required. +(You must use a minimum passphrase length of 10 characters and use uppercase letters, +lowercase letters, numbers, symbols) + + 53 + + + New passphrase + New passphrase + 72 + + + Repeat new passphrase + Repeat new passphrase + 82 + + + Show passphrase + + 89 + + + Confirm + + 109 + + + Return + + 112 + + + Cancel + + 119 + + + Esc + + 122 + + + + + + + Wallet Encryption Required + + 37 + 48 + + + There was no passphrase entered for the wallet. + +Wallet encryption is required for the security of your funds. + +What would you like to do? + + 37 + 48 + + + Wallet Encryption Failed + + 67 + 76 + 84 + 94 + 111 + + + The passphrase entered for wallet encryption was empty. Please try again. + + 68 + + + The passphrase's length has to be more than 10. Please try again. + + 77 + + + The passphrase must contain lower, upper, digit, symbol. Please try again. + + 85 + + + The passphrases entered for wallet encryption is too weak. Please try again. + + 95 + + + Wallet Encryption Successful + + 104 + + + Wallet passphrase was successfully set. +Please remember your passphrase as there is no way to recover it. + + 105 + + + The passphrases entered for wallet encryption do not match. Please try again. + + 112 + + + + + + + PRivaCY Coin Wallet Recovery Wizard + + 20 + + + Enter your mnemonics recovery phrase to recover your wallet + + 32 + + + Next + + 57 + + + + + + + Recovery Phrase Import Successful + + 29 + + + Your mnemonics have been successfully imported into the wallet. Rescanning will be scheduled to recover all your funds. + + 29 + + + Recovery Phrase Invalid + + 35 + + + Recovery phrase is invalid. Please try again and double check all words. + + 35 + + + + + + + A new data directory will be created. + A new data directory will be created. + 73 + + + name + name + 92 + + + Directory already exists. Add %1 if you intend to create a new directory here. + Directory already exists. Add %1 if you intend to create a new directory here. + 94 + + + Path already exists, and is not a directory. + Path already exists, and is not a directory. + 97 + + + Cannot create data directory here. + Cannot create data directory here. + 103 + + + + + PRCY + + 186 + + + Error: Specified data directory "%1" cannot be created. + Error: Specified data directory "%1" cannot be created. + 187 + + + Error + Error + 211 + + + %1 GB of free space available + %1 GB of free space available + 219 + + + (of %1 GB needed) + (of %1 GB needed) + 221 + + + + + + + version + version + 38 + + + PRCY + + 38 + + + (%1-bit) + (%1-bit) + 43 + 45 + + + About PRCY + + 49 + + + Command-line options + Command-line options + 69 + + + Usage: + Usage: + 70 + + + command-line options + command-line options + 71 + + + UI Options: + + 79 + + + Choose data directory on startup (default: %u) + + 80 + + + Show splash screen on startup (default: %u) + + 83 + + + Set language, for example "de_DE" (default: system locale) + Set language, for example "de_DE" (default: system locale) + 81 + + + Start minimized + Start minimized + 82 + + + + + PRCY is shutting down... + + 157 + + + Do not shut down the computer until this window disappears. + Do not shut down the computer until this window disappears. + 158 + + + + + + + to + to + 57 + + + All Types + + 84 + ../historypage.cpp300 + + + Sent + Sent + 89 + ../historypage.cpp303 + ../historypage.cpp304 + ../historypage.cpp317 + + + Received + Received + 94 + ../historypage.cpp301 + ../historypage.cpp302 + ../historypage.cpp317 + + + Mined + Mined + 99 + ../historypage.cpp305 + ../historypage.cpp306 + ../historypage.cpp314 + ../historypage.cpp317 + + + Minted + + 104 + ../historypage.cpp307 + ../historypage.cpp308 + ../historypage.cpp314 + ../historypage.cpp317 + + + Masternode + + 109 + ../historypage.cpp309 + ../historypage.cpp310 + ../historypage.cpp314 + ../historypage.cpp317 + + + Payment to yourself + Payment to yourself + 114 + ../historypage.cpp311 + ../historypage.cpp312 + ../historypage.cpp317 + + + Rewards + + 119 + ../historypage.cpp313 + + + Min Amount + + 146 + + + Date + Date + 200 + + + Type + Type + 205 + + + Address/Description + + 210 + + + Amount (PRCY) + + 215 + + + Confirmations + Confirmations + 220 + + + + + + + PRivaCY Coin Wallet Wizard + + 20 + + + Do you want to create a new wallet or recover from your mnemonics? + + 32 + + + Create a new wallet + + 41 + + + Recover from a mnemonic phrase + + 51 + + + Next + + 71 + + + + + + + Copy + + 40 + + + OK + + 41 + + + + + + + Welcome + Welcome + 14 + + + Welcome to the PRivaCY Coin Wallet. + + 23 + + + As this is the first time the program is launched, you can choose where the PRivaCY Coin Wallet will store its data. + + 49 + + + The PRivaCY Coin Wallet will download and store a copy of the PRCY block chain. At least %1GB of data will be stored in this directory, and it will grow over time. The wallet will also be stored in this directory. + + 59 + + + Use the default data directory + Use the default data directory + 69 + + + Use a custom data directory: + Use a custom data directory: + 76 + + + + + + + Form + Form + 14 + + + Alias + + 117 + + + Address + Address + 122 + + + Status + Status + 127 + + + Active + + 132 + + + Last Seen (UTC) + + 137 + + + Pubkey + + 142 + + + S&tart alias + + 155 + + + Start &all + + 162 + + + Start &MISSING + + 169 + + + &Update status + + 176 + + + + + + + Start alias + + 46 + + + Confirm masternode start + + 241 + + + Are you sure you want to start masternode %1? + + 242 + + + Confirm all masternodes start + + 265 + + + Are you sure you want to start ALL masternodes? + + 266 + + + Command is not available right now + + 289 + + + You can't use this command until masternode list is synced + + 290 + + + Confirm missing masternodes start + + 296 + + + Are you sure you want to start MISSING masternodes? + + 297 + + + + + + + MultiSend + + 17 + + + Enter whole numbers 1 - 100 + + 29 + + + Enter % to Give (1-100) + + 32 + + + Enter Address to Send to + + 48 + + + MultiSend allows you to automatically send up to 100% of your stake or masternode reward to a list of other PRCY addresses after it matures. +To Add: enter percentage to give and PRCY address to add to the MultiSend vector. +To Delete: Enter address to delete and press delete. +MultiSend will not be activated unless you have clicked Activate + + 64 + + + Add to MultiSend Vector + + 102 + + + Add + + 105 + + + Deactivate MultiSend + + 118 + + + Deactivate + + 121 + + + Choose an address from the address book + + 134 + + + Alt+A + Alt+A + 144 + + + Percentage of stake to send + + 157 + + + Percentage: + + 160 + + + Address to send portion of stake to + + 173 + + + Address: + + 176 + + + Delete Address From MultiSend Vector + + 192 + + + Delete + + 195 + + + Activate MultiSend + + 208 + + + Activate + + 211 + + + View MultiSend Vector + + 227 + + + View MultiSend + + 230 + + + Send For Stakes + + 246 + + + Send For Masternode Rewards + + 253 + + + + + + + The entered address: + + + 92 + + + is invalid. +Please check the address and try again. + + 92 + + + The total amount of your MultiSend vector is over 100% of your stake reward + + + 103 + + + Please Enter 1 - 100 for percent. + + 110 + + + MultiSend Vector + + + 130 + + + Removed + + 152 + + + Could not locate address + + + 154 + + + + + + + Open URI + Open URI + 14 + + + URI: + URI: + 29 + + + + + + + Options + Options + 14 + + + &Main + &Main + 27 + + + Size of &database cache + Size of &database cache + 45 + + + MB + MB + 61 + + + Number of script &verification threads + Number of script &verification threads + 88 + + + (0 = auto, <0 = leave that many cores free) + (0 = auto, <0 = leave that many cores free) + 101 + + + W&allet + W&allet + 137 + + + If you disable the spending of unconfirmed change, the change from a transaction<br/>cannot be used until that transaction has at least one confirmation.<br/>This also affects how your balance is computed. + If you disable the spending of unconfirmed change, the change from a transaction<br/>cannot be used until that transaction has at least one confirmation.<br/>This also affects how your balance is computed. + 169 + + + Automatically open the PRCY client port on the router. This only works when your router supports UPnP and it is enabled. + + 202 + + + Accept connections from outside + Accept connections from outside + 212 + + + Allow incoming connections + Allow incoming connections + 215 + + + &Connect through SOCKS5 proxy (default proxy): + &Connect through SOCKS5 proxy (default proxy): + 225 + + + Expert + Expert + 143 + + + Automatically start PRCY after logging in to the system. + + 33 + + + &Start PRCY on system login + + 36 + + + Whether to show coin control features or not. + Whether to show coin control features or not. + 149 + + + Enable coin &control features + Enable coin &control features + 152 + + + Show additional tab listing all your masternodes in first sub-tab<br/>and all masternodes on the network in second sub-tab. + + 159 + + + Show Masternodes Tab + + 162 + + + &Spend unconfirmed change + &Spend unconfirmed change + 172 + + + &Network + &Network + 196 + + + Language missing or translation incomplete? Help contributing translations here: +https://www.transifex.com/prcycoin-project/prcycoin-project-translations + + 409 + + + Map port using &UPnP + Map port using &UPnP + 205 + + + Connect to the PRCY network through a SOCKS5 proxy. + + 222 + + + Proxy &IP: + Proxy &IP: + 234 + + + IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1) + IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1) + 259 + + + &Port: + &Port: + 266 + + + Port of the proxy (e.g. 9050) + Port of the proxy (e.g. 9050) + 291 + + + &Window + &Window + 327 + + + Show only a tray icon after minimizing the window. + Show only a tray icon after minimizing the window. + 333 + + + &Minimize to the tray instead of the taskbar + &Minimize to the tray instead of the taskbar + 336 + + + Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu. + Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Quit in the menu. + 343 + + + M&inimize on close + M&inimize on close + 346 + + + &Display + &Display + 367 + + + User Interface &language: + User Interface &language: + 375 + + + The user interface language can be set here. This setting will take effect after restarting PRCYcoin. + + 388 + + + Interface Mode: + + 428 + + + Light + + 449 + + + Dark + + 511 + + + &Unit to show amounts in: + &Unit to show amounts in: + 537 + + + Choose the default subdivision unit to show in the interface and when sending coins. + Choose the default subdivision unit to show in the interface and when sending coins. + 550 + + + Decimal digits + Decimal digits + 561 + + + Hide empty balances + + 575 + 581 + + + Hide orphan stakes in transaction lists + + 588 + + + Hide orphan stakes + + 591 + + + Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |. + Third party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |. + 615 + 628 + + + Third party transaction URLs + Third party transaction URLs + 618 + + + Active command-line options that override above options: + Active command-line options that override above options: + 659 + + + Reset all client options to default. + Reset all client options to default. + 702 + + + &Reset Options + &Reset Options + 705 + + + &OK + &OK + 766 + + + &Cancel + &Cancel + 779 + + + + + + + default + default + 85 + + + none + none + 131 + + + Confirm options reset + Confirm options reset + 218 + + + Client restart required to activate changes. + Client restart required to activate changes. + 219 + 248 + + + Client will be shutdown, do you want to proceed? + Client will be shutdown, do you want to proceed? + 219 + + + This change would require a client restart. + This change would require a client restart. + 250 + + + The supplied proxy address is invalid. + The supplied proxy address is invalid. + 279 + + + The supplied proxy port is invalid. + + 286 + + + The supplied proxy settings are invalid. + + 294 + + + + + + + Turn staking on or off + + 70 + + + On + + 76 + 226 + + + Off + + 79 + 229 + + + Staking Mode: + + 57 + + + Backup Wallet + Backup Wallet + 105 + ../optionspage.cpp349 + + + Show Seed Phrase + + 125 + + + Theme Selection: + + 148 + + + Switch between Dark and Web Wallet theme + + 167 + + + Dark + + 173 + + + Web + + 176 + + + Number of digits to use: + + 244 + + + 6 + + 255 + + + 8 + + 260 + + + Request authentication code before sending any transactions + + 270 + + + Request passphrase before sending any transactions + + 277 + + + Change current passphrase + + 398 + + + Old passphrase + + 409 + + + New passphrase + New passphrase + 419 + + + Repeat new passphrase + Repeat new passphrase + 429 + + + Show passphrase + + 436 + + + Submit + + 457 + + + Clear All + + 470 + + + Quantity of PRCY to keep as spendable (not staking) + + 484 + + + Enabling this will incur a maximum 0.1 PRCY fee each time you receive a new deposit that needs to be consolidated for staking. + + 500 + + + Automatically add any new deposits received to your staked balance + + 503 + + + Save + + 542 + + + Disable + + 549 + + + Network Settings + + 602 + + + Automatically open the PRCY client port on the router. This only works when your router supports UPnP and it is enabled. + + 608 + + + Map port using &UPnP + Map port using &UPnP + 611 + + + Window Settings + + 621 + + + &Minimize to the tray instead of the taskbar + &Minimize to the tray instead of the taskbar + 627 + + + M&inimize on close + M&inimize on close + 634 + + + Privacy Settings + + 644 + + + Hide Balance when unlocked + + 650 + + + Lock "Send" tab when unlocked + + 657 + + + Alternative Currency Value + + 667 + + + Display alternative currency value of wallet on Overview + + 675 + + + Default Currency: + + 682 + + + USD + + 693 + + + CAD + + 698 + + + EUR + + 703 + + + GBP + + 708 + + + BTC + + 713 + + + ETH + + 718 + + + XAU + + 723 + + + XAG + + 728 + + + Two Factor Authentication + + 212 + + + Remember my authentication code for + + 284 + + + 1 Day + + 299 + + + 1 Week + + 306 + + + 1 Month + + 313 + + + Current Authentication Code + + 322 + + + + + + + Reserve Balance Empty + + 215 + + + PRCY reserve amount is empty and must be a minimum of 1. +Please click Disable if you would like to turn it off. + + 216 + + + Invalid Reserve Amount + + 224 + + + The amount you have attempted to keep as spendable is greater than the %1 (%2M) limit. Please try a smaller amount. + + 225 + + + Reserve Balance Set + + 239 + + + Reserve balance of %1 PRCY is successfully set. + + 240 + + + Reserve Balance Disabled + + 252 + + + Reserve balance disabled. + + 253 + + + Wallet Encryption Failed + + 271 + 295 + 301 + 307 + 313 + 326 + + + The passphrase entered for wallet encryption was empty or contained spaces. Please try again. + + 272 + + + The passphrase you have entered is the same as your old passphrase. Please use a different passphrase if you would like to change it. + + 296 + + + The passphrase's length has to be more than 10. Please try again. + + 302 + + + The passphrase must contain lower, upper, digit, symbol. Please try again. + + 308 + + + The passphrase is too weak. You must use a minimum passphrase length of 10 characters and use uppercase letters, lowercase letters, numbers, and symbols. Please try again. + + 314 + + + Passphrase Change Successful + + 319 + + + Wallet passphrase was successfully changed. +Please remember your passphrase as there is no way to recover it. + + 320 + + + The passphrases entered for wallet encryption do not match. Please try again. + + 327 + + + Wallet Data (*.dat) + Wallet Data (*.dat) + 350 + + + Wallet has been successfully backed up to + + 357 + + + Wallet Backup Successful + + 359 + + + Wallet Backup Failed + + 365 + + + Wallet backup failed. Please try again. + + 366 + + + Staking Disabled - Syncing Masternode list + + 417 + + + Enable Staking is disabled when you are still syncing the Masternode list as this is required. Please allow the wallet to fully sync this list before attempting to Enable Staking. + + 418 + + + Staking Setting + + 425 + + + Please unlock the wallet with your passphrase before changing this setting. + + 426 + 623 + 1005 + + + PoW blocks are still being mined. +Please wait until Block %1. + + 436 + + + Information + Information + 438 + 520 + + + Your stakeable balance is under the threshold of %1 PRCY. Please deposit more PRCY into your account in order to enable staking. + + 456 + + + Your balance requires a consolidation transaction which incurs a fee of between %1 to %2 PRCY. However after that transaction fee, your balance will be below the staking threshold of %3 PRCY. Please deposit more PRCY into your account or reduce your reserved amount in order to enable staking. + + 458 + + + Your stakeable balance is under the threshold of %1 PRCY. This is due to your reserve balance being too high. Please deposit more PRCY into your account or reduce your reserved amount in order to enable staking. + + 463 + + + Your stakeable balance is under the threshold of %1 PRCY. This is due to your reserve balance of %2 PRCY being too high. The wallet software has tried to consolidate your funds with the reserve balance but without success because of a consolidation fee of %3 PRCY. Please wait around 10 minutes for the wallet to resolve the reserve to enable staking. + + 467 + + + Warning: Staking Issue + + 473 + + + In order to enable staking with 100%% of your current balance, your previous PRCY deposits must be consolidated and reorganized. This will incur a fee of between %1 to %2 PRCY. + +Would you like to do this? + + 493 + + + In order to enable staking with 100%% of your current balance except the reserve balance, your previous PRCY deposits must be consolidated and reorganized. This will incur a fee of between %1 to %2 PRCY. + +Would you like to do this? + + 497 + + + Staking Needs Consolidation + + 502 + + + Consolidation transaction created! + + 521 + + + 2FA Setting + + 622 + + + SUCCESS! + + 670 + + + Two-factor authentication has been successfully enabled. + + 671 + + + UPNP Settings + + 839 + + + UPNP Settings successfully changed. Please restart the wallet for changes to take effect. + + 840 + + + 2FA Digit Settings + + 873 + 879 + + + 2FA Digit Settings have been changed successfully. + + 874 + + + 2FA Digit Settings have not been changed. + + 880 + + + Hide Balance When Unlocked + + 923 + + + Attempt to Disable 'Hide Balance when unlocked' failed or canceled. Wallet Locked for security. + + 924 + + + Lock Send Tab When Unlocked + + 957 + + + Attempt to Disable 'Lock Send Tab when unlocked' failed or canceled. Wallet Locked for security. + + 958 + + + Password Locked Setting + + 1004 + + + + + + + Form + Form + 20 + + + Blocks + + 91 + + + ??? + + 112 + 147 + + + of + + 128 + + + (loading) + + 159 + + + Balance + + 213 + + + Your current balance + + 236 + + + Your current spendable balance + Your current spendable balance + 362 + + + Pending: + Pending: + 384 + + + Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance + Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance + 403 + + + (syncing) + + 422 + + + Recent Transactions + + 488 + 491 + + + It is advised not to send or receive coins until your current sync is complete. + + 551 + + + Spendable: + Spendable: + 337 + + + + + + + + + 229 + + + + + + + Payment request error + Payment request error + 163 + + + URI handling + URI handling + 219 + 224 + + + Invalid payment address %1 + Invalid payment address %1 + 219 + + + Cannot start prcycoin: click-to-pay handler + + 164 + + + URI cannot be parsed! This can be caused by an invalid PRCY address or malformed URI parameters. + + 225 + + + + + + + NodeId + + 120 + + + Node/Service + + 120 + + + Ping + + 120 + + + Sent + Sent + 120 + + + Received + Received + 120 + + + User Agent + + 120 + + + + + + + Amount + Amount + 256 + + + + + + + %1 d + %1 d + 822 + + + %1 h + %1 h + 824 + + + %1 m + %1 m + 826 + + + %1 s + %1 s + 828 + 868 + + + NETWORK + NETWORK + 843 + + + BLOOM + + 847 + + + UNKNOWN + UNKNOWN + 850 + + + None + None + 858 + + + N/A + N/A + 863 + + + %1 ms + %1 ms + 863 + + + %1 B + %1 B + 874 + + + %1 KB + %1 KB + 876 + + + %1 MB + %1 MB + 878 + + + %1 GB + %1 GB + 880 + + + + + + + &Save Image... + &Save Image... + 35 + + + &Copy Image + &Copy Image + 38 + + + Save QR Code + Save QR Code + 69 + + + PNG Image (*.png) + PNG Image (*.png) + 69 + + + + + Request payment to %1 + Request payment to %1 + 132 + + + Payment information + Payment information + 138 + + + URI + URI + 139 + + + Address + Address + 141 + + + Amount + Amount + 143 + + + Label + Label + 145 + + + Message + Message + 147 + + + Resulting URI too long, try to reduce the text for label / message. + Resulting URI too long, try to reduce the text for label / message. + 155 + + + Error encoding URI into QR Code. + Error encoding URI into QR Code. + 159 + + + + + + + Tools window + Tools window + 14 + + + &Information + &Information + 24 + + + General + General + 46 + + + Name + Name + 187 + + + Client name + Client name + 53 + + + N/A + N/A + 33 + 63 + 86 + 112 + 138 + 161 + 197 + 220 + 243 + 279 + 302 + 368 + 845 + 868 + 891 + 914 + 937 + 960 + 983 + 1006 + 1029 + 1052 + 1075 + 1098 + 1121 + 1144 + 1167 + 1193 + 1216 + 1281 + 1416 + 1535 + + + Number of connections + Number of connections + 210 + + + Block chain + + 262 + + + &Open + &Open + 344 + + + Startup time + Startup time + 151 + + + Network + Network + 180 + + + Last block time + Last block time + 292 + + + Debug log file + Debug log file + 334 + + + Using OpenSSL version + Using OpenSSL version + 99 + + + Current number of blocks + Current number of blocks + 269 + + + Client version + Client version + 76 + + + Using BerkeleyDB version + Using BerkeleyDB version + 125 + + + Open the PRCY debug log file from the current data directory. This can take a few seconds for large log files. + + 341 + + + Number of Masternodes + Number of Masternodes + 233 + + + &Console + &Console + 376 + + + Clear console + Clear console + 425 + + + &Network Traffic + &Network Traffic + 448 + + + &Clear + &Clear + 500 + + + Totals + Totals + 516 + + + Received + Received + 580 + + + Sent + Sent + 660 + + + &Peers + &Peers + 701 + + + Banned peers + + 751 + + + Select a peer to view detailed information. + Select a peer to view detailed information. + 810 + ../rpcconsole.cpp322 + ../rpcconsole.cpp1077 + + + Whitelisted + + 835 + + + Direction + Direction + 858 + + + Protocol + + 881 + + + Version + Version + 904 + + + Services + Services + 927 + + + Ban Score + Ban Score + 1019 + + + Connection Time + Connection Time + 1042 + + + Last Send + Last Send + 1065 + + + Last Receive + Last Receive + 1088 + + + Bytes Sent + Bytes Sent + 1111 + + + Bytes Received + Bytes Received + 1134 + + + Ping Time + Ping Time + 1157 + + + The duration of a currently outstanding ping. + + 1180 + + + Ping Wait + + 1183 + + + Time Offset + + 1206 + + + &Wallet Repair + &Wallet Repair + 1246 + + + The buttons below will restart the wallet with command-line options to repair the wallet, fix issues with corrupt blockhain files or missing/obsolete transactions. + + 1261 + + + Custom Backup Path: + + 1297 + + + Custom Backups Threshold: + + 1462 + + + Rebuild block chain index from current blk000??.dat files. + + 1506 + + + Wallet In Use: + + 1271 + + + Salvage wallet + Salvage wallet + 1310 + + + Attempt to recover private keys from a corrupt wallet.dat. + + 1561 + + + Rescan blockchain files + Rescan blockchain files + 1577 + + + Recover transactions 1 + Recover transactions 1 + 1343 + + + Recover transactions from blockchain (keep meta-data, e.g. account owner). + + 1357 + + + Data Directory + + 354 + + + Last block hash + + 361 + + + Recover transactions 2 + Recover transactions 2 + 1435 + + + Rescan the block chain for missing wallet transactions. + + 1591 + + + Recover transactions from blockchain (drop meta-data). + + 1449 + + + Upgrade wallet format + Upgrade wallet format + 1373 + + + -resync: + + 1469 + + + Delete local Blockchain Folders + + 1522 + + + Deletes all local blockchain folders so the wallet synchronizes from scratch. + + 1476 + + + Starting Block + + 950 + + + Synced Headers + + 973 + + + Synced Blocks + + 996 + + + Wallet repair options. + Wallet repair options. + 1330 + + + Upgrade wallet to latest format on startup. (Note: this is NOT an update of the wallet itself!) + + 1387 + + + Rebuild index + Rebuild index + 1403 + + + + + + + In: + In: + 677 + + + Out: + Out: + 678 + + + Welcome to the PRCY RPC console. + + 639 + + + &Disconnect Node + + 419 + + + Ban Node for + + 420 + 421 + 422 + 423 + + + 1 &hour + + 420 + + + 1 &day + + 421 + + + 1 &week + + 422 + + + 1 &year + + 423 + + + &Unban Node + + 470 + + + This will delete your local blockchain folders and the wallet will synchronize the complete Blockchain from scratch.<br /><br /> + + 566 + + + This needs quite some time and downloads a lot of data.<br /><br /> + + 567 + + + Your transactions and funds will be visible again after the download has completed.<br /><br /> + + 568 + + + Do you want to continue?.<br /> + + 569 + + + Confirm resync Blockchain + + 570 + + + Use up and down arrows to navigate history, and %1 to clear screen. + + 640 + + + Type <b>help</b> for an overview of available commands. + Type <b>help</b> for an overview of available commands. + 641 + + + WARNING: Scammers have been active, telling users to type commands here, stealing their wallet contents. Do not use this console without fully understanding the ramifications of a command. + + 643 + + + (node id: %1) + + 904 + + + via %1 + via %1 + 906 + + + never + never + 909 + 910 + + + Inbound + Inbound + 919 + + + Outbound + Outbound + 919 + + + Yes + + 921 + + + No + + 921 + + + Unknown + Unknown + 933 + 939 + + + + + + + An optional message to attach to the payment request, which will be displayed when the request is opened.<br>Note: The message will not be sent with the payment over the PRCY network. + + 69 + 79 + + + Description (optional) + + 72 + + + Description: + + 82 + + + Amount: + Amount: + 98 + + + List of addresses to receive with + + 108 + 115 + + + Address: + + 118 + + + Submit payment request for address selected above + + 136 + + + &Submit + + 139 + + + PRCY Amount (optional) + + 177 + + + Copy Master Account address to clipboard + + 227 + + + Master Account address + + 237 + + + Remove Integrated Address + + 259 + + + Generate Integrated Address + + 269 + + + An optional amount to request. Leave this empty or zero to not request a specific amount. + An optional amount to request. Leave this empty or zero to not request a specific amount. + 95 + 174 + + + + + + + Copy label + Copy label + 36 + + + Copy message + Copy message + 37 + + + Copy amount + Copy amount + 38 + + + Copy address + Copy address + 39 + + + Invalid Amount + + 196 + + + Invalid amount entered. Please enter an amount less than %1 (%2M) PRCY. + + 197 + + + Enter Label + + 263 + + + Label (Payment ID is added by default) + + 264 + + + + + + + QR Code + QR Code + 29 + + + Copy &URI + Copy &URI + 75 + + + Copy &Address + Copy &Address + 85 + + + &Save Image... + &Save Image... + 95 + + + + + + + Transaction Details + + 14 + 20 + + + TXID: + + 34 + + + Copy transaction ID to clipboard + + 67 + + + Address: + + 87 + + + Private Key: + + 133 + + + Amount: + Amount: + 179 + + + Fee: + Fee: + 225 + + + Ring Size: + + 271 + + + Payment ID: + + 317 + + + In Block: + + 358 + + + Height: + + 372 + + + Hash: + + 425 + + + Copy address to clipboard + + 113 + 405 + 458 + + + Copy transaction private key to clipboard + + 159 + + + Copy Transaction Amount to clipboard + + 205 + + + Copy Transaction Fee to clipboard + + 251 + + + Copy Payment ID to clipboard + + 297 + 343 + + + + + + + Are You Sure? + + 200 + + + Are you sure you would like to delete this transaction from the local wallet? + +Note: They can only be restored from backup or rescan. + + 201 + + + Potential Masternode Collateral Detected! + + 207 + + + Potential Masternode Collateral Detected! +Are you sure? + +Note: They can only be restored from backup or rescan. + + 208 + + + Invalid or non-wallet transaction id + + 222 + + + Invalid or non-wallet transaction id. + + 223 + + + Unable to delete transaction id + + 230 + + + Unable to delete transaction id. + + 231 + + + Do not show successful confirmation again + + 238 + + + OK + + 239 + + + Success! + + 243 + + + Transaction ID successfully deleted. + + 245 + + + + + + + Send Coins + Send Coins + 14 + + + Confirm the send action + Confirm the send action + 828 + + + S&end + S&end + 831 + + + Send to multiple recipients at once + Send to multiple recipients at once + 751 + + + Coin Control Features + + 140 + + + Open Coin Control... + + 163 + + + Coins automatically selected + + 173 + + + Insufficient funds! + + 192 + + + Quantity: + Quantity: + 281 + + + Bytes: + Bytes: + 316 + + + Amount: + Amount: + 364 + + + Priority: + Priority: + 396 + + + medium + medium + 409 + + + Fee: + Fee: + 444 + + + Dust: + Dust: + 476 + + + no + no + 489 + + + After Fee: + After Fee: + 524 + + + Change: + Change: + 556 + + + If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address. + + 600 + + + Custom change address + + 603 + + + Split UTXO + + 623 + + + # of outputs + + 636 + + + UTXO Size: + + 643 + + + 0 PRCY + + 650 + + + Add &Recipient + Add &Recipient + 754 + + + Balance: + Balance: + 43 + + + + + + + Copy quantity + Copy quantity + 60 + + + Copy amount + Copy amount + 61 + + + Copy fee + Copy fee + 62 + + + Copy after fee + Copy after fee + 63 + + + Copy bytes + Copy bytes + 64 + + + Copy priority + Copy priority + 65 + + + Copy dust + Copy dust + 66 + + + Copy change + Copy change + 67 + + + Send Disabled - Syncing + + 144 + + + Sending PRCY is disabled when you are still syncing the wallet. Please allow the wallet to fully sync before attempting to send a transaction. + + 145 + + + Invalid Address + + 168 + + + Invalid address entered. Please make sure you are sending to a Stealth Address. + + 169 + + + Invalid Amount + + 176 + + + Invalid amount entered. Please enter an amount less than your Spendable Balance. + + 177 + + + Destination + + 205 + + + Are you sure you want to send? + + 210 + + + Estimated Transaction fee + + 212 + + + <span class='h3'>Total Amount = <b>%1</b><br/></center> + + 225 + + + Confirm Send Coins + + 233 + + + Insufficient Spendable Funds! + + 249 + + + Insufficient spendable funds. Send with smaller amount or wait for your coins become mature + + 250 + + + Insufficient Reserve Funds! + + 254 + + + Insufficient reserve funds. Send with smaller amount or turn off staking mode. + + 255 + + + Information + Information + 322 + + + Consolidation transaction created! + + 323 + + + Sweeping Transaction Creation Error + + 327 + 335 + + + Sweeping transaction creation failed due to an internal error. Please try again later. + + 328 + 336 + + + Unable to create transaction. Please try again later. + + 346 + + + Transaction Creation Error + + 349 + + + View on Explorer + + 381 + + + Copy + + 382 + + + OK + + 383 + + + Warning: Invalid PIVX address + + 531 + + + Warning: Unknown change address + + 539 + + + (no label) + (no label) + 549 + + + + + + + Remove this entry + Remove this entry + 81 + 225 + 310 + + + A&mount: + A&mount: + 258 + 343 + + + PRivaCY Coin Wallet Address to send to + + 68 + + + Wallet Address + + 71 + + + An optional description to attach to the payment + + 121 + + + Description (Optional) + + 124 + + + Amount of PRCY to send to address above + + 163 + + + PRCY Amount + + 166 + + + Use Spendable Balance + + 179 + + + Clear All + + 186 + + + Pay To: + Pay To: + 207 + 288 + + + Memo: + Memo: + 241 + 326 + + + + + + + Invalid Amount + + 139 + + + Invalid amount entered. Please enter an amount less than %1 (%2M) PRCY. + + 140 + + + + + + + Signatures - Sign / Verify a Message + Signatures - Sign / Verify a Message + 14 + + + &Sign Message + &Sign Message + 27 + + + You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + You can sign messages with your addresses to prove you own them. Be careful not to sign anything vague, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to. + 33 + + + The PRCY address to sign the message with + + 48 + + + Choose previously used address + Choose previously used address + 55 + 250 + + + Alt+A + Alt+A + 65 + 260 + + + Paste address from clipboard + Paste address from clipboard + 72 + + + Alt+P + Alt+P + 82 + + + Enter the message you want to sign here + Enter the message you want to sign here + 91 + + + Signature + Signature + 98 + + + Copy the current signature to the system clipboard + Copy the current signature to the system clipboard + 122 + + + Sign the message to prove you own this PRCY address + + 140 + + + The PRCY address the message was signed with + + 243 + + + Verify the message to ensure it was signed with the specified PRCY address + + 277 + + + Sign &Message + Sign &Message + 143 + + + Reset all sign message fields + Reset all sign message fields + 157 + + + Clear &All + Clear &All + 160 + 297 + + + &Verify Message + &Verify Message + 219 + + + Enter the signing address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. + Enter the signing address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. + 225 + + + Verify &Message + Verify &Message + 280 + + + Reset all verify message fields + Reset all verify message fields + 294 + + + + + + + Click "Sign Message" to generate signature + Click "Sign Message" to generate signature + 31 + + + The entered address is invalid. + The entered address is invalid. + 110 + 183 + + + Please check the address and try again. + Please check the address and try again. + 110 + 117 + 183 + 190 + + + The entered address does not refer to a key. + The entered address does not refer to a key. + 117 + 190 + + + Wallet unlock was cancelled. + Wallet unlock was cancelled. + 124 + + + Private key for the entered address is not available. + Private key for the entered address is not available. + 131 + + + Message signing failed. + Message signing failed. + 142 + + + Message signed. + Message signed. + 147 + + + The signature could not be decoded. + The signature could not be decoded. + 200 + + + Please check the signature and try again. + Please check the signature and try again. + 200 + 212 + + + The signature did not match the message digest. + The signature did not match the message digest. + 212 + + + Message verification failed. + Message verification failed. + 218 + + + Message verified. + Message verified. + 223 + + + + + + + PRivaCY Coin Wallet + + 37 + + + PRivaCY Coin Lite Mode Wallet + + 40 + + + Version %1 + Version %1 + 42 + + + The Bitcoin Core developers + The Bitcoin Core developers + 43 + + + The Dash Core developers + + 44 + + + The PIVX Core developers + + 45 + + + The DAPS Project developers + + 46 + + + The PRivaCY Coin developers + + 47 + + + + + + + [testnet] + [testnet] + 19 + + + + + + + KB/s + KB/s + 79 + + + + + + + 33 + + Open for %n more block(s) + Open for %n more block + + + Open for %n more block(s) + Open for %n more blocks + + + + Open until %1 + Open until %1 + 35 + + + conflicted + conflicted + 43 + 54 + 64 + 76 + + + %1/offline + %1/offline + 78 + + + %1/unconfirmed + %1/unconfirmed + 80 + + + %1 confirmations + %1 confirmations + 70 + 82 + + + %1/offline (verified via SwiftX) + + 45 + + + %1/confirmed (verified via SwiftX) + + 47 + + + %1 confirmations (verified via SwiftX) + + 49 + + + %1/offline (SwiftX verification in progress - %2 of %3 signatures) + + 56 + + + %1/confirmed (SwiftX verification in progress - %2 of %3 signatures ) + + 58 + + + %1 confirmations (SwiftX verification in progress - %2 of %3 signatures) + + 60 + + + %1/offline (SwiftX verification failed) + + 66 + + + %1/confirmed (SwiftX verification failed) + + 68 + + + Status + Status + 100 + + + , has not been successfully broadcast yet + , has not been successfully broadcast yet + 104 + + + 106 + + , broadcast through %n node(s) + , broadcast through %n node + + + , broadcast through %n node(s) + , broadcast through %n nodes + + + + Date + Date + 110 + + + Source + Source + 116 + + + Generated + Generated + 116 + + + From + From + 119 + 127 + 190 + + + unknown + unknown + 127 + + + To + To + 128 + 147 + 205 + + + own address + own address + 130 + + + watch-only + watch-only + 130 + 190 + + + label + label + 132 + + + Credit + Credit + 164 + 174 + 219 + 242 + 279 + + + 166 + + matures in %n more block(s) + matures in %n more block + + + matures in %n more block(s) + matures in %n more blocks + + + + not accepted + not accepted + 168 + + + Debit + Debit + 217 + 239 + 276 + + + Total debit + Total debit + 226 + + + Total credit + Total credit + 227 + + + Transaction fee + Transaction fee + 232 + + + Net amount + Net amount + 246 + + + Message + Message + 252 + 262 + + + Comment + Comment + 254 + + + Transaction ID + Transaction ID + 256 + + + Output index + + 257 + + + Generated coins must mature %1 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to "not accepted" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours. + Generated coins must mature %1 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to "not accepted" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours. + 266 + + + Debug information + Debug information + 273 + + + Transaction + Transaction + 281 + + + Inputs + Inputs + 284 + + + Amount + Amount + 301 + + + true + true + 302 + 303 + + + false + false + 302 + 303 + + + + + + + Transaction details + Transaction details + 14 + + + This pane shows a detailed description of the transaction + This pane shows a detailed description of the transaction + 20 + + + + + + + Date + Date + 290 + + + Type + Type + 290 + + + Address + Address + 290 + + + Confirmations + Confirmations + 290 + + + 348 + + Open for %n more block(s) + Open for %n more block + + + Open for %n more block(s) + Open for %n more blocks + + + + Open until %1 + Open until %1 + 351 + + + Offline + Offline + 354 + + + Unconfirmed + Unconfirmed + 357 + + + Confirming (%1 of %2 recommended confirmations) + Confirming (%1 of %2 recommended confirmations) + 360 + + + Confirmed (%1 confirmations) + Confirmed (%1 confirmations) + 363 + + + Conflicted + Conflicted + 366 + + + Immature (%1 confirmations, will be available after %2) + Immature (%1 confirmations, will be available after %2) + 369 + + + This block was not received by any other nodes and will probably not be accepted! + This block was not received by any other nodes and will probably not be accepted! + 372 + + + Received with + Received with + 410 + + + Masternode Reward + + 412 + + + Received from + Received from + 414 + + + Confirmed Count. + + 700 + + + Sent to + Sent to + 417 + + + Orphan Block - Generated but not accepted. This does not impact your holdings. + + 375 + + + Payment to yourself + Payment to yourself + 419 + + + Minted + + 421 + + + Mined + Mined + 423 + + + watch-only + watch-only + 457 + + + (n/a) + (n/a) + 474 + + + Transaction status. Hover over this field to show number of confirmations. + Transaction status. Hover over this field to show number of confirmations. + 688 + + + Date and time that the transaction was received. + Date and time that the transaction was received. + 690 + + + Type of transaction. + Type of transaction. + 692 + + + Whether or not a watch-only address is involved in this transaction. + Whether or not a watch-only address is involved in this transaction. + 694 + + + Destination address of transaction. + Destination address of transaction. + 696 + + + Amount removed from or added to balance. + Amount removed from or added to balance. + 698 + + + + + + + All + All + 68 + 85 + + + Today + Today + 69 + + + This week + This week + 70 + + + This month + This month + 71 + + + Last month + Last month + 72 + + + This year + This year + 73 + + + Range... + Range... + 74 + + + Most Common + Most Common + 86 + + + Received with + Received with + 87 + + + Sent to + Sent to + 88 + + + To yourself + To yourself + 89 + + + Mined + Mined + 90 + + + Minted + + 91 + + + Masternode Reward + + 92 + + + Other + Other + 93 + + + Enter address or label to search + Enter address or label to search + 99 + + + Min amount + Min amount + 103 + + + Copy address + Copy address + 138 + + + Copy label + Copy label + 139 + + + Copy amount + Copy amount + 140 + + + Copy transaction ID + Copy transaction ID + 141 + + + Edit label + Edit label + 142 + + + Show transaction details + Show transaction details + 143 + + + Hide orphan stakes + + 144 + + + Export Transaction History + Export Transaction History + 376 + + + Comma separated file (*.csv) + Comma separated file (*.csv) + 377 + + + Confirmed + Confirmed + 388 + + + Watch-only + Watch-only + 390 + + + Date + Date + 391 + + + Type + Type + 392 + + + Label + Label + 393 + + + Address + Address + 394 + + + ID + ID + 396 + + + Exporting Failed + Exporting Failed + 406 + + + There was an error trying to save the transaction history to %1. + There was an error trying to save the transaction history to %1. + 406 + + + Exporting Successful + Exporting Successful + 402 + + + The transaction history was successfully saved to %1. + The transaction history was successfully saved to %1. + 402 + + + Range: + Range: + 523 + + + to + to + 531 + + + + + + + Transaction Details + + 20 + + + Enter Code + + 31 + + + Please enter a six digit 2FA code: + + 45 + + + Confirm + + 302 + + + Return + + 305 + + + Cancel + + 312 + + + Esc + + 315 + + + + + + + Wrong 2FA Code + + 169 + + + Incorrect 2FA code entered. +Please try again. + + 170 + + + + + + + Transaction Details + + 20 + + + Enabling 2FA in your PRCY Desktop App + + 31 + + + After this step, you will need to periodically enter another 2FA code anytime you send a transaction from within this desktop app, so do not lose your 2FA code generator. + + 56 + + + Please enter a six digit 2FA code: + + 81 + + + Confirm + + 338 + + + Return + + 341 + + + Cancel + + 348 + + + Esc + + 351 + + + OPEN AUTHENTICATION APP + + 373 + + + + + + + Wrong 2FA Code + + 172 + + + Incorrect 2FA code entered. +Please try again. + + 173 + + + + + + + Below are your 2FA QR Code & Recovery Key. + + 28 + + + Please store them safely. Use them to regain access if you lose your device. + + 43 + + + QR Code + QR Code + 65 + + + Cancel + + 129 + + + Esc + + 132 + + + Next + + 142 + + + Return + + 145 + + + + + + + Resulting URI too long, try to reduce the text for label / message. + Resulting URI too long, try to reduce the text for label / message. + 89 + + + Error encoding URI into QR Code. + Error encoding URI into QR Code. + 93 + + + + + + + TxAmount + + 62 + + + lableDate + + 69 + + + TRANSACTION ID + + 168 + + + TO + + 173 + + + MM/DD/YYYY + + 178 + + + + + + + No wallet has been loaded. + No wallet has been loaded. + 25 + + + + + + + Send Coins + Send Coins + 332 + + + Mnemonic Recovery Phrase + + 367 + 392 + 419 + + + Attempt to view Mnemonic Phrase failed or canceled. Wallet locked for security. + + 368 + 393 + + + Are You Sure? + + 380 + + + Are you sure you would like to view your Mnemonic Phrase? +You will be required to enter your passphrase. Failed or canceled attempts will be logged. + + 381 + + + Copy + + 415 + + + OK + + 416 + + + Below is your Mnemonic Recovery Phrase, consisting of 24 seed words. Please copy/write these words down in order. We strongly recommend keeping multiple copies in different locations. + + 420 + + + + + + + &Export + &Export + 50 + + + Export the data in the current tab to a file + Export the data in the current tab to a file + 51 + + + Selected amount: + Selected amount: + 56 + + + Backup Wallet + Backup Wallet + 260 + + + Wallet Data (*.dat) + Wallet Data (*.dat) + 261 + + + + + + + (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) + (1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data) + 12 + + + Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times + Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times + 18 + + + Bind to given address and always listen on it. Use [host]:port notation for IPv6 + Bind to given address and always listen on it. Use [host]:port notation for IPv6 + 22 + + + Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6 + Bind to given address and whitelist peers connecting to it. Use [host]:port notation for IPv6 + 25 + + + Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces) + Bind to given address to listen for JSON-RPC connections. Use [host]:port notation for IPv6. This option can be specified multiple times (default: bind to all interfaces) + 28 + + + Cannot obtain a lock on data directory %s. PRCY is probably already running. + + 32 + + + Change automatic finalized budget voting behavior. mode=auto: Vote for only exact finalized budget match to my generated budget. (string, default: auto) + Change automatic finalized budget voting behavior. mode=auto: Vote for only exact finalized budget match to my generated budget. (string, default: auto) + 34 + + + Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u) + Continuously rate-limit free transactions to <n>*1000 bytes per minute (default:%u) + 40 + + + Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality) + Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality) + 43 + + + Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup + Delete all wallet transactions and only recover those parts of the blockchain through -rescan on startup + 46 + + + Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. + Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>. + 52 + + + Enter regression test mode, which uses a special chain in which blocks can be solved instantly. + Enter regression test mode, which uses a special chain in which blocks can be solved instantly. + 59 + + + Error: Listening for incoming connections failed (listen returned error %s) + Error: Listening for incoming connections failed (listen returned error %s) + 62 + + + Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. + Error: Unsupported argument -socks found. Setting SOCKS version isn't possible anymore, only SOCKS5 proxies are supported. + 68 + + + Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message) + Execute command when a relevant alert is received or we see a really long fork (%s in cmd is replaced by message) + 75 + + + Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) + Execute command when a wallet transaction changes (%s in cmd is replaced by TxID) + 78 + + + Execute command when the best block changes (%s in cmd is replaced by block hash) + Execute command when the best block changes (%s in cmd is replaced by block hash) + 81 + + + Execute command when the best block changes and its size is over (%s in cmd is replaced by block hash, %d with the block size) + + 84 + + + Flush database activity from memory pool to disk log every <n> megabytes (default: %u) + Flush database activity from memory pool to disk log every <n> megabytes (default: %u) + 93 + + + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) + If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u) + 96 + + + In this mode -genproclimit controls how many blocks are generated immediately. + In this mode -genproclimit controls how many blocks are generated immediately. + 99 + + + Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions) + Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions) + 102 + + + Keep the specified amount available for spending at all times (default: 0) + + 105 + + + Loading... Please do not interrupt this process as it could lead to a corrupt wallet. + + 107 + + + Log transaction priority and fee per kB when mining blocks (default: %u) + Log transaction priority and fee per kB when mining blocks (default: %u) + 110 + + + Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u) + Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u) + 112 + + + Maximum size of data in data carrier transactions we relay and mine (default: %u) + Maximum size of data in data carrier transactions we relay and mine (default: %u) + 118 + + + Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s) + Maximum total fees to use in a single wallet transaction, setting too low may abort large transactions (default: %s) + 123 + + + Number of seconds to keep misbehaving peers from reconnecting (default: %u) + Number of seconds to keep misbehaving peers from reconnecting (default: %u) + 126 + + + Output debugging information (default: %u, supplying <category> is optional) + Output debugging information (default: %u, supplying <category> is optional) + 128 + + + Randomize credentials for every proxy connection. This enables Tor stream isolation (default: %u) + + 133 + + + Require high priority for relaying free or low-fee transactions (default:%u) + Require high priority for relaying free or low-fee transactions (default:%u) + 136 + + + Rescanning... Please do not interrupt this process as it could lead to a corrupt wallet. + + 138 + + + Send trace/debug info to console instead of debug.log file (default: %u) + Send trace/debug info to console instead of debug.log file (default: %u) + 141 + + + Set maximum size of high-priority/low-fee transactions in bytes (default: %d) + Set maximum size of high-priority/low-fee transactions in bytes (default: %d) + 143 + + + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) + Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d) + 145 + + + Set the number of threads for coin generation if enabled (-1 = all cores, default: %d) + Set the number of threads for coin generation if enabled (-1 = all cores, default: %d) + 148 + + + Show N confirmations for a successfully locked transaction (0-9999, default: %u) + Show N confirmations for a successfully locked transaction (0-9999, default: %u) + 151 + + + Support filtering of blocks and transaction with bloom filters (default: %u) + + 161 + + + The block database contains a block which appears to be from the future. This may be due to your computer's date and time being set incorrectly. Only rebuild the block database if you are sure that your computer's date and time are correct + + 163 + + + There is an internal error in generating bulletproofs. Please try again later. + + 168 + + + This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard. + This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard. + 174 + + + Unable to bind to %s on this computer. PRCY is probably already running. + + 181 + + + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) + Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s) + 183 + + + Username and hashed password for JSON-RPC connections. The field <userpw> comes in the format: <USERNAME>:<SALT>$<HASH>. A canonical python script is included in share/rpcuser. This option can be specified multiple times + + 186 + + + Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction. + Warning: -maxtxfee is set very high! Fees this large could be paid on a single transaction. + 190 + + + Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction. + Warning: -paytxfee is set very high! This is the transaction fee you will pay if you send a transaction. + 193 + + + Warning: Please check that your computer's date and time are correct! If your clock is wrong PRCY will not work properly. + + 196 + + + Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. + Warning: The network does not appear to fully agree! Some miners appear to be experiencing issues. + 199 + + + Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. + Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade. + 202 + + + Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + Warning: error reading wallet.dat! All keys read correctly, but transaction data or address book entries might be missing or incorrect. + 205 + + + Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. + Warning: wallet.dat corrupt, data salvaged! Original wallet.dat saved as wallet.{timestamp}.bak in %s; if your balance or transactions are incorrect you should restore from a backup. + 208 + + + Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. + Whitelist peers connecting from the given netmask or IP address. Can be specified multiple times. + 212 + + + Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway + Whitelisted peers cannot be DoS banned and their transactions are always relayed, even if they are already in the mempool, useful e.g. for a gateway + 215 + + + You have attempted to send a total value that is comprised of more than 50 smaller deposits. This is a rare occurrence, and lowering the total value sent, or sending the same total value in two separate transactions will usually work around this limitation. + + 218 + + + You must specify a masternodeprivkey in the configuration. Please see documentation for help. + You must specify a masternodeprivkey in the configuration. Please see documentation for help. + 228 + + + (default: %s) + (default: %s) + 231 + + + (default: 1) + (default: 1) + 232 + + + Accept command line and JSON-RPC commands + Accept command line and JSON-RPC commands + 235 + + + Accept public REST requests (default: %u) + Accept public REST requests (default: %u) + 236 + + + Add a node to connect to and attempt to keep the connection open + Add a node to connect to and attempt to keep the connection open + 237 + + + Allow DNS lookups for -addnode, -seednode and -connect + Allow DNS lookups for -addnode, -seednode and -connect + 239 + + + Always query for peer addresses via DNS lookup (default: %u) + Always query for peer addresses via DNS lookup (default: %u) + 240 + + + Attempt to recover private keys from a corrupt wallet.dat + Attempt to recover private keys from a corrupt wallet.dat + 243 + + + Automatically create Tor hidden service (default: %d) + + 244 + + + Block creation options: + Block creation options: + 245 + + + Cannot downgrade wallet + Cannot downgrade wallet + 250 + + + Cannot write default address + Cannot write default address + 256 + + + Connect through SOCKS5 proxy + Connect through SOCKS5 proxy + 257 + + + Connect to a node to retrieve peer addresses, and disconnect + Connect to a node to retrieve peer addresses, and disconnect + 258 + + + Connection options: + Connection options: + 259 + + + Copyright (C) 2009-%i The Bitcoin Core Developers + Copyright (C) 2009-%i The Bitcoin Core Developers + 260 + + + Copyright (C) 2014-%i The Dash Core Developers + + 261 + + + Corrupted block database detected + Corrupted block database detected + 265 + + + Could not parse masternode.conf + Could not parse masternode.conf + 266 + + + Debugging/Testing options: + Debugging/Testing options: + 268 + + + Delete blockchain folders and resync from scratch + + 269 + + + Disable OS notifications for incoming transactions (default: %u) + + 270 + + + Disable safemode, override a real safe mode event (default: %u) + Disable safemode, override a real safe mode event (default: %u) + 271 + + + Discover own IP address (default: 1 when listening and no -externalip) + Discover own IP address (default: 1 when listening and no -externalip) + 272 + + + Do not load the wallet and disable wallet RPC calls + Do not load the wallet and disable wallet RPC calls + 275 + + + Do you want to rebuild the block database now? + Do you want to rebuild the block database now? + 276 + + + Done loading + Done loading + 277 + + + Enable Old Transaction Deletion + + 278 + + + Enable publish hash transaction (locked via SwiftX) in <address> + + 280 + + + Enable publish raw transaction (locked via SwiftX) in <address> + + 283 + + + Enable the client to act as a masternode (0-1, default: %u) + Enable the client to act as a masternode (0-1, default: %u) + 286 + + + Error initializing block database + Error initializing block database + 289 + + + Error initializing wallet database environment %s! + Error initializing wallet database environment %s! + 290 + + + Error loading block database + Error loading block database + 291 + + + Error loading wallet.dat + Error loading wallet.dat + 292 + + + Error loading wallet.dat: Wallet corrupted + Error loading wallet.dat: Wallet corrupted + 293 + + + Error opening block database + Error opening block database + 295 + + + Error reading from database, shutting down. + Error reading from database, shutting down. + 296 + + + Error + Error + 297 + + + Error: A fatal internal error occured, see debug.log for details + Error: A fatal internal error occured, see debug.log for details + 299 + + + Error: Disk space is low! + Error: Disk space is low! + 301 + + + Error: Unsupported argument -tor found, use -onion. + Error: Unsupported argument -tor found, use -onion. + 303 + + + Failed to generate RingCT + + 304 + + + Failed to listen on any port. Use -listen=0 if you want this. + Failed to listen on any port. Use -listen=0 if you want this. + 306 + + + Force safe mode (default: %u) + Force safe mode (default: %u) + 309 + + + Generate coins (default: %u) + Generate coins (default: %u) + 310 + + + How many blocks to check at startup (default: %u, 0 = all) + How many blocks to check at startup (default: %u, 0 = all) + 311 + + + If <category> is not supplied, output all debugging information. + If <category> is not supplied, output all debugging information. + 312 + + + Importing... + Importing... + 313 + + + Imports blocks from external blk000??.dat file + Imports blocks from external blk000??.dat file + 314 + + + Include IP addresses in debug output (default: %u) + Include IP addresses in debug output (default: %u) + 315 + + + Incorrect or no genesis block found. Wrong datadir for network? + Incorrect or no genesis block found. Wrong datadir for network? + 316 + + + Information + Information + 317 + + + Initialization sanity check failed. PRCY is shutting down. + + 318 + + + Insufficient funds. + Insufficient funds. + 320 + + + Invalid -onion address or hostname: '%s' + + 323 + + + Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s) + Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s) + 325 + + + Invalid amount for -reservebalance=<amount> + + 326 + + + Invalid masternodeprivkey. Please see documenation. + Invalid masternodeprivkey. Please see documenation. + 327 + + + Invalid netmask specified in -whitelist: '%s' + Invalid netmask specified in -whitelist: '%s' + 328 + + + Reindex the %s money supply statistics + + 367 + + + SwiftX options: + + 397 + + + This is a pre-release test build - use at your own risk - do not use for staking or merchant applications! + + 171 + + + Accept connections from outside (default: 1 if no -proxy or -connect/-noconnect) + + 15 + + + Connect only to the specified node(s); -noconnect or -connect=0 alone to disable automatic connections + + 37 + + + Delete transaction every <n> blocks during inital block download (default: %i) + + 49 + + + Enable SwiftX, show confirmations for locked transactions (bool, default: %s) + + 55 + + + Enable or disable staking functionality for PRCY inputs (0-1, default: %u) + + 57 + + + Error: The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here. + + 64 + + + Exclude debugging information for a category. Can be used in conjunction with -debug=1 to output debug logs for all categories except one or more specified categories. + + 71 + + + Fees (in %s/Kb) smaller than this are considered zero fee for relaying (default: %s) + + 87 + + + Fees (in %s/Kb) smaller than this are considered zero fee for transaction creation (default: %s) + + 90 + + + Maximum average size of an index occurrence in the block spam filter (default: %u) + + 115 + + + Maximum size of the list of indexes in the block spam filter (default: %u) + + 121 + + + Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect/-noconnect) + + 130 + + + Specify custom backup path to add a copy of any wallet backup. If set as dir, every backup generates a timestamped file. If set as file, will rewrite to that file every backup. + + 154 + + + Specify location of debug log file: this can be an absolute path or a path relative to the data directory (default: %s) + + 158 + + + Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments. + + 178 + + + You have attempted to send more than 50 UTXOs in a single transaction. To work around this limitation, please either lower the total amount of the transaction or send two separate transactions with 50% of your total desired amount. + + 223 + + + (must be %d for %s-net) + + 233 + + + <category> can be: + + 234 + + + All inputs should have the same number of decoys + + 238 + + + Append comment to the user agent string + + 241 + + + Attempt to force blockchain corruption recovery + + 242 + + + Cannot compute LIJ for ring signature in secp256k1_ec_pubkey_tweak_add + + 246 + + + Cannot compute LIJ for ring signature in secp256k1_ec_pubkey_tweak_mul + + 247 + + + Cannot compute RIJ for ring signature in secp256k1_ec_pubkey_tweak_mul + + 248 + + + Cannot compute two elements and serialize it to pubkey + + 249 + + + Cannot extract public key from script pubkey + + 251 + + + Cannot find corresponding private key + + 252 + + + Cannot parse the commitment for inputs + + 253 + + + Cannot parse the commitment for transaction fee + + 254 + + + Cannot resolve -%s address: '%s' + + 255 + + + Copyright (C) 2015-%i The PIVX Core Developers + + 262 + + + Copyright (C) 2018-%i The DAPS Project developers + + 263 + + + Copyright (C) 2020-%i The PRivaCY Coin Developers + + 264 + + + Currently the Number of supported recipients must be 1 + + 267 + + + Display the stake modifier calculations in the debug.log file. + + 273 + + + Display verbose coin stake messages in the debug.log file. + + 274 + + + Enable publish hash block in <address> + + 279 + + + Enable publish hash transaction in <address> + + 281 + + + Enable publish raw block in <address> + + 282 + + + Enable publish raw transaction in <address> + + 284 + + + Enable staking functionality (0-1, default: %u) + + 285 + + + Error in CreateTransaction. Please try again. + + 287 + + + Error in CreateTransactionBulletProof. Please try again. + + 288 + + + Error loading wallet.dat: Wallet requires newer version of PRCYcoin + + 294 + + + Error: -listen must be true if -masternode is set. + + 298 + + + Error: A fatal internal error occurred, see debug.log for details + + 300 + + + Error: Invalid port %d for running a masternode. + + 302 + + + Failed to generate bulletproof + + 305 + + + Failed to parse host:port string + + 307 + + + Fee (in %s/kB) to add to transactions you send (default: %s) + + 308 + + + Input commitments are not correct + + 319 + + + Invalid -masternodeaddr address: %s + + 321 + + + Invalid -masternodeaddr port %d, only %d is supported on %s-net. + + 322 + + + Invalid amount for -%s=<amount>: '%s' + + 324 + + + Invalid port %d detected in masternode.conf + + 329 + + + Keep at most <n> unconnectable transactions in memory (default: %u) + Keep at most <n> unconnectable transactions in memory (default: %u) + 330 + + + Line: %d + Line: %d + 334 + + + Listen for JSON-RPC connections on <port> (default: %u or testnet: %u) + Listen for JSON-RPC connections on <port> (default: %u or testnet: %u) + 335 + + + Listen for connections on <port> (default: %u or testnet: %u) + Listen for connections on <port> (default: %u or testnet: %u) + 336 + + + Loading addresses... + Loading addresses... + 337 + + + Loading banlist... + + 338 + + + Loading block index... + Loading block index... + 339 + + + Loading budget cache... + Loading budget cache... + 340 + + + Loading masternode cache... + Loading masternode cache... + 341 + + + Loading masternode payment cache... + Loading masternode payment cache... + 342 + + + Lock masternodes from masternode configuration file (default: %u) + Lock masternodes from masternode configuration file (default: %u) + 343 + + + Lookup(): Invalid -proxy address or hostname: '%s' + + 344 + + + Maintain at most <n> connections to peers (default: %u) + Maintain at most <n> connections to peers (default: %u) + 345 + + + Masternode options: + Masternode options: + 346 + + + Masternodes are required to run on port %d for %s-net + + 347 + + + Maximum per-connection receive buffer, <n>*1000 bytes (default: %u) + Maximum per-connection receive buffer, <n>*1000 bytes (default: %u) + 348 + + + Maximum per-connection send buffer, <n>*1000 bytes (default: %u) + Maximum per-connection send buffer, <n>*1000 bytes (default: %u) + 349 + + + Need to specify a port with -whitebind: '%s' + Need to specify a port with -whitebind: '%s' + 350 + + + Node relay options: + Node relay options: + 351 + + + Not enough file descriptors available. + Not enough file descriptors available. + 352 + + + Number of automatic wallet backups (default: 10) + Number of automatic wallet backups (default: 10) + 353 + + + Only accept block chain matching built-in checkpoints (default: %u) + Only accept block chain matching built-in checkpoints (default: %u) + 355 + + + Only connect to nodes in network <net> (ipv4, ipv6 or onion) + Only connect to nodes in network <net> (ipv4, ipv6 or onion) + 356 + + + Options: + Options: + 357 + + + Password for JSON-RPC connections + Password for JSON-RPC connections + 358 + + + Preparing for resync... + + 359 + + + Prepend debug output with timestamp (default: %u) + Prepend debug output with timestamp (default: %u) + 360 + + + Print version and exit + + 361 + + + RPC server options: + RPC server options: + 362 + + + Randomly drop 1 of every <n> network messages + Randomly drop 1 of every <n> network messages + 363 + + + Randomly fuzz 1 of every <n> network messages + Randomly fuzz 1 of every <n> network messages + 364 + + + Rebuild block chain index from current blk000??.dat files + Rebuild block chain index from current blk000??.dat files + 365 + + + Recalculating PRCY supply... + + 366 + + + Relay and mine data carrier transactions (default: %u) + Relay and mine data carrier transactions (default: %u) + 368 + + + Relay non-P2SH multisig (default: %u) + Relay non-P2SH multisig (default: %u) + 369 + + + Rescan the block chain for missing wallet transactions + Rescan the block chain for missing wallet transactions + 370 + + + Rescanning... + Rescanning... + 371 + + + Run a thread to flush wallet periodically (default: %u) + Run a thread to flush wallet periodically (default: %u) + 372 + + + Run in the background as a daemon and accept commands + Run in the background as a daemon and accept commands + 373 + + + Send transactions as zero-fee transactions if possible (default: %u) + Send transactions as zero-fee transactions if possible (default: %u) + 374 + + + Set database cache size in megabytes (%d to %d, default: %d) + Set database cache size in megabytes (%d to %d, default: %d) + 375 + + + Set external address:port to get to this masternode (example: %s) + Set external address:port to get to this masternode (example: %s) + 376 + + + Set key pool size to <n> (default: %u) + Set key pool size to <n> (default: %u) + 377 + + + Set maximum block size in bytes (default: %d) + Set maximum block size in bytes (default: %d) + 378 + + + Set minimum block size in bytes (default: %u) + Set minimum block size in bytes (default: %u) + 379 + + + Set the Maximum reorg depth (default: %u) + + 380 + + + Set the masternode private key + Set the masternode private key + 381 + + + Set the number of threads to service RPC calls (default: %d) + Set the number of threads to service RPC calls (default: %d) + 382 + + + Sets the DB_PRIVATE flag in the wallet db environment (default: %u) + Sets the DB_PRIVATE flag in the wallet db environment (default: %u) + 383 + + + Show all debugging options (usage: --help -help-debug) + Show all debugging options (usage: --help -help-debug) + 384 + + + Shrink debug.log file on client startup (default: 1 when no -debug) + Shrink debug.log file on client startup (default: 1 when no -debug) + 385 + + + Keep the last <n> transactions (default: %i) + + 331 + + + Keep transactions for at least <n> blocks (default: %i) + + 332 + + + Limit size of signature cache to <n> MiB (default: %u) + + 333 + + + Number of custom location backups to retain (default: %d) + + 354 + + + Signing transaction failed + Signing transaction failed + 386 + + + Specify configuration file (default: %s) + Specify configuration file (default: %s) + 387 + + + Specify connection timeout in milliseconds (minimum: 1, default: %d) + Specify connection timeout in milliseconds (minimum: 1, default: %d) + 388 + + + Specify data directory + Specify data directory + 389 + + + Specify masternode configuration file (default: %s) + Specify masternode configuration file (default: %s) + 390 + + + Specify pid file (default: %s) + Specify pid file (default: %s) + 391 + + + Specify wallet file (within data directory) + Specify wallet file (within data directory) + 392 + + + Specify your own public address + Specify your own public address + 393 + + + Spend unconfirmed change when sending transactions (default: %u) + Spend unconfirmed change when sending transactions (default: %u) + 394 + + + Staking options: + + 395 + + + Stop running after importing blocks from disk (default: %u) + Stop running after importing blocks from disk (default: %u) + 396 + + + Synchronization failed + Synchronization failed + 398 + + + Synchronization finished + Synchronization finished + 399 + + + Synchronization pending... + Synchronization pending... + 400 + + + Synchronizing budgets... + Synchronizing budgets... + 401 + + + Synchronizing masternode winners... + Synchronizing masternode winners... + 402 + + + Synchronizing masternodes... + Synchronizing masternodes... + 403 + + + This help message + This help message + 404 + + + This is experimental software. + This is experimental software. + 405 + + + This is intended for regression testing tools and app development. + This is intended for regression testing tools and app development. + 406 + + + Threshold for disconnecting misbehaving peers (default: %u) + Threshold for disconnecting misbehaving peers (default: %u) + 407 + + + Too many decoys + + 408 + + + Tor control port password (default: empty) + + 409 + + + Tor control port to use if onion listening enabled (default: %s) + + 410 + + + Transaction amount too small + Transaction amount too small + 411 + + + Transaction amounts must be positive + Transaction amounts must be positive + 412 + + + Transaction too large for fee policy + Transaction too large for fee policy + 413 + + + Transaction too large + Transaction too large + 414 + + + Unable to bind to %s on this computer (bind returned error %s) + Unable to bind to %s on this computer (bind returned error %s) + 415 + + + Unable to start HTTP server. See debug log for details. + + 416 + + + Unknown network specified in -onlynet: '%s' + Unknown network specified in -onlynet: '%s' + 417 + + + Unsupported logging category %s=%s. + + 418 + + + Upgrade wallet to latest format + Upgrade wallet to latest format + 419 + + + Use UPnP to map the listening port (default: %u) + Use UPnP to map the listening port (default: %u) + 420 + + + Use UPnP to map the listening port (default: 1 when listening) + Use UPnP to map the listening port (default: 1 when listening) + 421 + + + Use a custom max chain reorganization depth (default: %u) + + 422 + + + Use block spam filter (default: %u) + + 423 + + + Use the test network + Use the test network + 424 + + + User Agent comment (%s) contains unsafe characters. + + 425 + + + Username for JSON-RPC connections + Username for JSON-RPC connections + 426 + + + Verifying blocks... + Verifying blocks... + 427 + + + Verifying wallet... + Verifying wallet... + 428 + + + Wallet %s resides outside data directory %s + Wallet %s resides outside data directory %s + 429 + + + Wallet needed to be rewritten: restart PRCY to complete + + 430 + + + Wallet options: + Wallet options: + 431 + + + Wallet window title + Wallet window title + 432 + + + Warning + Warning + 433 + + + Warning: This version is obsolete, upgrade required! + Warning: This version is obsolete, upgrade required! + 434 + + + Warning: Unsupported argument -benchmark ignored, use -debug=bench. + Warning: Unsupported argument -benchmark ignored, use -debug=bench. + 435 + + + Warning: Unsupported argument -debugnet ignored, use -debug=net. + Warning: Unsupported argument -debugnet ignored, use -debug=net. + 436 + + + You need to rebuild the database using -reindex to change -txindex + You need to rebuild the database using -reindex to change -txindex + 437 + + + Zapping all transactions from wallet... + Zapping all transactions from wallet... + 438 + + + ZeroMQ notification options: + + 439 + + + isValid(): Invalid -proxy address or hostname: '%s' + + 440 + + + on startup + on startup + 441 + + + wallet.dat corrupt, salvage failed + wallet.dat corrupt, salvage failed + 442 + + + + diff --git a/src/qt/networkstyle.h b/src/qt/networkstyle.h index 2533755f9b..f346cdcf27 100644 --- a/src/qt/networkstyle.h +++ b/src/qt/networkstyle.h @@ -13,7 +13,7 @@ class NetworkStyle { public: - /** Get style associated with provided BIP70 network id, or 0 if not known */ + /** Get style associated with provided network id, or 0 if not known */ static const NetworkStyle* instantiate(const QString& networkId); const QString& getAppName() const { return appName; } diff --git a/src/qt/notificator.cpp b/src/qt/notificator.cpp index 7e88baf3eb..ace267ff4e 100644 --- a/src/qt/notificator.cpp +++ b/src/qt/notificator.cpp @@ -18,13 +18,8 @@ #include #include #endif -// Include ApplicationServices.h after QtDbus to avoid redefinition of check(). -// This affects at least OSX 10.6. See /usr/include/AssertMacros.h for details. -// Note: This could also be worked around using: - #ifdef Q_OS_MAC #include "macnotificationhandler.h" -#include #endif diff --git a/src/qt/openuridialog.cpp b/src/qt/openuridialog.cpp index 815a585125..2bc91a3d9a 100644 --- a/src/qt/openuridialog.cpp +++ b/src/qt/openuridialog.cpp @@ -40,12 +40,3 @@ void OpenURIDialog::accept() ui->uriEdit->setValid(false); } } - -void OpenURIDialog::on_selectFileButton_clicked() -{ - QString filename = GUIUtil::getOpenFileName(this, tr("Select payment request file to open"), "", "", NULL); - if (filename.isEmpty()) - return; - QUrl fileUri = QUrl::fromLocalFile(filename); - ui->uriEdit->setText("prcycoin:?r=" + QUrl::toPercentEncoding(fileUri.toString())); -} diff --git a/src/qt/openuridialog.h b/src/qt/openuridialog.h index c3fc32a95b..6e5e172c8d 100644 --- a/src/qt/openuridialog.h +++ b/src/qt/openuridialog.h @@ -25,9 +25,6 @@ class OpenURIDialog : public QDialog protected Q_SLOTS: void accept(); -private Q_SLOTS: - void on_selectFileButton_clicked(); - private: Ui::OpenURIDialog* ui; }; diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index 4a21e7e5f3..4f16057bba 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -27,7 +27,7 @@ #include "wallet/walletdb.h" #endif -#include +#include #include #include @@ -364,23 +364,6 @@ void OptionsModel::setDisplayUnit(const QVariant& value) } } -bool OptionsModel::getProxySettings(QNetworkProxy& proxy) const -{ - // Directly query current base proxy, because - // GUI settings can be overridden with -proxy. - proxyType curProxy; - if (GetProxy(NET_IPV4, curProxy)) { - proxy.setType(QNetworkProxy::Socks5Proxy); - proxy.setHostName(QString::fromStdString(curProxy.proxy.ToStringIP())); - proxy.setPort(curProxy.proxy.GetPort()); - - return true; - } else - proxy.setType(QNetworkProxy::NoProxy); - - return false; -} - void OptionsModel::setRestartRequired(bool fRequired) { QSettings settings; diff --git a/src/qt/optionsmodel.h b/src/qt/optionsmodel.h index b4c360646c..a911056c5c 100644 --- a/src/qt/optionsmodel.h +++ b/src/qt/optionsmodel.h @@ -9,10 +9,6 @@ #include -QT_BEGIN_NAMESPACE -class QNetworkProxy; -QT_END_NAMESPACE - /** Interface from Qt to configuration data structure for Bitcoin client. To Qt, the options are presented as a list with the different options laid out vertically. @@ -63,7 +59,6 @@ class OptionsModel : public QAbstractListModel bool getMinimizeOnClose() { return fMinimizeOnClose; } int getDisplayUnit() { return nDisplayUnit; } QString getThirdPartyTxUrls() { return strThirdPartyTxUrls; } - bool getProxySettings(QNetworkProxy& proxy) const; bool getCoinControlFeatures() { return fCoinControlFeatures; } const QString& getOverriddenByCommandLine() { return strOverriddenByCommandLine; } diff --git a/src/qt/optionspage.cpp b/src/qt/optionspage.cpp index dab97ecfd1..3c50a6792a 100644 --- a/src/qt/optionspage.cpp +++ b/src/qt/optionspage.cpp @@ -211,21 +211,19 @@ void OptionsPage::on_pushButtonSave_clicked() { double dAmount = ui->lineEditWithhold->text().toDouble(); if (ui->lineEditWithhold->text().trimmed().isEmpty()) { ui->lineEditWithhold->setStyleSheet("border: 2px solid red"); - QMessageBox msgBox; - msgBox.setWindowTitle("Reserve Balance Empty"); - msgBox.setText("PRCY reserve amount is empty and must be a minimum of 1.\nPlease click Disable if you would like to turn it off."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Information); - msgBox.exec(); + GUIUtil::showMessageBox( + tr("Reserve Balance Empty"), + tr("PRCY reserve amount is empty and must be a minimum of 1.\nPlease click Disable if you would like to turn it off."), + QMessageBox::Information); return; } - if (dAmount < 0.0 || dAmount > 250000000) { - QMessageBox msgBox; - msgBox.setWindowTitle("Invalid Reserve Amount"); - msgBox.setText("The amount you have attempted to keep as spendable is greater than the 250,000,000 (250M) limit. Please try a smaller amount."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Warning); - msgBox.exec(); + if (dAmount < 0.0 || dAmount > MAX_MONEY_OUT) { + CAmount maxMoneyInCoins = MAX_MONEY_OUT / COIN; + CAmount maxMoneyInMillions = maxMoneyInCoins / 1000000; + GUIUtil::showMessageBox( + tr("Invalid Reserve Amount"), + tr("The amount you have attempted to keep as spendable is greater than the %1 (%2M) limit. Please try a smaller amount.").arg(maxMoneyInCoins).arg(maxMoneyInMillions), + QMessageBox::Warning); return; } nReserveBalance = getValidatedAmount(); @@ -235,14 +233,12 @@ void OptionsPage::on_pushButtonSave_clicked() { Q_EMIT model->stakingStatusChanged(nLastCoinStakeSearchInterval); ui->lineEditWithhold->setStyleSheet(GUIUtil::loadStyleSheet()); - + QString reserveBalance = ui->lineEditWithhold->text().trimmed(); - QMessageBox msgBox; - msgBox.setWindowTitle("Reserve Balance Set"); - msgBox.setText("Reserve balance of " + reserveBalance + " PRCY is successfully set."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Information); - msgBox.exec(); + GUIUtil::showMessageBox( + tr("Reserve Balance Set"), + tr("Reserve balance of %1 PRCY is successfully set.").arg(reserveBalance), + QMessageBox::Information); } void OptionsPage::on_pushButtonDisable_clicked() { @@ -252,12 +248,10 @@ void OptionsPage::on_pushButtonDisable_clicked() { walletdb.WriteReserveAmount(0); Q_EMIT model->stakingStatusChanged(nLastCoinStakeSearchInterval); - QMessageBox msgBox; - msgBox.setWindowTitle("Reserve Balance Disabled"); - msgBox.setText("Reserve balance disabled."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Information); - msgBox.exec(); + GUIUtil::showMessageBox( + tr("Reserve Balance Disabled"), + tr("Reserve balance disabled."), + QMessageBox::Information); } void OptionsPage::keyPressEvent(QKeyEvent* event) @@ -273,12 +267,10 @@ void OptionsPage::setMapper() void OptionsPage::on_pushButtonPassword_clicked() { if ( (!ui->lineEditNewPass->text().length()) || (!ui->lineEditNewPassRepeat->text().length()) ) { - QMessageBox msgBox; - msgBox.setWindowTitle("Wallet Encryption Failed"); - msgBox.setText("The passphrase entered for wallet encryption was empty or contained spaces. Please try again."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); + GUIUtil::showMessageBox( + tr("Wallet Encryption Failed"), + tr("The passphrase entered for wallet encryption was empty or contained spaces. Please try again."), + QMessageBox::Critical); return; } //disable password submit button @@ -299,53 +291,41 @@ void OptionsPage::on_pushButtonPassword_clicked() double guesses; if (oldPass == newPass) { - QMessageBox msgBox; - msgBox.setWindowTitle("Wallet Encryption Failed"); - msgBox.setText("The passphrase you have entered is the same as your old passphrase. Please use a different passphrase if you would like to change it."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); + GUIUtil::showMessageBox( + tr("Wallet Encryption Failed"), + tr("The passphrase you have entered is the same as your old passphrase. Please use a different passphrase if you would like to change it."), + QMessageBox::Critical); } else if (newPass.length() < 10) { - QMessageBox msgBox; - msgBox.setWindowTitle("Wallet Encryption Failed"); - msgBox.setText("The passphrase's length has to be more than 10. Please try again."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); + GUIUtil::showMessageBox( + tr("Wallet Encryption Failed"), + tr("The passphrase's length has to be more than 10. Please try again."), + QMessageBox::Critical); } else if (!pwalletMain->checkPassPhraseRule(newPass.c_str())) { - QMessageBox msgBox; - msgBox.setWindowTitle("Wallet Encryption Failed"); - msgBox.setText("The passphrase must contain lower, upper, digit, symbol. Please try again."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); + GUIUtil::showMessageBox( + tr("Wallet Encryption Failed"), + tr("The passphrase must contain lower, upper, digit, symbol. Please try again."), + QMessageBox::Critical); } else if (zxcvbn_password_strength(newPass.c_str(), NULL, &guesses, NULL) < 0 || guesses < 10000) { - QMessageBox msgBox; - msgBox.setWindowTitle("Wallet Encryption Failed"); - msgBox.setText("The passphrase is too weak. You must use a minimum passphrase length of 10 characters and use uppercase letters, lowercase letters, numbers, and symbols. Please try again."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); + GUIUtil::showMessageBox( + tr("Wallet Encryption Failed"), + tr("The passphrase is too weak. You must use a minimum passphrase length of 10 characters and use uppercase letters, lowercase letters, numbers, and symbols. Please try again."), + QMessageBox::Critical); } else if (model->changePassphrase(oldPass, newPass)) { - QMessageBox msgBox; - msgBox.setWindowTitle("Passphrase Change Successful"); - msgBox.setText("Wallet passphrase was successfully changed.\nPlease remember your passphrase as there is no way to recover it."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Information); - msgBox.exec(); + GUIUtil::showMessageBox( + tr("Passphrase Change Successful"), + tr("Wallet passphrase was successfully changed.\nPlease remember your passphrase as there is no way to recover it."), + QMessageBox::Information); success = true; } } else { - QMessageBox msgBox; - msgBox.setWindowTitle("Wallet Encryption Failed"); - msgBox.setText("The passphrases entered for wallet encryption do not match. Please try again."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); + GUIUtil::showMessageBox( + tr("Wallet Encryption Failed"), + tr("The passphrases entered for wallet encryption do not match. Please try again."), + QMessageBox::Critical); } if (success) @@ -374,20 +354,17 @@ void OptionsPage::on_pushButtonBackup_clicked(){ if (model->backupWallet(QString(filename))) { ui->pushButtonBackup->setStyleSheet("border: 2px solid green"); - QMessageBox msgBox; - msgBox.setWindowTitle("Wallet Backup Successful"); - msgBox.setText("Wallet has been successfully backed up to " + filename); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Information); - msgBox.exec(); + QString msg = tr("Wallet has been successfully backed up to "); + GUIUtil::showMessageBox( + tr("Wallet Backup Successful"), + msg + filename, + QMessageBox::Information); } else { ui->pushButtonBackup->setStyleSheet("border: 2px solid red"); - QMessageBox msgBox; - msgBox.setWindowTitle("Wallet Backup Failed"); - msgBox.setText("Wallet backup failed. Please try again."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); + GUIUtil::showMessageBox( + tr("Wallet Backup Failed"), + tr("Wallet backup failed. Please try again."), + QMessageBox::Critical); } ui->pushButtonBackup->repaint(); } @@ -436,74 +413,72 @@ bool OptionsPage::matchNewPasswords() void OptionsPage::on_EnableStaking(ToggleButton* widget) { if (!masternodeSync.IsSynced()) { - QMessageBox msgBox; - msgBox.setWindowTitle("Staking Disabled - Syncing Masternode list"); - msgBox.setText("Enable Staking is disabled when you are still syncing the Masternode list as this is required. Please allow the wallet to fully sync this list before attempting to Enable Staking."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Warning); - msgBox.exec(); + GUIUtil::showMessageBox( + tr("Staking Disabled - Syncing Masternode list"), + tr("Enable Staking is disabled when you are still syncing the Masternode list as this is required. Please allow the wallet to fully sync this list before attempting to Enable Staking."), + QMessageBox::Warning); return; } int status = model->getEncryptionStatus(); if (status == WalletModel::Locked || status == WalletModel::UnlockedForStakingOnly) { - QMessageBox msgBox; - msgBox.setWindowTitle("Staking Setting"); - msgBox.setIcon(QMessageBox::Information); - msgBox.setText("Please unlock the wallet with your passphrase before changing this setting."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.exec(); + GUIUtil::showMessageBox( + tr("Staking Setting"), + tr("Please unlock the wallet with your passphrase before changing this setting."), + QMessageBox::Information); widget->setState(!widget->getState()); return; } + QString errorMessage; if (chainActive.Height() < Params().LAST_POW_BLOCK()) { if (widget->getState()) { - QString msg; - msg.sprintf("PoW blocks are still being mined.\nPlease wait until Block %d.", Params().LAST_POW_BLOCK()); - QMessageBox msgBox; - msgBox.setWindowTitle("Information"); - msgBox.setIcon(QMessageBox::Information); - msgBox.setText(msg); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.exec(); + int lastPowBlock = Params().LAST_POW_BLOCK(); + errorMessage = tr("PoW blocks are still being mined.\nPlease wait until Block %1.").arg(lastPowBlock); + GUIUtil::showMessageBox( + tr("Information"), + errorMessage, + QMessageBox::Information); } widget->setState(false); pwalletMain->WriteStakingStatus(false); return; } if (widget->getState()){ - QString error; CAmount minFee, maxFee; + const CAmount minStakingAmount = model->getMinStakingAmount(); StakingStatusError stt = pwalletMain->StakingCoinStatus(minFee, maxFee); - std::string errorMessage; - if (stt == StakingStatusError::UNSTAKABLE_BALANCE_TOO_LOW || + if (stt == StakingStatusError::UNSTAKABLE_BALANCE_TOO_LOW || stt == UNSTAKABLE_BALANCE_RESERVE_TOO_HIGH || stt == UNSTAKABLE_BALANCE_RESERVE_TOO_HIGH_CONSOLIDATION_FAILED || stt == UNSTAKABLE_BALANCE_TOO_LOW_CONSOLIDATION_FAILED) { - QMessageBox msgBox; + if (stt == StakingStatusError::UNSTAKABLE_BALANCE_TOO_LOW) { - errorMessage = "Your stakeable balance is under the threshold of 2500 PRCY. Please deposit more PRCY into your account in order to enable staking."; + errorMessage = tr("Your stakeable balance is under the threshold of %1 PRCY. Please deposit more PRCY into your account in order to enable staking.").arg(minStakingAmount); } else if (stt == UNSTAKABLE_BALANCE_TOO_LOW_CONSOLIDATION_FAILED) { - errorMessage = "Your balance requires a consolidation transaction which incurs a fee of between " + FormatMoney(minFee) + " to " + FormatMoney(maxFee) + " PRCY. However after that transaction fee, your balance will be below the staking threshold of 2500 PRCY. Please deposit more PRCY into your account or reduce your reserved amount in order to enable staking."; + errorMessage = tr("Your balance requires a consolidation transaction which incurs a fee of between %1 to %2 PRCY. However after that transaction fee, your balance will be below the staking threshold of %3 PRCY. Please deposit more PRCY into your account or reduce your reserved amount in order to enable staking.") + .arg(QString::fromStdString(FormatMoney(minFee))) + .arg(QString::fromStdString(FormatMoney(maxFee))) + .arg(minStakingAmount); } else if (stt == UNSTAKABLE_BALANCE_RESERVE_TOO_HIGH) { - errorMessage = "Your stakeable balance is under the threshold of 2500 PRCY. This is due to your reserve balance being too high. Please deposit more PRCY into your account or reduce your reserved amount in order to enable staking."; + errorMessage = tr("Your stakeable balance is under the threshold of %1 PRCY. This is due to your reserve balance being too high. Please deposit more PRCY into your account or reduce your reserved amount in order to enable staking.").arg(minStakingAmount); } else { SetRingSize(0); CAmount totalFee = maxFee + pwalletMain->ComputeFee(1, 2, MAX_RING_SIZE); - errorMessage = "Your stakeable balance is under the threshold of 2500 PRCY. This is due to your reserve balance of " + FormatMoney(nReserveBalance) + " PRCY being too high. The wallet software has tried to consolidate your funds with the reserve balance but without success because of a consolidation fee of " + FormatMoney(totalFee) + " PRCY. Please wait around 10 minutes for the wallet to resolve the reserve to enable staking."; + errorMessage = tr("Your stakeable balance is under the threshold of %1 PRCY. This is due to your reserve balance of %2 PRCY being too high. The wallet software has tried to consolidate your funds with the reserve balance but without success because of a consolidation fee of %3 PRCY. Please wait around 10 minutes for the wallet to resolve the reserve to enable staking.") + .arg(minStakingAmount) + .arg(QString::fromStdString(FormatMoney(nReserveBalance))) + .arg(QString::fromStdString(FormatMoney(totalFee))); } - QString msg = QString::fromStdString(errorMessage); - msgBox.setWindowTitle("Warning: Staking Issue"); - msgBox.setIcon(QMessageBox::Warning); - msgBox.setText(msg); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.exec(); + GUIUtil::showMessageBox( + tr("Warning: Staking Issue"), + errorMessage, + QMessageBox::Warning); widget->setState(false); nLastCoinStakeSearchInterval = 0; Q_EMIT model->stakingStatusChanged(false); - pwalletMain->WriteStakingStatus(false); - return; - } + pwalletMain->WriteStakingStatus(false); + return; + } if (stt == StakingStatusError::STAKING_OK) { pwalletMain->WriteStakingStatus(true); Q_EMIT model->stakingStatusChanged(true); @@ -514,14 +489,18 @@ void OptionsPage::on_EnableStaking(ToggleButton* widget) return; } - QMessageBox::StandardButton reply; if (stt == StakingStatusError::STAKABLE_NEED_CONSOLIDATION) { - errorMessage = "In order to enable staking with 100% of your current balance, your previous PRCY deposits must be consolidated and reorganized. This will incur a fee of between " + FormatMoney(minFee) + " to " + FormatMoney(maxFee) + " PRCY.\n\nWould you like to do this?"; + errorMessage = tr("In order to enable staking with 100%% of your current balance, your previous PRCY deposits must be consolidated and reorganized. This will incur a fee of between %1 to %2 PRCY.\n\nWould you like to do this?") + .arg(QString::fromStdString(FormatMoney(minFee))) + .arg(QString::fromStdString(FormatMoney(maxFee))); } else { - errorMessage = "In order to enable staking with 100% of your current balance except the reserve balance, your previous PRCY deposits must be consolidated and reorganized. This will incur a fee of between " + FormatMoney(minFee) + " to " + FormatMoney(maxFee) + " PRCY.\n\nWould you like to do this?"; + errorMessage = tr("In order to enable staking with 100%% of your current balance except the reserve balance, your previous PRCY deposits must be consolidated and reorganized. This will incur a fee of between %1 to %2 PRCY.\n\nWould you like to do this?") + .arg(QString::fromStdString(FormatMoney(minFee))) + .arg(QString::fromStdString(FormatMoney(maxFee))); } - reply = QMessageBox::question(this, "Staking Needs Consolidation", QString::fromStdString(errorMessage), QMessageBox::Yes|QMessageBox::No|QMessageBox::Ignore); - if (reply == QMessageBox::Yes) { + QMessageBox::StandardButton reply; + reply = QMessageBox::question(this, tr("Staking Needs Consolidation"), errorMessage, QMessageBox::Yes|QMessageBox::No|QMessageBox::Ignore); + if (reply == QMessageBox::Yes) { pwalletMain->WriteStakingStatus(true); Q_EMIT model->stakingStatusChanged(true); model->generateCoins(true, 1); @@ -529,7 +508,6 @@ void OptionsPage::on_EnableStaking(ToggleButton* widget) pwalletMain->combineMode = CombineMode::ON; saveConsolidationSettingTime(ui->addNewFunds->isChecked()); bool success = false; - const CAmount minStakingAmount = model->getMinStakingAmount();; try { uint32_t nTime = pwalletMain->ReadAutoConsolidateSettingTime(); nTime = (nTime == 0)? GetAdjustedTime() : nTime; @@ -538,17 +516,14 @@ void OptionsPage::on_EnableStaking(ToggleButton* widget) minStakingAmount, nTime); if (success) { //nConsolidationTime = 1800; - QString msg = "Consolidation transaction created!"; - QMessageBox msgBox; - msgBox.setWindowTitle("Information"); - msgBox.setIcon(QMessageBox::Information); - msgBox.setText(msg); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.exec(); + GUIUtil::showMessageBox( + tr("Information"), + tr("Consolidation transaction created!"), + QMessageBox::Information); } } catch (const std::exception& err) { LogPrintf("Sweeping failed, will be done automatically when coins become mature"); - } + } return; } else if (reply == QMessageBox::No) { nLastCoinStakeSearchInterval = 0; @@ -606,7 +581,6 @@ void OptionsPage::on_EnableStaking(ToggleButton* widget) msgBox.exec(); return; } - if (success){ WalletUtil::getTx(pwalletMain, resultTx.GetHash()); QString txhash = resultTx.GetHash().GetHex().c_str(); @@ -619,7 +593,6 @@ void OptionsPage::on_EnableStaking(ToggleButton* widget) msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); msgBox.setIcon(QMessageBox::Information); msgBox.exec(); - if (msgBox.clickedButton() == copyButton) { //Copy txhash to clipboard GUIUtil::setClipboard(txhash); @@ -645,12 +618,10 @@ void OptionsPage::on_Enable2FA(ToggleButton* widget) { int status = model->getEncryptionStatus(); if (status == WalletModel::Locked || status == WalletModel::UnlockedForStakingOnly) { - QMessageBox msgBox; - msgBox.setWindowTitle("2FA Setting"); - msgBox.setIcon(QMessageBox::Information); - msgBox.setText("Please unlock the wallet with your passphrase before changing this setting."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.exec(); + GUIUtil::showMessageBox( + tr("2FA Setting"), + tr("Please unlock the wallet with your passphrase before changing this setting."), + QMessageBox::Information); ui->toggle2FA->setState(!ui->toggle2FA->getState()); return; @@ -695,12 +666,10 @@ void OptionsPage::dialogIsFinished(int result) { pwalletMain->Write2FALastTime(current.toTime_t()); enable2FA(); - QMessageBox msgBox; - msgBox.setWindowTitle("SUCCESS!"); - msgBox.setIcon(QMessageBox::Information); - msgBox.setText("Two-factor authentication has been successfully enabled."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.exec(); + GUIUtil::showMessageBox( + tr("SUCCESS!"), + tr("Two-factor authentication has been successfully enabled."), + QMessageBox::Information); } if (result == QDialog::Rejected) @@ -760,7 +729,7 @@ void OptionsPage::enable2FA() { value.sprintf("%c", chrlist[5]); ui->code_6->setText(value); } - + int period = pwalletMain->Read2FAPeriod(); typeOf2FA = NONE2FA; if (period == 1) { @@ -824,7 +793,7 @@ void OptionsPage::on_week() { codedlg.setWindowTitle("2FA Code Verification"); codedlg.setStyleSheet(GUIUtil::loadStyleSheet()); connect(&codedlg, SIGNAL(finished (int)), this, SLOT(confirmDialogIsFinished(int))); - codedlg.exec(); + codedlg.exec(); } void OptionsPage::on_month() { @@ -841,69 +810,7 @@ void OptionsPage::onShowMnemonic() { if(!model) return; - int status = model->getEncryptionStatus(); - if (status == WalletModel::Locked || status == WalletModel::UnlockedForStakingOnly) { - WalletModel::UnlockContext ctx(model->requestUnlock(AskPassphraseDialog::Context::Unlock_Full, true)); - if (!ctx.isValid()) { - QMessageBox msgBox; - msgBox.setWindowTitle("Mnemonic Recovery Phrase"); - msgBox.setIcon(QMessageBox::Information); - msgBox.setText("Attempt to view Mnemonic Phrase failed or canceled. Wallet locked for security."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.exec(); - LogPrintf("Attempt to view Mnemonic Phrase failed or canceled. Wallet locked for security.\n"); - return; - } else { - SecureString pass; - model->setWalletLocked(false, pass); - LogPrintf("Attempt to view Mnemonic Phrase successful.\n"); - } - } else { - QMessageBox::StandardButton reply; - reply = QMessageBox::question(this, "Are You Sure?", "Are you sure you would like to view your Mnemonic Phrase?\nYou will be required to enter your passphrase. Failed or canceled attempts will be logged.", QMessageBox::Yes|QMessageBox::No); - if (reply == QMessageBox::Yes) { - model->setWalletLocked(true); - WalletModel::UnlockContext ctx(model->requestUnlock(AskPassphraseDialog::Context::Unlock_Full, true)); - if (!ctx.isValid()) { - QMessageBox msgBox; - msgBox.setWindowTitle("Mnemonic Recovery Phrase"); - msgBox.setIcon(QMessageBox::Information); - msgBox.setText("Attempt to view Mnemonic Phrase failed or canceled. Wallet locked for security."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.exec(); - LogPrintf("Attempt to view Mnemonic Phrase failed or canceled. Wallet locked for security.\n"); - return; - } else { - SecureString pass; - model->setWalletLocked(false, pass); - LogPrintf("Attempt to view Mnemonic Phrase successful.\n"); - } - } else { - LogPrintf("Attempt to view Mnemonic Phrase canceled.\n"); - return; - } - } - QString phrase = ""; - std::string recoverySeedPhrase = ""; - if (model->getSeedPhrase(recoverySeedPhrase)) { - phrase = QString::fromStdString(recoverySeedPhrase); - } - - QMessageBox msgBox; - QPushButton *copyButton = msgBox.addButton(tr("Copy"), QMessageBox::ActionRole); - QPushButton *okButton = msgBox.addButton(tr("OK"), QMessageBox::ActionRole); - copyButton->setStyleSheet("background:transparent;"); - copyButton->setIcon(QIcon(":/icons/editcopy")); - msgBox.setWindowTitle("Mnemonic Recovery Phrase"); - msgBox.setText("Below is your Mnemonic Recovery Phrase, consisting of 24 seed words. Please copy/write these words down in order. We strongly recommend keeping multiple copies in different locations."); - msgBox.setInformativeText("\n" + phrase + ""); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.exec(); - - if (msgBox.clickedButton() == copyButton) { - //Copy Mnemonic Recovery Phrase to clipboard - GUIUtil::setClipboard(phrase); - } + model->showSeedPhrase(); } void OptionsPage::setAutoConsolidate(int state) { @@ -928,12 +835,10 @@ void OptionsPage::mapPortUpnp_clicked(int state) } else { settings.setValue("fUseUPnP", false); } - QMessageBox msgBox; - msgBox.setWindowTitle("UPNP Settings"); - msgBox.setIcon(QMessageBox::Information); - msgBox.setText("UPNP Settings successfully changed. Please restart the wallet for changes to take effect."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.exec(); + GUIUtil::showMessageBox( + tr("UPNP Settings"), + tr("UPNP Settings successfully changed. Please restart the wallet for changes to take effect."), + QMessageBox::Information); } void OptionsPage::minimizeToTray_clicked(int state) @@ -964,20 +869,16 @@ void OptionsPage::changeDigits(int digit) if (reply == QMessageBox::Yes) { digit = ui->comboBox->currentText().toInt(); settings.setValue("2fadigits", digit); - QMessageBox msgBox; - msgBox.setWindowTitle("2FA Digit Settings"); - msgBox.setIcon(QMessageBox::Information); - msgBox.setText("2FA Digit Settings have been changed successfully."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.exec(); + GUIUtil::showMessageBox( + tr("2FA Digit Settings"), + tr("2FA Digit Settings have been changed successfully."), + QMessageBox::Information); return; } else { - QMessageBox msgBox; - msgBox.setWindowTitle("2FA Digit Settings"); - msgBox.setIcon(QMessageBox::Information); - msgBox.setText("2FA Digit Settings have not been changed."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.exec(); + GUIUtil::showMessageBox( + tr("2FA Digit Settings"), + tr("2FA Digit Settings have not been changed."), + QMessageBox::Information); return; } } @@ -1018,12 +919,10 @@ void OptionsPage::hideBalanceStaking_clicked(int state) { model->setWalletLocked(true); WalletModel::UnlockContext ctx(model->requestUnlock(AskPassphraseDialog::Context::Unlock_Full, true)); if (!ctx.isValid()) { - QMessageBox msgBox; - msgBox.setWindowTitle("Hide Balance When Unlocked"); - msgBox.setIcon(QMessageBox::Information); - msgBox.setText("Attempt to Disable 'Hide Balance when unlocked' failed or canceled. Wallet Locked for security."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.exec(); + GUIUtil::showMessageBox( + tr("Hide Balance When Unlocked"), + tr("Attempt to Disable 'Hide Balance when unlocked' failed or canceled. Wallet Locked for security."), + QMessageBox::Information); LogPrintf("Attempt to Disable 'Hide Balance when unlocked' failed or canceled. Wallet Locked for security.\n"); settings.setValue("fHideBalance", true); ui->hideBalanceStaking->setChecked(true); @@ -1054,12 +953,10 @@ void OptionsPage::lockSendStaking_clicked(int state) { model->setWalletLocked(true); WalletModel::UnlockContext ctx(model->requestUnlock(AskPassphraseDialog::Context::Unlock_Full, true)); if (!ctx.isValid()) { - QMessageBox msgBox; - msgBox.setWindowTitle("Lock Send Tab When Unlocked"); - msgBox.setIcon(QMessageBox::Information); - msgBox.setText("Attempt to Disable 'Lock Send Tab when unlocked' failed or canceled. Wallet Locked for security."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.exec(); + GUIUtil::showMessageBox( + tr("Lock Send Tab When Unlocked"), + tr("Attempt to Disable 'Lock Send Tab when unlocked' failed or canceled. Wallet Locked for security."), + QMessageBox::Information); LogPrintf("Attempt to Disable 'Lock Send Tab when unlocked' failed or canceled. Wallet Locked for security.\n"); settings.setValue("fLockSendStaking", true); ui->lockSendStaking->setChecked(true); @@ -1103,12 +1000,10 @@ void OptionsPage::checkForUnlock() { int status = model->getEncryptionStatus(); if (status == WalletModel::Locked || status == WalletModel::UnlockedForStakingOnly) { - QMessageBox msgBox; - msgBox.setWindowTitle("Password Locked Setting"); - msgBox.setIcon(QMessageBox::Information); - msgBox.setText("Please unlock the wallet with your passphrase before changing this setting."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.exec(); + GUIUtil::showMessageBox( + tr("Password Locked Setting"), + tr("Please unlock the wallet with your passphrase before changing this setting."), + QMessageBox::Information); return; } } diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index 2975c02c54..be7c96e24c 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -9,6 +9,7 @@ #include "ui_overviewpage.h" #include "bitcoinunits.h" #include "clientmodel.h" +#include "curl_json.h" #include "guiconstants.h" #include "guiutil.h" #include "init.h" @@ -123,12 +124,20 @@ OverviewPage::OverviewPage(QWidget* parent) : QDialog(parent, Qt::WindowSystemMe pingNetworkInterval->start(); // Init getCurrencyValueInterval - getCurrencyValueInterval = new QTimer(this); - manager = new QNetworkAccessManager(this); - connect(getCurrencyValueInterval, SIGNAL(timeout()), this, SLOT(getCurrencyValue())); - connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(setCurrencyValue(QNetworkReply*))); - getCurrencyValueInterval->setInterval(300000); - getCurrencyValueInterval->start(); + updateJSONtimer = new QTimer(this); + updateGUItimer = new QTimer(this); + cgReply = new JsonDownload; + + connect(updateJSONtimer, SIGNAL(timeout()), SLOT(getCurrencyValue())); + connect(updateGUItimer, SIGNAL(timeout()), SLOT(setCurrencyValue())); + + updateJSONtimer->setInterval(300000); //Check every 5 minutes. + updateJSONtimer->start(); + + updateGUItimer->setInterval(15000); //Check every 15 seconds. + updateGUItimer->start(); + + getCurrencyValue(); initSyncCircle(.8); @@ -573,19 +582,10 @@ void OverviewPage::getCurrencyValue() ui->labelCurrencyValue->setText(""); return; } - if (isRuninngQuery) { - return; - } - isRuninngQuery = true; - QNetworkRequest request; - QUrl coinGeckoUrl = QUrl("https://api.coingecko.com/api/v3/simple/price?ids=prcy-coin&vs_currencies=" + defaultCurrency + "&include_market_cap=false&include_24hr_vol=false&include_24hr_change=false&include_last_updated_at=false"); - request.setUrl(coinGeckoUrl); - request.setHeader(QNetworkRequest::ServerHeader, "application/json"); - reply = manager->get(request); - reply->ignoreSslErrors(); + getHttpsJson("https://api.coingecko.com/api/v3/simple/price?ids=prcy-coin&vs_currencies=" + defaultCurrency.toStdString() + "&include_market_cap=false&include_24hr_vol=false&include_24hr_change=false&include_last_updated_at=false", cgReply, CG_HEADERS); } -void OverviewPage::setCurrencyValue(QNetworkReply* reply) +void OverviewPage::setCurrencyValue() { // Get Default Currency from Settings QString defaultCurrency = settings.value("strDefaultCurrency").toString(); @@ -608,12 +608,10 @@ void OverviewPage::setCurrencyValue(QNetworkReply* reply) defaultCurrencySymbol = "XAG"; } - reply->deleteLater(); - if(reply->error() == QNetworkReply::NoError) { + if (cgReply->failed == false && cgReply->complete == true) { try { // Parse data - QByteArray data = reply->readAll(); - QJsonDocument jsonDocument(QJsonDocument::fromJson(data)); + QJsonDocument jsonDocument(QJsonDocument::fromJson(cgReply->response.c_str())); const QJsonObject item = jsonDocument.object(); const QJsonObject currency = item["prcy-coin"].toObject(); auto currencyValue = currency[defaultCurrency.toLower()].toDouble(); @@ -626,8 +624,5 @@ void OverviewPage::setCurrencyValue(QNetworkReply* reply) } catch (...) { LogPrintf("%s: Error parsing CoinGecko API JSON\n", __func__); } - } else { - LogPrintf("%s: Error checking for Alternative Currency value: %d\n", __func__, reply->error()); } - isRuninngQuery = false; } diff --git a/src/qt/overviewpage.h b/src/qt/overviewpage.h index f0700a88d1..c17346fb00 100644 --- a/src/qt/overviewpage.h +++ b/src/qt/overviewpage.h @@ -6,6 +6,7 @@ #define BITCOIN_QT_OVERVIEWPAGE_H #include "amount.h" +#include "curl_json.h" #include #include @@ -13,7 +14,6 @@ #include #include #include -#include class ClientModel; class TransactionFilterProxy; @@ -92,10 +92,9 @@ public Q_SLOTS: QRect getCircleGeometry(QWidget* parent, float ratioToParent); // Check Currency Value via CoinGecko.com API - QNetworkAccessManager* manager; - QNetworkReply* reply; - QTimer* getCurrencyValueInterval; - bool isRuninngQuery = false; + QTimer* updateJSONtimer; + QTimer* updateGUItimer; + JsonDownload* cgReply; private Q_SLOTS: void updateDisplayUnit(); @@ -106,7 +105,7 @@ private Q_SLOTS: void updateLockStatus(int status); // Check Currency Value via CoinGecko.com API void getCurrencyValue(); - void setCurrencyValue(QNetworkReply* reply); + void setCurrencyValue(); }; #endif // BITCOIN_QT_OVERVIEWPAGE_H diff --git a/src/qt/paymentrequest.proto b/src/qt/paymentrequest.proto deleted file mode 100644 index b2281c4c7b..0000000000 --- a/src/qt/paymentrequest.proto +++ /dev/null @@ -1,46 +0,0 @@ -// -// Simple Bitcoin Payment Protocol messages -// -// Use fields 100+ for extensions; -// to avoid conflicts, register extensions at: -// https://en.bitcoin.it/wiki/Payment_Request -// - -package payments; -option java_package = "org.bitcoin.protocols.payments"; -option java_outer_classname = "Protos"; - -// Generalized form of "send payment to this/these bitcoin addresses" -message Output { - optional uint64 amount = 1 [default = 0]; // amount is integer-number-of-satoshis - required bytes script = 2; // usually one of the standard Script forms -} -message PaymentDetails { - optional string network = 1 [default = "main"]; // "main" or "test" - repeated Output outputs = 2; // Where payment should be sent - required uint64 time = 3; // Timestamp; when payment request created - optional uint64 expires = 4; // Timestamp; when this request should be considered invalid - optional string memo = 5; // Human-readable description of request for the customer - optional string payment_url = 6; // URL to send Payment and get PaymentACK - optional bytes merchant_data = 7; // Arbitrary data to include in the Payment message -} -message PaymentRequest { - optional uint32 payment_details_version = 1 [default = 1]; - optional string pki_type = 2 [default = "none"]; // none / x509+sha256 / x509+sha1 - optional bytes pki_data = 3; // depends on pki_type - required bytes serialized_payment_details = 4; // PaymentDetails - optional bytes signature = 5; // pki-dependent signature -} -message X509Certificates { - repeated bytes certificate = 1; // DER-encoded X.509 certificate chain -} -message Payment { - optional bytes merchant_data = 1; // From PaymentDetails.merchant_data - repeated bytes transactions = 2; // Signed transactions that satisfy PaymentDetails.outputs - repeated Output refund_to = 3; // Where to send refunds, if a refund is necessary - optional string memo = 4; // Human-readable message for the merchant -} -message PaymentACK { - required Payment payment = 1; // Payment message that triggered this ACK - optional string memo = 2; // human-readable message for customer -} diff --git a/src/qt/paymentrequestplus.cpp b/src/qt/paymentrequestplus.cpp deleted file mode 100644 index 8b195f1da4..0000000000 --- a/src/qt/paymentrequestplus.cpp +++ /dev/null @@ -1,207 +0,0 @@ -// Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -// -// Wraps dumb protocol buffer paymentRequest -// with some extra methods -// - -#include "paymentrequestplus.h" - -#include - -#include - -#include -#include -#include - - -class SSLVerifyError : public std::runtime_error -{ -public: - SSLVerifyError(std::string err) : std::runtime_error(err) {} -}; - -bool PaymentRequestPlus::parse(const QByteArray& data) -{ - bool parseOK = paymentRequest.ParseFromArray(data.data(), data.size()); - if (!parseOK) { - qWarning() << "PaymentRequestPlus::parse : Error parsing payment request"; - return false; - } - if (paymentRequest.payment_details_version() > 1) { - qWarning() << "PaymentRequestPlus::parse : Received up-version payment details, version=" << paymentRequest.payment_details_version(); - return false; - } - - parseOK = details.ParseFromString(paymentRequest.serialized_payment_details()); - if (!parseOK) { - qWarning() << "PaymentRequestPlus::parse : Error parsing payment details"; - paymentRequest.Clear(); - return false; - } - return true; -} - -bool PaymentRequestPlus::SerializeToString(std::string* output) const -{ - return paymentRequest.SerializeToString(output); -} - -bool PaymentRequestPlus::IsInitialized() const -{ - return paymentRequest.IsInitialized(); -} - -QString PaymentRequestPlus::getPKIType() const -{ - if (!IsInitialized()) return QString("none"); - return QString::fromStdString(paymentRequest.pki_type()); -} - -bool PaymentRequestPlus::getMerchant(X509_STORE* certStore, QString& merchant) const -{ - merchant.clear(); - - if (!IsInitialized()) - return false; - - // One day we'll support more PKI types, but just - // x509 for now: - const EVP_MD* digestAlgorithm = NULL; - if (paymentRequest.pki_type() == "x509+sha256") { - digestAlgorithm = EVP_sha256(); - } else if (paymentRequest.pki_type() == "x509+sha1") { - digestAlgorithm = EVP_sha1(); - } else if (paymentRequest.pki_type() == "none") { - qWarning() << "PaymentRequestPlus::getMerchant : Payment request: pki_type == none"; - return false; - } else { - qWarning() << "PaymentRequestPlus::getMerchant : Payment request: unknown pki_type " << QString::fromStdString(paymentRequest.pki_type()); - return false; - } - - payments::X509Certificates certChain; - if (!certChain.ParseFromString(paymentRequest.pki_data())) { - qWarning() << "PaymentRequestPlus::getMerchant : Payment request: error parsing pki_data"; - return false; - } - - std::vector certs; - const QDateTime currentTime = QDateTime::currentDateTime(); - for (int i = 0; i < certChain.certificate_size(); i++) { - QByteArray certData(certChain.certificate(i).data(), certChain.certificate(i).size()); - QSslCertificate qCert(certData, QSsl::Der); - if (currentTime < qCert.effectiveDate() || currentTime > qCert.expiryDate()) { - qWarning() << "PaymentRequestPlus::getMerchant : Payment request: certificate expired or not yet active: " << qCert; - return false; - } -#if QT_VERSION >= 0x050000 - if (qCert.isBlacklisted()) { - qWarning() << "PaymentRequestPlus::getMerchant : Payment request: certificate blacklisted: " << qCert; - return false; - } -#endif - const unsigned char* data = (const unsigned char*)certChain.certificate(i).data(); - X509* cert = d2i_X509(NULL, &data, certChain.certificate(i).size()); - if (cert) - certs.push_back(cert); - } - if (certs.empty()) { - qWarning() << "PaymentRequestPlus::getMerchant : Payment request: empty certificate chain"; - return false; - } - - // The first cert is the signing cert, the rest are untrusted certs that chain - // to a valid root authority. OpenSSL needs them separately. - STACK_OF(X509)* chain = sk_X509_new_null(); - for (int i = certs.size() - 1; i > 0; i--) { - sk_X509_push(chain, certs[i]); - } - X509* signing_cert = certs[0]; - - // Now create a "store context", which is a single use object for checking, - // load the signing cert into it and verify. - X509_STORE_CTX* store_ctx = X509_STORE_CTX_new(); - if (!store_ctx) { - qWarning() << "PaymentRequestPlus::getMerchant : Payment request: error creating X509_STORE_CTX"; - return false; - } - - char* website = NULL; - bool fResult = true; - try { - if (!X509_STORE_CTX_init(store_ctx, certStore, signing_cert, chain)) { - int error = X509_STORE_CTX_get_error(store_ctx); - throw SSLVerifyError(X509_verify_cert_error_string(error)); - } - - // Now do the verification! - int result = X509_verify_cert(store_ctx); - if (result != 1) { - int error = X509_STORE_CTX_get_error(store_ctx); - throw SSLVerifyError(X509_verify_cert_error_string(error)); - } - X509_NAME* certname = X509_get_subject_name(signing_cert); - - // Valid cert; check signature: - payments::PaymentRequest rcopy(paymentRequest); // Copy - rcopy.set_signature(std::string("")); - std::string data_to_verify; // Everything but the signature - rcopy.SerializeToString(&data_to_verify); - -#if OPENSSL_VERSION_NUMBER >= 0x10100000L - EVP_MD_CTX *ctx = EVP_MD_CTX_new(); - if (!ctx) throw SSLVerifyError("Error allocating OpenSSL context."); -#else - EVP_MD_CTX _ctx; - EVP_MD_CTX *ctx; - ctx = &_ctx; -#endif - EVP_PKEY* pubkey = X509_get_pubkey(signing_cert); - EVP_MD_CTX_init(ctx); - if (!EVP_VerifyInit_ex(ctx, digestAlgorithm, NULL) || - !EVP_VerifyUpdate(ctx, data_to_verify.data(), data_to_verify.size()) || - !EVP_VerifyFinal(ctx, (const unsigned char*)paymentRequest.signature().data(), paymentRequest.signature().size(), pubkey)) { - throw SSLVerifyError("Bad signature, invalid PaymentRequest."); - } -#if OPENSSL_VERSION_NUMBER >= 0x10100000L - EVP_MD_CTX_free(ctx); -#endif - - // OpenSSL API for getting human printable strings from certs is baroque. - int textlen = X509_NAME_get_text_by_NID(certname, NID_commonName, NULL, 0); - website = new char[textlen + 1]; - if (X509_NAME_get_text_by_NID(certname, NID_commonName, website, textlen + 1) == textlen && textlen > 0) { - merchant = website; - } else { - throw SSLVerifyError("Bad certificate, missing common name."); - } - // TODO: detect EV certificates and set merchant = business name instead of unfriendly NID_commonName ? - } catch (const SSLVerifyError& err) { - fResult = false; - qWarning() << "PaymentRequestPlus::getMerchant : SSL error: " << err.what(); - } - - if (website) - delete[] website; - X509_STORE_CTX_free(store_ctx); - for (unsigned int i = 0; i < certs.size(); i++) - X509_free(certs[i]); - - return fResult; -} - -QList > PaymentRequestPlus::getPayTo() const -{ - QList > result; - for (int i = 0; i < details.outputs_size(); i++) { - const unsigned char* scriptStr = (const unsigned char*)details.outputs(i).script().data(); - CScript s(scriptStr, scriptStr + details.outputs(i).script().size()); - - result.append(std::make_pair(s, details.outputs(i).amount())); - } - return result; -} diff --git a/src/qt/paymentrequestplus.h b/src/qt/paymentrequestplus.h deleted file mode 100644 index 79e7fd8993..0000000000 --- a/src/qt/paymentrequestplus.h +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 2011-2014 The Bitcoin developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#ifndef BITCOIN_QT_PAYMENTREQUESTPLUS_H -#define BITCOIN_QT_PAYMENTREQUESTPLUS_H - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#include "paymentrequest.pb.h" -#pragma GCC diagnostic pop - -#include "base58.h" - -#include - -#include -#include -#include - -// -// Wraps dumb protocol buffer paymentRequest -// with extra methods -// - -class PaymentRequestPlus -{ -public: - PaymentRequestPlus() {} - - bool parse(const QByteArray& data); - bool SerializeToString(std::string* output) const; - - bool IsInitialized() const; - QString getPKIType() const; - // Returns true if merchant's identity is authenticated, and - // returns human-readable merchant identity in merchant - bool getMerchant(X509_STORE* certStore, QString& merchant) const; - - // Returns list of outputs, amount - QList > getPayTo() const; - - const payments::PaymentDetails& getDetails() const { return details; } - -private: - payments::PaymentRequest paymentRequest; - payments::PaymentDetails details; -}; - -#endif // BITCOIN_QT_PAYMENTREQUESTPLUS_H diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp index ba812512d4..8150008eb2 100644 --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -32,45 +32,12 @@ #include #include #include -#include -#include -#include -#include -#include -#include -#include #include -#include #include const int BITCOIN_IPC_CONNECT_TIMEOUT = 1000; // milliseconds const QString BITCOIN_IPC_PREFIX("prcycoin:"); -// BIP70 payment protocol messages -const char* BIP70_MESSAGE_PAYMENTACK = "PaymentACK"; -const char* BIP70_MESSAGE_PAYMENTREQUEST = "PaymentRequest"; -// BIP71 payment protocol media types -const char* BIP71_MIMETYPE_PAYMENT = "application/prcycoin-payment"; -const char* BIP71_MIMETYPE_PAYMENTACK = "application/prcycoin-paymentack"; -const char* BIP71_MIMETYPE_PAYMENTREQUEST = "application/prcycoin-paymentrequest"; -// BIP70 max payment request size in bytes (DoS protection) -const qint64 BIP70_MAX_PAYMENTREQUEST_SIZE = 50000; - -struct X509StoreDeleter { - void operator()(X509_STORE* b) { - X509_STORE_free(b); - } -}; - -struct X509Deleter { - void operator()(X509* b) { X509_free(b); } -}; - -namespace // Anon namespace -{ - - std::unique_ptr certStore; -} // // Create a name that is unique for: @@ -97,79 +64,6 @@ static QString ipcServerName() static QList savedPaymentRequests; -static void ReportInvalidCertificate(const QSslCertificate& cert) -{ - qDebug() << QString("%1: Payment server found an invalid certificate: ").arg(__func__) << cert.serialNumber() << cert.subjectInfo(QSslCertificate::CommonName) << cert.subjectInfo(QSslCertificate::DistinguishedNameQualifier) << cert.subjectInfo(QSslCertificate::OrganizationalUnitName); -} - -// -// Load OpenSSL's list of root certificate authorities -// -void PaymentServer::LoadRootCAs(X509_STORE* _store) -{ - // Unit tests mostly use this, to pass in fake root CAs: - if (_store) { - certStore.reset(_store); - return; - } - - // Normal execution, use either -rootcertificates or system certs: - certStore.reset(X509_STORE_new()); - - // Note: use "-system-" default here so that users can pass -rootcertificates="" - // and get 'I don't like X.509 certificates, don't trust anybody' behavior: - QString certFile = QString::fromStdString(GetArg("-rootcertificates", "-system-")); - - if (certFile.isEmpty()) - return; // Empty store - - QList certList; - - if (certFile != "-system-") { - certList = QSslCertificate::fromPath(certFile); - // Use those certificates when fetching payment requests, too: - QSslConfiguration::defaultConfiguration().setCaCertificates(certList); - } else - certList = QSslConfiguration::systemCaCertificates(); - - int nRootCerts = 0; - const QDateTime currentTime = QDateTime::currentDateTime(); - Q_FOREACH (const QSslCertificate& cert, certList) { - if (currentTime < cert.effectiveDate() || currentTime > cert.expiryDate()) { - ReportInvalidCertificate(cert); - continue; - } - - // Blacklisted certificate - if (cert.isBlacklisted()) { - ReportInvalidCertificate(cert); - continue; - } - QByteArray certData = cert.toDer(); - const unsigned char* data = (const unsigned char*)certData.data(); - - std::unique_ptr x509(d2i_X509(0, &data, certData.size())); - if (x509 && X509_STORE_add_cert(certStore.get(), x509.get())) { - // Note: X509_STORE increases the reference count to the X509 object, - // we still have to release our reference to it. - ++nRootCerts; - } else { - ReportInvalidCertificate(cert); - continue; - } - } - qWarning() << "PaymentServer::LoadRootCAs : Loaded " << nRootCerts << " root certificates"; - - // Project for another day: - // Fetch certificate revocation lists, and add them to certStore. - // Issues to consider: - // performance (start a thread to fetch in background?) - // privacy (fetch through tor/proxy so IP address isn't revealed) - // would it be easier to just use a compiled-in blacklist? - // or use Qt's blacklist? - // "certificate stapling" with server-side caching is more efficient -} - // // Sending to the server is done synchronously, at startup. // If the server isn't already running, startup continues, @@ -204,22 +98,6 @@ void PaymentServer::ipcParseCommandLine(int argc, char* argv[]) SelectParams(CBaseChainParams::TESTNET); } } - } else if (QFile::exists(arg)) // Filename - { - savedPaymentRequests.append(arg); - - PaymentRequestPlus request; - if (readPaymentRequestFromFile(arg, request)) { - if (request.getDetails().network() == "main") { - SelectParams(CBaseChainParams::MAIN); - } else if (request.getDetails().network() == "test") { - SelectParams(CBaseChainParams::TESTNET); - } - } - } else { - // Printing to debug.log is about the best we can do here, the - // GUI hasn't started yet so we can't pop up a message box. - qWarning() << "PaymentServer::ipcSendCommandLine : Payment request file does not exist: " << arg; } } } @@ -264,13 +142,8 @@ bool PaymentServer::ipcSendCommandLine() PaymentServer::PaymentServer(QObject* parent, bool startLocalServer) : QObject(parent), saveURIs(true), uriServer(0), - netManager(0), optionsModel(0) { - // Verify that the version of the library that we linked against is - // compatible with the version of the headers we compiled against. - GOOGLE_PROTOBUF_VERIFY_VERSION; - // Install global event filter to catch QFileOpenEvents // on Mac: sent when you click prcycoin: links // other OSes: helpful when dealing with payment request files (in the future) @@ -291,19 +164,16 @@ PaymentServer::PaymentServer(QObject* parent, bool startLocalServer) : QObject(p tr("Cannot start prcycoin: click-to-pay handler")); } else { connect(uriServer, SIGNAL(newConnection()), this, SLOT(handleURIConnection())); - connect(this, SIGNAL(receivedPaymentACK(QString)), this, SLOT(handlePaymentACK(QString))); } } } PaymentServer::~PaymentServer() { - google::protobuf::ShutdownProtobufLibrary(); } // -// OSX-specific way of handling prcycoin: URIs and -// PaymentRequest mime types +// OSX-specific way of handling prcycoin: URIs // bool PaymentServer::eventFilter(QObject* object, QEvent* event) { @@ -321,36 +191,8 @@ bool PaymentServer::eventFilter(QObject* object, QEvent* event) return QObject::eventFilter(object, event); } -void PaymentServer::initNetManager() -{ - if (!optionsModel) - return; - if (netManager != NULL) - delete netManager; - - // netManager is used to fetch paymentrequests given in prcycoin: URIs - netManager = new QNetworkAccessManager(this); - - QNetworkProxy proxy; - - // Query active SOCKS5 proxy - if (optionsModel->getProxySettings(proxy)) { - netManager->setProxy(proxy); - - qDebug() << "PaymentServer::initNetManager : Using SOCKS5 proxy" << proxy.hostName() << ":" << proxy.port(); - } else - qDebug() << "PaymentServer::initNetManager : No active proxy server found."; - - connect(netManager, SIGNAL(finished(QNetworkReply*)), - this, SLOT(netRequestFinished(QNetworkReply*))); - connect(netManager, SIGNAL(sslErrors(QNetworkReply*, const QList&)), - this, SLOT(reportSslErrors(QNetworkReply*, const QList&))); -} - void PaymentServer::uiReady() { - initNetManager(); - saveURIs = false; Q_FOREACH (const QString& s, savedPaymentRequests) { handleURIOrFile(s); @@ -368,34 +210,23 @@ void PaymentServer::handleURIOrFile(const QString& s) if (s.startsWith(BITCOIN_IPC_PREFIX, Qt::CaseInsensitive)) // prcycoin: URI { QUrlQuery uri((QUrl(s))); - SendCoinsRecipient recipient; - if (GUIUtil::parseBitcoinURI(s, &recipient)) { - CBitcoinAddress address(recipient.address.toStdString()); - if (!address.IsValid()) { - Q_EMIT message(tr("URI handling"), tr("Invalid payment address %1").arg(recipient.address), - CClientUIInterface::MSG_ERROR); + // normal URI + { + SendCoinsRecipient recipient; + if (GUIUtil::parseBitcoinURI(s, &recipient)) { + CBitcoinAddress address(recipient.address.toStdString()); + if (!address.IsValid()) { + Q_EMIT message(tr("URI handling"), tr("Invalid payment address %1").arg(recipient.address), + CClientUIInterface::MSG_ERROR); + } else + Q_EMIT receivedPaymentRequest(recipient); } else - Q_EMIT receivedPaymentRequest(recipient); - } else - Q_EMIT message(tr("URI handling"), - tr("URI cannot be parsed! This can be caused by an invalid PRCY address or malformed URI parameters."), - CClientUIInterface::ICON_WARNING); - - return; - } + Q_EMIT message(tr("URI handling"), + tr("URI cannot be parsed! This can be caused by an invalid PRCY address or malformed URI parameters."), + CClientUIInterface::ICON_WARNING); - if (QFile::exists(s)) // payment request file - { - PaymentRequestPlus request; - SendCoinsRecipient recipient; - if (!readPaymentRequestFromFile(s, request)) { - Q_EMIT message(tr("Payment request file handling"), - tr("Payment request file cannot be read! This can be caused by an invalid payment request file."), - CClientUIInterface::ICON_WARNING); - } else if (processPaymentRequest(request, recipient)) - Q_EMIT receivedPaymentRequest(recipient); - - return; + return; + } } } @@ -420,251 +251,7 @@ void PaymentServer::handleURIConnection() handleURIOrFile(msg); } -// -// Warning: readPaymentRequestFromFile() is used in ipcSendCommandLine() -// so don't use "Q_EMIT message()", but "QMessageBox::"! -// -bool PaymentServer::readPaymentRequestFromFile(const QString& filename, PaymentRequestPlus& request) -{ - QFile f(filename); - if (!f.open(QIODevice::ReadOnly)) { - qWarning() << QString("PaymentServer::%1: Failed to open %2").arg(__func__).arg(filename); - return false; - } - - // BIP70 DoS protection - if (f.size() > BIP70_MAX_PAYMENTREQUEST_SIZE) { - qWarning() << QString("PaymentServer::%1: Payment request %2 is too large (%3 bytes, allowed %4 bytes).") - .arg(__func__) - .arg(filename) - .arg(f.size()) - .arg(BIP70_MAX_PAYMENTREQUEST_SIZE); - return false; - } - - QByteArray data = f.readAll(); - - return request.parse(data); -} - -bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, SendCoinsRecipient& recipient) -{ - if (!optionsModel) - return false; - - if (request.IsInitialized()) { - const payments::PaymentDetails& details = request.getDetails(); - - // Payment request network matches client network? - if (details.network() != Params().NetworkIDString()) { - Q_EMIT message(tr("Payment request rejected"), tr("Payment request network doesn't match client network."), - CClientUIInterface::MSG_ERROR); - - return false; - } - - // Expired payment request? - if (details.has_expires() && (int64_t)details.expires() < GetTime()) { - Q_EMIT message(tr("Payment request rejected"), tr("Payment request has expired."), - CClientUIInterface::MSG_ERROR); - - return false; - } - } else { - Q_EMIT message(tr("Payment request error"), tr("Payment request is not initialized."), - CClientUIInterface::MSG_ERROR); - - return false; - } - - recipient.paymentRequest = request; - recipient.message = GUIUtil::HtmlEscape(request.getDetails().memo()); - - request.getMerchant(certStore.get(), recipient.authenticatedMerchant); - - QList > sendingTos = request.getPayTo(); - QStringList addresses; - - Q_FOREACH (const PAIRTYPE(CScript, CAmount) & sendingTo, sendingTos) { - // Extract and check destination addresses - CTxDestination dest; - if (ExtractDestination(sendingTo.first, dest)) { - // Append destination address - addresses.append(QString::fromStdString(CBitcoinAddress(dest).ToString())); - } else if (!recipient.authenticatedMerchant.isEmpty()) { - // Insecure payments to custom prcycoin addresses are not supported - // (there is no good way to tell the user where they are paying in a way - // they'd have a chance of understanding). - Q_EMIT message(tr("Payment request rejected"), - tr("Unverified payment requests to custom payment scripts are unsupported."), - CClientUIInterface::MSG_ERROR); - return false; - } - - // Extract and check amounts - CTxOut txOut(sendingTo.second, sendingTo.first); - if (txOut.IsDust(::minRelayTxFee)) { - Q_EMIT message(tr("Payment request error"), tr("Requested payment amount of %1 is too small (considered dust).").arg(BitcoinUnits::formatWithUnit(optionsModel->getDisplayUnit(), sendingTo.second)), - CClientUIInterface::MSG_ERROR); - - return false; - } - - recipient.amount += sendingTo.second; - } - // Store addresses and format them to fit nicely into the GUI - recipient.address = addresses.join("
"); - - if (!recipient.authenticatedMerchant.isEmpty()) { - qDebug() << "PaymentServer::processPaymentRequest : Secure payment request from " << recipient.authenticatedMerchant; - } else { - qDebug() << "PaymentServer::processPaymentRequest : Insecure payment request to " << addresses.join(", "); - } - - return true; -} - -void PaymentServer::fetchRequest(const QUrl& url) -{ - QNetworkRequest netRequest; - netRequest.setAttribute(QNetworkRequest::User, BIP70_MESSAGE_PAYMENTREQUEST); - netRequest.setUrl(url); - netRequest.setRawHeader("User-Agent", CLIENT_NAME.c_str()); - netRequest.setRawHeader("Accept", BIP71_MIMETYPE_PAYMENTREQUEST); - netManager->get(netRequest); -} - -void PaymentServer::fetchPaymentACK(CWallet* wallet, SendCoinsRecipient recipient, QByteArray transaction) -{ - const payments::PaymentDetails& details = recipient.paymentRequest.getDetails(); - if (!details.has_payment_url()) - return; - - QNetworkRequest netRequest; - netRequest.setAttribute(QNetworkRequest::User, BIP70_MESSAGE_PAYMENTACK); - netRequest.setUrl(QString::fromStdString(details.payment_url())); - netRequest.setHeader(QNetworkRequest::ContentTypeHeader, BIP71_MIMETYPE_PAYMENT); - netRequest.setRawHeader("User-Agent", CLIENT_NAME.c_str()); - netRequest.setRawHeader("Accept", BIP71_MIMETYPE_PAYMENTACK); - - payments::Payment payment; - payment.set_merchant_data(details.merchant_data()); - payment.add_transactions(transaction.data(), transaction.size()); - - // Create a new refund address, or re-use: - QString account = tr("Refund from %1").arg(recipient.authenticatedMerchant); - std::string strAccount = account.toStdString(); - std::set refundAddresses = wallet->GetAccountAddresses(strAccount); - if (!refundAddresses.empty()) { - CScript s = GetScriptForDestination(*refundAddresses.begin()); - payments::Output* refund_to = payment.add_refund_to(); - refund_to->set_script(&s[0], s.size()); - } else { - CPubKey newKey; - if (wallet->GetKeyFromPool(newKey)) { - CKeyID keyID = newKey.GetID(); - wallet->SetAddressBook(keyID, strAccount, "refund"); - - CScript s = GetScriptForDestination(keyID); - payments::Output* refund_to = payment.add_refund_to(); - refund_to->set_script(&s[0], s.size()); - } else { - // This should never happen, because sending coins should have - // just unlocked the wallet and refilled the keypool. - qWarning() << "PaymentServer::fetchPaymentACK : Error getting refund key, refund_to not set"; - } - } - - int length = payment.ByteSize(); - netRequest.setHeader(QNetworkRequest::ContentLengthHeader, length); - QByteArray serData(length, '\0'); - if (payment.SerializeToArray(serData.data(), length)) { - netManager->post(netRequest, serData); - } else { - // This should never happen, either. - qWarning() << "PaymentServer::fetchPaymentACK : Error serializing payment message"; - } -} - -void PaymentServer::netRequestFinished(QNetworkReply* reply) -{ - reply->deleteLater(); - - // BIP70 DoS protection - if (reply->size() > BIP70_MAX_PAYMENTREQUEST_SIZE) { - QString msg = tr("Payment request %1 is too large (%2 bytes, allowed %3 bytes).") - .arg(reply->request().url().toString()) - .arg(reply->size()) - .arg(BIP70_MAX_PAYMENTREQUEST_SIZE); - - qWarning() << QString("PaymentServer::%1:").arg(__func__) << msg; - Q_EMIT message(tr("Payment request DoS protection"), msg, CClientUIInterface::MSG_ERROR); - return; - } - - if (reply->error() != QNetworkReply::NoError) { - QString msg = tr("Error communicating with %1: %2") - .arg(reply->request().url().toString()) - .arg(reply->errorString()); - - qWarning() << "PaymentServer::netRequestFinished: " << msg; - Q_EMIT message(tr("Payment request error"), msg, CClientUIInterface::MSG_ERROR); - return; - } - - QByteArray data = reply->readAll(); - - QString requestType = reply->request().attribute(QNetworkRequest::User).toString(); - if (requestType == BIP70_MESSAGE_PAYMENTREQUEST) { - PaymentRequestPlus request; - SendCoinsRecipient recipient; - if (!request.parse(data)) { - qWarning() << "PaymentServer::netRequestFinished : Error parsing payment request"; - Q_EMIT message(tr("Payment request error"), - tr("Payment request cannot be parsed!"), - CClientUIInterface::MSG_ERROR); - } else if (processPaymentRequest(request, recipient)) - Q_EMIT receivedPaymentRequest(recipient); - - return; - } else if (requestType == BIP70_MESSAGE_PAYMENTACK) { - payments::PaymentACK paymentACK; - if (!paymentACK.ParseFromArray(data.data(), data.size())) { - QString msg = tr("Bad response from server %1") - .arg(reply->request().url().toString()); - - qWarning() << "PaymentServer::netRequestFinished : " << msg; - Q_EMIT message(tr("Payment request error"), msg, CClientUIInterface::MSG_ERROR); - } else { - Q_EMIT receivedPaymentACK(GUIUtil::HtmlEscape(paymentACK.memo())); - } - } -} - -void PaymentServer::reportSslErrors(QNetworkReply* reply, const QList& errs) -{ - Q_UNUSED(reply); - - QString errString; - Q_FOREACH (const QSslError& err, errs) { - qWarning() << "PaymentServer::reportSslErrors : " << err; - errString += err.errorString() + "\n"; - } - Q_EMIT message(tr("Network request error"), errString, CClientUIInterface::MSG_ERROR); -} - void PaymentServer::setOptionsModel(OptionsModel* optionsModel) { this->optionsModel = optionsModel; } - -void PaymentServer::handlePaymentACK(const QString& paymentACKMsg) -{ - // currently we don't futher process or store the paymentACK message - Q_EMIT message(tr("Payment acknowledged"), paymentACKMsg, CClientUIInterface::ICON_INFORMATION | CClientUIInterface::MODAL); -} - -X509_STORE* PaymentServer::getCertStore() -{ - return certStore.get(); -} diff --git a/src/qt/paymentserver.h b/src/qt/paymentserver.h index 74c7b88ae2..29a317a852 100644 --- a/src/qt/paymentserver.h +++ b/src/qt/paymentserver.h @@ -32,7 +32,6 @@ // sends them to the server. // -#include "paymentrequestplus.h" #include "walletmodel.h" #include @@ -46,15 +45,9 @@ QT_BEGIN_NAMESPACE class QApplication; class QByteArray; class QLocalServer; -class QNetworkAccessManager; -class QNetworkReply; -class QSslError; class QUrl; QT_END_NAMESPACE -// BIP70 max payment request size in bytes (DoS protection) -extern const qint64 BIP70_MAX_PAYMENTREQUEST_SIZE; - class PaymentServer : public QObject { Q_OBJECT @@ -75,29 +68,13 @@ class PaymentServer : public QObject PaymentServer(QObject* parent, bool startLocalServer = true); ~PaymentServer(); - // Load root certificate authorities. Pass NULL (default) - // to read from the file specified in the -rootcertificates setting, - // or, if that's not set, to use the system default root certificates. - // If you pass in a store, you should not X509_STORE_free it: it will be - // freed either at exit or when another set of CAs are loaded. - static void LoadRootCAs(X509_STORE* store = NULL); - - // Return certificate store - static X509_STORE* getCertStore(); - // OptionsModel is used for getting proxy settings and display unit void setOptionsModel(OptionsModel* optionsModel); - // This is now public, because we use it in paymentservertests.cpp - static bool readPaymentRequestFromFile(const QString& filename, PaymentRequestPlus& request); - Q_SIGNALS: // Fired when a valid payment request is received void receivedPaymentRequest(SendCoinsRecipient); - // Fired when a valid PaymentACK is received - void receivedPaymentACK(const QString& paymentACKMsg); - // Fired when a message should be reported to the user void message(const QString& title, const QString& message, unsigned int style); @@ -106,17 +83,11 @@ public Q_SLOTS: // to display payment requests to the user void uiReady(); - // Submit Payment message to a merchant, get back PaymentACK: - void fetchPaymentACK(CWallet* wallet, SendCoinsRecipient recipient, QByteArray transaction); - // Handle an incoming URI, URI with local file scheme or file void handleURIOrFile(const QString& s); private Q_SLOTS: void handleURIConnection(); - void netRequestFinished(QNetworkReply*); - void reportSslErrors(QNetworkReply*, const QList&); - void handlePaymentACK(const QString& paymentACKMsg); protected: // Constructor registers this on the parent QApplication to @@ -124,15 +95,8 @@ private Q_SLOTS: bool eventFilter(QObject* object, QEvent* event); private: - bool processPaymentRequest(PaymentRequestPlus& request, SendCoinsRecipient& recipient); - void fetchRequest(const QUrl& url); - - // Setup networking - void initNetManager(); - bool saveURIs; // true during startup QLocalServer* uriServer; - QNetworkAccessManager* netManager; // Used to fetch payment requests OptionsModel* optionsModel; }; diff --git a/src/qt/prcycoin.cpp b/src/qt/prcycoin.cpp index a10d5dd7f5..2898265f6b 100644 --- a/src/qt/prcycoin.cpp +++ b/src/qt/prcycoin.cpp @@ -67,15 +67,14 @@ #if defined(QT_STATICPLUGIN) #include -#if QT_VERSION < 0x050400 -Q_IMPORT_PLUGIN(AccessibleFactory) -#endif #if defined(QT_QPA_PLATFORM_XCB) Q_IMPORT_PLUGIN(QXcbIntegrationPlugin); #elif defined(QT_QPA_PLATFORM_WINDOWS) Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin); +Q_IMPORT_PLUGIN(QWindowsVistaStylePlugin); #elif defined(QT_QPA_PLATFORM_COCOA) Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin); +Q_IMPORT_PLUGIN(QMacStylePlugin); #endif //Q_IMPORT_PLUGIN(QGifPlugin); #endif @@ -460,7 +459,6 @@ void BitcoinApplication::initializeResult(int retval) returnValue = retval ? 0 : 1; if (retval) { #ifdef ENABLE_WALLET - PaymentServer::LoadRootCAs(); paymentServer->setOptionsModel(optionsModel); #endif clientModel = new ClientModel(optionsModel); @@ -588,18 +586,23 @@ int main(int argc, char* argv[]) Q_INIT_RESOURCE(prcycoin_locale); Q_INIT_RESOURCE(prcycoin); - BitcoinApplication app(argc, argv); -#if QT_VERSION > 0x050100 // Generate high-dpi pixmaps QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); -#endif #if QT_VERSION >= 0x050600 - QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); #endif #ifdef Q_OS_MAC QApplication::setAttribute(Qt::AA_DontShowIconsInMenus); #endif +#if defined(QT_QPA_PLATFORM_ANDROID) + QApplication::setAttribute(Qt::AA_DontUseNativeMenuBar); + QApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings); + QApplication::setAttribute(Qt::AA_DontUseNativeDialogs); +#endif + + BitcoinApplication app(argc, argv); + // Register meta types used for QMetaObject::invokeMethod qRegisterMetaType(); // Need to pass name here as CAmount is a typedef (see http://qt-project.org/doc/qt-5/qmetatype.html#qRegisterMetaType) diff --git a/src/qt/prcycoinstrings.cpp b/src/qt/prcycoinstrings.cpp index eb22f8a034..50791836c9 100644 --- a/src/qt/prcycoinstrings.cpp +++ b/src/qt/prcycoinstrings.cpp @@ -47,11 +47,16 @@ QT_TRANSLATE_NOOP("prcycoin-core", "" "Delete all wallet transactions and only recover those parts of the " "blockchain through -rescan on startup"), QT_TRANSLATE_NOOP("prcycoin-core", "" +"Delete transaction every blocks during inital block download (default: " +"%i)"), +QT_TRANSLATE_NOOP("prcycoin-core", "" "Distributed under the MIT software license, see the accompanying file " "COPYING or ."), QT_TRANSLATE_NOOP("prcycoin-core", "" "Enable SwiftX, show confirmations for locked transactions (bool, default: %s)"), QT_TRANSLATE_NOOP("prcycoin-core", "" +"Enable or disable staking functionality for PRCY inputs (0-1, default: %u)"), +QT_TRANSLATE_NOOP("prcycoin-core", "" "Enter regression test mode, which uses a special chain in which blocks can " "be solved instantly."), QT_TRANSLATE_NOOP("prcycoin-core", "" @@ -108,9 +113,14 @@ QT_TRANSLATE_NOOP("prcycoin-core", "" "Maintain a full transaction index, used by the getrawtransaction rpc call " "(default: %u)"), QT_TRANSLATE_NOOP("prcycoin-core", "" +"Maximum average size of an index occurrence in the block spam filter " +"(default: %u)"), +QT_TRANSLATE_NOOP("prcycoin-core", "" "Maximum size of data in data carrier transactions we relay and mine " "(default: %u)"), QT_TRANSLATE_NOOP("prcycoin-core", "" +"Maximum size of the list of indexes in the block spam filter (default: %u)"), +QT_TRANSLATE_NOOP("prcycoin-core", "" "Maximum total fees to use in a single wallet transaction, setting too low " "may abort large transactions (default: %s)"), QT_TRANSLATE_NOOP("prcycoin-core", "" @@ -171,12 +181,13 @@ QT_TRANSLATE_NOOP("prcycoin-core", "" QT_TRANSLATE_NOOP("prcycoin-core", "" "Unable to bind to %s on this computer. PRCY is probably already running."), QT_TRANSLATE_NOOP("prcycoin-core", "" -"Unable to locate enough funds for this transaction that are not equal 10000 " -"PRCY."), -QT_TRANSLATE_NOOP("prcycoin-core", "" "Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: " "%s)"), QT_TRANSLATE_NOOP("prcycoin-core", "" +"Username and hashed password for JSON-RPC connections. The field " +"comes in the format: :$. A canonical python script is " +"included in share/rpcuser. This option can be specified multiple times"), +QT_TRANSLATE_NOOP("prcycoin-core", "" "Warning: -maxtxfee is set very high! Fees this large could be paid on a " "single transaction."), QT_TRANSLATE_NOOP("prcycoin-core", "" @@ -264,6 +275,7 @@ QT_TRANSLATE_NOOP("prcycoin-core", "Display verbose coin stake messages in the d QT_TRANSLATE_NOOP("prcycoin-core", "Do not load the wallet and disable wallet RPC calls"), QT_TRANSLATE_NOOP("prcycoin-core", "Do you want to rebuild the block database now?"), QT_TRANSLATE_NOOP("prcycoin-core", "Done loading"), +QT_TRANSLATE_NOOP("prcycoin-core", "Enable Old Transaction Deletion"), QT_TRANSLATE_NOOP("prcycoin-core", "Enable publish hash block in
"), QT_TRANSLATE_NOOP("prcycoin-core", "Enable publish hash transaction (locked via SwiftX) in
"), QT_TRANSLATE_NOOP("prcycoin-core", "Enable publish hash transaction in
"), @@ -282,7 +294,6 @@ QT_TRANSLATE_NOOP("prcycoin-core", "Error loading wallet.dat: Wallet corrupted") QT_TRANSLATE_NOOP("prcycoin-core", "Error loading wallet.dat: Wallet requires newer version of PRCYcoin"), QT_TRANSLATE_NOOP("prcycoin-core", "Error opening block database"), QT_TRANSLATE_NOOP("prcycoin-core", "Error reading from database, shutting down."), -QT_TRANSLATE_NOOP("prcycoin-core", "Error recovering public key."), QT_TRANSLATE_NOOP("prcycoin-core", "Error"), QT_TRANSLATE_NOOP("prcycoin-core", "Error: -listen must be true if -masternode is set."), QT_TRANSLATE_NOOP("prcycoin-core", "Error: A fatal internal error occured, see debug.log for details"), @@ -290,12 +301,10 @@ QT_TRANSLATE_NOOP("prcycoin-core", "Error: A fatal internal error occurred, see QT_TRANSLATE_NOOP("prcycoin-core", "Error: Disk space is low!"), QT_TRANSLATE_NOOP("prcycoin-core", "Error: Invalid port %d for running a masternode."), QT_TRANSLATE_NOOP("prcycoin-core", "Error: Unsupported argument -tor found, use -onion."), -QT_TRANSLATE_NOOP("prcycoin-core", "Failed to generate RingCT for Sweeping transaction"), -QT_TRANSLATE_NOOP("prcycoin-core", "Failed to generate bulletproof for Sweeping transaction"), +QT_TRANSLATE_NOOP("prcycoin-core", "Failed to generate RingCT"), QT_TRANSLATE_NOOP("prcycoin-core", "Failed to generate bulletproof"), QT_TRANSLATE_NOOP("prcycoin-core", "Failed to listen on any port. Use -listen=0 if you want this."), QT_TRANSLATE_NOOP("prcycoin-core", "Failed to parse host:port string"), -QT_TRANSLATE_NOOP("prcycoin-core", "Failed to read block"), QT_TRANSLATE_NOOP("prcycoin-core", "Fee (in %s/kB) to add to transactions you send (default: %s)"), QT_TRANSLATE_NOOP("prcycoin-core", "Force safe mode (default: %u)"), QT_TRANSLATE_NOOP("prcycoin-core", "Generate coins (default: %u)"), @@ -318,9 +327,10 @@ QT_TRANSLATE_NOOP("prcycoin-core", "Invalid amount for -reservebalance=" QT_TRANSLATE_NOOP("prcycoin-core", "Invalid masternodeprivkey. Please see documenation."), QT_TRANSLATE_NOOP("prcycoin-core", "Invalid netmask specified in -whitelist: '%s'"), QT_TRANSLATE_NOOP("prcycoin-core", "Invalid port %d detected in masternode.conf"), -QT_TRANSLATE_NOOP("prcycoin-core", "Invalid private key."), QT_TRANSLATE_NOOP("prcycoin-core", "Keep at most unconnectable transactions in memory (default: %u)"), -QT_TRANSLATE_NOOP("prcycoin-core", "Limit size of signature cache to entries (default: %u)"), +QT_TRANSLATE_NOOP("prcycoin-core", "Keep the last transactions (default: %i)"), +QT_TRANSLATE_NOOP("prcycoin-core", "Keep transactions for at least blocks (default: %i)"), +QT_TRANSLATE_NOOP("prcycoin-core", "Limit size of signature cache to MiB (default: %u)"), QT_TRANSLATE_NOOP("prcycoin-core", "Line: %d"), QT_TRANSLATE_NOOP("prcycoin-core", "Listen for JSON-RPC connections on (default: %u or testnet: %u)"), QT_TRANSLATE_NOOP("prcycoin-core", "Listen for connections on (default: %u or testnet: %u)"), @@ -341,6 +351,7 @@ QT_TRANSLATE_NOOP("prcycoin-core", "Need to specify a port with -whitebind: '%s' QT_TRANSLATE_NOOP("prcycoin-core", "Node relay options:"), QT_TRANSLATE_NOOP("prcycoin-core", "Not enough file descriptors available."), QT_TRANSLATE_NOOP("prcycoin-core", "Number of automatic wallet backups (default: 10)"), +QT_TRANSLATE_NOOP("prcycoin-core", "Number of custom location backups to retain (default: %d)"), QT_TRANSLATE_NOOP("prcycoin-core", "Only accept block chain matching built-in checkpoints (default: %u)"), QT_TRANSLATE_NOOP("prcycoin-core", "Only connect to nodes in network (ipv4, ipv6 or onion)"), QT_TRANSLATE_NOOP("prcycoin-core", "Options:"), @@ -361,7 +372,6 @@ QT_TRANSLATE_NOOP("prcycoin-core", "Rescanning..."), QT_TRANSLATE_NOOP("prcycoin-core", "Run a thread to flush wallet periodically (default: %u)"), QT_TRANSLATE_NOOP("prcycoin-core", "Run in the background as a daemon and accept commands"), QT_TRANSLATE_NOOP("prcycoin-core", "Send transactions as zero-fee transactions if possible (default: %u)"), -QT_TRANSLATE_NOOP("prcycoin-core", "Session timed out."), QT_TRANSLATE_NOOP("prcycoin-core", "Set database cache size in megabytes (%d to %d, default: %d)"), QT_TRANSLATE_NOOP("prcycoin-core", "Set external address:port to get to this masternode (example: %s)"), QT_TRANSLATE_NOOP("prcycoin-core", "Set key pool size to (default: %u)"), @@ -373,8 +383,6 @@ QT_TRANSLATE_NOOP("prcycoin-core", "Set the number of threads to service RPC cal QT_TRANSLATE_NOOP("prcycoin-core", "Sets the DB_PRIVATE flag in the wallet db environment (default: %u)"), QT_TRANSLATE_NOOP("prcycoin-core", "Show all debugging options (usage: --help -help-debug)"), QT_TRANSLATE_NOOP("prcycoin-core", "Shrink debug.log file on client startup (default: 1 when no -debug)"), -QT_TRANSLATE_NOOP("prcycoin-core", "Signing failed."), -QT_TRANSLATE_NOOP("prcycoin-core", "Signing timed out."), QT_TRANSLATE_NOOP("prcycoin-core", "Signing transaction failed"), QT_TRANSLATE_NOOP("prcycoin-core", "Specify configuration file (default: %s)"), QT_TRANSLATE_NOOP("prcycoin-core", "Specify connection timeout in milliseconds (minimum: 1, default: %d)"), @@ -412,6 +420,7 @@ QT_TRANSLATE_NOOP("prcycoin-core", "Upgrade wallet to latest format"), QT_TRANSLATE_NOOP("prcycoin-core", "Use UPnP to map the listening port (default: %u)"), QT_TRANSLATE_NOOP("prcycoin-core", "Use UPnP to map the listening port (default: 1 when listening)"), QT_TRANSLATE_NOOP("prcycoin-core", "Use a custom max chain reorganization depth (default: %u)"), +QT_TRANSLATE_NOOP("prcycoin-core", "Use block spam filter (default: %u)"), QT_TRANSLATE_NOOP("prcycoin-core", "Use the test network"), QT_TRANSLATE_NOOP("prcycoin-core", "User Agent comment (%s) contains unsafe characters."), QT_TRANSLATE_NOOP("prcycoin-core", "Username for JSON-RPC connections"), diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp index 01e05d5d42..f5708f8f6e 100644 --- a/src/qt/receivecoinsdialog.cpp +++ b/src/qt/receivecoinsdialog.cpp @@ -189,13 +189,13 @@ void ReceiveCoinsDialog::updateDisplayUnit() void ReceiveCoinsDialog::on_receiveButton_clicked() { double dAmount = ui->reqAmount->text().toDouble(); - if (dAmount < 0.0 || dAmount > MAX_MONEY_OUT) { - QMessageBox msgBox; - msgBox.setWindowTitle("Invalid Amount"); - msgBox.setText("Invalid amount entered. Please enter an amount less than 2.1B PRCY."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Warning); - msgBox.exec(); + CAmount maxMoneyInCoins = MAX_MONEY_OUT / COIN; + CAmount maxMoneyInMillions = maxMoneyInCoins / 1000000; + if (dAmount < 0.0 || dAmount > maxMoneyInCoins) { + GUIUtil::showMessageBox( + tr("Invalid Amount"), + tr("Invalid amount entered. Please enter an amount less than %1 (%2M) PRCY.").arg(maxMoneyInCoins).arg(maxMoneyInMillions), + QMessageBox::Warning); return; } if (!model || !model->getOptionsModel() || !model->getAddressTableModel()) diff --git a/src/qt/res/movies/makespinner.sh b/src/qt/res/movies/makespinner.sh new file mode 100644 index 0000000000..625fb17173 --- /dev/null +++ b/src/qt/res/movies/makespinner.sh @@ -0,0 +1,6 @@ +for i in {1..35} +do + value=$(printf "%03d" $i) + angle=$(($i * 10)) + convert spinner-000.png -background "rgba(0,0,0,0.0)" -distort SRT $angle spinner-$value.png +done diff --git a/src/qt/res/movies/spinner-000.png b/src/qt/res/movies/spinner-000.png index 1749c85928..1e92d859da 100644 Binary files a/src/qt/res/movies/spinner-000.png and b/src/qt/res/movies/spinner-000.png differ diff --git a/src/qt/res/movies/spinner-001.png b/src/qt/res/movies/spinner-001.png index d464820687..d167f20541 100644 Binary files a/src/qt/res/movies/spinner-001.png and b/src/qt/res/movies/spinner-001.png differ diff --git a/src/qt/res/movies/spinner-002.png b/src/qt/res/movies/spinner-002.png index aca0c7f307..4a1f1f8e56 100644 Binary files a/src/qt/res/movies/spinner-002.png and b/src/qt/res/movies/spinner-002.png differ diff --git a/src/qt/res/movies/spinner-003.png b/src/qt/res/movies/spinner-003.png index 8d24983238..fb1c2cd4ad 100644 Binary files a/src/qt/res/movies/spinner-003.png and b/src/qt/res/movies/spinner-003.png differ diff --git a/src/qt/res/movies/spinner-004.png b/src/qt/res/movies/spinner-004.png index ec616718b2..4df2132344 100644 Binary files a/src/qt/res/movies/spinner-004.png and b/src/qt/res/movies/spinner-004.png differ diff --git a/src/qt/res/movies/spinner-005.png b/src/qt/res/movies/spinner-005.png index 74790b142c..5d6f41e0dc 100644 Binary files a/src/qt/res/movies/spinner-005.png and b/src/qt/res/movies/spinner-005.png differ diff --git a/src/qt/res/movies/spinner-006.png b/src/qt/res/movies/spinner-006.png index 941fd7891b..c1f7d18899 100644 Binary files a/src/qt/res/movies/spinner-006.png and b/src/qt/res/movies/spinner-006.png differ diff --git a/src/qt/res/movies/spinner-007.png b/src/qt/res/movies/spinner-007.png index 94bca7d10d..1e794b2626 100644 Binary files a/src/qt/res/movies/spinner-007.png and b/src/qt/res/movies/spinner-007.png differ diff --git a/src/qt/res/movies/spinner-008.png b/src/qt/res/movies/spinner-008.png index 598cce1720..df12ea8719 100644 Binary files a/src/qt/res/movies/spinner-008.png and b/src/qt/res/movies/spinner-008.png differ diff --git a/src/qt/res/movies/spinner-009.png b/src/qt/res/movies/spinner-009.png index 60ffe62aec..18fc3a7d16 100644 Binary files a/src/qt/res/movies/spinner-009.png and b/src/qt/res/movies/spinner-009.png differ diff --git a/src/qt/res/movies/spinner-010.png b/src/qt/res/movies/spinner-010.png index 437bf7c9db..a79c845fe8 100644 Binary files a/src/qt/res/movies/spinner-010.png and b/src/qt/res/movies/spinner-010.png differ diff --git a/src/qt/res/movies/spinner-011.png b/src/qt/res/movies/spinner-011.png index 3f5dda7d37..57baf66895 100644 Binary files a/src/qt/res/movies/spinner-011.png and b/src/qt/res/movies/spinner-011.png differ diff --git a/src/qt/res/movies/spinner-012.png b/src/qt/res/movies/spinner-012.png index c15aefdf9f..9deae7853a 100644 Binary files a/src/qt/res/movies/spinner-012.png and b/src/qt/res/movies/spinner-012.png differ diff --git a/src/qt/res/movies/spinner-013.png b/src/qt/res/movies/spinner-013.png index 810712dde0..0659d48dec 100644 Binary files a/src/qt/res/movies/spinner-013.png and b/src/qt/res/movies/spinner-013.png differ diff --git a/src/qt/res/movies/spinner-014.png b/src/qt/res/movies/spinner-014.png index 0adba83405..bc1ef51bde 100644 Binary files a/src/qt/res/movies/spinner-014.png and b/src/qt/res/movies/spinner-014.png differ diff --git a/src/qt/res/movies/spinner-015.png b/src/qt/res/movies/spinner-015.png index b7e25b395a..24b57b62c2 100644 Binary files a/src/qt/res/movies/spinner-015.png and b/src/qt/res/movies/spinner-015.png differ diff --git a/src/qt/res/movies/spinner-016.png b/src/qt/res/movies/spinner-016.png index d2fdb2deb5..d622872651 100644 Binary files a/src/qt/res/movies/spinner-016.png and b/src/qt/res/movies/spinner-016.png differ diff --git a/src/qt/res/movies/spinner-017.png b/src/qt/res/movies/spinner-017.png index 055fc2828c..f48f688db2 100644 Binary files a/src/qt/res/movies/spinner-017.png and b/src/qt/res/movies/spinner-017.png differ diff --git a/src/qt/res/movies/spinner-018.png b/src/qt/res/movies/spinner-018.png index db306aa4e8..a2c8f38b1d 100644 Binary files a/src/qt/res/movies/spinner-018.png and b/src/qt/res/movies/spinner-018.png differ diff --git a/src/qt/res/movies/spinner-019.png b/src/qt/res/movies/spinner-019.png index f5b7806b9f..9d7cc35d82 100644 Binary files a/src/qt/res/movies/spinner-019.png and b/src/qt/res/movies/spinner-019.png differ diff --git a/src/qt/res/movies/spinner-020.png b/src/qt/res/movies/spinner-020.png index a84853d59c..1a07acc454 100644 Binary files a/src/qt/res/movies/spinner-020.png and b/src/qt/res/movies/spinner-020.png differ diff --git a/src/qt/res/movies/spinner-021.png b/src/qt/res/movies/spinner-021.png index 7dcc2f672a..9cea8f2543 100644 Binary files a/src/qt/res/movies/spinner-021.png and b/src/qt/res/movies/spinner-021.png differ diff --git a/src/qt/res/movies/spinner-022.png b/src/qt/res/movies/spinner-022.png index ae8c3ddc94..60250f6dea 100644 Binary files a/src/qt/res/movies/spinner-022.png and b/src/qt/res/movies/spinner-022.png differ diff --git a/src/qt/res/movies/spinner-023.png b/src/qt/res/movies/spinner-023.png index 4db3407003..fc290a0cf2 100644 Binary files a/src/qt/res/movies/spinner-023.png and b/src/qt/res/movies/spinner-023.png differ diff --git a/src/qt/res/movies/spinner-024.png b/src/qt/res/movies/spinner-024.png index d29feb4c56..c5dcf1eae9 100644 Binary files a/src/qt/res/movies/spinner-024.png and b/src/qt/res/movies/spinner-024.png differ diff --git a/src/qt/res/movies/spinner-025.png b/src/qt/res/movies/spinner-025.png index b399a26210..7f3577a4de 100644 Binary files a/src/qt/res/movies/spinner-025.png and b/src/qt/res/movies/spinner-025.png differ diff --git a/src/qt/res/movies/spinner-026.png b/src/qt/res/movies/spinner-026.png index e692a637b2..1663ddf44c 100644 Binary files a/src/qt/res/movies/spinner-026.png and b/src/qt/res/movies/spinner-026.png differ diff --git a/src/qt/res/movies/spinner-027.png b/src/qt/res/movies/spinner-027.png index 74205bc22e..d0e6da4503 100644 Binary files a/src/qt/res/movies/spinner-027.png and b/src/qt/res/movies/spinner-027.png differ diff --git a/src/qt/res/movies/spinner-028.png b/src/qt/res/movies/spinner-028.png index 912279c8f6..2a7aba50e2 100644 Binary files a/src/qt/res/movies/spinner-028.png and b/src/qt/res/movies/spinner-028.png differ diff --git a/src/qt/res/movies/spinner-029.png b/src/qt/res/movies/spinner-029.png index 27f1d5218c..c8ca15c1e1 100644 Binary files a/src/qt/res/movies/spinner-029.png and b/src/qt/res/movies/spinner-029.png differ diff --git a/src/qt/res/movies/spinner-030.png b/src/qt/res/movies/spinner-030.png index cc8af11030..c847c99a93 100644 Binary files a/src/qt/res/movies/spinner-030.png and b/src/qt/res/movies/spinner-030.png differ diff --git a/src/qt/res/movies/spinner-031.png b/src/qt/res/movies/spinner-031.png index 0d0a5b182b..403443144e 100644 Binary files a/src/qt/res/movies/spinner-031.png and b/src/qt/res/movies/spinner-031.png differ diff --git a/src/qt/res/movies/spinner-032.png b/src/qt/res/movies/spinner-032.png index 63026d656d..f9db080567 100644 Binary files a/src/qt/res/movies/spinner-032.png and b/src/qt/res/movies/spinner-032.png differ diff --git a/src/qt/res/movies/spinner-033.png b/src/qt/res/movies/spinner-033.png index 7550af7b7a..43f57719e7 100644 Binary files a/src/qt/res/movies/spinner-033.png and b/src/qt/res/movies/spinner-033.png differ diff --git a/src/qt/res/movies/spinner-034.png b/src/qt/res/movies/spinner-034.png index afcd2c2826..c26656ff17 100644 Binary files a/src/qt/res/movies/spinner-034.png and b/src/qt/res/movies/spinner-034.png differ diff --git a/src/qt/res/movies/spinner-035.png b/src/qt/res/movies/spinner-035.png new file mode 100644 index 0000000000..e471f950a3 Binary files /dev/null and b/src/qt/res/movies/spinner-035.png differ diff --git a/src/qt/revealtxdialog.cpp b/src/qt/revealtxdialog.cpp index 9f9e3dab2b..48df507fe3 100644 --- a/src/qt/revealtxdialog.cpp +++ b/src/qt/revealtxdialog.cpp @@ -17,38 +17,7 @@ RevealTxDialog::RevealTxDialog(QWidget *parent) : { ui->setupUi(this); - ui->pushButtonCopyID->setStyleSheet("background:transparent;"); - ui->pushButtonCopyID->setIcon(QIcon(":/icons/editcopy")); - connect(ui->pushButtonCopyID, SIGNAL(clicked()), this, SLOT(copyID())); - - ui->pushButtonCopyAddr->setStyleSheet("background:transparent;"); - ui->pushButtonCopyAddr->setIcon(QIcon(":/icons/editcopy")); - connect(ui->pushButtonCopyAddr, SIGNAL(clicked()), this, SLOT(copyAddress())); - - ui->pushButtonCopyPrivKey->setStyleSheet("background:transparent;"); - ui->pushButtonCopyPrivKey->setIcon(QIcon(":/icons/editcopy")); - connect(ui->pushButtonCopyPrivKey, SIGNAL(clicked()), this, SLOT(copyPrivateKey())); - - ui->pushButtonCopyTxAmount->setStyleSheet("background:transparent;"); - ui->pushButtonCopyTxAmount->setIcon(QIcon(":/icons/editcopy")); - connect(ui->pushButtonCopyTxAmount, SIGNAL(clicked()), this, SLOT(copyTxAmount())); - - ui->pushButtonCopyTxFee->setStyleSheet("background:transparent;"); - ui->pushButtonCopyTxFee->setIcon(QIcon(":/icons/editcopy")); - connect(ui->pushButtonCopyTxFee, SIGNAL(clicked()), this, SLOT(copyTxFee())); - - ui->pushButtonCopyTxPaymentID->setStyleSheet("background:transparent;"); - ui->pushButtonCopyTxPaymentID->setIcon(QIcon(":/icons/editcopy")); - connect(ui->pushButtonCopyTxPaymentID, SIGNAL(clicked()), this, SLOT(copyTxPaymentID())); - - ui->pushButtonCopyTxRingSize->setStyleSheet("background:transparent;"); - ui->pushButtonCopyTxRingSize->setIcon(QIcon(":/icons/editcopy")); - connect(ui->pushButtonCopyTxRingSize, SIGNAL(clicked()), this, SLOT(copyTxRingSize())); - - ui->pushButtonOpenTXID->setStyleSheet("background:transparent;"); - ui->pushButtonOpenTXID->setIcon(QIcon(":/icons/eye")); - connect(ui->pushButtonOpenTXID, SIGNAL(clicked()), this, SLOT(openTXinExplorer())); - + setupButtons(); ui->buttonBox->button(QDialogButtonBox::Reset)->setText("Delete Transaction?"); connect(ui->buttonBox->button(QDialogButtonBox::Reset), SIGNAL(clicked()), this, SLOT(deleteTransaction())); } @@ -58,6 +27,45 @@ RevealTxDialog::~RevealTxDialog() delete ui; } +struct ButtonInfo +{ + QString name; + void (RevealTxDialog::*slot)(); +}; + +void RevealTxDialog::setupButtons() +{ + std::vector buttons = { + {"pushButtonCopyID", &RevealTxDialog::copyID}, + {"pushButtonCopyAddr", &RevealTxDialog::copyAddress}, + {"pushButtonCopyPrivKey", &RevealTxDialog::copyPrivateKey}, + {"pushButtonCopyTxAmount", &RevealTxDialog::copyTxAmount}, + {"pushButtonCopyTxFee", &RevealTxDialog::copyTxFee}, + {"pushButtonCopyTxPaymentID", &RevealTxDialog::copyTxPaymentID}, + {"pushButtonCopyTxRingSize", &RevealTxDialog::copyTxRingSize}, + {"pushButtonOpenTXID", &RevealTxDialog::openTXinExplorer}, + {"pushButtonCopyBlockHash", &RevealTxDialog::copyBlockHash}, + {"pushButtonCopyBlockHeight", &RevealTxDialog::copyBlockHeight}, + {"pushButtonOpenBlock", &RevealTxDialog::openBlockInExplorer}, + {"pushButtonOpenBlock1", &RevealTxDialog::openBlockInExplorer}, + }; + + for(const auto& button : buttons) + { + QPushButton *pushButton = this->findChild(button.name); + if(pushButton != nullptr) + { + pushButton->setStyleSheet("background:transparent;"); + if(button.name == "pushButtonOpenTXID" || button.name == "pushButtonOpenBlock" || button.name == "pushButtonOpenBlock1") { + pushButton->setIcon(QIcon(":/icons/eye")); + } else { + pushButton->setIcon(QIcon(":/icons/editcopy")); + } + connect(pushButton, &QPushButton::clicked, this, button.slot); + } + } +} + void RevealTxDialog::setTxID(QString strId) { ui->lblTxID->setText(strId); @@ -73,16 +81,16 @@ void RevealTxDialog::setTxPrivKey(QString strPrivKey) ui->lblPrivateKey->setText(strPrivKey); } -void RevealTxDialog::setTxAmount(QString amount) +void RevealTxDialog::setTxAmount(CAmount amount) { int nDisplayUnit; - ui->lblTxAmount->setText(amount.append(" PRCY")); + ui->lblTxAmount->setText(BitcoinUnits::format(nDisplayUnit, amount, false, BitcoinUnits::separatorAlways)); } void RevealTxDialog::setTxFee(CAmount fee) { int nDisplayUnit; - ui->lblTxFee->setText(BitcoinUnits::formatHtmlWithUnit(0, fee, false, BitcoinUnits::separatorAlways)); + ui->lblTxFee->setText(BitcoinUnits::format(nDisplayUnit, fee, false, BitcoinUnits::separatorAlways)); } void RevealTxDialog::setTxPaymentID(uint64_t paymentID) @@ -100,6 +108,16 @@ void RevealTxDialog::setTxRingSize(int64_t ringSize) ui->lblTxRingSize->setText(QString::number(ringSize)); } +void RevealTxDialog::setBlockHeight(int blockHeight) +{ + ui->lblBlockHeight->setText(QString::number(blockHeight)); +} + +void RevealTxDialog::setBlockHash(QString blockHash) +{ + ui->lblBlockHash->setText(blockHash); +} + void RevealTxDialog::on_buttonBox_accepted() { //We currently don't do anything on accept @@ -140,6 +158,16 @@ void RevealTxDialog::copyTxRingSize(){ clipboard->setText(ui->lblTxRingSize->text()); } +void RevealTxDialog::copyBlockHeight(){ + QClipboard *clipboard = QApplication::clipboard(); + clipboard->setText(ui->lblBlockHeight->text()); +} + +void RevealTxDialog::copyBlockHash(){ + QClipboard *clipboard = QApplication::clipboard(); + clipboard->setText(ui->lblBlockHash->text()); +} + void RevealTxDialog::openTXinExplorer() { QString URL; @@ -152,6 +180,18 @@ void RevealTxDialog::openTXinExplorer() QDesktopServices::openUrl(QUrl(URL.append(ui->lblTxID->text()))); } +void RevealTxDialog::openBlockInExplorer() +{ + QString URL; + // Adjust link depending on Network + if (Params().NetworkID() == CBaseChainParams::MAIN) { + URL = "https://explorer.prcycoin.com/block/"; + } else if (Params().NetworkID() == CBaseChainParams::TESTNET){ + URL = "https://testnet.prcycoin.com/block/"; + } + QDesktopServices::openUrl(QUrl(URL.append(ui->lblBlockHash->text()))); +} + void RevealTxDialog::deleteTransaction() { bool hideSuccess = settings.value("fHideDeleteSuccess", false).toBool(); @@ -178,16 +218,20 @@ void RevealTxDialog::deleteTransaction() // Check it exists if (!pwalletMain->mapWallet.count(hash)) { - QMessageBox msgBox; - msgBox.setWindowTitle(tr("Invalid or non-wallet transaction id")); - msgBox.setIcon(QMessageBox::Critical); - msgBox.setText(tr("Invalid or non-wallet transaction id.")); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.exec(); + GUIUtil::showMessageBox( + tr("Invalid or non-wallet transaction id"), + tr("Invalid or non-wallet transaction id."), + QMessageBox::Critical); return; } // Erase it - pwalletMain->EraseFromWallet(hash); + if (!pwalletMain->EraseFromWallet(hash)) { + GUIUtil::showMessageBox( + tr("Unable to delete transaction id"), + tr("Unable to delete transaction id."), + QMessageBox::Critical); + return; + } // Display Success! dialog if not disabled QMessageBox msgBox; diff --git a/src/qt/revealtxdialog.h b/src/qt/revealtxdialog.h index d93acba055..927c2cf94e 100644 --- a/src/qt/revealtxdialog.h +++ b/src/qt/revealtxdialog.h @@ -19,13 +19,16 @@ class RevealTxDialog : public QDialog explicit RevealTxDialog(QWidget *parent = 0); ~RevealTxDialog(); + void setupButtons(); void setTxID(QString strId); void setTxAddress(QString strAddr); void setTxPrivKey(QString strPrivKey); - void setTxAmount(QString amount); + void setTxAmount(CAmount amount); void setTxFee(CAmount fee); void setTxPaymentID(uint64_t paymentID); void setTxRingSize(int64_t ringSize); + void setBlockHeight(int blockheight); + void setBlockHash(QString blockHash); private Q_SLOTS: void on_buttonBox_accepted(); @@ -36,7 +39,10 @@ private Q_SLOTS: void copyTxFee(); void copyTxPaymentID(); void copyTxRingSize(); + void copyBlockHash(); + void copyBlockHeight(); void openTXinExplorer(); + void openBlockInExplorer(); void deleteTransaction(); private: diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 2d72e0b5b6..dc2db159ab 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -88,7 +88,7 @@ class QtRPCTimerBase: public QObject, public RPCTimerBase { Q_OBJECT public: - QtRPCTimerBase(boost::function& func, int64_t millis): + QtRPCTimerBase(std::function& func, int64_t millis): func(func) { timer.setSingleShot(true); @@ -100,7 +100,7 @@ private Q_SLOTS: void timeout() { func(); } private: QTimer timer; - boost::function func; + std::function func; }; class QtRPCTimerInterface: public RPCTimerInterface @@ -108,7 +108,7 @@ class QtRPCTimerInterface: public RPCTimerInterface public: ~QtRPCTimerInterface() {} const char *Name() { return "Qt"; } - RPCTimerBase* NewTimer(boost::function& func, int64_t millis) + RPCTimerBase* NewTimer(std::function& func, int64_t millis) { return new QtRPCTimerBase(func, millis); } @@ -487,7 +487,6 @@ void RPCConsole::setClientModel(ClientModel* model) // Provide initial values ui->clientVersion->setText(model->formatFullVersion()); ui->clientName->setText(model->clientName()); - ui->buildDate->setText(model->formatBuildDate()); ui->dataDir->setText(model->dataDir()); ui->startupTime->setText(model->formatClientStartupTime()); ui->networkName->setText(QString::fromStdString(Params().NetworkIDString())); diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index 90a38ed3c6..7b76261a9e 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -140,12 +140,10 @@ SendCoinsDialog::~SendCoinsDialog(){ void SendCoinsDialog::on_sendButton_clicked(){ if (!masternodeSync.IsBlockchainSynced()) { - QMessageBox msgBox; - msgBox.setWindowTitle("Send Disabled - Syncing"); - msgBox.setText("Sending PRCY is disabled when you are still syncing the wallet. Please allow the wallet to fully sync before attempting to send a transaction."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Warning); - msgBox.exec(); + GUIUtil::showMessageBox( + tr("Send Disabled - Syncing"), + tr("Sending PRCY is disabled when you are still syncing the wallet. Please allow the wallet to fully sync before attempting to send a transaction."), + QMessageBox::Warning); return; } if (!ui->entries->count()) @@ -166,22 +164,18 @@ void SendCoinsDialog::on_sendButton_clicked(){ form->errorAmount(isValidAmount); if (!isValidAddresss) { - QMessageBox msgBox; - msgBox.setWindowTitle("Invalid Address"); - msgBox.setText("Invalid address entered. Please make sure you are sending to a Stealth Address."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Warning); - msgBox.exec(); + GUIUtil::showMessageBox( + tr("Invalid Address"), + tr("Invalid address entered. Please make sure you are sending to a Stealth Address."), + QMessageBox::Warning); return; } if (!isValidAmount) { - QMessageBox msgBox; - msgBox.setWindowTitle("Invalid Amount"); - msgBox.setText("Invalid amount entered. Please enter an amount less than your Spendable Balance."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Warning); - msgBox.exec(); + GUIUtil::showMessageBox( + tr("Invalid Amount"), + tr("Invalid amount entered. Please enter an amount less than your Spendable Balance."), + QMessageBox::Warning); return; } @@ -251,19 +245,15 @@ void SendCoinsDialog::on_sendButton_clicked(){ CAmount spendable = pwalletMain->GetSpendableBalance(); if (!(recipient.amount <= nReserveBalance && recipient.amount <= spendable)) { if (recipient.amount > spendable) { - QMessageBox msgBox; - msgBox.setWindowTitle("Insufficient Spendable Funds!"); - msgBox.setText("Insufficient spendable funds. Send with smaller amount or wait for your coins become mature"); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Information); - msgBox.exec(); + GUIUtil::showMessageBox( + tr("Insufficient Spendable Funds!"), + tr("Insufficient spendable funds. Send with smaller amount or wait for your coins become mature"), + QMessageBox::Information); } else if (recipient.amount > nReserveBalance) { - QMessageBox msgBox; - msgBox.setWindowTitle("Insufficient Reserve Funds!"); - msgBox.setText("Insufficient reserve funds. Send with smaller amount or turn off staking mode."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Information); - msgBox.exec(); + GUIUtil::showMessageBox( + tr("Insufficient Reserve Funds!"), + tr("Insufficient reserve funds. Send with smaller amount or turn off staking mode."), + QMessageBox::Information); } return; } @@ -328,30 +318,23 @@ void SendCoinsDialog::sendTx() { send_amount, nTime); nReserveBalance = backupReserve; if (success) { - QString msg = "Consolidation transaction created!"; - QMessageBox msgBox; - msgBox.setWindowTitle("Information"); - msgBox.setIcon(QMessageBox::Information); - msgBox.setText(msg); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.exec(); + GUIUtil::showMessageBox( + tr("Information"), + tr("Consolidation transaction created!"), + QMessageBox::Information); } else { - QMessageBox msgBox; - msgBox.setWindowTitle("Sweeping Transaction Creation Error"); - msgBox.setText(QString("Sweeping transaction creation failed due to an internal error. Please try again later.")); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); + GUIUtil::showMessageBox( + tr("Sweeping Transaction Creation Error"), + tr("Sweeping transaction creation failed due to an internal error. Please try again later."), + QMessageBox::Critical); } } catch (const std::exception& err1) { nReserveBalance = backupReserve; - QMessageBox msgBox; LogPrintf("ERROR:%s: %s\n", __func__, err1.what()); - msgBox.setWindowTitle("Sweeping Transaction Creation Error"); - msgBox.setText(QString("Sweeping transaction creation failed due to an internal error. Please try again later.")); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); + GUIUtil::showMessageBox( + tr("Sweeping Transaction Creation Error"), + tr("Sweeping transaction creation failed due to an internal error. Please try again later."), + QMessageBox::Critical); } return; } else { @@ -359,15 +342,13 @@ void SendCoinsDialog::sendTx() { } } else { QString msg = err.what(); - if (msg == "") { - msg = "Unable to create transaction. Please try again later."; + if (msg.isEmpty()) { + msg = tr("Unable to create transaction. Please try again later."); } - QMessageBox msgBox; - msgBox.setWindowTitle("Transaction Creation Error"); - msgBox.setText(msg); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Critical); - msgBox.exec(); + GUIUtil::showMessageBox( + tr("Transaction Creation Error"), + msg, + QMessageBox::Critical); } return; } @@ -380,11 +361,12 @@ void SendCoinsDialog::sendTx() { pwalletMain->ComputeStealthPublicAddress("masteraccount", myAddress); bool showCheckBox = false; int indexOut = -1; + const CAmount collateralAmount = Params().MNCollateralAmt(); if (sendAddress == myAddress) { for (int i=0; i < (int)resultTx.vout.size(); i++) { CTxOut& out = resultTx.vout[i]; CAmount value = pwalletMain->getCTxOutValue(resultTx, out); - if (value == Params().MNCollateralAmt()) { + if (value == collateralAmount) { showCheckBox = true; indexOut = i; } diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp index 2edbbd2c5e..3636689870 100644 --- a/src/qt/sendcoinsentry.cpp +++ b/src/qt/sendcoinsentry.cpp @@ -129,15 +129,16 @@ static inline int64_t roundint64(double d) return (int64_t)(d > 0 ? d + 0.5 : d - 0.5); } -CAmount SendCoinsEntry::getValidatedAmount() { +CAmount SendCoinsEntry::getValidatedAmount() +{ double dAmount = ui->payAmount->text().toDouble(); - if (dAmount < 0.0 || dAmount > MAX_MONEY_OUT) { - QMessageBox msgBox; - msgBox.setWindowTitle("Invalid Amount"); - msgBox.setText("Invalid amount entered. Please enter an amount less than 2.1B PRCY."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.setIcon(QMessageBox::Warning); - msgBox.exec(); + CAmount maxMoneyInCoins = MAX_MONEY_OUT / COIN; + CAmount maxMoneyInMillions = maxMoneyInCoins / 1000000; + if (dAmount < 0.0 || dAmount > maxMoneyInCoins) { + GUIUtil::showMessageBox( + tr("Invalid Amount"), + tr("Invalid amount entered. Please enter an amount less than %1 (%2M) PRCY.").arg(maxMoneyInCoins).arg(maxMoneyInMillions), + QMessageBox::Warning); } CAmount nAmount = roundint64(dAmount * COIN); return nAmount; @@ -145,11 +146,6 @@ CAmount SendCoinsEntry::getValidatedAmount() { SendCoinsRecipient SendCoinsEntry::getValue() { - // Payment request - if (recipient.paymentRequest.IsInitialized()) - return recipient; - - // Normal payment recipient.address = ui->payTo->text(); recipient.label = ui->addAsLabel->text(); recipient.amount = getValidatedAmount(); @@ -169,24 +165,6 @@ void SendCoinsEntry::setValue(const SendCoinsRecipient& value) { recipient = value; - if (recipient.paymentRequest.IsInitialized()) // payment request - { - if (recipient.authenticatedMerchant.isEmpty()) // insecure - { - ui->payTo_is->setText(recipient.address); - ui->memoTextLabel_is->setText(recipient.message); - ui->payAmount_is->setValue(recipient.amount); - ui->payAmount_is->setReadOnly(true); - setCurrentWidget(ui->SendCoins_InsecurePaymentRequest); - } else // secure - { - ui->payTo_s->setText(recipient.authenticatedMerchant); - ui->memoTextLabel_s->setText(recipient.message); - ui->payAmount_s->setValue(recipient.amount); - ui->payAmount_s->setReadOnly(true); - setCurrentWidget(ui->SendCoins_SecurePaymentRequest); - } - } else // normal payment { ui->addAsLabel->clear(); ui->payTo->setText(recipient.address); // this may set a label from addressbook diff --git a/src/qt/test/paymentrequestdata.h b/src/qt/test/paymentrequestdata.h deleted file mode 100644 index aeaa7d89a0..0000000000 --- a/src/qt/test/paymentrequestdata.h +++ /dev/null @@ -1,311 +0,0 @@ -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -// -// Data for paymentservertests.cpp -// - -// Base64/DER-encoded fake certificate authority certificate. -// Convert pem to base64/der with: -// cat file.pem | openssl x509 -inform PEM -outform DER | openssl enc -base64 -// -// Serial Number: 10302349811211485352 (0x8ef94c91b112c0a8) -// Issuer: CN=PaymentRequest Test CA -// Subject: CN=PaymentRequest Test CA -// Not Valid After : Dec 8 16:37:24 2022 GMT -// -const char* caCert_BASE64 = -"\ -MIIB0DCCATmgAwIBAgIJAI75TJGxEsCoMA0GCSqGSIb3DQEBCwUAMCExHzAdBgNV\ -BAMTFlBheW1lbnRSZXF1ZXN0IFRlc3QgQ0EwHhcNMTIxMjEwMTYzNzI0WhcNMjIx\ -MjA4MTYzNzI0WjAhMR8wHQYDVQQDExZQYXltZW50UmVxdWVzdCBUZXN0IENBMIGf\ -MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCvua59nX9radoqDYyplcns5qdVDTN1\ -7tmcGixmMYOYU3UYMU55VSsJs0dWKnMm3COQDY+N63c0XSbRqarBcsLTkaNASuPX\ -FCv1VWuEKSyy5xe4zeoDU7CVSzlxtQD9wbZW/s3ISjgaXBpwn6eVmntb0JwYxxPc\ -M1u/hrMD8BDbSQIDAQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUA\ -A4GBADSaRgK5xe47XxycXBhHhr0Wgl4pAsFsufqA9aB9r8KNEHJ0yUvvbD/jaJJM\ -RtQcf0AJ9olzUMY4syehxbzUJP6aeXhZEYiMvdvcv9D55clq6+WLLlNT3jBgAaVn\ -p3waRjPD4bUX3nv+ojz5s4puw7Qq5QUZlhGsMzPvwDGCmZkL\ -"; - -// -// This payment request validates directly against the -// above certificate authority. -// -const char* paymentrequest1_BASE64 = -"\ -Egt4NTA5K3NoYTI1NhrxAwruAzCCAeowggFToAMCAQICAQEwDQYJKoZIhvcNAQEL\ -BQAwITEfMB0GA1UEAxMWUGF5bWVudFJlcXVlc3QgVGVzdCBDQTAeFw0xMjEyMTAx\ -NjM3MjRaFw0yMjEyMDgxNjM3MjRaMEMxGTAXBgNVBAMMEHRlc3RtZXJjaGFudC5v\ -cmcxJjAkBgNVBAoMHVBheW1lbnQgUmVxdWVzdCBUZXN0IE1lcmNoYW50MIGfMA0G\ -CSqGSIb3DQEBAQUAA4GNADCBiQKBgQDHkMy8W1u6HsWlSqdWTmMKf54gICxNfxbY\ -+rcMtAftr62hCYx2d2QiSRd1pCUzmo12IiSX3WxSHwaTnT3MFD6jRx6+zM6XdGar\ -I2zpYle11ANzu4gAthN17uRQHV2O5QxVtzNaMdKeJLXT2L9tfEdyL++9ZUqoQmdA\ -YG9ix330hQIDAQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4GB\ -AIkyO99KC68bi9PFRyQQ7nvn5GlQEb3Ca1bRG5+AKN9N5vc8rZ9G2hejtM8wEXni\ -eGBP+chVMsbTPEHKLrwREn7IvcyCcbAStaklPC3w0B/2idQSHskb6P3X13OR2bTH\ -a2+6wuhsOZRUrVNr24rM95DKx/eCC6JN1VW+qRPU6fqzIjQSHwiw2wYSGXapFJVg\ -igPI+6XpExtNLO/i1WFV8ZmoiKwYsuHFiwUqC1VuaXRUZXN0T25lKoABS0j59iMU\ -Uc9MdIfwsO1BskIET0eJSGNZ7eXb9N62u+qf831PMpEHkmlGpk8rHy92nPcgua/U\ -Yt8oZMn3QaTZ5A6HjJbc3A73eLylp1a0SwCl+KDMEvDQhqMn1jAVu2v92AH3uB7n\ -SiWVbw0tX/68iSQEGGfh9n6ee/8Myb3ICdw=\ -"; - -// -// Signed, but expired, merchant cert in the request -// -const char* paymentrequest2_BASE64 = -"\ -Egt4NTA5K3NoYTI1NhrsAwrpAzCCAeUwggFOoAMCAQICAQMwDQYJKoZIhvcNAQEL\ -BQAwITEfMB0GA1UEAxMWUGF5bWVudFJlcXVlc3QgVGVzdCBDQTAeFw0xMzAyMjMy\ -MTI2NDNaFw0xMzAyMjQyMTI2NDNaMD4xHDAaBgNVBAMME2V4cGlyZWRtZXJjaGFu\ -dC5vcmcxHjAcBgNVBAoMFUV4cGlyZWQgVGVzdCBNZXJjaGFudDCBnzANBgkqhkiG\ -9w0BAQEFAAOBjQAwgYkCgYEAx5DMvFtbuh7FpUqnVk5jCn+eICAsTX8W2Pq3DLQH\ -7a+toQmMdndkIkkXdaQlM5qNdiIkl91sUh8Gk509zBQ+o0cevszOl3RmqyNs6WJX\ -tdQDc7uIALYTde7kUB1djuUMVbczWjHSniS109i/bXxHci/vvWVKqEJnQGBvYsd9\ -9IUCAwEAAaMQMA4wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOBgQAaU137\ -j53rvSjlmYZpZ4RWTP7EdD6fl5ZxBeXHytN6DQL33H0eD7OFHt+ofc7E6D7keubl\ -UfCu+jOvt/MvvPUmtCI9yXZ0dNC4sjyETv+wQpxO0UNZwOM4uegdCzlo6Bi3pD4/\ -KKLdMkWuUfuPBmoammny74lZaOVr5deKXztTuCI0Eh8IsNsGEhl2qRSVYIoDyPul\ -6RMbTSzv4tVhVfGZqIisGLLhxYsFKgtVbml0VGVzdFR3byqAAXHuo4nZEPniLpkd\ -y30TkwBxVgprWJ18a9z/7Py35Qss/JMbOXbnBhJtmJCdIowHRI0aa+zqt3KKKAXi\ -mm+V4seMgxTcxMS+eDDkiTcB/RtWWSyRcS2ANjFeY0T4SLMwiCL9qWPi03hr8j96\ -tejrSPOBNSJ3Mi/q5u2Yl4gJZY2b\ -"; - -// -// 10-long chain, all intermediates valid -// -const char* paymentrequest3_BASE64 = -"\ -Egt4NTA5K3NoYTI1Nhq8JAr/AzCCAfswggFkoAMCAQICAQEwDQYJKoZIhvcNAQEL\ -BQAwPzEUMBIGA1UEAwwLdGVzdGNhOC5vcmcxJzAlBgNVBAoMHlBheW1lbnQgUmVx\ -dWVzdCBJbnRlcm1lZGlhdGUgODAeFw0xMzAyMjMyMjQyMzFaFw0yMzAyMjEyMjQy\ -MzFaMDYxGjAYBgNVBAMMEXRlc3RtZXJjaGFudDgub3JnMRgwFgYDVQQKDA9UZXN0\ -IE1lcmNoYW50IDgwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMMCHA3hiHbS\ -TKZ5K9jHRwE8NxkGp3IOx56PDB2diNkldG8XweTcRq7bBm7pdiBt4IVggtfs+6hE\ -hDYIOecyoAnVzPFTdvQ7KQdQ/fD9YLe6lk+o0edOqutPMyrxLFjSluXxEQyk7fdt\ -URloMMYfp3p1/hFCboA1rAsQ2RW38hR5AgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8w\ -DQYJKoZIhvcNAQELBQADgYEAPsdFatnc2RJSpvZsw+nCiPVsllycw5ELglq9vfJz\ -nJJucRxgzmqI2iuas1ugwbXn0BEIRLK7vMF/qBzQR6M/nTxttah+KEu+okjps9vJ\ -cIyhfTyGPC5xkHaHZ7sG+UHOFhPw0/kXn0x+pbVgBZ5315axqcp1R+DTSj/whMAr\ -n0AKiAQwggIEMIIBbaADAgECAgECMA0GCSqGSIb3DQEBCwUAMD8xFDASBgNVBAMM\ -C3Rlc3RjYTcub3JnMScwJQYDVQQKDB5QYXltZW50IFJlcXVlc3QgSW50ZXJtZWRp\ -YXRlIDcwHhcNMTMwMjIzMjI0MjMxWhcNMjMwMjIxMjI0MjMxWjA/MRQwEgYDVQQD\ -DAt0ZXN0Y2E4Lm9yZzEnMCUGA1UECgweUGF5bWVudCBSZXF1ZXN0IEludGVybWVk\ -aWF0ZSA4MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDexUFfxb1sThvabp7u\ -dZz59ciThGmmAW0nP4tjrgEACgvWIInr2dZpTHbiQNF34ycsk0le1JD93D7Qb8rd\ -25OrpaO8XS2Li2zjR9cleixXjSLwV/zv8zJ8yPl/27XL++PDTKBXVpJ8/Syp+9Ty\ -plV1BqDhqtIHb/QSHEkTQXjeYQIDAQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqG\ -SIb3DQEBCwUAA4GBACMooQVbkbIZ2DaPwHDc4ULwguG3VI2Kzj50UdExmHtzm2S4\ -MQei+n+HEPjtJAx5OY520+10nfuP+12H2DRLQmWmdvDpeQ/Cv0yavlw4ZRejRFo7\ -KS83C0wo5rd+qTvvOmAN4UTArWkzYcEUulPdiXnRamb0WQHTeVdIbHVkMormCogE\ -MIICBDCCAW2gAwIBAgIBAjANBgkqhkiG9w0BAQsFADA/MRQwEgYDVQQDDAt0ZXN0\ -Y2E2Lm9yZzEnMCUGA1UECgweUGF5bWVudCBSZXF1ZXN0IEludGVybWVkaWF0ZSA2\ -MB4XDTEzMDIyMzIyNDIzMVoXDTIzMDIyMTIyNDIzMVowPzEUMBIGA1UEAwwLdGVz\ -dGNhNy5vcmcxJzAlBgNVBAoMHlBheW1lbnQgUmVxdWVzdCBJbnRlcm1lZGlhdGUg\ -NzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAtjBRazrkebXAhXsbjimrMIRm\ -W/f9SwAHwXfc042keNtl0t2z6XE6UPcR2v/KrssXuCZgodeYxz6IM6lWosCM1xot\ -C3ChKKFBfVO30reuKBRUxXfKAFqxaG0YOAEzdZkkY9AGhqWloeSmgxpIfhInU0EF\ -JjCwrJ6IkijBatGoAAECAwEAAaMQMA4wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0B\ -AQsFAAOBgQDBRTi1MolmOA0niHYX0A2lN5QWHkCfX0A7GwyoMA3dvM45m/NYd4WB\ -X+HwfnfYcI6X9jOgNo5OWmc4GGsld0HlxwMYEKISBS9PbSHPBrb3TBOlw5ztQpXZ\ -91+bOhLux52Fr03sK7v9qExmBM12M8UR2ltpzAMiUgLLMHyPfiWkvQqIBDCCAgQw\ -ggFtoAMCAQICAQIwDQYJKoZIhvcNAQELBQAwPzEUMBIGA1UEAwwLdGVzdGNhNS5v\ -cmcxJzAlBgNVBAoMHlBheW1lbnQgUmVxdWVzdCBJbnRlcm1lZGlhdGUgNTAeFw0x\ -MzAyMjMyMjQyMzBaFw0yMzAyMjEyMjQyMzBaMD8xFDASBgNVBAMMC3Rlc3RjYTYu\ -b3JnMScwJQYDVQQKDB5QYXltZW50IFJlcXVlc3QgSW50ZXJtZWRpYXRlIDYwgZ8w\ -DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANJSH3xivX1t9olIdHsznI1aE9SD7t9i\ -SZJsIB0otoETHZRVv9M9LvyzBNK98ZV+kTOlST7PJgC0d9BQM9sgYApSRq5oqKDM\ -9FXbOm/yaReAbU3mkFNFw5roTlJ5ThEy0yOGT/DS0YBRaGIvRPRj2DiqDVdCZZ+w\ -4jo1IYHkZt4FAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQAD\ -gYEATm6+J1OmbrothO60xALKonWMBKr6hudb4amkFBqKbA9wMeM3jl+I/yKfz/Uf\ -xWuJ071IhiNv6Gxx5YwNvhUe1xMhUqHv0gpyK1Z47bD+kYS2se5sWNPNo3Y9qZDG\ -IXiGQxwHmrzaFk79Uy1xsmvsEz42w6hr25Yaw7HkIgrFveoKiAQwggIEMIIBbaAD\ -AgECAgECMA0GCSqGSIb3DQEBCwUAMD8xFDASBgNVBAMMC3Rlc3RjYTQub3JnMScw\ -JQYDVQQKDB5QYXltZW50IFJlcXVlc3QgSW50ZXJtZWRpYXRlIDQwHhcNMTMwMjIz\ -MjI0MjMwWhcNMjMwMjIxMjI0MjMwWjA/MRQwEgYDVQQDDAt0ZXN0Y2E1Lm9yZzEn\ -MCUGA1UECgweUGF5bWVudCBSZXF1ZXN0IEludGVybWVkaWF0ZSA1MIGfMA0GCSqG\ -SIb3DQEBAQUAA4GNADCBiQKBgQC7vVUFpxHzz2Tr/xij3k58s8d/BPA0R6D5RXTV\ -vmhAzc1Zuin4zUKRFs/aCj/0yED8Wu/COfNGF4tVlRNMdl9EcFsxa8XGEL4eAZa+\ -H/rOHH+7/1EINrrVWhZlUecyhilN8jmCZmqEM3ecuD0NAViqyMrgmaiFmsLoQZpE\ -GepDUQIDAQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4GBAEdJ\ -Ss8jWiooja3WZzHXeF95QkBJNjIlpDLGcpl4opOYLSuEl9Uxp//LaQQiXuzpj4/I\ -pkWGQmMy5HOyH1lqDyiMgXpcG8PE0jEQAoEUGZ0QEqB1mZ6BCrYvmUuf/5aSVd8Y\ -6lKMR3WzFDYU9Zy0nzuHB/3nvp6MeDRQeRMtYvz4CogEMIICBDCCAW2gAwIBAgIB\ -AjANBgkqhkiG9w0BAQsFADA/MRQwEgYDVQQDDAt0ZXN0Y2EzLm9yZzEnMCUGA1UE\ -CgweUGF5bWVudCBSZXF1ZXN0IEludGVybWVkaWF0ZSAzMB4XDTEzMDIyMzIyNDIy\ -OVoXDTIzMDIyMTIyNDIyOVowPzEUMBIGA1UEAwwLdGVzdGNhNC5vcmcxJzAlBgNV\ -BAoMHlBheW1lbnQgUmVxdWVzdCBJbnRlcm1lZGlhdGUgNDCBnzANBgkqhkiG9w0B\ -AQEFAAOBjQAwgYkCgYEAxYYo3w2UXiYg6O8b4QgwN/vgreTkiW122Ep/z2TiDrhV\ -MhfOOiKdwYESPflfnXnVaQQzCGexYTQqsvqvzHSyna5hL0zPTRJxSKmTVrXRsWtp\ -dCRhjxCGipS3tlQBDi7vb+7SNRIBK4dBjjGzALNk7gMCpy+yM8f6I043jTlmGb0C\ -AwEAAaMQMA4wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOBgQDU+IQxt3Oh\ -KqaUYWC23+cB2gekvWqwMBnrCNrX/Dp+kjoJKUoR2Fs3qw53raHES4SIhpGT9l9l\ -rppNQgFe/JMHeYqOZMZO+6kuU0olJanBJ14tPIc7zlMTQ9OfmZ6v07IpyFbsQDtR\ -hpe80DpuvSFPfJ4fh0WrQf6kn3KDVpGDnAqIBDCCAgQwggFtoAMCAQICAQIwDQYJ\ -KoZIhvcNAQELBQAwPzEUMBIGA1UEAwwLdGVzdGNhMi5vcmcxJzAlBgNVBAoMHlBh\ -eW1lbnQgUmVxdWVzdCBJbnRlcm1lZGlhdGUgMjAeFw0xMzAyMjMyMjQyMjlaFw0y\ -MzAyMjEyMjQyMjlaMD8xFDASBgNVBAMMC3Rlc3RjYTMub3JnMScwJQYDVQQKDB5Q\ -YXltZW50IFJlcXVlc3QgSW50ZXJtZWRpYXRlIDMwgZ8wDQYJKoZIhvcNAQEBBQAD\ -gY0AMIGJAoGBANzgVP99Qg98e6NsKEz1v5KqRB7NTBRRsYnBvb/TSWipvMQaCYuE\ -yk1xG57x++QuASKeR3QHRQJOoAhQaj9JLUhSSv9GQ5PrFLLsOFv7L1tpzXHh2dOB\ -IW92X2yFRW2s39q+Q21yvN+N8uoKdqXhzRA+dDoXh3cavaVeHX1G+IrlAgMBAAGj\ -EDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADgYEASTwg84cX+1UhOG9s\ -ejFV3m34QuI1hPZ+qhqVJlRYUtego8Wng1BburDSwqVAv4ch2wi3c2s4e8J7AXyL\ -tzSbSQG4RN0oZi0mR8EtTTN+Mix/hBIk79dMZg85+I29uFA6Zj2d9oAhQv2qkHhc\ -6tcaheNvkQRlCyH68k3iF1Fqf+4KiAQwggIEMIIBbaADAgECAgECMA0GCSqGSIb3\ -DQEBCwUAMD8xFDASBgNVBAMMC3Rlc3RjYTEub3JnMScwJQYDVQQKDB5QYXltZW50\ -IFJlcXVlc3QgSW50ZXJtZWRpYXRlIDEwHhcNMTMwMjIzMjI0MjI5WhcNMjMwMjIx\ -MjI0MjI5WjA/MRQwEgYDVQQDDAt0ZXN0Y2EyLm9yZzEnMCUGA1UECgweUGF5bWVu\ -dCBSZXF1ZXN0IEludGVybWVkaWF0ZSAyMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCB\ -iQKBgQDaV8zhfyQuSf/f+fauMfgs3g/RnWy9yxxUkvQneQQPH3uZzCyk3A6q72ip\ -TtwNqiibG9455L9A7SaUjGtnpUz0NKT/VWUdqbfCl1PqXjEZbDobbAQ5hxLGOTyL\ -RQhLIcgeq2/BnmeCqHsC4md04nUp+nBo1HwKyygvK+9sMbCp/wIDAQABoxAwDjAM\ -BgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4GBACvYyE+PPmWFkbjyRu9LAt8D\ -crtyYYLRClKSg6tVvutwukLG2l//kDOohYkJtgTqr6LnCIIIwYdXN+4wxugmw4cn\ -PIZmP6kovxjhhVM95okilor1zniTAo3RN7JDIfTGNgxLdGu1btt7DOFL4zTbeSJM\ -b8M1JpPftehH+x/VLyuUCuoDMIIB5jCCAU+gAwIBAgIBBTANBgkqhkiG9w0BAQsF\ -ADAhMR8wHQYDVQQDExZQYXltZW50UmVxdWVzdCBUZXN0IENBMB4XDTEzMDIyMzIy\ -NDIyOFoXDTIzMDIyMTIyNDIyOFowPzEUMBIGA1UEAwwLdGVzdGNhMS5vcmcxJzAl\ -BgNVBAoMHlBheW1lbnQgUmVxdWVzdCBJbnRlcm1lZGlhdGUgMTCBnzANBgkqhkiG\ -9w0BAQEFAAOBjQAwgYkCgYEAo5Vy9H3nA/OOkF5Ap89yfVNSiTay/LYCaB0eALpc\ -U690U75O9Q3w2M+2AN8wpbbHsJHZMIjEeBRoQfjlYXW1ucQTxWKyT+liu0D25mGX\ -X27CBXBd4iXTxVII/iX+u3lcjORjoHOBy7QgeIDIIS9y0vYu8eArpjh7m4thrVgI\ -RtMCAwEAAaMQMA4wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOBgQB9LKcV\ -JK9sjASNzpQlpUp7nCiw5FSjVY+XMRIKK/kavzlKjZ+InsmmyRVGjDoZi9GrqG9P\ -VHgLBxi2VtVjmokZoNPqao3OfhqORAubC+JR/JLepM7aDaxDdTHVhSUk4lgNAvi2\ -6dGY7nZMsnHlPQ2tPp/HvRRiMq1oDjlylc8VTCI2Eh8IsNsGEhl2qRSVYIoDyPul\ -6RMbTSzv4tVhVfGZqIisGLLhxYsFKg1Vbml0VGVzdFRocmVlKoABn2HTsUQtMNI4\ -yNvkfkFNka3pRvTUTydJrvyfmEeLzImfM1BWddZjnywku9RToNFZZNgow5QnljmF\ -chhR/aHOuEMTxmc12K4rNlgYtHCsxLP9zd+6u0cva3TucZ6EzS8PKEib/+r12/52\ -664NuWA9WtsK7QCFrK2K95PnVCRmWl0=\ -"; - -// -// Long chain, with an invalid (expired) cert in the middle -// -const char* paymentrequest4_BASE64 = -"\ -Egt4NTA5K3NoYTI1NhqeJAr/AzCCAfswggFkoAMCAQICAQEwDQYJKoZIhvcNAQEL\ -BQAwPzEUMBIGA1UEAwwLdGVzdGNhOC5vcmcxJzAlBgNVBAoMHlBheW1lbnQgUmVx\ -dWVzdCBJbnRlcm1lZGlhdGUgODAeFw0xMzAyMjMyMjQyMzFaFw0yMzAyMjEyMjQy\ -MzFaMDYxGjAYBgNVBAMMEXRlc3RtZXJjaGFudDgub3JnMRgwFgYDVQQKDA9UZXN0\ -IE1lcmNoYW50IDgwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMMCHA3hiHbS\ -TKZ5K9jHRwE8NxkGp3IOx56PDB2diNkldG8XweTcRq7bBm7pdiBt4IVggtfs+6hE\ -hDYIOecyoAnVzPFTdvQ7KQdQ/fD9YLe6lk+o0edOqutPMyrxLFjSluXxEQyk7fdt\ -URloMMYfp3p1/hFCboA1rAsQ2RW38hR5AgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8w\ -DQYJKoZIhvcNAQELBQADgYEAPsdFatnc2RJSpvZsw+nCiPVsllycw5ELglq9vfJz\ -nJJucRxgzmqI2iuas1ugwbXn0BEIRLK7vMF/qBzQR6M/nTxttah+KEu+okjps9vJ\ -cIyhfTyGPC5xkHaHZ7sG+UHOFhPw0/kXn0x+pbVgBZ5315axqcp1R+DTSj/whMAr\ -n0AKiAQwggIEMIIBbaADAgECAgECMA0GCSqGSIb3DQEBCwUAMD8xFDASBgNVBAMM\ -C3Rlc3RjYTcub3JnMScwJQYDVQQKDB5QYXltZW50IFJlcXVlc3QgSW50ZXJtZWRp\ -YXRlIDcwHhcNMTMwMjIzMjI0MjMxWhcNMjMwMjIxMjI0MjMxWjA/MRQwEgYDVQQD\ -DAt0ZXN0Y2E4Lm9yZzEnMCUGA1UECgweUGF5bWVudCBSZXF1ZXN0IEludGVybWVk\ -aWF0ZSA4MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDexUFfxb1sThvabp7u\ -dZz59ciThGmmAW0nP4tjrgEACgvWIInr2dZpTHbiQNF34ycsk0le1JD93D7Qb8rd\ -25OrpaO8XS2Li2zjR9cleixXjSLwV/zv8zJ8yPl/27XL++PDTKBXVpJ8/Syp+9Ty\ -plV1BqDhqtIHb/QSHEkTQXjeYQIDAQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqG\ -SIb3DQEBCwUAA4GBACMooQVbkbIZ2DaPwHDc4ULwguG3VI2Kzj50UdExmHtzm2S4\ -MQei+n+HEPjtJAx5OY520+10nfuP+12H2DRLQmWmdvDpeQ/Cv0yavlw4ZRejRFo7\ -KS83C0wo5rd+qTvvOmAN4UTArWkzYcEUulPdiXnRamb0WQHTeVdIbHVkMormCogE\ -MIICBDCCAW2gAwIBAgIBAjANBgkqhkiG9w0BAQsFADA/MRQwEgYDVQQDDAt0ZXN0\ -Y2E2Lm9yZzEnMCUGA1UECgweUGF5bWVudCBSZXF1ZXN0IEludGVybWVkaWF0ZSA2\ -MB4XDTEzMDIyMzIyNDIzMVoXDTIzMDIyMTIyNDIzMVowPzEUMBIGA1UEAwwLdGVz\ -dGNhNy5vcmcxJzAlBgNVBAoMHlBheW1lbnQgUmVxdWVzdCBJbnRlcm1lZGlhdGUg\ -NzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAtjBRazrkebXAhXsbjimrMIRm\ -W/f9SwAHwXfc042keNtl0t2z6XE6UPcR2v/KrssXuCZgodeYxz6IM6lWosCM1xot\ -C3ChKKFBfVO30reuKBRUxXfKAFqxaG0YOAEzdZkkY9AGhqWloeSmgxpIfhInU0EF\ -JjCwrJ6IkijBatGoAAECAwEAAaMQMA4wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0B\ -AQsFAAOBgQDBRTi1MolmOA0niHYX0A2lN5QWHkCfX0A7GwyoMA3dvM45m/NYd4WB\ -X+HwfnfYcI6X9jOgNo5OWmc4GGsld0HlxwMYEKISBS9PbSHPBrb3TBOlw5ztQpXZ\ -91+bOhLux52Fr03sK7v9qExmBM12M8UR2ltpzAMiUgLLMHyPfiWkvQqIBDCCAgQw\ -ggFtoAMCAQICAQIwDQYJKoZIhvcNAQELBQAwPzEUMBIGA1UEAwwLdGVzdGNhNS5v\ -cmcxJzAlBgNVBAoMHlBheW1lbnQgUmVxdWVzdCBJbnRlcm1lZGlhdGUgNTAeFw0x\ -MzAyMjMyMjQyMzBaFw0yMzAyMjEyMjQyMzBaMD8xFDASBgNVBAMMC3Rlc3RjYTYu\ -b3JnMScwJQYDVQQKDB5QYXltZW50IFJlcXVlc3QgSW50ZXJtZWRpYXRlIDYwgZ8w\ -DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANJSH3xivX1t9olIdHsznI1aE9SD7t9i\ -SZJsIB0otoETHZRVv9M9LvyzBNK98ZV+kTOlST7PJgC0d9BQM9sgYApSRq5oqKDM\ -9FXbOm/yaReAbU3mkFNFw5roTlJ5ThEy0yOGT/DS0YBRaGIvRPRj2DiqDVdCZZ+w\ -4jo1IYHkZt4FAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQAD\ -gYEATm6+J1OmbrothO60xALKonWMBKr6hudb4amkFBqKbA9wMeM3jl+I/yKfz/Uf\ -xWuJ071IhiNv6Gxx5YwNvhUe1xMhUqHv0gpyK1Z47bD+kYS2se5sWNPNo3Y9qZDG\ -IXiGQxwHmrzaFk79Uy1xsmvsEz42w6hr25Yaw7HkIgrFveoK6gMwggHmMIIBT6AD\ -AgECAgEGMA0GCSqGSIb3DQEBCwUAMCExHzAdBgNVBAMTFlBheW1lbnRSZXF1ZXN0\ -IFRlc3QgQ0EwHhcNMTMwMjIzMjI1OTUxWhcNMTMwMjI0MjI1OTUxWjA/MRQwEgYD\ -VQQDDAt0ZXN0Y2E1Lm9yZzEnMCUGA1UECgweUGF5bWVudCBSZXF1ZXN0IEludGVy\ -bWVkaWF0ZSA1MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7vVUFpxHzz2Tr\ -/xij3k58s8d/BPA0R6D5RXTVvmhAzc1Zuin4zUKRFs/aCj/0yED8Wu/COfNGF4tV\ -lRNMdl9EcFsxa8XGEL4eAZa+H/rOHH+7/1EINrrVWhZlUecyhilN8jmCZmqEM3ec\ -uD0NAViqyMrgmaiFmsLoQZpEGepDUQIDAQABoxAwDjAMBgNVHRMEBTADAQH/MA0G\ -CSqGSIb3DQEBCwUAA4GBAEmcUEnhua/oiXy1fwScLgMqt+jk9mHRpE6SVsIop23Q\ -CY2JfpG6RxhMMzzzhGklEGN6cxG0HCi6B3HJx6PYrFEfTB0rW4K6m0Tvx3WpS9mN\ -uoEuJHLy18ausI/sYAPDHCL+SfBVcqorpaIG2sSpZouRBjRHAyqFAYlwlW87uq5n\ -CogEMIICBDCCAW2gAwIBAgIBAjANBgkqhkiG9w0BAQsFADA/MRQwEgYDVQQDDAt0\ -ZXN0Y2EzLm9yZzEnMCUGA1UECgweUGF5bWVudCBSZXF1ZXN0IEludGVybWVkaWF0\ -ZSAzMB4XDTEzMDIyMzIyNDIyOVoXDTIzMDIyMTIyNDIyOVowPzEUMBIGA1UEAwwL\ -dGVzdGNhNC5vcmcxJzAlBgNVBAoMHlBheW1lbnQgUmVxdWVzdCBJbnRlcm1lZGlh\ -dGUgNDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAxYYo3w2UXiYg6O8b4Qgw\ -N/vgreTkiW122Ep/z2TiDrhVMhfOOiKdwYESPflfnXnVaQQzCGexYTQqsvqvzHSy\ -na5hL0zPTRJxSKmTVrXRsWtpdCRhjxCGipS3tlQBDi7vb+7SNRIBK4dBjjGzALNk\ -7gMCpy+yM8f6I043jTlmGb0CAwEAAaMQMA4wDAYDVR0TBAUwAwEB/zANBgkqhkiG\ -9w0BAQsFAAOBgQDU+IQxt3OhKqaUYWC23+cB2gekvWqwMBnrCNrX/Dp+kjoJKUoR\ -2Fs3qw53raHES4SIhpGT9l9lrppNQgFe/JMHeYqOZMZO+6kuU0olJanBJ14tPIc7\ -zlMTQ9OfmZ6v07IpyFbsQDtRhpe80DpuvSFPfJ4fh0WrQf6kn3KDVpGDnAqIBDCC\ -AgQwggFtoAMCAQICAQIwDQYJKoZIhvcNAQELBQAwPzEUMBIGA1UEAwwLdGVzdGNh\ -Mi5vcmcxJzAlBgNVBAoMHlBheW1lbnQgUmVxdWVzdCBJbnRlcm1lZGlhdGUgMjAe\ -Fw0xMzAyMjMyMjQyMjlaFw0yMzAyMjEyMjQyMjlaMD8xFDASBgNVBAMMC3Rlc3Rj\ -YTMub3JnMScwJQYDVQQKDB5QYXltZW50IFJlcXVlc3QgSW50ZXJtZWRpYXRlIDMw\ -gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANzgVP99Qg98e6NsKEz1v5KqRB7N\ -TBRRsYnBvb/TSWipvMQaCYuEyk1xG57x++QuASKeR3QHRQJOoAhQaj9JLUhSSv9G\ -Q5PrFLLsOFv7L1tpzXHh2dOBIW92X2yFRW2s39q+Q21yvN+N8uoKdqXhzRA+dDoX\ -h3cavaVeHX1G+IrlAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEL\ -BQADgYEASTwg84cX+1UhOG9sejFV3m34QuI1hPZ+qhqVJlRYUtego8Wng1BburDS\ -wqVAv4ch2wi3c2s4e8J7AXyLtzSbSQG4RN0oZi0mR8EtTTN+Mix/hBIk79dMZg85\ -+I29uFA6Zj2d9oAhQv2qkHhc6tcaheNvkQRlCyH68k3iF1Fqf+4KiAQwggIEMIIB\ -baADAgECAgECMA0GCSqGSIb3DQEBCwUAMD8xFDASBgNVBAMMC3Rlc3RjYTEub3Jn\ -MScwJQYDVQQKDB5QYXltZW50IFJlcXVlc3QgSW50ZXJtZWRpYXRlIDEwHhcNMTMw\ -MjIzMjI0MjI5WhcNMjMwMjIxMjI0MjI5WjA/MRQwEgYDVQQDDAt0ZXN0Y2EyLm9y\ -ZzEnMCUGA1UECgweUGF5bWVudCBSZXF1ZXN0IEludGVybWVkaWF0ZSAyMIGfMA0G\ -CSqGSIb3DQEBAQUAA4GNADCBiQKBgQDaV8zhfyQuSf/f+fauMfgs3g/RnWy9yxxU\ -kvQneQQPH3uZzCyk3A6q72ipTtwNqiibG9455L9A7SaUjGtnpUz0NKT/VWUdqbfC\ -l1PqXjEZbDobbAQ5hxLGOTyLRQhLIcgeq2/BnmeCqHsC4md04nUp+nBo1HwKyygv\ -K+9sMbCp/wIDAQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4GB\ -ACvYyE+PPmWFkbjyRu9LAt8DcrtyYYLRClKSg6tVvutwukLG2l//kDOohYkJtgTq\ -r6LnCIIIwYdXN+4wxugmw4cnPIZmP6kovxjhhVM95okilor1zniTAo3RN7JDIfTG\ -NgxLdGu1btt7DOFL4zTbeSJMb8M1JpPftehH+x/VLyuUCuoDMIIB5jCCAU+gAwIB\ -AgIBBTANBgkqhkiG9w0BAQsFADAhMR8wHQYDVQQDExZQYXltZW50UmVxdWVzdCBU\ -ZXN0IENBMB4XDTEzMDIyMzIyNDIyOFoXDTIzMDIyMTIyNDIyOFowPzEUMBIGA1UE\ -AwwLdGVzdGNhMS5vcmcxJzAlBgNVBAoMHlBheW1lbnQgUmVxdWVzdCBJbnRlcm1l\ -ZGlhdGUgMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAo5Vy9H3nA/OOkF5A\ -p89yfVNSiTay/LYCaB0eALpcU690U75O9Q3w2M+2AN8wpbbHsJHZMIjEeBRoQfjl\ -YXW1ucQTxWKyT+liu0D25mGXX27CBXBd4iXTxVII/iX+u3lcjORjoHOBy7QgeIDI\ -IS9y0vYu8eArpjh7m4thrVgIRtMCAwEAAaMQMA4wDAYDVR0TBAUwAwEB/zANBgkq\ -hkiG9w0BAQsFAAOBgQB9LKcVJK9sjASNzpQlpUp7nCiw5FSjVY+XMRIKK/kavzlK\ -jZ+InsmmyRVGjDoZi9GrqG9PVHgLBxi2VtVjmokZoNPqao3OfhqORAubC+JR/JLe\ -pM7aDaxDdTHVhSUk4lgNAvi26dGY7nZMsnHlPQ2tPp/HvRRiMq1oDjlylc8VTCI1\ -Eh8IsNsGEhl2qRSVYIoDyPul6RMbTSzv4tVhVfGZqIisGLLhxYsFKgxVbml0VGVz\ -dEZvdXIqgAEBE1PP93Tkpif35F+dYmXn9kLA/1djcPjCs2o2rwRMM4Uk356O5dgu\ -HXQjsfdR58qZQS9CS5DAtRUf0R8+43/wijO/hb49VNaNXmY+/cPHMkahP2aV3tZi\ -FAyZblLik9A7ZvF+UsjeFQiHB5wzWQvbqk5wQ4yabHIXoYv/E0q+eQ==\ -"; - -const char* paymentrequest5_BASE64 = -"\ -Egt4NTA5K3NoYTI1NhrxAwruAzCCAeowggFToAMCAQICAQEwDQYJKoZIhvcNAQEL\ -BQAwITEfMB0GA1UEAxMWUGF5bWVudFJlcXVlc3QgVGVzdCBDQTAeFw0xMzA0MTkx\ -NzIwMDZaFw0yMzA0MTcxNzIwMDZaMEMxGTAXBgNVBAMMEHRlc3RtZXJjaGFudC5v\ -cmcxJjAkBgNVBAoMHVBheW1lbnQgUmVxdWVzdCBUZXN0IE1lcmNoYW50MIGfMA0G\ -CSqGSIb3DQEBAQUAA4GNADCBiQKBgQDhV6Yn47aEEmbl50YLvXoqGEJA51I/40wr\ -Z6VQGdXYaRqYktagrWDlgYY9h0JQ1bQhm8HgW7ju0R4NaDTXUqxg4HjprF0z3Mfm\ -/6mmebkLOOptfkVD7ceAteNI7cyuqWGIAZA7D9mV97mXoCAtTlBUycvkmoiClCCS\ -h0EpF/UTaQIDAQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4GB\ -AGIRwW7I0QvLga+RnJoJSZNZQbtu4rQW3xmoz8WfZMBYXX3QBYg5ftycbdK+/IbP\ -qozfjGW2AS6DNArvpveSPDTK9+GJBNo1paiNtVqwXkC3Ddscv5AIms1eZGiIOQNC\ -mUvdLkpoXo48WAer3EGsZ3B15GyNEELc0q9W5yUebba1IjUSHwiw2wYSGXapFJVg\ -igPI+6XpExtNLO/i1WFV8ZmoiKwYuPvFiwUqDFVuaXRUZXN0Rml2ZSqAAXdsMgdG\ -ssymvca1S/1KeM3n8Ydi2fi1JUzAAr59xPvNJRUeqCLP9upHn5z7br3P12Oz9A20\ -5/4wL4ClPRPVnOHgij0bEg+y0tGESqmF1rfOfXDszlo2U92wCxS07kq79YAZJ1Zo\ -XYh860/Q4wvc7lfiTe+dXBzPKAKhMy91yETY\ -"; diff --git a/src/qt/test/paymentservertests.cpp b/src/qt/test/paymentservertests.cpp deleted file mode 100644 index 7cd5a857e9..0000000000 --- a/src/qt/test/paymentservertests.cpp +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include "paymentservertests.h" - -#include "optionsmodel.h" -#include "paymentrequestdata.h" - -#include "random.h" -#include "util.h" -#include "utilstrencodings.h" - -#include -#include - -#include -#include - -X509 *parse_b64der_cert(const char* cert_data) -{ - std::vector data = DecodeBase64(cert_data); - assert(data.size() > 0); - const unsigned char* dptr = &data[0]; - X509 *cert = d2i_X509(NULL, &dptr, data.size()); - assert(cert); - return cert; -} - -// -// Test payment request handling -// - -static SendCoinsRecipient handleRequest(PaymentServer* server, std::vector& data) -{ - RecipientCatcher sigCatcher; - QObject::connect(server, SIGNAL(receivedPaymentRequest(SendCoinsRecipient)), - &sigCatcher, SLOT(getRecipient(SendCoinsRecipient))); - - // Write data to a temp file: - QTemporaryFile f; - f.open(); - f.write((const char*)&data[0], data.size()); - f.close(); - - // Create a QObject, install event filter from PaymentServer - // and send a file open event to the object - QObject object; - object.installEventFilter(server); - QFileOpenEvent event(f.fileName()); - // If sending the event fails, this will cause sigCatcher to be empty, - // which will lead to a test failure anyway. - QCoreApplication::sendEvent(&object, &event); - - QObject::disconnect(server, SIGNAL(receivedPaymentRequest(SendCoinsRecipient)), - &sigCatcher, SLOT(getRecipient(SendCoinsRecipient))); - - // Return results from sigCatcher - return sigCatcher.recipient; -} - -void PaymentServerTests::paymentServerTests() -{ - SelectParams(CBaseChainParams::MAIN); - OptionsModel optionsModel; - PaymentServer* server = new PaymentServer(NULL, false); - X509_STORE* caStore = X509_STORE_new(); - X509_STORE_add_cert(caStore, parse_b64der_cert(caCert_BASE64)); - PaymentServer::LoadRootCAs(caStore); - server->setOptionsModel(&optionsModel); - server->uiReady(); - - // Now feed PaymentRequests to server, and observe signals it produces: - std::vector data = DecodeBase64(paymentrequest1_BASE64); - SendCoinsRecipient r = handleRequest(server, data); - QString merchant; - r.paymentRequest.getMerchant(caStore, merchant); - QCOMPARE(merchant, QString("testmerchant.org")); - - // Version of the above, with an expired certificate: - data = DecodeBase64(paymentrequest2_BASE64); - r = handleRequest(server, data); - r.paymentRequest.getMerchant(caStore, merchant); - QCOMPARE(merchant, QString("")); - - // Long certificate chain: - data = DecodeBase64(paymentrequest3_BASE64); - r = handleRequest(server, data); - r.paymentRequest.getMerchant(caStore, merchant); - QCOMPARE(merchant, QString("testmerchant8.org")); - - // Long certificate chain, with an expired certificate in the middle: - data = DecodeBase64(paymentrequest4_BASE64); - r = handleRequest(server, data); - r.paymentRequest.getMerchant(caStore, merchant); - QCOMPARE(merchant, QString("")); - - // Validly signed, but by a CA not in our root CA list: - data = DecodeBase64(paymentrequest5_BASE64); - r = handleRequest(server, data); - r.paymentRequest.getMerchant(caStore, merchant); - QCOMPARE(merchant, QString("")); - - // Try again with no root CA's, verifiedMerchant should be empty: - caStore = X509_STORE_new(); - PaymentServer::LoadRootCAs(caStore); - data = DecodeBase64(paymentrequest1_BASE64); - r = handleRequest(server, data); - r.paymentRequest.getMerchant(caStore, merchant); - QCOMPARE(merchant, QString("")); - - unsigned long lDoSProtectionTrigger = (unsigned long) BIP70_MAX_PAYMENTREQUEST_SIZE + 1; - std::string randData(lDoSProtectionTrigger, '\0'); - unsigned char* buff = reinterpret_cast(&randData[0]); - - // Just get some random data big enough to trigger BIP70 DoS protection - // unsigned char randData[BIP70_MAX_PAYMENTREQUEST_SIZE + 1]; - // GetRandBytes(randData, sizeof(randData)); - GetRandBytes(buff, sizeof(buff)); - // Write data to a temp file: - QTemporaryFile tempFile; - tempFile.open(); - tempFile.write((const char*)buff, sizeof(buff)); - tempFile.close(); - // Trigger BIP70 DoS protection - QCOMPARE(PaymentServer::readPaymentRequestFromFile(tempFile.fileName(), r.paymentRequest), false); - - delete server; -} - -void RecipientCatcher::getRecipient(SendCoinsRecipient r) -{ - recipient = r; -} diff --git a/src/qt/test/paymentservertests.h b/src/qt/test/paymentservertests.h deleted file mode 100644 index b56ad66fbe..0000000000 --- a/src/qt/test/paymentservertests.h +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#ifndef BITCOIN_QT_TEST_PAYMENTSERVERTESTS_H -#define BITCOIN_QT_TEST_PAYMENTSERVERTESTS_H - -#include "../paymentserver.h" - -#include -#include - -class PaymentServerTests : public QObject -{ - Q_OBJECT - -private Q_SLOTS: - void paymentServerTests(); -}; - -// Dummy class to receive paymentserver signals. -// If SendCoinsRecipient was a proper QObject, then -// we could use QSignalSpy... but it's not. -class RecipientCatcher : public QObject -{ - Q_OBJECT - -public Q_SLOTS: - void getRecipient(SendCoinsRecipient r); - -public: - SendCoinsRecipient recipient; -}; - -#endif // BITCOIN_QT_TEST_PAYMENTSERVERTESTS_H diff --git a/src/qt/test/test_main.cpp b/src/qt/test/test_main.cpp index bc4f4ad87e..fc2cbc2712 100644 --- a/src/qt/test/test_main.cpp +++ b/src/qt/test/test_main.cpp @@ -12,10 +12,6 @@ #include "util.h" #include "uritests.h" -#ifdef ENABLE_WALLET -#include "paymentservertests.h" -#endif - #include #include #include @@ -54,11 +50,6 @@ int main(int argc, char *argv[]) URITests test1; if (QTest::qExec(&test1) != 0) fInvalid = true; -#ifdef ENABLE_WALLET - PaymentServerTests test2; - if (QTest::qExec(&test2) != 0) - fInvalid = true; -#endif return fInvalid; } diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index 2b752a73f1..aa0dad2a82 100644 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -261,19 +261,6 @@ QString TransactionDesc::toHTML(CWallet* wallet, CWalletTx& wtx, TransactionReco if (r.first == "Message") strHTML += "
" + tr("Message") + ":
" + GUIUtil::HtmlEscape(r.second, true) + "
"; - // - // PaymentRequest info: - // - Q_FOREACH (const PAIRTYPE(std::string, std::string) & r, wtx.vOrderForm) { - if (r.first == "PaymentRequest") { - PaymentRequestPlus req; - req.parse(QByteArray::fromRawData(r.second.data(), r.second.size())); - QString merchant; - if (req.getMerchant(PaymentServer::getCertStore(), merchant)) - strHTML += "" + tr("Merchant") + ": " + GUIUtil::HtmlEscape(merchant) + "
"; - } - } - if (wtx.IsCoinBase()) { quint32 numBlocksToMaturity = Params().COINBASE_MATURITY() + 1; strHTML += "
" + tr("Generated coins must mature %1 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to \"not accepted\" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.").arg(QString::number(numBlocksToMaturity)) + "
"; diff --git a/src/qt/utilitydialog.cpp b/src/qt/utilitydialog.cpp index 67d604b00a..78ee02f1d1 100644 --- a/src/qt/utilitydialog.cpp +++ b/src/qt/utilitydialog.cpp @@ -80,7 +80,6 @@ HelpMessageDialog::HelpMessageDialog(QWidget* parent, bool about) : QDialog(pare strUsage += HelpMessageOpt("-choosedatadir", strprintf(tr("Choose data directory on startup (default: %u)").toStdString(), DEFAULT_CHOOSE_DATADIR)); strUsage += HelpMessageOpt("-lang=", tr("Set language, for example \"de_DE\" (default: system locale)").toStdString()); strUsage += HelpMessageOpt("-min", tr("Start minimized").toStdString()); - strUsage += HelpMessageOpt("-rootcertificates=", tr("Set SSL root certificates for payment request (default: -system-)").toStdString()); strUsage += HelpMessageOpt("-splash", strprintf(tr("Show splash screen on startup (default: %u)").toStdString(), DEFAULT_SPLASHSCREEN)); QString coreOptions = QString::fromStdString(strUsage); text = version + "\n" + header + "\n" + coreOptions; diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index c11fb20fb5..e4aad45fe5 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -34,6 +34,7 @@ #include #include #include +#include WalletModel::WalletModel(CWallet* wallet, OptionsModel* optionsModel, QObject* parent) : QObject(parent), wallet(wallet), optionsModel(optionsModel), addressTableModel(0), @@ -285,22 +286,7 @@ WalletModel::SendCoinsReturn WalletModel::prepareTransaction(WalletModelTransact // Pre-check input data for validity Q_FOREACH (const SendCoinsRecipient& rcp, recipients) { - if (rcp.paymentRequest.IsInitialized()) { // PaymentRequest... - CAmount subtotal = 0; - const payments::PaymentDetails& details = rcp.paymentRequest.getDetails(); - for (int i = 0; i < details.outputs_size(); i++) { - const payments::Output& out = details.outputs(i); - if (out.amount() <= 0) continue; - subtotal += out.amount(); - const unsigned char* scriptStr = (const unsigned char*)out.script().data(); - CScript scriptPubKey(scriptStr, scriptStr + out.script().size()); - vecSend.push_back(std::pair(scriptPubKey, out.amount())); - } - if (subtotal <= 0) { - return InvalidAmount; - } - total += subtotal; - } else { // User-entered prcycoin address / amount: + { // User-entered prcycoin address / amount: if (!validateAddress(rcp.address)) { return InvalidAddress; } @@ -370,6 +356,78 @@ WalletModel::SendCoinsReturn WalletModel::sendCoins(WalletModelTransaction& tran return SendCoinsReturn(TransactionCommitFailed); } +void WalletModel::showSeedPhrase() +{ + WalletModel::EncryptionStatus encryptionStatus = getEncryptionStatus(); + + if (encryptionStatus == WalletModel::Locked || encryptionStatus == WalletModel::UnlockedForStakingOnly) { + WalletModel::UnlockContext ctx(requestUnlock(AskPassphraseDialog::Context::Unlock_Full, true)); + if (!ctx.isValid()) { + GUIUtil::showMessageBox( + tr("Mnemonic Recovery Phrase"), + tr("Attempt to view Mnemonic Phrase failed or canceled. Wallet locked for security."), + QMessageBox::Information); + LogPrintf("Attempt to view Mnemonic Phrase failed or canceled. Wallet locked for security.\n"); + return; + } else { + SecureString pass; + setWalletLocked(false, pass); + LogPrintf("Attempt to view Mnemonic Phrase successful.\n"); + } + } else { + QMessageBox msgBox; + msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); + msgBox.setWindowTitle(tr("Are You Sure?")); + msgBox.setText(tr("Are you sure you would like to view your Mnemonic Phrase?\nYou will be required to enter your passphrase. Failed or canceled attempts will be logged.")); + msgBox.setStandardButtons(QMessageBox::Yes|QMessageBox::No); + msgBox.setDefaultButton(QMessageBox::No); + msgBox.setIcon(QMessageBox::Question); + int reply = msgBox.exec(); + + if (reply == QMessageBox::Yes) { + setWalletLocked(true); + WalletModel::UnlockContext ctx(requestUnlock(AskPassphraseDialog::Context::Unlock_Full, true)); + if (!ctx.isValid()) { + GUIUtil::showMessageBox( + tr("Mnemonic Recovery Phrase"), + tr("Attempt to view Mnemonic Phrase failed or canceled. Wallet locked for security."), + QMessageBox::Information); + LogPrintf("Attempt to view Mnemonic Phrase failed or canceled. Wallet locked for security.\n"); + return; + } else { + SecureString pass; + setWalletLocked(false, pass); + LogPrintf("Attempt to view Mnemonic Phrase successful.\n"); + } + } else { + LogPrintf("Attempt to view Mnemonic Phrase canceled.\n"); + return; + } + } + + QString phrase = ""; + std::string recoverySeedPhrase = ""; + if (getSeedPhrase(recoverySeedPhrase)) { + phrase = QString::fromStdString(recoverySeedPhrase); + } + + QMessageBox msgBox; + QPushButton *copyButton = msgBox.addButton(tr("Copy"), QMessageBox::ActionRole); + QPushButton *okButton = msgBox.addButton(tr("OK"), QMessageBox::ActionRole); + copyButton->setStyleSheet("background:transparent;"); + copyButton->setIcon(QIcon(":/icons/editcopy")); + msgBox.setWindowTitle(tr("Mnemonic Recovery Phrase")); + msgBox.setText(tr("Below is your Mnemonic Recovery Phrase, consisting of 24 seed words. Please copy/write these words down in order. We strongly recommend keeping multiple copies in different locations.")); + msgBox.setInformativeText("\n" + phrase + ""); + msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); + msgBox.exec(); + + if (msgBox.clickedButton() == copyButton) { + //Copy Mnemonic Recovery Phrase to clipboard + GUIUtil::setClipboard(phrase); + } +} + OptionsModel* WalletModel::getOptionsModel() { return optionsModel; diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index 204acd8d59..83878662d2 100644 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -5,12 +5,16 @@ #ifndef BITCOIN_QT_WALLETMODEL_H #define BITCOIN_QT_WALLETMODEL_H +#if defined(HAVE_CONFIG_H) +#include "config/prcycoin-config.h" +#endif + #include "askpassphrasedialog.h" -#include "paymentrequestplus.h" #include "walletmodeltransaction.h" #include "allocators.h" /* for SecureString */ #include "guiutil.h" +#include "key.h" #include "swifttx.h" #include "wallet/wallet.h" #include "init.h" @@ -58,8 +62,8 @@ class SendCoinsRecipient // If from a payment request, this is used for storing the memo QString message; - // If from a payment request, paymentRequest.IsInitialized() will be true - PaymentRequestPlus paymentRequest; + // serialized string to ensure load/store is lossless + std::string sPaymentRequest{}; // Empty if no authentication or invalid signature/cert/etc. QString authenticatedMerchant; @@ -74,9 +78,6 @@ class SendCoinsRecipient std::string sAddress = address.toStdString(); std::string sLabel = label.toStdString(); std::string sMessage = message.toStdString(); - std::string sPaymentRequest; - if (!ser_action.ForRead() && paymentRequest.IsInitialized()) - paymentRequest.SerializeToString(&sPaymentRequest); std::string sAuthenticatedMerchant = authenticatedMerchant.toStdString(); READWRITE(this->nVersion); @@ -92,8 +93,6 @@ class SendCoinsRecipient address = QString::fromStdString(sAddress); label = QString::fromStdString(sLabel); message = QString::fromStdString(sMessage); - if (!sPaymentRequest.empty()) - paymentRequest.parse(QByteArray::fromRawData(sPaymentRequest.data(), sPaymentRequest.size())); authenticatedMerchant = QString::fromStdString(sAuthenticatedMerchant); } } @@ -186,6 +185,8 @@ class WalletModel : public QObject // Wallet backup bool backupWallet(const QString& filename); + void showSeedPhrase(); + // RAI object for unlocking wallet, returned by requestUnlock() class UnlockContext { diff --git a/src/qt/walletmodeltransaction.h b/src/qt/walletmodeltransaction.h index 83eb6cbfbf..dc699e822f 100644 --- a/src/qt/walletmodeltransaction.h +++ b/src/qt/walletmodeltransaction.h @@ -7,6 +7,9 @@ #include "walletmodel.h" +#include "amount.h" +#include "primitives/transaction.h" + #include class SendCoinsRecipient; diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp index 79e09f465b..b7132eb5c1 100644 --- a/src/qt/walletview.cpp +++ b/src/qt/walletview.cpp @@ -271,71 +271,7 @@ void WalletView::showSeedPhrase() if(!walletModel) return; - WalletModel::EncryptionStatus encryptionStatus = walletModel->getEncryptionStatus(); - - if (encryptionStatus == WalletModel::Locked || encryptionStatus == WalletModel::UnlockedForStakingOnly) { - WalletModel::UnlockContext ctx(walletModel->requestUnlock(AskPassphraseDialog::Context::Unlock_Full, true)); - if (!ctx.isValid()) { - QMessageBox msgBox; - msgBox.setWindowTitle("Mnemonic Recovery Phrase"); - msgBox.setIcon(QMessageBox::Information); - msgBox.setText("Attempt to view Mnemonic Phrase failed or canceled. Wallet locked for security."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.exec(); - LogPrintf("Attempt to view Mnemonic Phrase failed or canceled. Wallet locked for security.\n"); - return; - } else { - SecureString pass; - walletModel->setWalletLocked(false, pass); - LogPrintf("Attempt to view Mnemonic Phrase successful.\n"); - } - } else { - QMessageBox::StandardButton reply; - reply = QMessageBox::question(this, "Are You Sure?", "Are you sure you would like to view your Mnemonic Phrase?\nYou will be required to enter your passphrase. Failed or canceled attempts will be logged.", QMessageBox::Yes|QMessageBox::No); - if (reply == QMessageBox::Yes) { - walletModel->setWalletLocked(true); - WalletModel::UnlockContext ctx(walletModel->requestUnlock(AskPassphraseDialog::Context::Unlock_Full, true)); - if (!ctx.isValid()) { - QMessageBox msgBox; - msgBox.setWindowTitle("Mnemonic Recovery Phrase"); - msgBox.setIcon(QMessageBox::Information); - msgBox.setText("Attempt to view Mnemonic Phrase failed or canceled. Wallet locked for security."); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.exec(); - LogPrintf("Attempt to view Mnemonic Phrase failed or canceled. Wallet locked for security.\n"); - return; - } else { - SecureString pass; - walletModel->setWalletLocked(false, pass); - LogPrintf("Attempt to view Mnemonic Phrase successful.\n"); - } - } else { - LogPrintf("Attempt to view Mnemonic Phrase canceled.\n"); - return; - } - } - - QString phrase = ""; - std::string recoverySeedPhrase = ""; - if (walletModel->getSeedPhrase(recoverySeedPhrase)) { - phrase = QString::fromStdString(recoverySeedPhrase); - } - - QMessageBox msgBox; - QPushButton *copyButton = msgBox.addButton(tr("Copy"), QMessageBox::ActionRole); - QPushButton *okButton = msgBox.addButton(tr("OK"), QMessageBox::ActionRole); - copyButton->setStyleSheet("background:transparent;"); - copyButton->setIcon(QIcon(":/icons/editcopy")); - msgBox.setWindowTitle("Mnemonic Recovery Phrase"); - msgBox.setText("Below is your Mnemonic Recovery Phrase, consisting of 24 seed words. Please copy/write these words down in order. We strongly recommend keeping multiple copies in different locations."); - msgBox.setInformativeText("\n" + phrase + ""); - msgBox.setStyleSheet(GUIUtil::loadStyleSheet()); - msgBox.exec(); - - if (msgBox.clickedButton() == copyButton) { - //Copy Mnemonic Recovery Phrase to clipboard - GUIUtil::setClipboard(phrase); - } + walletModel->showSeedPhrase(); } void WalletView::changePassphrase() diff --git a/src/rest.cpp b/src/rest.cpp index 5367ee5282..433c0ba363 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -8,6 +8,7 @@ #include "primitives/transaction.h" #include "main.h" #include "httpserver.h" +#include "rpc/blockchain.h" #include "rpc/server.h" #include "streams.h" #include "sync.h" @@ -17,11 +18,9 @@ #include #include -#include static const size_t MAX_GETUTXOS_OUTPOINTS = 15; //allow a max of 15 outpoints to be queried at once - enum RetFormat { RF_UNDEF, RF_BINARY, @@ -54,18 +53,9 @@ struct CCoin { } }; - -extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry); - -extern UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false); - -extern UniValue mempoolInfoToJSON(); - -extern UniValue mempoolToJSON(bool fVerbose = false); - -extern void ScriptPubKeyToJSON(const CScript &scriptPubKey, UniValue &out, bool fIncludeHex); - -extern UniValue blockheaderToJSON(const CBlockIndex *blockindex); +/* Defined in rawtransaction.cpp */ +void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry); +void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex); static bool RESTERR(HTTPRequest *req, enum HTTPStatusCode status, std::string message) { req->WriteHeader("Content-Type", "text/plain"); @@ -485,7 +475,8 @@ static bool rest_getutxos(HTTPRequest *req, const std::string &strURIPart) { std::vector bitmap; std::vector outs; std::string bitmapStringRepresentation; - boost::dynamic_bitset hits(vOutPoints.size()); + std::vector hits; + bitmap.resize((vOutPoints.size() + 7) / 8); { LOCK2(cs_main, mempool.cs); @@ -501,12 +492,12 @@ static bool rest_getutxos(HTTPRequest *req, const std::string &strURIPart) { for (size_t i = 0; i < vOutPoints.size(); i++) { CCoins coins; uint256 hash = vOutPoints[i].hash; + bool hit = false; if (view.GetCoins(hash, coins)) { mempool.pruneSpent(hash, coins); if (coins.IsAvailable(vOutPoints[i].n)) { - hits[i] = true; + hit = true; // Safe to index into vout here because IsAvailable checked if it's off the end of the array, or if - // n is valid but points to an already spent output (IsNull). CCoin coin; coin.nTxVer = coins.nVersion; @@ -517,11 +508,12 @@ static bool rest_getutxos(HTTPRequest *req, const std::string &strURIPart) { } } - bitmapStringRepresentation.append( - hits[i] ? "1" : "0"); // form a binary string representation (human-readable for json output) + hits.push_back(hit); + bitmapStringRepresentation.append(hit ? "1" : "0"); // form a binary string representation (human-readable for json output) + bitmap[i / 8] |= ((uint8_t)hit) << (i % 8); } } - boost::to_block_range(hits, std::back_inserter(bitmap)); + switch (rf) { case RF_BINARY: { // serialize data @@ -550,24 +542,24 @@ static bool rest_getutxos(HTTPRequest *req, const std::string &strURIPart) { // pack in some essentials // use more or less the same output as mentioned in Bip64 - objGetUTXOResponse.push_back(Pair("chainHeight", chainActive.Height())); - objGetUTXOResponse.push_back(Pair("chaintipHash", chainActive.Tip()->GetBlockHash().GetHex())); - objGetUTXOResponse.push_back(Pair("bitmap", bitmapStringRepresentation)); + objGetUTXOResponse.pushKV("chainHeight", chainActive.Height()); + objGetUTXOResponse.pushKV("chaintipHash", chainActive.Tip()->GetBlockHash().GetHex()); + objGetUTXOResponse.pushKV("bitmap", bitmapStringRepresentation); UniValue utxos(UniValue::VARR); for ( const CCoin &coin : outs) { UniValue utxo(UniValue::VOBJ); - utxo.push_back(Pair("txvers", (int32_t) coin.nTxVer)); - utxo.push_back(Pair("height", (int32_t) coin.nHeight)); - utxo.push_back(Pair("value", ValueFromAmount(coin.out.nValue))); + utxo.pushKV("txvers", (int32_t) coin.nTxVer); + utxo.pushKV("height", (int32_t) coin.nHeight); + utxo.pushKV("value", ValueFromAmount(coin.out.nValue)); // include the script in a json output UniValue o(UniValue::VOBJ); ScriptPubKeyToJSON(coin.out.scriptPubKey, o, true); - utxo.push_back(Pair("scriptPubKey", o)); + utxo.pushKV("scriptPubKey", o); utxos.push_back(utxo); } - objGetUTXOResponse.push_back(Pair("utxos", utxos)); + objGetUTXOResponse.pushKV("utxos", utxos); // return json string std::string strJSON = objGetUTXOResponse.write() + "\n"; diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index cfe508aeee..c29337ea41 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -6,6 +6,8 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include "rpc/blockchain.h" + #include "checkpoints.h" #include "main.h" #include "rpc/server.h" @@ -67,45 +69,45 @@ double GetDifficulty(const CBlockIndex* blockindex) UniValue blockheaderToJSON(const CBlockIndex* blockindex) { UniValue result(UniValue::VOBJ); - result.push_back(Pair("hash", blockindex->GetBlockHash().GetHex())); + result.pushKV("hash", blockindex->GetBlockHash().GetHex()); int confirmations = -1; // Only report confirmations if the block is on the main chain if (chainActive.Contains(blockindex)) confirmations = chainActive.Height() - blockindex->nHeight + 1; - result.push_back(Pair("confirmations", confirmations)); - result.push_back(Pair("height", blockindex->nHeight)); - result.push_back(Pair("version", blockindex->nVersion)); - result.push_back(Pair("merkleroot", blockindex->hashMerkleRoot.GetHex())); - result.push_back(Pair("time", (int64_t)blockindex->nTime)); - result.push_back(Pair("mediantime", (int64_t)blockindex->GetMedianTimePast())); - result.push_back(Pair("nonce", (uint64_t)blockindex->nNonce)); - result.push_back(Pair("bits", strprintf("%08x", blockindex->nBits))); - result.push_back(Pair("difficulty", GetDifficulty(blockindex))); - result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex())); - result.push_back(Pair("acc_checkpoint", blockindex->nAccumulatorCheckpoint.GetHex())); + result.pushKV("confirmations", confirmations); + result.pushKV("height", blockindex->nHeight); + result.pushKV("version", blockindex->nVersion); + result.pushKV("merkleroot", blockindex->hashMerkleRoot.GetHex()); + result.pushKV("time", (int64_t)blockindex->nTime); + result.pushKV("mediantime", (int64_t)blockindex->GetMedianTimePast()); + result.pushKV("nonce", (uint64_t)blockindex->nNonce); + result.pushKV("bits", strprintf("%08x", blockindex->nBits)); + result.pushKV("difficulty", GetDifficulty(blockindex)); + result.pushKV("chainwork", blockindex->nChainWork.GetHex()); + result.pushKV("acc_checkpoint", blockindex->nAccumulatorCheckpoint.GetHex()); if (blockindex->pprev) - result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex())); + result.pushKV("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()); CBlockIndex *pnext = chainActive.Next(blockindex); if (pnext) - result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex())); + result.pushKV("nextblockhash", pnext->GetBlockHash().GetHex()); return result; } -UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false) +UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails) { UniValue result(UniValue::VOBJ); - result.push_back(Pair("hash", block.GetHash().GetHex())); + result.pushKV("hash", block.GetHash().GetHex()); int confirmations = -1; // Only report confirmations if the block is on the main chain if (chainActive.Contains(blockindex)) confirmations = chainActive.Height() - blockindex->nHeight + 1; - result.push_back(Pair("confirmations", confirmations)); - result.push_back(Pair("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION))); - result.push_back(Pair("height", blockindex->nHeight)); - result.push_back(Pair("version", block.nVersion)); - result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex())); - result.push_back(Pair("acc_checkpoint", block.nAccumulatorCheckpoint.GetHex())); + result.pushKV("confirmations", confirmations); + result.pushKV("size", (int)::GetSerializeSize(block, SER_NETWORK, PROTOCOL_VERSION)); + result.pushKV("height", blockindex->nHeight); + result.pushKV("version", block.nVersion); + result.pushKV("merkleroot", block.hashMerkleRoot.GetHex()); + result.pushKV("acc_checkpoint", block.nAccumulatorCheckpoint.GetHex()); UniValue txs(UniValue::VARR); for (const CTransaction& tx : block.vtx) { if (txDetails) { @@ -115,23 +117,23 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx } else txs.push_back(tx.GetHash().GetHex()); } - result.push_back(Pair("tx", txs)); - result.push_back(Pair("time", block.GetBlockTime())); - result.push_back(Pair("mediantime", (int64_t)blockindex->GetMedianTimePast())); - result.push_back(Pair("nonce", (uint64_t)block.nNonce)); - result.push_back(Pair("bits", strprintf("%08x", block.nBits))); - result.push_back(Pair("difficulty", GetDifficulty(blockindex))); - result.push_back(Pair("chainwork", blockindex->nChainWork.GetHex())); + result.pushKV("tx", txs); + result.pushKV("time", block.GetBlockTime()); + result.pushKV("mediantime", (int64_t)blockindex->GetMedianTimePast()); + result.pushKV("nonce", (uint64_t)block.nNonce); + result.pushKV("bits", strprintf("%08x", block.nBits)); + result.pushKV("difficulty", GetDifficulty(blockindex)); + result.pushKV("chainwork", blockindex->nChainWork.GetHex()); if (blockindex->pprev) - result.push_back(Pair("previousblockhash", blockindex->pprev->GetBlockHash().GetHex())); + result.pushKV("previousblockhash", blockindex->pprev->GetBlockHash().GetHex()); CBlockIndex* pnext = chainActive.Next(blockindex); if (pnext) - result.push_back(Pair("nextblockhash", pnext->GetBlockHash().GetHex())); + result.pushKV("nextblockhash", pnext->GetBlockHash().GetHex()); - result.push_back(Pair("modifier", strprintf("%016x", blockindex->nStakeModifier))); + result.pushKV("modifier", strprintf("%016x", blockindex->nStakeModifier)); - result.push_back(Pair("moneysupply",ValueFromAmount(blockindex->nMoneySupply))); + result.pushKV("moneysupply",ValueFromAmount(blockindex->nMoneySupply)); std::string minetype = "PoW"; if (blockindex->IsProofOfStake()) { minetype = "PoS"; @@ -139,12 +141,12 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx minetype = "PoA"; } - result.push_back(Pair("minetype", minetype)); + result.pushKV("minetype", minetype); if (blockindex->IsProofOfAudit()) { //This is a PoA block //Read information of PoS blocks audited by this PoA block - result.push_back(Pair("previouspoahash", block.hashPrevPoABlock.GetHex())); + result.pushKV("previouspoahash", block.hashPrevPoABlock.GetHex()); UniValue posBlockInfos(UniValue::VARR); bool auditResult = true; for (int i = 0; i < block.posBlocksAudited.size(); i++) { @@ -154,9 +156,9 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx posBlockInfos.push_back(objPoSBlockInfo); auditResult = auditResult & (block.posBlocksAudited[i].nTime > 0); } - result.push_back(Pair("auditsuccess", auditResult? "true": "false")); - result.push_back(Pair("posblocks", posBlockInfos)); - result.push_back(Pair("poscount", (int)block.posBlocksAudited.size())); + result.pushKV("auditsuccess", auditResult? "true": "false"); + result.pushKV("posblocks", posBlockInfos); + result.pushKV("poscount", (int)block.posBlocksAudited.size()); } return result; @@ -266,8 +268,8 @@ UniValue waitfornewblock(const UniValue& params, bool fHelp) block = latestblock; } UniValue ret(UniValue::VOBJ); - ret.push_back(Pair("hash", block.hash.GetHex())); - ret.push_back(Pair("height", block.height)); + ret.pushKV("hash", block.hash.GetHex()); + ret.pushKV("height", block.height); return ret; } @@ -311,8 +313,8 @@ UniValue waitforblock(const UniValue& params, bool fHelp) } UniValue ret(UniValue::VOBJ); - ret.push_back(Pair("hash", block.hash.GetHex())); - ret.push_back(Pair("height", block.height)); + ret.pushKV("hash", block.hash.GetHex()); + ret.pushKV("height", block.height); return ret; } @@ -356,8 +358,8 @@ UniValue waitforblockheight(const UniValue& params, bool fHelp) block = latestblock; } UniValue ret(UniValue::VOBJ); - ret.push_back(Pair("hash", block.hash.GetHex())); - ret.push_back(Pair("height", block.height)); + ret.pushKV("hash", block.hash.GetHex()); + ret.pushKV("height", block.height); return ret; } @@ -377,7 +379,7 @@ UniValue getdifficulty(const UniValue& params, bool fHelp) } -UniValue mempoolToJSON(bool fVerbose = false) +UniValue mempoolToJSON(bool fVerbose) { if (fVerbose) { LOCK(mempool.cs); @@ -386,12 +388,12 @@ UniValue mempoolToJSON(bool fVerbose = false) const uint256& hash = entry.first; const CTxMemPoolEntry& e = entry.second; UniValue info(UniValue::VOBJ); - info.push_back(Pair("size", (int)e.GetTxSize())); - info.push_back(Pair("fee", ValueFromAmount(e.GetFee()))); - info.push_back(Pair("time", e.GetTime())); - info.push_back(Pair("height", (int)e.GetHeight())); - info.push_back(Pair("startingpriority", e.GetPriority(e.GetHeight()))); - info.push_back(Pair("currentpriority", e.GetPriority(chainActive.Height()))); + info.pushKV("size", (int)e.GetTxSize()); + info.pushKV("fee", ValueFromAmount(e.GetFee())); + info.pushKV("time", e.GetTime()); + info.pushKV("height", (int)e.GetHeight()); + info.pushKV("startingpriority", e.GetPriority(e.GetHeight())); + info.pushKV("currentpriority", e.GetPriority(chainActive.Height())); const CTransaction& tx = e.GetTx(); std::set setDepends; for (const CTxIn& txin : tx.vin) { @@ -404,8 +406,8 @@ UniValue mempoolToJSON(bool fVerbose = false) depends.push_back(dep); } - info.push_back(Pair("depends", depends)); - o.push_back(Pair(hash.ToString(), info)); + info.pushKV("depends", depends); + o.pushKV(hash.ToString(), info); } return o; } else { @@ -621,13 +623,13 @@ UniValue gettxoutsetinfo(const UniValue& params, bool fHelp) CCoinsStats stats; FlushStateToDisk(); if (pcoinsTip->GetStats(stats)) { - ret.push_back(Pair("height", (int64_t)stats.nHeight)); - ret.push_back(Pair("bestblock", stats.hashBlock.GetHex())); - ret.push_back(Pair("transactions", (int64_t)stats.nTransactions)); - ret.push_back(Pair("txouts", (int64_t)stats.nTransactionOutputs)); - ret.push_back(Pair("bytes_serialized", (int64_t)stats.nSerializedSize)); - ret.push_back(Pair("hash_serialized", stats.hashSerialized.GetHex())); - ret.push_back(Pair("total_amount", ValueFromAmount(chainActive.Tip()->nMoneySupply))); + ret.pushKV("height", (int64_t)stats.nHeight); + ret.pushKV("bestblock", stats.hashBlock.GetHex()); + ret.pushKV("transactions", (int64_t)stats.nTransactions); + ret.pushKV("txouts", (int64_t)stats.nTransactionOutputs); + ret.pushKV("bytes_serialized", (int64_t)stats.nSerializedSize); + ret.pushKV("hash_serialized", stats.hashSerialized.GetHex()); + ret.pushKV("total_amount", ValueFromAmount(chainActive.Tip()->nMoneySupply)); } return ret; } @@ -694,17 +696,17 @@ UniValue gettxout(const UniValue& params, bool fHelp) BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock()); CBlockIndex* pindex = it->second; - ret.push_back(Pair("bestblock", pindex->GetBlockHash().GetHex())); + ret.pushKV("bestblock", pindex->GetBlockHash().GetHex()); if ((unsigned int)coins.nHeight == MEMPOOL_HEIGHT) - ret.push_back(Pair("confirmations", 0)); + ret.pushKV("confirmations", 0); else - ret.push_back(Pair("confirmations", pindex->nHeight - coins.nHeight + 1)); - ret.push_back(Pair("value", ValueFromAmount(coins.vout[n].nValue))); + ret.pushKV("confirmations", pindex->nHeight - coins.nHeight + 1); + ret.pushKV("value", ValueFromAmount(coins.vout[n].nValue)); UniValue o(UniValue::VOBJ); ScriptPubKeyToJSON(coins.vout[n].scriptPubKey, o, true); - ret.push_back(Pair("scriptPubKey", o)); - ret.push_back(Pair("version", coins.nVersion)); - ret.push_back(Pair("coinbase", coins.fCoinBase)); + ret.pushKV("scriptPubKey", o); + ret.pushKV("version", coins.nVersion); + ret.pushKV("coinbase", coins.fCoinBase); return ret; } @@ -748,19 +750,19 @@ static UniValue SoftForkMajorityDesc(int minVersion, CBlockIndex* pindex, int nR pstart = pstart->pprev; } UniValue rv(UniValue::VOBJ); - rv.push_back(Pair("status", nFound >= nRequired)); - rv.push_back(Pair("found", nFound)); - rv.push_back(Pair("required", nRequired)); - rv.push_back(Pair("window", Params().ToCheckBlockUpgradeMajority())); + rv.pushKV("status", nFound >= nRequired); + rv.pushKV("found", nFound); + rv.pushKV("required", nRequired); + rv.pushKV("window", Params().ToCheckBlockUpgradeMajority()); return rv; } static UniValue SoftForkDesc(const std::string &name, int version, CBlockIndex* pindex) { UniValue rv(UniValue::VOBJ); - rv.push_back(Pair("id", name)); - rv.push_back(Pair("version", version)); - rv.push_back(Pair("enforce", SoftForkMajorityDesc(version, pindex, Params().EnforceBlockUpgradeMajority()))); - rv.push_back(Pair("reject", SoftForkMajorityDesc(version, pindex, Params().RejectBlockOutdatedMajority()))); + rv.pushKV("id", name); + rv.pushKV("version", version); + rv.pushKV("enforce", SoftForkMajorityDesc(version, pindex, Params().EnforceBlockUpgradeMajority())); + rv.pushKV("reject", SoftForkMajorityDesc(version, pindex, Params().RejectBlockOutdatedMajority())); return rv; } @@ -772,7 +774,7 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) "Returns an object containing various state info regarding block chain processing.\n" "\nResult:\n" "{\n" - " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n" + " \"chain\": \"xxxx\", (string) current network name (main, test, regtest)\n" " \"blocks\": xxxxxx, (numeric) the current number of blocks processed in the server\n" " \"headers\": xxxxxx, (numeric) the current number of headers we have validated\n" " \"bestblockhash\": \"...\", (string) the hash of the currently best block\n" @@ -799,17 +801,17 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) LOCK(cs_main); UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("chain", Params().NetworkIDString())); - obj.push_back(Pair("blocks", (int)chainActive.Height())); - obj.push_back(Pair("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1)); - obj.push_back(Pair("bestblockhash", chainActive.Tip()->GetBlockHash().GetHex())); - obj.push_back(Pair("difficulty", (double)GetDifficulty())); - obj.push_back(Pair("verificationprogress", Checkpoints::GuessVerificationProgress(chainActive.Tip()))); - obj.push_back(Pair("chainwork", chainActive.Tip()->nChainWork.GetHex())); + obj.pushKV("chain", Params().NetworkIDString()); + obj.pushKV("blocks", (int)chainActive.Height()); + obj.pushKV("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1); + obj.pushKV("bestblockhash", chainActive.Tip()->GetBlockHash().GetHex()); + obj.pushKV("difficulty", (double)GetDifficulty()); + obj.pushKV("verificationprogress", Checkpoints::GuessVerificationProgress(chainActive.Tip())); + obj.pushKV("chainwork", chainActive.Tip()->nChainWork.GetHex()); CBlockIndex* tip = chainActive.Tip(); UniValue softforks(UniValue::VARR); softforks.push_back(SoftForkDesc("bip65", 5, tip)); - obj.push_back(Pair("softforks", softforks)); + obj.pushKV("softforks", softforks); return obj; } @@ -882,11 +884,11 @@ UniValue getchaintips(const UniValue& params, bool fHelp) UniValue res(UniValue::VARR); for (const CBlockIndex* block : setTips) { UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("height", block->nHeight)); - obj.push_back(Pair("hash", block->phashBlock->GetHex())); + obj.pushKV("height", block->nHeight); + obj.pushKV("hash", block->phashBlock->GetHex()); const int branchLen = block->nHeight - chainActive.FindFork(block)->nHeight; - obj.push_back(Pair("branchlen", branchLen)); + obj.pushKV("branchlen", branchLen); std::string status; if (chainActive.Contains(block)) { @@ -908,7 +910,7 @@ UniValue getchaintips(const UniValue& params, bool fHelp) // No clue. status = "unknown"; } - obj.push_back(Pair("status", status)); + obj.pushKV("status", status); res.push_back(obj); } @@ -959,10 +961,10 @@ UniValue getfeeinfo(const UniValue& params, bool fHelp) UniValue mempoolInfoToJSON() { UniValue ret(UniValue::VOBJ); - ret.push_back(Pair("size", (int64_t) mempool.size())); - ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize())); + ret.pushKV("size", (int64_t) mempool.size()); + ret.pushKV("bytes", (int64_t) mempool.GetTotalTxSize()); - //ret.push_back(Pair("usage", (int64_t) mempool.DynamicMemoryUsage())); + //ret.pushKV("usage", (int64_t) mempool.DynamicMemoryUsage()); return ret; } @@ -1128,10 +1130,10 @@ UniValue getinvalid (const UniValue& params, bool fHelp) } UniValue objTx(UniValue::VOBJ); - objTx.push_back(Pair("inv_out", it.first.ToString())); + objTx.pushKV("inv_out", it.first.ToString()); CAmount nValue = tx.vout[out.n].nValue; - objTx.push_back(Pair("value", FormatMoney(nValue))); + objTx.pushKV("value", FormatMoney(nValue)); //Search the txin's to see if any of them are "valid". UniValue objMixedValid(UniValue::VOBJ); @@ -1150,7 +1152,7 @@ UniValue getinvalid (const UniValue& params, bool fHelp) //This is a valid outpoint that mixed with an invalid outpoint. Investigate this person. //Information leakage, not covering their tracks well enough CAmount nValid = txPrev.vout[in2.prevout.n].nValue; - objMixedValid.push_back(Pair(FormatMoney(nValid), in2.prevout.ToString())); + objMixedValid.pushKV(FormatMoney(nValid), in2.prevout.ToString()); nMixedValid += nValid; mapMixedValid[in2.prevout] = 1; @@ -1163,9 +1165,9 @@ UniValue getinvalid (const UniValue& params, bool fHelp) if (!coins || !coins->IsAvailable(out.n)) fSpent = true; - objTx.push_back(Pair("spent", fSpent)); + objTx.pushKV("spent", fSpent); if (!objMixedValid.empty()) - objTx.push_back(Pair("mixed_with_valid", objMixedValid)); + objTx.pushKV("mixed_with_valid", objMixedValid); CScript scriptPubKey = tx.vout[out.n].scriptPubKey; if (!fSpent) { @@ -1186,13 +1188,13 @@ UniValue getinvalid (const UniValue& params, bool fHelp) UniValue objAddresses(UniValue::VOBJ); for (auto it : mapBanAddress) - objAddresses.push_back(Pair(it.first.ToString(), FormatMoney(it.second))); + objAddresses.pushKV(it.first.ToString(), FormatMoney(it.second)); UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("addresses_with_invalid", objAddresses)); - obj.push_back(Pair("total_unspent", FormatMoney(nUnspent))); - obj.push_back(Pair("total_minted", FormatMoney(nMint))); - obj.push_back(Pair("total_valid_used", FormatMoney(nMixedValid))); + obj.pushKV("addresses_with_invalid", objAddresses); + obj.pushKV("total_unspent", FormatMoney(nUnspent)); + obj.pushKV("total_minted", FormatMoney(nMint)); + obj.pushKV("total_valid_used", FormatMoney(nMixedValid)); ret.push_back(obj); return ret; @@ -1422,8 +1424,8 @@ UniValue getblockindexstats(const UniValue& params, bool fHelp) { validaterange(params, heightStart, heightEnd); // return object UniValue ret(UniValue::VOBJ); - ret.push_back(Pair("Starting block", heightStart)); - ret.push_back(Pair("Ending block", heightEnd)); + ret.pushKV("Starting block", heightStart); + ret.pushKV("Ending block", heightEnd); bool fFeeOnly = false; if (params.size() > 2) { @@ -1495,12 +1497,12 @@ UniValue getblockindexstats(const UniValue& params, bool fHelp) { CFeeRate nFeeRate = CFeeRate(nFees, nBytes); // return UniValue object - ret.push_back(Pair("txcount", (int64_t)nTxCount)); - ret.push_back(Pair("txcount_all", (int64_t)nTxCount_all)); - ret.push_back(Pair("txbytes", (int64_t)nBytes)); - ret.push_back(Pair("ttlfee", FormatMoney(nFees))); - ret.push_back(Pair("ttlfee_all", FormatMoney(nFees_all))); - ret.push_back(Pair("feeperkb", FormatMoney(nFeeRate.GetFeePerK()))); + ret.pushKV("txcount", (int64_t)nTxCount); + ret.pushKV("txcount_all", (int64_t)nTxCount_all); + ret.pushKV("txbytes", (int64_t)nBytes); + ret.pushKV("ttlfee", FormatMoney(nFees)); + ret.pushKV("ttlfee_all", FormatMoney(nFees_all)); + ret.pushKV("feeperkb", FormatMoney(nFeeRate.GetFeePerK())); return ret; } diff --git a/src/rpc/blockchain.h b/src/rpc/blockchain.h new file mode 100644 index 0000000000..c021441b0a --- /dev/null +++ b/src/rpc/blockchain.h @@ -0,0 +1,40 @@ +// Copyright (c) 2017 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_RPC_BLOCKCHAIN_H +#define BITCOIN_RPC_BLOCKCHAIN_H + +class CBlock; +class CBlockIndex; +class CScript; +class CTransaction; +class uint256; +class UniValue; + +/** + * Get the difficulty of the net wrt to the given block index, or the chain tip if + * not provided. + * + * @return A floating point number that is a multiple of the main net minimum + * difficulty (4295032833 hashes). + */ +double GetDifficulty(const CBlockIndex* blockindex = nullptr); + +/** Callback for when block tip changed. */ +void RPCNotifyBlockChange(bool ibd, const CBlockIndex *); + +/** Block description to JSON */ +UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false); + +/** Mempool information to JSON */ +UniValue mempoolInfoToJSON(); + +/** Mempool to JSON */ +UniValue mempoolToJSON(bool fVerbose = false); + +/** Block header to JSON */ +UniValue blockheaderToJSON(const CBlockIndex* blockindex); + +#endif + diff --git a/src/rpc/budget.cpp b/src/rpc/budget.cpp index 577e3d29d0..9201e80f72 100644 --- a/src/rpc/budget.cpp +++ b/src/rpc/budget.cpp @@ -28,27 +28,27 @@ void budgetToJSON(CBudgetProposal* pbudgetProposal, UniValue& bObj) ExtractDestination(pbudgetProposal->GetPayee(), address1); CBitcoinAddress address2(address1); - bObj.push_back(Pair("Name", pbudgetProposal->GetName())); - bObj.push_back(Pair("URL", pbudgetProposal->GetURL())); - bObj.push_back(Pair("Hash", pbudgetProposal->GetHash().ToString())); - bObj.push_back(Pair("FeeHash", pbudgetProposal->nFeeTXHash.ToString())); - bObj.push_back(Pair("BlockStart", (int64_t)pbudgetProposal->GetBlockStart())); - bObj.push_back(Pair("BlockEnd", (int64_t)pbudgetProposal->GetBlockEnd())); - bObj.push_back(Pair("TotalPaymentCount", (int64_t)pbudgetProposal->GetTotalPaymentCount())); - bObj.push_back(Pair("RemainingPaymentCount", (int64_t)pbudgetProposal->GetRemainingPaymentCount())); - bObj.push_back(Pair("PaymentAddress", address2.ToString())); - bObj.push_back(Pair("Ratio", pbudgetProposal->GetRatio())); - bObj.push_back(Pair("Yeas", (int64_t)pbudgetProposal->GetYeas())); - bObj.push_back(Pair("Nays", (int64_t)pbudgetProposal->GetNays())); - bObj.push_back(Pair("Abstains", (int64_t)pbudgetProposal->GetAbstains())); - bObj.push_back(Pair("TotalPayment", ValueFromAmount(pbudgetProposal->GetAmount() * pbudgetProposal->GetTotalPaymentCount()))); - bObj.push_back(Pair("MonthlyPayment", ValueFromAmount(pbudgetProposal->GetAmount()))); - bObj.push_back(Pair("IsEstablished", pbudgetProposal->IsEstablished())); + bObj.pushKV("Name", pbudgetProposal->GetName()); + bObj.pushKV("URL", pbudgetProposal->GetURL()); + bObj.pushKV("Hash", pbudgetProposal->GetHash().ToString()); + bObj.pushKV("FeeHash", pbudgetProposal->nFeeTXHash.ToString()); + bObj.pushKV("BlockStart", (int64_t)pbudgetProposal->GetBlockStart()); + bObj.pushKV("BlockEnd", (int64_t)pbudgetProposal->GetBlockEnd()); + bObj.pushKV("TotalPaymentCount", (int64_t)pbudgetProposal->GetTotalPaymentCount()); + bObj.pushKV("RemainingPaymentCount", (int64_t)pbudgetProposal->GetRemainingPaymentCount()); + bObj.pushKV("PaymentAddress", address2.ToString()); + bObj.pushKV("Ratio", pbudgetProposal->GetRatio()); + bObj.pushKV("Yeas", (int64_t)pbudgetProposal->GetYeas()); + bObj.pushKV("Nays", (int64_t)pbudgetProposal->GetNays()); + bObj.pushKV("Abstains", (int64_t)pbudgetProposal->GetAbstains()); + bObj.pushKV("TotalPayment", ValueFromAmount(pbudgetProposal->GetAmount() * pbudgetProposal->GetTotalPaymentCount())); + bObj.pushKV("MonthlyPayment", ValueFromAmount(pbudgetProposal->GetAmount())); + bObj.pushKV("IsEstablished", pbudgetProposal->IsEstablished()); std::string strError = ""; - bObj.push_back(Pair("IsValid", pbudgetProposal->IsValid(strError))); - bObj.push_back(Pair("IsValidReason", strError.c_str())); - bObj.push_back(Pair("fValid", pbudgetProposal->fValid)); + bObj.pushKV("IsValid", pbudgetProposal->IsValid(strError)); + bObj.pushKV("IsValidReason", strError.c_str()); + bObj.pushKV("fValid", pbudgetProposal->fValid); } UniValue preparebudget(const UniValue& params, bool fHelp) @@ -290,9 +290,9 @@ UniValue mnbudgetvote(const UniValue& params, bool fHelp) while (true) { if (!CMessageSigner::GetKeysFromSecret(strMasterNodePrivKey, keyMasternode, pubKeyMasternode)) { failed++; - statusObj.push_back(Pair("node", "local")); - statusObj.push_back(Pair("result", "failed")); - statusObj.push_back(Pair("error", "Masternode signing error, could not set key correctly.")); + statusObj.pushKV("node", "local"); + statusObj.pushKV("result", "failed"); + statusObj.pushKV("error", "Masternode signing error, could not set key correctly."); resultsObj.push_back(statusObj); break; } @@ -300,9 +300,9 @@ UniValue mnbudgetvote(const UniValue& params, bool fHelp) CMasternode* pmn = mnodeman.Find(activeMasternode.vin); if (pmn == NULL) { failed++; - statusObj.push_back(Pair("node", "local")); - statusObj.push_back(Pair("result", "failed")); - statusObj.push_back(Pair("error", "Failure to find masternode in list : " + activeMasternode.vin.ToString())); + statusObj.pushKV("node", "local"); + statusObj.pushKV("result", "failed"); + statusObj.pushKV("error", "Failure to find masternode in list : " + activeMasternode.vin.ToString()); resultsObj.push_back(statusObj); break; } @@ -310,9 +310,9 @@ UniValue mnbudgetvote(const UniValue& params, bool fHelp) CBudgetVote vote(activeMasternode.vin, hash, nVote); if (!vote.Sign(keyMasternode, pubKeyMasternode)) { failed++; - statusObj.push_back(Pair("node", "local")); - statusObj.push_back(Pair("result", "failed")); - statusObj.push_back(Pair("error", "Failure to sign.")); + statusObj.pushKV("node", "local"); + statusObj.pushKV("result", "failed"); + statusObj.pushKV("error", "Failure to sign."); resultsObj.push_back(statusObj); break; } @@ -322,22 +322,22 @@ UniValue mnbudgetvote(const UniValue& params, bool fHelp) success++; budget.mapSeenMasternodeBudgetVotes.insert(std::make_pair(vote.GetHash(), vote)); vote.Relay(); - statusObj.push_back(Pair("node", "local")); - statusObj.push_back(Pair("result", "success")); - statusObj.push_back(Pair("error", "")); + statusObj.pushKV("node", "local"); + statusObj.pushKV("result", "success"); + statusObj.pushKV("error", ""); } else { failed++; - statusObj.push_back(Pair("node", "local")); - statusObj.push_back(Pair("result", "failed")); - statusObj.push_back(Pair("error", "Error voting : " + strError)); + statusObj.pushKV("node", "local"); + statusObj.pushKV("result", "failed"); + statusObj.pushKV("error", "Error voting : " + strError); } resultsObj.push_back(statusObj); break; } UniValue returnObj(UniValue::VOBJ); - returnObj.push_back(Pair("overall", strprintf("Voted successfully %d time(s) and failed %d time(s).", success, failed))); - returnObj.push_back(Pair("detail", resultsObj)); + returnObj.pushKV("overall", strprintf("Voted successfully %d time(s) and failed %d time(s).", success, failed)); + returnObj.pushKV("detail", resultsObj); return returnObj; } @@ -356,9 +356,9 @@ UniValue mnbudgetvote(const UniValue& params, bool fHelp) if (!CMessageSigner::GetKeysFromSecret(mne.getPrivKey(), keyMasternode, pubKeyMasternode)) { failed++; - statusObj.push_back(Pair("node", mne.getAlias())); - statusObj.push_back(Pair("result", "failed")); - statusObj.push_back(Pair("error", "Masternode signing error, could not set key correctly.")); + statusObj.pushKV("node", mne.getAlias()); + statusObj.pushKV("result", "failed"); + statusObj.pushKV("error", "Masternode signing error, could not set key correctly."); resultsObj.push_back(statusObj); continue; } @@ -366,9 +366,9 @@ UniValue mnbudgetvote(const UniValue& params, bool fHelp) CMasternode* pmn = mnodeman.Find(pubKeyMasternode); if (pmn == NULL) { failed++; - statusObj.push_back(Pair("node", mne.getAlias())); - statusObj.push_back(Pair("result", "failed")); - statusObj.push_back(Pair("error", "Can't find masternode by pubkey")); + statusObj.pushKV("node", mne.getAlias()); + statusObj.pushKV("result", "failed"); + statusObj.pushKV("error", "Can't find masternode by pubkey"); resultsObj.push_back(statusObj); continue; } @@ -376,9 +376,9 @@ UniValue mnbudgetvote(const UniValue& params, bool fHelp) CBudgetVote vote(pmn->vin, hash, nVote); if (!vote.Sign(keyMasternode, pubKeyMasternode)) { failed++; - statusObj.push_back(Pair("node", mne.getAlias())); - statusObj.push_back(Pair("result", "failed")); - statusObj.push_back(Pair("error", "Failure to sign.")); + statusObj.pushKV("node", mne.getAlias()); + statusObj.pushKV("result", "failed"); + statusObj.pushKV("error", "Failure to sign."); resultsObj.push_back(statusObj); continue; } @@ -388,22 +388,22 @@ UniValue mnbudgetvote(const UniValue& params, bool fHelp) budget.mapSeenMasternodeBudgetVotes.insert(std::make_pair(vote.GetHash(), vote)); vote.Relay(); success++; - statusObj.push_back(Pair("node", mne.getAlias())); - statusObj.push_back(Pair("result", "success")); - statusObj.push_back(Pair("error", "")); + statusObj.pushKV("node", mne.getAlias()); + statusObj.pushKV("result", "success"); + statusObj.pushKV("error", ""); } else { failed++; - statusObj.push_back(Pair("node", mne.getAlias())); - statusObj.push_back(Pair("result", "failed")); - statusObj.push_back(Pair("error", strError.c_str())); + statusObj.pushKV("node", mne.getAlias()); + statusObj.pushKV("result", "failed"); + statusObj.pushKV("error", strError.c_str()); } resultsObj.push_back(statusObj); } UniValue returnObj(UniValue::VOBJ); - returnObj.push_back(Pair("overall", strprintf("Voted successfully %d time(s) and failed %d time(s).", success, failed))); - returnObj.push_back(Pair("detail", resultsObj)); + returnObj.pushKV("overall", strprintf("Voted successfully %d time(s) and failed %d time(s).", success, failed)); + returnObj.pushKV("detail", resultsObj); return returnObj; } @@ -429,9 +429,9 @@ UniValue mnbudgetvote(const UniValue& params, bool fHelp) if(!CMessageSigner::GetKeysFromSecret(mne.getPrivKey(), keyMasternode, pubKeyMasternode)){ failed++; - statusObj.push_back(Pair("node", mne.getAlias())); - statusObj.push_back(Pair("result", "failed")); - statusObj.push_back(Pair("error", "Masternode signing error, could not set key correctly.")); + statusObj.pushKV("node", mne.getAlias()); + statusObj.pushKV("result", "failed"); + statusObj.pushKV("error", "Masternode signing error, could not set key correctly."); resultsObj.push_back(statusObj); continue; } @@ -440,9 +440,9 @@ UniValue mnbudgetvote(const UniValue& params, bool fHelp) if(pmn == NULL) { failed++; - statusObj.push_back(Pair("node", mne.getAlias())); - statusObj.push_back(Pair("result", "failed")); - statusObj.push_back(Pair("error", "Can't find masternode by pubkey")); + statusObj.pushKV("node", mne.getAlias()); + statusObj.pushKV("result", "failed"); + statusObj.pushKV("error", "Can't find masternode by pubkey"); resultsObj.push_back(statusObj); continue; } @@ -450,9 +450,9 @@ UniValue mnbudgetvote(const UniValue& params, bool fHelp) CBudgetVote vote(pmn->vin, hash, nVote); if(!vote.Sign(keyMasternode, pubKeyMasternode)){ failed++; - statusObj.push_back(Pair("node", mne.getAlias())); - statusObj.push_back(Pair("result", "failed")); - statusObj.push_back(Pair("error", "Failure to sign.")); + statusObj.pushKV("node", mne.getAlias()); + statusObj.pushKV("result", "failed"); + statusObj.pushKV("error", "Failure to sign."); resultsObj.push_back(statusObj); continue; } @@ -462,22 +462,22 @@ UniValue mnbudgetvote(const UniValue& params, bool fHelp) budget.mapSeenMasternodeBudgetVotes.insert(std::make_pair(vote.GetHash(), vote)); vote.Relay(); success++; - statusObj.push_back(Pair("node", mne.getAlias())); - statusObj.push_back(Pair("result", "success")); - statusObj.push_back(Pair("error", "")); + statusObj.pushKV("node", mne.getAlias()); + statusObj.pushKV("result", "success"); + statusObj.pushKV("error", ""); } else { failed++; - statusObj.push_back(Pair("node", mne.getAlias())); - statusObj.push_back(Pair("result", "failed")); - statusObj.push_back(Pair("error", strError.c_str())); + statusObj.pushKV("node", mne.getAlias()); + statusObj.pushKV("result", "failed"); + statusObj.pushKV("error", strError.c_str()); } resultsObj.push_back(statusObj); } UniValue returnObj(UniValue::VOBJ); - returnObj.push_back(Pair("overall", strprintf("Voted successfully %d time(s) and failed %d time(s).", success, failed))); - returnObj.push_back(Pair("detail", resultsObj)); + returnObj.pushKV("overall", strprintf("Voted successfully %d time(s) and failed %d time(s).", success, failed)); + returnObj.pushKV("detail", resultsObj); return returnObj; } @@ -520,11 +520,11 @@ UniValue getbudgetvotes(const UniValue& params, bool fHelp) std::map::iterator it = pbudgetProposal->mapVotes.begin(); while (it != pbudgetProposal->mapVotes.end()) { UniValue bObj(UniValue::VOBJ); - bObj.push_back(Pair("mnId", (*it).second.vin.prevout.hash.ToString())); - bObj.push_back(Pair("nHash", (*it).first.ToString().c_str())); - bObj.push_back(Pair("Vote", (*it).second.GetVoteString())); - bObj.push_back(Pair("nTime", (int64_t)(*it).second.nTime)); - bObj.push_back(Pair("fValid", (*it).second.fValid)); + bObj.pushKV("mnId", (*it).second.vin.prevout.hash.ToString()); + bObj.pushKV("nHash", (*it).first.ToString().c_str()); + bObj.pushKV("Vote", (*it).second.GetVoteString()); + bObj.pushKV("nTime", (int64_t)(*it).second.nTime); + bObj.pushKV("fValid", (*it).second.fValid); ret.push_back(bObj); @@ -604,8 +604,8 @@ UniValue getbudgetprojection(const UniValue& params, bool fHelp) UniValue bObj(UniValue::VOBJ); budgetToJSON(pbudgetProposal, bObj); - bObj.push_back(Pair("Alloted", ValueFromAmount(pbudgetProposal->GetAllotted()))); - bObj.push_back(Pair("TotalBudgetAlloted", ValueFromAmount(nTotalAllotted))); + bObj.pushKV("Alloted", ValueFromAmount(pbudgetProposal->GetAllotted())); + bObj.pushKV("TotalBudgetAlloted", ValueFromAmount(nTotalAllotted)); ret.push_back(bObj); } @@ -782,18 +782,18 @@ UniValue mnfinalbudget(const UniValue& params, bool fHelp) if (!CMessageSigner::GetKeysFromSecret(mne.getPrivKey(), keyMasternode, pubKeyMasternode)) { failed++; - statusObj.push_back(Pair("result", "failed")); - statusObj.push_back(Pair("errorMessage", "Masternode signing error, could not set key correctly.")); - resultsObj.push_back(Pair(mne.getAlias(), statusObj)); + statusObj.pushKV("result", "failed"); + statusObj.pushKV("errorMessage", "Masternode signing error, could not set key correctly."); + resultsObj.pushKV(mne.getAlias(), statusObj); continue; } CMasternode* pmn = mnodeman.Find(pubKeyMasternode); if (pmn == NULL) { failed++; - statusObj.push_back(Pair("result", "failed")); - statusObj.push_back(Pair("errorMessage", "Can't find masternode by pubkey")); - resultsObj.push_back(Pair(mne.getAlias(), statusObj)); + statusObj.pushKV("result", "failed"); + statusObj.pushKV("errorMessage", "Can't find masternode by pubkey"); + resultsObj.pushKV(mne.getAlias(), statusObj); continue; } @@ -801,9 +801,9 @@ UniValue mnfinalbudget(const UniValue& params, bool fHelp) CFinalizedBudgetVote vote(pmn->vin, hash); if (!vote.Sign(keyMasternode, pubKeyMasternode)) { failed++; - statusObj.push_back(Pair("result", "failed")); - statusObj.push_back(Pair("errorMessage", "Failure to sign.")); - resultsObj.push_back(Pair(mne.getAlias(), statusObj)); + statusObj.pushKV("result", "failed"); + statusObj.pushKV("errorMessage", "Failure to sign."); + resultsObj.pushKV(mne.getAlias(), statusObj); continue; } @@ -812,18 +812,18 @@ UniValue mnfinalbudget(const UniValue& params, bool fHelp) budget.mapSeenFinalizedBudgetVotes.insert(std::make_pair(vote.GetHash(), vote)); vote.Relay(); success++; - statusObj.push_back(Pair("result", "success")); + statusObj.pushKV("result", "success"); } else { failed++; - statusObj.push_back(Pair("result", strError.c_str())); + statusObj.pushKV("result", strError.c_str()); } - resultsObj.push_back(Pair(mne.getAlias(), statusObj)); + resultsObj.pushKV(mne.getAlias(), statusObj); } UniValue returnObj(UniValue::VOBJ); - returnObj.push_back(Pair("overall", strprintf("Voted successfully %d time(s) and failed %d time(s).", success, failed))); - returnObj.push_back(Pair("detail", resultsObj)); + returnObj.pushKV("overall", strprintf("Voted successfully %d time(s) and failed %d time(s).", success, failed)); + returnObj.pushKV("detail", resultsObj); return returnObj; } @@ -867,19 +867,19 @@ UniValue mnfinalbudget(const UniValue& params, bool fHelp) std::vector winningFbs = budget.GetFinalizedBudgets(); for (CFinalizedBudget* finalizedBudget : winningFbs) { UniValue bObj(UniValue::VOBJ); - bObj.push_back(Pair("FeeTX", finalizedBudget->nFeeTXHash.ToString())); - bObj.push_back(Pair("Hash", finalizedBudget->GetHash().ToString())); - bObj.push_back(Pair("BlockStart", (int64_t)finalizedBudget->GetBlockStart())); - bObj.push_back(Pair("BlockEnd", (int64_t)finalizedBudget->GetBlockEnd())); - bObj.push_back(Pair("Proposals", finalizedBudget->GetProposals())); - bObj.push_back(Pair("VoteCount", (int64_t)finalizedBudget->GetVoteCount())); - bObj.push_back(Pair("Status", finalizedBudget->GetStatus())); + bObj.pushKV("FeeTX", finalizedBudget->nFeeTXHash.ToString()); + bObj.pushKV("Hash", finalizedBudget->GetHash().ToString()); + bObj.pushKV("BlockStart", (int64_t)finalizedBudget->GetBlockStart()); + bObj.pushKV("BlockEnd", (int64_t)finalizedBudget->GetBlockEnd()); + bObj.pushKV("Proposals", finalizedBudget->GetProposals()); + bObj.pushKV("VoteCount", (int64_t)finalizedBudget->GetVoteCount()); + bObj.pushKV("Status", finalizedBudget->GetStatus()); std::string strError = ""; - bObj.push_back(Pair("IsValid", finalizedBudget->IsValid(strError))); - bObj.push_back(Pair("IsValidReason", strError.c_str())); + bObj.pushKV("IsValid", finalizedBudget->IsValid(strError)); + bObj.pushKV("IsValidReason", strError.c_str()); - resultObj.push_back(Pair(finalizedBudget->GetName(), bObj)); + resultObj.pushKV(finalizedBudget->GetName(), bObj); } return resultObj; @@ -901,11 +901,11 @@ UniValue mnfinalbudget(const UniValue& params, bool fHelp) std::map::iterator it = pfinalBudget->mapVotes.begin(); while (it != pfinalBudget->mapVotes.end()) { UniValue bObj(UniValue::VOBJ); - bObj.push_back(Pair("nHash", (*it).first.ToString().c_str())); - bObj.push_back(Pair("nTime", (int64_t)(*it).second.nTime)); - bObj.push_back(Pair("fValid", (*it).second.fValid)); + bObj.pushKV("nHash", (*it).first.ToString().c_str()); + bObj.pushKV("nTime", (int64_t)(*it).second.nTime); + bObj.pushKV("fValid", (*it).second.fValid); - obj.push_back(Pair((*it).second.vin.prevout.ToStringShort(), bObj)); + obj.pushKV((*it).second.vin.prevout.ToStringShort(), bObj); it++; } diff --git a/src/rpc/masternode.cpp b/src/rpc/masternode.cpp index af709b75e9..535a8ad2ea 100644 --- a/src/rpc/masternode.cpp +++ b/src/rpc/masternode.cpp @@ -213,19 +213,19 @@ UniValue listmasternodes(const UniValue& params, bool fHelp) LookupHost(strHost.c_str(), node, false); std::string strNetwork = GetNetworkName(node.GetNetwork()); - obj.push_back(Pair("rank", (strStatus == "ENABLED" ? s.first : 0))); - obj.push_back(Pair("network", strNetwork)); - obj.push_back(Pair("txhash", strTxHash)); - obj.push_back(Pair("outidx", (uint64_t)oIdx)); - obj.push_back(Pair("pubkey", HexStr(mn->pubKeyMasternode))); - obj.push_back(Pair("status", strStatus)); - obj.push_back(Pair("addr", CBitcoinAddress(mn->pubKeyCollateralAddress.GetID()).ToString())); + obj.pushKV("rank", (strStatus == "ENABLED" ? s.first : 0)); + obj.pushKV("network", strNetwork); + obj.pushKV("txhash", strTxHash); + obj.pushKV("outidx", (uint64_t)oIdx); + obj.pushKV("pubkey", HexStr(mn->pubKeyMasternode)); + obj.pushKV("status", strStatus); + obj.pushKV("addr", CBitcoinAddress(mn->pubKeyCollateralAddress.GetID()).ToString()); std::string mnStealth(mn->vin.masternodeStealthAddress.begin(), mn->vin.masternodeStealthAddress.end()); - obj.push_back(Pair("stealthaddress", mnStealth)); - obj.push_back(Pair("version", mn->protocolVersion)); - obj.push_back(Pair("lastseen", (int64_t)mn->lastPing.sigTime)); - obj.push_back(Pair("activetime", (int64_t)(mn->lastPing.sigTime - mn->sigTime))); - obj.push_back(Pair("lastpaid", (int64_t)mn->GetLastPaid())); + obj.pushKV("stealthaddress", mnStealth); + obj.pushKV("version", mn->protocolVersion); + obj.pushKV("lastseen", (int64_t)mn->lastPing.sigTime); + obj.pushKV("activetime", (int64_t)(mn->lastPing.sigTime - mn->sigTime)); + obj.pushKV("lastpaid", (int64_t)mn->GetLastPaid()); ret.push_back(obj); } @@ -260,13 +260,13 @@ UniValue getmasternodecount (const UniValue& params, bool fHelp) mnodeman.CountNetworks(ActiveProtocol(), ipv4, ipv6, onion); - obj.push_back(Pair("total", mnodeman.size())); - obj.push_back(Pair("stable", mnodeman.stable_size())); - obj.push_back(Pair("enabled", mnodeman.CountEnabled())); - obj.push_back(Pair("inqueue", nCount)); - obj.push_back(Pair("ipv4", ipv4)); - obj.push_back(Pair("ipv6", ipv6)); - obj.push_back(Pair("onion", onion)); + obj.pushKV("total", mnodeman.size()); + obj.pushKV("stable", mnodeman.stable_size()); + obj.pushKV("enabled", mnodeman.CountEnabled()); + obj.pushKV("inqueue", nCount); + obj.pushKV("ipv4", ipv4); + obj.pushKV("ipv6", ipv6); + obj.pushKV("onion", onion); return obj; } @@ -294,11 +294,11 @@ UniValue masternodecurrent (const UniValue& params, bool fHelp) CMasternode* winner = mnodeman.GetNextMasternodeInQueueForPayment(nHeight, true, nCount); if (winner) { UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("protocol", (int64_t)winner->protocolVersion)); - obj.push_back(Pair("txhash", winner->vin.prevout.hash.ToString())); - obj.push_back(Pair("pubkey", CBitcoinAddress(winner->pubKeyCollateralAddress.GetID()).ToString())); - obj.push_back(Pair("lastseen", (winner->lastPing == CMasternodePing()) ? winner->sigTime : (int64_t)winner->lastPing.sigTime)); - obj.push_back(Pair("activeseconds", (winner->lastPing == CMasternodePing()) ? 0 : (int64_t)(winner->lastPing.sigTime - winner->sigTime))); + obj.pushKV("protocol", (int64_t)winner->protocolVersion); + obj.pushKV("txhash", winner->vin.prevout.hash.ToString()); + obj.pushKV("pubkey", CBitcoinAddress(winner->pubKeyCollateralAddress.GetID()).ToString()); + obj.pushKV("lastseen", (winner->lastPing == CMasternodePing()) ? winner->sigTime : (int64_t)winner->lastPing.sigTime); + obj.pushKV("activeseconds", (winner->lastPing == CMasternodePing()) ? 0 : (int64_t)(winner->lastPing.sigTime - winner->sigTime)); return obj; } @@ -321,9 +321,9 @@ bool StartMasternodeEntry(UniValue& statusObjRet, CMasternodeBroadcast& mnbRet, fSuccessRet = CMasternodeBroadcast::Create(mne.getIp(), mne.getPrivKey(), mne.getTxHash(), mne.getOutputIndex(), errorMessage, mnbRet); - statusObjRet.push_back(Pair("alias", mne.getAlias())); - statusObjRet.push_back(Pair("result", fSuccessRet ? "success" : "failed")); - statusObjRet.push_back(Pair("error", fSuccessRet ? "" : errorMessage)); + statusObjRet.pushKV("alias", mne.getAlias()); + statusObjRet.pushKV("result", fSuccessRet ? "success" : "failed"); + statusObjRet.pushKV("error", fSuccessRet ? "" : errorMessage); return true; } @@ -351,7 +351,7 @@ void SerializeMNB(UniValue& statusObjRet, const CMasternodeBroadcast& mnb, const successful++; CDataStream ssMnb(SER_NETWORK, PROTOCOL_VERSION); ssMnb << mnb; - statusObjRet.push_back(Pair("hex", HexStr(ssMnb.begin(), ssMnb.end()))); + statusObjRet.pushKV("hex", HexStr(ssMnb.begin(), ssMnb.end())); } else { failed++; } @@ -454,8 +454,8 @@ UniValue startmasternode (const UniValue& params, bool fHelp) pwalletMain->Lock(); UniValue returnObj(UniValue::VOBJ); - returnObj.push_back(Pair("overall", strprintf("Successfully started %d masternodes, failed to start %d, total %d", successful, failed, successful + failed))); - returnObj.push_back(Pair("detail", resultsObj)); + returnObj.pushKV("overall", strprintf("Successfully started %d masternodes, failed to start %d, total %d", successful, failed, successful + failed)); + returnObj.pushKV("detail", resultsObj); return returnObj; } @@ -485,8 +485,8 @@ UniValue startmasternode (const UniValue& params, bool fHelp) pwalletMain->Lock(); if(!found) { - statusObj.push_back(Pair("success", false)); - statusObj.push_back(Pair("error_message", "Could not find alias in config. Verify with list-conf.")); + statusObj.pushKV("success", false); + statusObj.pushKV("error_message", "Could not find alias in config. Verify with list-conf."); } return statusObj; @@ -530,11 +530,12 @@ UniValue createmasternode(const UniValue& params, bool fHelp) UniValue ret(UniValue::VARR); int indexOut = -1; + const CAmount collateralAmount = Params().MNCollateralAmt(); for (int i=0; i < (int)wtx.vout.size(); i++) { UniValue obj(UniValue::VOBJ); CTxOut& out = wtx.vout[i]; CAmount value = pwalletMain->getCTxOutValue(wtx, out); - if (value == Params().MNCollateralAmt()) { + if (value == collateralAmount) { indexOut = i; // Lock collateral output @@ -542,9 +543,9 @@ UniValue createmasternode(const UniValue& params, bool fHelp) pwalletMain->LockCoin(collateralOut); LogPrintf("Masternode transaction: %s:%i has been locked\n", wtx.GetHash().GetHex().c_str(), indexOut); - obj.push_back(Pair("txhash", wtx.GetHash().GetHex().c_str())); - obj.push_back(Pair("outputidx", indexOut)); - obj.push_back(Pair("genkey", CBitcoinSecret(secret).ToString())); + obj.pushKV("txhash", wtx.GetHash().GetHex().c_str()); + obj.pushKV("outputidx", indexOut); + obj.pushKV("genkey", CBitcoinSecret(secret).ToString()); ret.push_back(obj); } } @@ -596,8 +597,8 @@ UniValue getmasternodeoutputs (const UniValue& params, bool fHelp) UniValue ret(UniValue::VARR); for (COutput& out : possibleCoins) { UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("txhash", out.tx->GetHash().ToString())); - obj.push_back(Pair("outputidx", out.i)); + obj.pushKV("txhash", out.tx->GetHash().ToString()); + obj.pushKV("outputidx", out.i); ret.push_back(obj); } @@ -654,12 +655,12 @@ UniValue listmasternodeconf (const UniValue& params, bool fHelp) strStatus.find(strFilter) == std::string::npos) continue; UniValue mnObj(UniValue::VOBJ); - mnObj.push_back(Pair("alias", mne.getAlias())); - mnObj.push_back(Pair("address", mne.getIp())); - mnObj.push_back(Pair("privateKey", mne.getPrivKey())); - mnObj.push_back(Pair("txHash", mne.getTxHash())); - mnObj.push_back(Pair("outputIndex", mne.getOutputIndex())); - mnObj.push_back(Pair("status", strStatus)); + mnObj.pushKV("alias", mne.getAlias()); + mnObj.pushKV("address", mne.getIp()); + mnObj.pushKV("privateKey", mne.getPrivKey()); + mnObj.pushKV("txHash", mne.getTxHash()); + mnObj.pushKV("outputIndex", mne.getOutputIndex()); + mnObj.pushKV("status", strStatus); ret.push_back(mnObj); } @@ -694,12 +695,12 @@ UniValue getmasternodestatus (const UniValue& params, bool fHelp) if (pmn) { UniValue mnObj(UniValue::VOBJ); - mnObj.push_back(Pair("txhash", activeMasternode.vin.prevout.hash.ToString())); - mnObj.push_back(Pair("outputidx", (uint64_t)activeMasternode.vin.prevout.n)); - mnObj.push_back(Pair("netaddr", activeMasternode.service.ToString())); - mnObj.push_back(Pair("addr", CBitcoinAddress(pmn->pubKeyCollateralAddress.GetID()).ToString())); - mnObj.push_back(Pair("status", activeMasternode.GetStatus())); - mnObj.push_back(Pair("message", activeMasternode.GetStatusMessage())); + mnObj.pushKV("txhash", activeMasternode.vin.prevout.hash.ToString()); + mnObj.pushKV("outputidx", (uint64_t)activeMasternode.vin.prevout.n); + mnObj.pushKV("netaddr", activeMasternode.service.ToString()); + mnObj.pushKV("addr", CBitcoinAddress(pmn->pubKeyCollateralAddress.GetID()).ToString()); + mnObj.pushKV("status", activeMasternode.GetStatus()); + mnObj.pushKV("message", activeMasternode.GetStatusMessage()); return mnObj; } throw std::runtime_error("Masternode not found in the list of available masternodes. Current status: " @@ -767,7 +768,7 @@ UniValue getmasternodewinners (const UniValue& params, bool fHelp) for (int i = nHeight - nLast; i < nHeight + 20; i++) { UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("nHeight", i)); + obj.pushKV("nHeight", i); std::string strPayment = GetRequiredPaymentsString(i); if (strFilter != "" && strPayment.find(strFilter) == std::string::npos) continue; @@ -781,24 +782,24 @@ UniValue getmasternodewinners (const UniValue& params, bool fHelp) std::size_t pos = t.find(":"); std::string strAddress = t.substr(0,pos); uint64_t nVotes = atoi(t.substr(pos+1)); - addr.push_back(Pair("address", strAddress)); - addr.push_back(Pair("nVotes", nVotes)); + addr.pushKV("address", strAddress); + addr.pushKV("nVotes", nVotes); winner.push_back(addr); } - obj.push_back(Pair("winner", winner)); + obj.pushKV("winner", winner); } else if (strPayment.find("Unknown") == std::string::npos) { UniValue winner(UniValue::VOBJ); std::size_t pos = strPayment.find(":"); std::string strAddress = strPayment.substr(0,pos); uint64_t nVotes = atoi(strPayment.substr(pos+1)); - winner.push_back(Pair("address", strAddress)); - winner.push_back(Pair("nVotes", nVotes)); - obj.push_back(Pair("winner", winner)); + winner.pushKV("address", strAddress); + winner.pushKV("nVotes", nVotes); + obj.pushKV("winner", winner); } else { UniValue winner(UniValue::VOBJ); - winner.push_back(Pair("address", strPayment)); - winner.push_back(Pair("nVotes", 0)); - obj.push_back(Pair("winner", winner)); + winner.pushKV("address", strPayment); + winner.pushKV("nVotes", 0); + obj.pushKV("winner", winner); } ret.push_back(obj); @@ -848,7 +849,7 @@ UniValue getmasternodescores (const UniValue& params, bool fHelp) } } if (pBestMasternode) - obj.push_back(Pair(strprintf("%d", nHeight), pBestMasternode->vin.prevout.hash.ToString().c_str())); + obj.pushKV(strprintf("%d", nHeight), pBestMasternode->vin.prevout.hash.ToString().c_str()); } return obj; @@ -879,9 +880,9 @@ UniValue getcurrentseesawreward (const UniValue& params, bool fHelp) CAmount masternodeReward = GetSeeSaw(nReward, 0, nblockHeight); CAmount stakingnodeReward = nReward - masternodeReward; - obj.push_back(Pair("Masternode Reward", ValueFromAmount(masternodeReward))); - obj.push_back(Pair("Staking Reward", ValueFromAmount(stakingnodeReward))); - obj.push_back(Pair("Total Reward", ValueFromAmount(nReward))); + obj.pushKV("Masternode Reward", ValueFromAmount(masternodeReward)); + obj.pushKV("Staking Reward", ValueFromAmount(stakingnodeReward)); + obj.pushKV("Total Reward", ValueFromAmount(nReward)); return obj; } @@ -914,10 +915,10 @@ UniValue getseesawrewardwithheight (const UniValue& params, bool fHelp) CAmount masternodeReward = GetSeeSaw(nReward, 0, nblockHeight); CAmount stakingnodeReward = nReward - masternodeReward; - obj.push_back(Pair("Block Height", nblockHeight)); - obj.push_back(Pair("Masternode Reward", ValueFromAmount(masternodeReward))); - obj.push_back(Pair("Staking Reward", ValueFromAmount(stakingnodeReward))); - obj.push_back(Pair("Total Reward", ValueFromAmount(nReward))); + obj.pushKV("Block Height", nblockHeight); + obj.pushKV("Masternode Reward", ValueFromAmount(masternodeReward)); + obj.pushKV("Staking Reward", ValueFromAmount(stakingnodeReward)); + obj.pushKV("Total Reward", ValueFromAmount(nReward)); return obj; } @@ -946,8 +947,8 @@ UniValue getseesawrewardratio (const UniValue& params, bool fHelp) CAmount masternodeReward = GetSeeSaw(nReward, 0, nblockHeight); int masternodeRatio = (masternodeReward * 100)/nReward; - obj.push_back(Pair("Masternode Reward Ratio", masternodeRatio)); - obj.push_back(Pair("Staking Reward Ratio", 100 - masternodeRatio)); + obj.pushKV("Masternode Reward Ratio", masternodeRatio); + obj.pushKV("Staking Reward Ratio", 100 - masternodeRatio); return obj; } @@ -1020,7 +1021,7 @@ UniValue createmasternodebroadcast(const UniValue& params, bool fHelp) bool found = false; UniValue statusObj(UniValue::VOBJ); - statusObj.push_back(Pair("alias", alias)); + statusObj.pushKV("alias", alias); for (CMasternodeConfig::CMasternodeEntry mne : masternodeConfig.getEntries()) { if(mne.getAlias() == alias) { @@ -1036,8 +1037,8 @@ UniValue createmasternodebroadcast(const UniValue& params, bool fHelp) } if(!found) { - statusObj.push_back(Pair("success", false)); - statusObj.push_back(Pair("error_message", "Could not find alias in config. Verify with list-conf.")); + statusObj.pushKV("success", false); + statusObj.pushKV("error_message", "Could not find alias in config. Verify with list-conf."); } return statusObj; @@ -1069,8 +1070,8 @@ UniValue createmasternodebroadcast(const UniValue& params, bool fHelp) } UniValue returnObj(UniValue::VOBJ); - returnObj.push_back(Pair("overall", strprintf("Successfully created broadcast messages for %d masternodes, failed to create %d, total %d", successful, failed, successful + failed))); - returnObj.push_back(Pair("detail", resultsObj)); + returnObj.pushKV("overall", strprintf("Successfully created broadcast messages for %d masternodes, failed to create %d, total %d", successful, failed, successful + failed)); + returnObj.pushKV("detail", resultsObj); return returnObj; } @@ -1117,22 +1118,22 @@ UniValue decodemasternodebroadcast(const UniValue & params, bool fHelp) UniValue resultObj(UniValue::VOBJ); - resultObj.push_back(Pair("vin", mnb.vin.prevout.ToString())); - resultObj.push_back(Pair("addr", mnb.addr.ToString())); - resultObj.push_back(Pair("pubkeycollateral", CBitcoinAddress(mnb.pubKeyCollateralAddress.GetID()).ToString())); - resultObj.push_back(Pair("pubkeymasternode", CBitcoinAddress(mnb.pubKeyMasternode.GetID()).ToString())); - resultObj.push_back(Pair("vchsig", EncodeBase64(&mnb.sig[0], mnb.sig.size()))); - resultObj.push_back(Pair("sigtime", mnb.sigTime)); - resultObj.push_back(Pair("protocolversion", mnb.protocolVersion)); - resultObj.push_back(Pair("nlastdsq", mnb.nLastDsq)); + resultObj.pushKV("vin", mnb.vin.prevout.ToString()); + resultObj.pushKV("addr", mnb.addr.ToString()); + resultObj.pushKV("pubkeycollateral", CBitcoinAddress(mnb.pubKeyCollateralAddress.GetID()).ToString()); + resultObj.pushKV("pubkeymasternode", CBitcoinAddress(mnb.pubKeyMasternode.GetID()).ToString()); + resultObj.pushKV("vchsig", EncodeBase64(&mnb.sig[0], mnb.sig.size())); + resultObj.pushKV("sigtime", mnb.sigTime); + resultObj.pushKV("protocolversion", mnb.protocolVersion); + resultObj.pushKV("nlastdsq", mnb.nLastDsq); UniValue lastPingObj(UniValue::VOBJ); - lastPingObj.push_back(Pair("vin", mnb.lastPing.vin.prevout.ToString())); - lastPingObj.push_back(Pair("blockhash", mnb.lastPing.blockHash.ToString())); - lastPingObj.push_back(Pair("sigtime", mnb.lastPing.sigTime)); - lastPingObj.push_back(Pair("vchsig", EncodeBase64(&mnb.lastPing.vchSig[0], mnb.lastPing.vchSig.size()))); + lastPingObj.pushKV("vin", mnb.lastPing.vin.prevout.ToString()); + lastPingObj.pushKV("blockhash", mnb.lastPing.blockHash.ToString()); + lastPingObj.pushKV("sigtime", mnb.lastPing.sigTime); + lastPingObj.pushKV("vchsig", EncodeBase64(&mnb.lastPing.vchSig[0], mnb.lastPing.vchSig.size())); - resultObj.push_back(Pair("lastping", lastPingObj)); + resultObj.pushKV("lastping", lastPingObj); return resultObj; } diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 1f2b705359..82bd7ea956 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -15,6 +15,7 @@ #include "miner.h" #include "net.h" #include "poa.h" +#include "rpc/blockchain.h" #include "rpc/server.h" #include "util.h" #ifdef ENABLE_WALLET @@ -327,7 +328,7 @@ UniValue getmininginfo(const UniValue& params, bool fHelp) " \"hashespersec\": n (numeric) The hashes per second of the generation, or 0 if no generation.\n" " \"pooledtx\": n (numeric) The size of the mem pool\n" " \"testnet\": true|false (boolean) If using testnet or not\n" - " \"chain\": \"xxxx\", (string) current network name as defined in BIP70 (main, test, regtest)\n" + " \"chain\": \"xxxx\", (string) current network name (main, test, regtest)\n" "}\n" "\nExamples:\n" + HelpExampleCli("getmininginfo", "") + HelpExampleRpc("getmininginfo", "")); @@ -335,19 +336,19 @@ UniValue getmininginfo(const UniValue& params, bool fHelp) LOCK(cs_main); UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("blocks", (int)chainActive.Height())); - obj.push_back(Pair("currentblocksize", (uint64_t)nLastBlockSize)); - obj.push_back(Pair("currentblocktx", (uint64_t)nLastBlockTx)); - obj.push_back(Pair("difficulty", (double)GetDifficulty())); - obj.push_back(Pair("errors", GetWarnings("statusbar"))); - obj.push_back(Pair("genproclimit", (int)GetArg("-genproclimit", -1))); - obj.push_back(Pair("networkhashps", getnetworkhashps(params, false))); - obj.push_back(Pair("pooledtx", (uint64_t)mempool.size())); - obj.push_back(Pair("testnet", Params().TestnetToBeDeprecatedFieldRPC())); - obj.push_back(Pair("chain", Params().NetworkIDString())); + obj.pushKV("blocks", (int)chainActive.Height()); + obj.pushKV("currentblocksize", (uint64_t)nLastBlockSize); + obj.pushKV("currentblocktx", (uint64_t)nLastBlockTx); + obj.pushKV("difficulty", (double)GetDifficulty()); + obj.pushKV("errors", GetWarnings("statusbar")); + obj.pushKV("genproclimit", (int)GetArg("-genproclimit", -1)); + obj.pushKV("networkhashps", getnetworkhashps(params, false)); + obj.pushKV("pooledtx", (uint64_t)mempool.size()); + obj.pushKV("testnet", Params().TestnetToBeDeprecatedFieldRPC()); + obj.pushKV("chain", Params().NetworkIDString()); #ifdef ENABLE_WALLET - obj.push_back(Pair("generate", getgenerate(params, false))); - obj.push_back(Pair("hashespersec", gethashespersec(params, false))); + obj.pushKV("generate", getgenerate(params, false)); + obj.pushKV("hashespersec", gethashespersec(params, false)); #endif return obj; } @@ -620,26 +621,26 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) UniValue entry(UniValue::VOBJ); - entry.push_back(Pair("data", EncodeHexTx(tx))); + entry.pushKV("data", EncodeHexTx(tx)); - entry.push_back(Pair("hash", txHash.GetHex())); + entry.pushKV("hash", txHash.GetHex()); UniValue deps(UniValue::VARR); for (const CTxIn& in : tx.vin) { if (setTxIndex.count(in.prevout.hash)) deps.push_back(setTxIndex[in.prevout.hash]); } - entry.push_back(Pair("depends", deps)); + entry.pushKV("depends", deps); int index_in_template = i - 1; - entry.push_back(Pair("fee", pblocktemplate->vTxFees[index_in_template])); - entry.push_back(Pair("sigops", pblocktemplate->vTxSigOps[index_in_template])); + entry.pushKV("fee", pblocktemplate->vTxFees[index_in_template]); + entry.pushKV("sigops", pblocktemplate->vTxSigOps[index_in_template]); transactions.push_back(entry); } UniValue aux(UniValue::VOBJ); - aux.push_back(Pair("flags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end()))); + aux.pushKV("flags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end())); uint256 hashTarget = uint256().SetCompact(pblock->nBits); @@ -653,36 +654,36 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) UniValue aVotes(UniValue::VARR); UniValue result(UniValue::VOBJ); - result.push_back(Pair("capabilities", aCaps)); - result.push_back(Pair("version", pblock->nVersion)); - result.push_back(Pair("previousblockhash", pblock->hashPrevBlock.GetHex())); - result.push_back(Pair("transactions", transactions)); - result.push_back(Pair("coinbaseaux", aux)); - result.push_back(Pair("coinbasevalue", (int64_t)pblock->vtx[0].GetValueOut())); - result.push_back(Pair("longpollid", chainActive.Tip()->GetBlockHash().GetHex() + i64tostr(nTransactionsUpdatedLast))); - result.push_back(Pair("target", hashTarget.GetHex())); - result.push_back(Pair("mintime", (int64_t)pindexPrev->GetMedianTimePast() + 1)); - result.push_back(Pair("mutable", aMutable)); - result.push_back(Pair("noncerange", "00000000ffffffff")); - result.push_back(Pair("curtime", pblock->GetBlockTime())); - result.push_back(Pair("bits", strprintf("%08x", pblock->nBits))); - result.push_back(Pair("height", (int64_t)(pindexPrev->nHeight + 1))); - result.push_back(Pair("votes", aVotes)); + result.pushKV("capabilities", aCaps); + result.pushKV("version", pblock->nVersion); + result.pushKV("previousblockhash", pblock->hashPrevBlock.GetHex()); + result.pushKV("transactions", transactions); + result.pushKV("coinbaseaux", aux); + result.pushKV("coinbasevalue", (int64_t)pblock->vtx[0].GetValueOut()); + result.pushKV("longpollid", chainActive.Tip()->GetBlockHash().GetHex() + i64tostr(nTransactionsUpdatedLast)); + result.pushKV("target", hashTarget.GetHex()); + result.pushKV("mintime", (int64_t)pindexPrev->GetMedianTimePast() + 1); + result.pushKV("mutable", aMutable); + result.pushKV("noncerange", "00000000ffffffff"); + result.pushKV("curtime", pblock->GetBlockTime()); + result.pushKV("bits", strprintf("%08x", pblock->nBits)); + result.pushKV("height", (int64_t)(pindexPrev->nHeight + 1)); + result.pushKV("votes", aVotes); if (pblock->payee != CScript()) { CTxDestination address1; ExtractDestination(pblock->payee, address1); CBitcoinAddress address2(address1); - result.push_back(Pair("payee", address2.ToString().c_str())); - result.push_back(Pair("payee_amount", (int64_t)pblock->vtx[0].vout[1].nValue)); + result.pushKV("payee", address2.ToString().c_str()); + result.pushKV("payee_amount", (int64_t)pblock->vtx[0].vout[1].nValue); } else { - result.push_back(Pair("payee", "")); - result.push_back(Pair("payee_amount", "")); + result.pushKV("payee", ""); + result.pushKV("payee_amount", ""); } - result.push_back(Pair("masternode_payments", pblock->nTime > Params().StartMasternodePayments())); - result.push_back(Pair("enforce_masternode_payments", true)); + result.pushKV("masternode_payments", pblock->nTime > Params().StartMasternodePayments()); + result.pushKV("enforce_masternode_payments", true); return result; } @@ -790,31 +791,31 @@ UniValue getpoablocktemplate(const UniValue& params, bool fHelp) UniValue entry(UniValue::VOBJ); - entry.push_back(Pair("data", EncodeHexTx(tx))); + entry.pushKV("data", EncodeHexTx(tx)); - entry.push_back(Pair("hash", txHash.GetHex())); + entry.pushKV("hash", txHash.GetHex()); UniValue deps(UniValue::VARR); for (const CTxIn& in : tx.vin) { if (setTxIndex.count(in.prevout.hash)) deps.push_back(setTxIndex[in.prevout.hash]); } - entry.push_back(Pair("depends", deps)); + entry.pushKV("depends", deps); int index_in_template = i - 1; - entry.push_back(Pair("fee", pblocktemplate->vTxFees[index_in_template])); - entry.push_back(Pair("sigops", pblocktemplate->vTxSigOps[index_in_template])); + entry.pushKV("fee", pblocktemplate->vTxFees[index_in_template]); + entry.pushKV("sigops", pblocktemplate->vTxSigOps[index_in_template]); transactions.push_back(entry); } UniValue coinbasetxn(UniValue::VOBJ); CTransaction& tx = pblock->vtx[0]; - coinbasetxn.push_back(Pair("data", EncodeHexTx(tx))); - coinbasetxn.push_back(Pair("hash", tx.GetHash().GetHex())); + coinbasetxn.pushKV("data", EncodeHexTx(tx)); + coinbasetxn.pushKV("hash", tx.GetHash().GetHex()); UniValue aux(UniValue::VOBJ); - aux.push_back(Pair("flags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end()))); + aux.pushKV("flags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end())); UniValue aMutable(UniValue::VARR); if (aMutable.empty()) { @@ -828,7 +829,7 @@ UniValue getpoablocktemplate(const UniValue& params, bool fHelp) for (size_t idx = 0; idx < pblock->posBlocksAudited.size(); idx++) { UniValue entry(UniValue::VOBJ); PoSBlockSummary pos = pblock->posBlocksAudited.at(idx); - entry.push_back(Pair("data", EncodeHexPoSBlockSummary(pos))); + entry.pushKV("data", EncodeHexPoSBlockSummary(pos)); posBlocksAudited.push_back(entry); } @@ -838,32 +839,32 @@ UniValue getpoablocktemplate(const UniValue& params, bool fHelp) pblock->SetVersionPoABlock(); UniValue result(UniValue::VOBJ); - result.push_back(Pair("version", pblock->nVersion)); - result.push_back(Pair("previouspoablockhash", pblock->hashPrevPoABlock.GetHex())); - result.push_back(Pair("poamerkleroot", poaMerkleRoot.GetHex())); - result.push_back(Pair("transactions", transactions)); - result.push_back(Pair("coinbasetxn", coinbasetxn)); - result.push_back(Pair("coinbasevalue", (int64_t)pblock->vtx[0].GetValueOut())); - result.push_back(Pair("noncerange", "00000000ffffffff")); - result.push_back(Pair("curtime", pblock->GetBlockTime())); - result.push_back(Pair("bits", strprintf("%08x", pblock->nBits))); - result.push_back(Pair("target", hashTarget.GetHex())); - result.push_back(Pair("height", (int64_t)(pindexPrev->nHeight + 1))); - result.push_back(Pair("posblocksaudited", posBlocksAudited)); + result.pushKV("version", pblock->nVersion); + result.pushKV("previouspoablockhash", pblock->hashPrevPoABlock.GetHex()); + result.pushKV("poamerkleroot", poaMerkleRoot.GetHex()); + result.pushKV("transactions", transactions); + result.pushKV("coinbasetxn", coinbasetxn); + result.pushKV("coinbasevalue", (int64_t)pblock->vtx[0].GetValueOut()); + result.pushKV("noncerange", "00000000ffffffff"); + result.pushKV("curtime", pblock->GetBlockTime()); + result.pushKV("bits", strprintf("%08x", pblock->nBits)); + result.pushKV("target", hashTarget.GetHex()); + result.pushKV("height", (int64_t)(pindexPrev->nHeight + 1)); + result.pushKV("posblocksaudited", posBlocksAudited); if (pblock->payee != CScript()) { CTxDestination address1; ExtractDestination(pblock->payee, address1); CBitcoinAddress address2(address1); - result.push_back(Pair("payee", address2.ToString().c_str())); - result.push_back(Pair("payee_amount", (int64_t)pblock->vtx[0].vout[1].nValue)); + result.pushKV("payee", address2.ToString().c_str()); + result.pushKV("payee_amount", (int64_t)pblock->vtx[0].vout[1].nValue); } else { - result.push_back(Pair("payee", "")); - result.push_back(Pair("payee_amount", "")); + result.pushKV("payee", ""); + result.pushKV("payee_amount", ""); } - result.push_back(Pair("masternode_payments", pblock->nTime > Params().StartMasternodePayments())); - result.push_back(Pair("enforce_masternode_payments", true)); + result.pushKV("masternode_payments", pblock->nTime > Params().StartMasternodePayments()); + result.pushKV("enforce_masternode_payments", true); return result; } } @@ -875,11 +876,11 @@ UniValue setminingnbits(const UniValue& params, bool fHelp) { unsigned int nbits = (unsigned int) params[0].get_int64(); int changed= params[1].get_int(); UniValue result(UniValue::VOBJ); - result.push_back(Pair("previous_bits", strprintf("%08x", N_BITS))); + result.pushKV("previous_bits", strprintf("%08x", N_BITS)); if (changed) { N_BITS = nbits; } - result.push_back(Pair("current_bits", strprintf("%08x", N_BITS))); + result.pushKV("current_bits", strprintf("%08x", N_BITS)); return result; } diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 1608c5322d..bd4006f5f5 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -14,6 +14,7 @@ #include "masternode-sync.h" #include "net.h" #include "netbase.h" +#include "rpc/blockchain.h" #include "rpc/server.h" #include "timedata.h" #include "util.h" @@ -77,55 +78,59 @@ UniValue getinfo(const UniValue ¶ms, bool fHelp) { GetProxy(NET_IPV4, proxy); UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("version", CLIENT_VERSION)); - obj.push_back(Pair("protocolversion", PROTOCOL_VERSION)); + obj.pushKV("version", CLIENT_VERSION); + obj.pushKV("protocolversion", PROTOCOL_VERSION); #ifdef ENABLE_WALLET if (pwalletMain) { - obj.push_back(Pair("walletversion", pwalletMain->GetVersion())); - obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance()))); + obj.pushKV("walletversion", pwalletMain->GetVersion()); + obj.pushKV("balance", ValueFromAmount(pwalletMain->GetBalance())); } #endif - obj.push_back(Pair("blocks", (int) chainActive.Height())); - obj.push_back(Pair("synced", masternodeSync.IsBlockchainSynced())); - obj.push_back(Pair("timeoffset", GetTimeOffset())); - obj.push_back(Pair("connections", (int) vNodes.size())); - obj.push_back(Pair("proxy", (proxy.IsValid() ? proxy.proxy.ToStringIPPort() : std::string()))); - obj.push_back(Pair("difficulty", (double) GetDifficulty())); - obj.push_back(Pair("testnet", Params().TestnetToBeDeprecatedFieldRPC())); - obj.push_back(Pair("moneysupply",ValueFromAmount(chainActive.Tip()->nMoneySupply))); + obj.pushKV("blocks", (int) chainActive.Height()); + obj.pushKV("synced", masternodeSync.IsBlockchainSynced()); + obj.pushKV("timeoffset", GetTimeOffset()); + obj.pushKV("connections", (int) vNodes.size()); + obj.pushKV("proxy", (proxy.IsValid() ? proxy.proxy.ToStringIPPort() : std::string())); + obj.pushKV("difficulty", (double) GetDifficulty()); + obj.pushKV("testnet", Params().TestnetToBeDeprecatedFieldRPC()); + obj.pushKV("moneysupply",ValueFromAmount(chainActive.Tip()->nMoneySupply)); #ifdef ENABLE_WALLET if (pwalletMain) { - obj.push_back(Pair("keypoololdest", pwalletMain->GetOldestKeyPoolTime())); + obj.pushKV("keypoololdest", pwalletMain->GetOldestKeyPoolTime()); } if (pwalletMain && pwalletMain->IsCrypted()) - obj.push_back(Pair("unlocked_until", nWalletUnlockTime)); - obj.push_back(Pair("paytxfee", ValueFromAmount(payTxFee.GetFeePerK()))); + obj.pushKV("unlocked_until", nWalletUnlockTime); + obj.pushKV("paytxfee", ValueFromAmount(payTxFee.GetFeePerK())); #endif - obj.push_back(Pair("relayfee", ValueFromAmount(::minRelayTxFee.GetFeePerK()))); - bool nStaking = false; - if (mapHashedBlocks.count(chainActive.Tip()->nHeight)) - nStaking = true; - else if (mapHashedBlocks.count(chainActive.Tip()->nHeight - 1) && nLastCoinStakeSearchInterval) - nStaking = true; - if (pwalletMain->IsLocked()) { - obj.push_back(Pair("staking mode", ("disabled"))); - obj.push_back(Pair("staking status", ("inactive (wallet locked)"))); - } else { - obj.push_back(Pair("staking mode", (pwalletMain->ReadStakingStatus() ? "enabled" : "disabled"))); - if (vNodes.empty()) { - obj.push_back(Pair("staking status", ("inactive (no peer connections)"))); - } else if (!masternodeSync.IsSynced()) { - obj.push_back(Pair("staking status", ("inactive (syncing masternode list)"))); - } else if (!pwalletMain->MintableCoins() && pwalletMain->combineMode == CombineMode::ON) { - obj.push_back(Pair("staking status", ("delayed (waiting for 100 blocks)"))); - } else if (!pwalletMain->MintableCoins()) { - obj.push_back(Pair("staking status", ("inactive (no mintable coins)"))); + obj.pushKV("relayfee", ValueFromAmount(::minRelayTxFee.GetFeePerK())); +#ifdef ENABLE_WALLET + if (pwalletMain) { + bool nStaking = false; + if (mapHashedBlocks.count(chainActive.Tip()->nHeight)) + nStaking = true; + else if (mapHashedBlocks.count(chainActive.Tip()->nHeight - 1) && nLastCoinStakeSearchInterval) + nStaking = true; + if (pwalletMain->IsLocked()) { + obj.pushKV("staking mode", ("disabled")); + obj.pushKV("staking status", ("inactive (wallet locked)")); } else { - obj.push_back(Pair("staking status", (nStaking ? "active (attempting to mint a block)" : "idle (waiting for next round)"))); + obj.pushKV("staking mode", (pwalletMain->ReadStakingStatus() ? "enabled" : "disabled")); + if (vNodes.empty()) { + obj.pushKV("staking status", ("inactive (no peer connections)")); + } else if (!masternodeSync.IsSynced()) { + obj.pushKV("staking status", ("inactive (syncing masternode list)")); + } else if (!pwalletMain->MintableCoins() && pwalletMain->combineMode == CombineMode::ON) { + obj.pushKV("staking status", ("delayed (waiting for 100 blocks)")); + } else if (!pwalletMain->MintableCoins()) { + obj.pushKV("staking status", ("inactive (no mintable coins)")); + } else { + obj.pushKV("staking status", (nStaking ? "active (attempting to mint a block)" : "idle (waiting for next round)")); + } } } - obj.push_back(Pair("errors", GetWarnings("statusbar"))); +#endif + obj.pushKV("errors", GetWarnings("statusbar")); return obj; } @@ -143,7 +148,7 @@ UniValue getversion(const UniValue ¶ms, bool fHelp) { LOCK(cs_main); UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("version", CLIENT_VERSION)); + obj.pushKV("version", CLIENT_VERSION); return obj; } @@ -189,22 +194,22 @@ UniValue mnsync(const UniValue ¶ms, bool fHelp) { if (strMode == "status") { UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("IsBlockchainSynced", masternodeSync.IsBlockchainSynced())); - obj.push_back(Pair("lastMasternodeList", masternodeSync.lastMasternodeList)); - obj.push_back(Pair("lastMasternodeWinner", masternodeSync.lastMasternodeWinner)); - obj.push_back(Pair("lastBudgetItem", masternodeSync.lastBudgetItem)); - obj.push_back(Pair("lastFailure", masternodeSync.lastFailure)); - obj.push_back(Pair("nCountFailures", masternodeSync.nCountFailures)); - obj.push_back(Pair("sumMasternodeList", masternodeSync.sumMasternodeList)); - obj.push_back(Pair("sumMasternodeWinner", masternodeSync.sumMasternodeWinner)); - obj.push_back(Pair("sumBudgetItemProp", masternodeSync.sumBudgetItemProp)); - obj.push_back(Pair("sumBudgetItemFin", masternodeSync.sumBudgetItemFin)); - obj.push_back(Pair("countMasternodeList", masternodeSync.countMasternodeList)); - obj.push_back(Pair("countMasternodeWinner", masternodeSync.countMasternodeWinner)); - obj.push_back(Pair("countBudgetItemProp", masternodeSync.countBudgetItemProp)); - obj.push_back(Pair("countBudgetItemFin", masternodeSync.countBudgetItemFin)); - obj.push_back(Pair("RequestedMasternodeAssets", masternodeSync.RequestedMasternodeAssets)); - obj.push_back(Pair("RequestedMasternodeAttempt", masternodeSync.RequestedMasternodeAttempt)); + obj.pushKV("IsBlockchainSynced", masternodeSync.IsBlockchainSynced()); + obj.pushKV("lastMasternodeList", masternodeSync.lastMasternodeList); + obj.pushKV("lastMasternodeWinner", masternodeSync.lastMasternodeWinner); + obj.pushKV("lastBudgetItem", masternodeSync.lastBudgetItem); + obj.pushKV("lastFailure", masternodeSync.lastFailure); + obj.pushKV("nCountFailures", masternodeSync.nCountFailures); + obj.pushKV("sumMasternodeList", masternodeSync.sumMasternodeList); + obj.pushKV("sumMasternodeWinner", masternodeSync.sumMasternodeWinner); + obj.pushKV("sumBudgetItemProp", masternodeSync.sumBudgetItemProp); + obj.pushKV("sumBudgetItemFin", masternodeSync.sumBudgetItemFin); + obj.pushKV("countMasternodeList", masternodeSync.countMasternodeList); + obj.pushKV("countMasternodeWinner", masternodeSync.countMasternodeWinner); + obj.pushKV("countBudgetItemProp", masternodeSync.countBudgetItemProp); + obj.pushKV("countBudgetItemFin", masternodeSync.countBudgetItemFin); + obj.pushKV("RequestedMasternodeAssets", masternodeSync.RequestedMasternodeAssets); + obj.pushKV("RequestedMasternodeAttempt", masternodeSync.RequestedMasternodeAttempt); return obj; } @@ -231,11 +236,11 @@ class DescribeAddressVisitor : public boost::static_visitor { UniValue obj(UniValue::VOBJ); CPubKey vchPubKey; - obj.push_back(Pair("isscript", false)); + obj.pushKV("isscript", false); if (mine == ISMINE_SPENDABLE) { pwalletMain->GetPubKey(keyID, vchPubKey); - obj.push_back(Pair("pubkey", HexStr(vchPubKey))); - obj.push_back(Pair("iscompressed", vchPubKey.IsCompressed())); + obj.pushKV("pubkey", HexStr(vchPubKey)); + obj.pushKV("iscompressed", vchPubKey.IsCompressed()); } return obj; } @@ -243,21 +248,21 @@ class DescribeAddressVisitor : public boost::static_visitor UniValue operator()(const CScriptID &scriptID) const { UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("isscript", true)); + obj.pushKV("isscript", true); CScript subscript; pwalletMain->GetCScript(scriptID, subscript); std::vector addresses; txnouttype whichType; int nRequired; ExtractDestinations(subscript, whichType, addresses, nRequired); - obj.push_back(Pair("script", GetTxnOutputType(whichType))); - obj.push_back(Pair("hex", HexStr(subscript.begin(), subscript.end()))); + obj.pushKV("script", GetTxnOutputType(whichType)); + obj.pushKV("hex", HexStr(subscript.begin(), subscript.end())); UniValue a(UniValue::VARR); for (const CTxDestination& addr : addresses) a.push_back(CBitcoinAddress(addr).ToString()); - obj.push_back(Pair("addresses", a)); + obj.pushKV("addresses", a); if (whichType == TX_MULTISIG) - obj.push_back(Pair("sigsrequired", nRequired)); + obj.pushKV("sigsrequired", nRequired); return obj; } }; @@ -298,22 +303,22 @@ UniValue validateaddress(const UniValue& params, bool fHelp) bool isValid = address.IsValid(); UniValue ret(UniValue::VOBJ); - ret.push_back(Pair("isvalid", isValid)); + ret.pushKV("isvalid", isValid); if (isValid) { CTxDestination dest = address.Get(); std::string currentAddress = address.ToString(); - ret.push_back(Pair("address", currentAddress)); + ret.pushKV("address", currentAddress); CScript scriptPubKey = GetScriptForDestination(dest); - ret.push_back(Pair("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end()))); + ret.pushKV("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end())); #ifdef ENABLE_WALLET isminetype mine = pwalletMain ? IsMine(*pwalletMain, dest) : ISMINE_NO; - ret.push_back(Pair("ismine", bool(mine & ISMINE_SPENDABLE))); - ret.push_back(Pair("iswatchonly", bool(mine & ISMINE_WATCH_ONLY))); + ret.pushKV("ismine", bool(mine & ISMINE_SPENDABLE)); + ret.pushKV("iswatchonly", bool(mine & ISMINE_WATCH_ONLY)); UniValue detail = boost::apply_visitor(DescribeAddressVisitor(mine), dest); ret.pushKVs(detail); if (pwalletMain && pwalletMain->mapAddressBook.count(dest)) - ret.push_back(Pair("account", pwalletMain->mapAddressBook[dest].name)); + ret.pushKV("account", pwalletMain->mapAddressBook[dest].name); #endif } return ret; @@ -347,7 +352,7 @@ UniValue validatestealthaddress(const UniValue& params, bool fHelp) if (!CWallet::DecodeStealthAddress(addr, viewKey, spendKey, hasPaymentID, paymentID)) { isValid = false; } - ret.push_back(Pair("isvalid", isValid)); + ret.pushKV("isvalid", isValid); return ret; } @@ -447,8 +452,8 @@ UniValue createmultisig(const UniValue& params, bool fHelp) { CBitcoinAddress address(innerID); UniValue result(UniValue::VOBJ); - result.push_back(Pair("address", address.ToString())); - result.push_back(Pair("redeemScript", HexStr(inner.begin(), inner.end()))); + result.pushKV("address", address.ToString()); + result.pushKV("redeemScript", HexStr(inner.begin(), inner.end())); return result; } @@ -620,13 +625,13 @@ UniValue getstakingstatus(const UniValue& params, bool fHelp) UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("haveconnections", !vNodes.empty())); + obj.pushKV("haveconnections", !vNodes.empty()); if (pwalletMain) { - obj.push_back(Pair("walletunlocked", !pwalletMain->IsLocked())); - obj.push_back(Pair("mintablecoins", pwalletMain->MintableCoins())); - obj.push_back(Pair("enoughcoins", nReserveBalance <= pwalletMain->GetBalance())); + obj.pushKV("walletunlocked", !pwalletMain->IsLocked()); + obj.pushKV("mintablecoins", pwalletMain->MintableCoins()); + obj.pushKV("enoughcoins", nReserveBalance <= pwalletMain->GetBalance()); } - obj.push_back(Pair("masternodes-synced", masternodeSync.IsSynced())); + obj.pushKV("masternodes-synced", masternodeSync.IsSynced()); bool nStaking = false; if (mapHashedBlocks.count(chainActive.Tip()->nHeight)) @@ -634,20 +639,20 @@ UniValue getstakingstatus(const UniValue& params, bool fHelp) else if (mapHashedBlocks.count(chainActive.Tip()->nHeight - 1) && nLastCoinStakeSearchInterval) nStaking = true; if (pwalletMain->IsLocked()) { - obj.push_back(Pair("staking mode", ("disabled"))); - obj.push_back(Pair("staking status", ("inactive (wallet locked)"))); + obj.pushKV("staking mode", ("disabled")); + obj.pushKV("staking status", ("inactive (wallet locked)")); } else { - obj.push_back(Pair("staking mode", (pwalletMain->ReadStakingStatus() ? "enabled" : "disabled"))); + obj.pushKV("staking mode", (pwalletMain->ReadStakingStatus() ? "enabled" : "disabled")); if (vNodes.empty()) { - obj.push_back(Pair("staking status", ("inactive (no peer connections)"))); + obj.pushKV("staking status", ("inactive (no peer connections)")); } else if (!masternodeSync.IsSynced()) { - obj.push_back(Pair("staking status", ("inactive (syncing masternode list)"))); + obj.pushKV("staking status", ("inactive (syncing masternode list)")); } else if (!pwalletMain->MintableCoins() && pwalletMain->combineMode == CombineMode::ON) { - obj.push_back(Pair("staking status", ("delayed (waiting for 100 blocks)"))); + obj.pushKV("staking status", ("delayed (waiting for 100 blocks)")); } else if (!pwalletMain->MintableCoins()) { - obj.push_back(Pair("staking status", ("inactive (no mintable coins)"))); + obj.pushKV("staking status", ("inactive (no mintable coins)")); } else { - obj.push_back(Pair("staking status", (nStaking ? "active (attempting to mint a block)" : "idle (waiting for next round)"))); + obj.pushKV("staking status", (nStaking ? "active (attempting to mint a block)" : "idle (waiting for next round)")); } } return obj; diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index 71cd4d8afe..ee447d6cd6 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -118,38 +118,38 @@ UniValue getpeerinfo(const UniValue& params, bool fHelp) UniValue obj(UniValue::VOBJ); CNodeStateStats statestats; bool fStateStats = GetNodeStateStats(stats.nodeid, statestats); - obj.push_back(Pair("id", stats.nodeid)); - obj.push_back(Pair("addr", stats.addrName)); + obj.pushKV("id", stats.nodeid); + obj.pushKV("addr", stats.addrName); if (!(stats.addrLocal.empty())) - obj.push_back(Pair("addrlocal", stats.addrLocal)); - obj.push_back(Pair("services", strprintf("%016x", stats.nServices))); - obj.push_back(Pair("lastsend", stats.nLastSend)); - obj.push_back(Pair("lastrecv", stats.nLastRecv)); - obj.push_back(Pair("bytessent", stats.nSendBytes)); - obj.push_back(Pair("bytesrecv", stats.nRecvBytes)); - obj.push_back(Pair("conntime", stats.nTimeConnected)); - obj.push_back(Pair("timeoffset", stats.nTimeOffset)); - obj.push_back(Pair("pingtime", stats.dPingTime)); + obj.pushKV("addrlocal", stats.addrLocal); + obj.pushKV("services", strprintf("%016x", stats.nServices)); + obj.pushKV("lastsend", stats.nLastSend); + obj.pushKV("lastrecv", stats.nLastRecv); + obj.pushKV("bytessent", stats.nSendBytes); + obj.pushKV("bytesrecv", stats.nRecvBytes); + obj.pushKV("conntime", stats.nTimeConnected); + obj.pushKV("timeoffset", stats.nTimeOffset); + obj.pushKV("pingtime", stats.dPingTime); if (stats.dPingWait > 0.0) - obj.push_back(Pair("pingwait", stats.dPingWait)); - obj.push_back(Pair("version", stats.nVersion)); + obj.pushKV("pingwait", stats.dPingWait); + obj.pushKV("version", stats.nVersion); // Use the sanitized form of subver here, to avoid tricksy remote peers from // corrupting or modifiying the JSON output by putting special characters in // their ver message. - obj.push_back(Pair("subver", stats.cleanSubVer)); - obj.push_back(Pair("inbound", stats.fInbound)); - obj.push_back(Pair("startingheight", stats.nStartingHeight)); + obj.pushKV("subver", stats.cleanSubVer); + obj.pushKV("inbound", stats.fInbound); + obj.pushKV("startingheight", stats.nStartingHeight); if (fStateStats) { - obj.push_back(Pair("banscore", statestats.nMisbehavior)); - obj.push_back(Pair("synced_headers", statestats.nSyncHeight)); - obj.push_back(Pair("synced_blocks", statestats.nCommonHeight)); + obj.pushKV("banscore", statestats.nMisbehavior); + obj.pushKV("synced_headers", statestats.nSyncHeight); + obj.pushKV("synced_blocks", statestats.nCommonHeight); UniValue heights(UniValue::VARR); for (int height : statestats.vHeightInFlight) { heights.push_back(height); } - obj.push_back(Pair("inflight", heights)); + obj.pushKV("inflight", heights); } - obj.push_back(Pair("whitelisted", stats.fWhitelisted)); + obj.pushKV("whitelisted", stats.fWhitelisted); ret.push_back(obj); } @@ -270,16 +270,16 @@ UniValue getaddednodeinfo(const UniValue& params, bool fHelp) for (const AddedNodeInfo& info : vInfo) { UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("addednode", info.strAddedNode)); - obj.push_back(Pair("connected", info.fConnected)); + obj.pushKV("addednode", info.strAddedNode); + obj.pushKV("connected", info.fConnected); UniValue addresses(UniValue::VARR); if (info.fConnected) { UniValue address(UniValue::VOBJ); - address.push_back(Pair("address", info.resolvedAddress.ToString())); - address.push_back(Pair("connected", info.fInbound ? "inbound" : "outbound")); + address.pushKV("address", info.resolvedAddress.ToString()); + address.pushKV("connected", info.fInbound ? "inbound" : "outbound"); addresses.push_back(address); } - obj.push_back(Pair("addresses", addresses)); + obj.pushKV("addresses", addresses); ret.push_back(obj); } @@ -303,9 +303,9 @@ UniValue getnettotals(const UniValue& params, bool fHelp) HelpExampleCli("getnettotals", "") + HelpExampleRpc("getnettotals", "")); UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("totalbytesrecv", CNode::GetTotalBytesRecv())); - obj.push_back(Pair("totalbytessent", CNode::GetTotalBytesSent())); - obj.push_back(Pair("timemillis", GetTimeMillis())); + obj.pushKV("totalbytesrecv", CNode::GetTotalBytesRecv()); + obj.pushKV("totalbytessent", CNode::GetTotalBytesSent()); + obj.pushKV("timemillis", GetTimeMillis()); return obj; } @@ -319,11 +319,11 @@ static UniValue GetNetworksInfo() proxyType proxy; UniValue obj(UniValue::VOBJ); GetProxy(network, proxy); - obj.push_back(Pair("name", GetNetworkName(network))); - obj.push_back(Pair("limited", IsLimited(network))); - obj.push_back(Pair("reachable", IsReachable(network))); - obj.push_back(Pair("proxy", proxy.IsValid() ? proxy.proxy.ToStringIPPort() : std::string())); - obj.push_back(Pair("proxy_randomize_credentials", proxy.randomize_credentials)); + obj.pushKV("name", GetNetworkName(network)); + obj.pushKV("limited", IsLimited(network)); + obj.pushKV("reachable", IsReachable(network)); + obj.pushKV("proxy", proxy.IsValid() ? proxy.proxy.ToStringIPPort() : std::string()); + obj.pushKV("proxy_randomize_credentials", proxy.randomize_credentials); networks.push_back(obj); } return networks; @@ -368,26 +368,26 @@ UniValue getnetworkinfo(const UniValue& params, bool fHelp) LOCK(cs_main); UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("version", CLIENT_VERSION)); - obj.push_back(Pair("subversion", strSubVersion)); - obj.push_back(Pair("protocolversion", PROTOCOL_VERSION)); - obj.push_back(Pair("localservices", strprintf("%016x", nLocalServices))); - obj.push_back(Pair("timeoffset", GetTimeOffset())); - obj.push_back(Pair("connections", (int)vNodes.size())); - obj.push_back(Pair("networks", GetNetworksInfo())); - obj.push_back(Pair("relayfee", ValueFromAmount(::minRelayTxFee.GetFeePerK()))); + obj.pushKV("version", CLIENT_VERSION); + obj.pushKV("subversion", strSubVersion); + obj.pushKV("protocolversion", PROTOCOL_VERSION); + obj.pushKV("localservices", strprintf("%016x", nLocalServices)); + obj.pushKV("timeoffset", GetTimeOffset()); + obj.pushKV("connections", (int)vNodes.size()); + obj.pushKV("networks", GetNetworksInfo()); + obj.pushKV("relayfee", ValueFromAmount(::minRelayTxFee.GetFeePerK())); UniValue localAddresses(UniValue::VARR); { LOCK(cs_mapLocalHost); for (const std::pair &item : mapLocalHost) { UniValue rec(UniValue::VOBJ); - rec.push_back(Pair("address", item.first.ToString())); - rec.push_back(Pair("port", item.second.nPort)); - rec.push_back(Pair("score", item.second.nScore)); + rec.pushKV("address", item.first.ToString()); + rec.pushKV("port", item.second.nPort); + rec.pushKV("score", item.second.nScore); localAddresses.push_back(rec); } } - obj.push_back(Pair("localaddresses", localAddresses)); + obj.pushKV("localaddresses", localAddresses); return obj; } @@ -463,10 +463,10 @@ UniValue listbanned(const UniValue& params, bool fHelp) { CBanEntry banEntry = (*it).second; UniValue rec(UniValue::VOBJ); - rec.push_back(Pair("address", (*it).first.ToString())); - rec.push_back(Pair("banned_until", banEntry.nBanUntil)); - rec.push_back(Pair("ban_created", banEntry.nCreateTime)); - rec.push_back(Pair("ban_reason", banEntry.banReasonToString())); + rec.pushKV("address", (*it).first.ToString()); + rec.pushKV("banned_until", banEntry.nBanUntil); + rec.pushKV("ban_created", banEntry.nCreateTime); + rec.pushKV("ban_reason", banEntry.banReasonToString()); bannedAddresses.push_back(rec); } return bannedAddresses; diff --git a/src/rpc/protocol.cpp b/src/rpc/protocol.cpp index 4b17c9dfe8..a70b9d553c 100644 --- a/src/rpc/protocol.cpp +++ b/src/rpc/protocol.cpp @@ -33,9 +33,9 @@ std::string JSONRPCRequest(const std::string& strMethod, const UniValue& params, const UniValue& id) { UniValue request(UniValue::VOBJ); - request.push_back(Pair("method", strMethod)); - request.push_back(Pair("params", params)); - request.push_back(Pair("id", id)); + request.pushKV("method", strMethod); + request.pushKV("params", params); + request.pushKV("id", id); return request.write() + "\n"; } @@ -43,11 +43,11 @@ UniValue JSONRPCReplyObj(const UniValue& result, const UniValue& error, const Un { UniValue reply(UniValue::VOBJ); if (!error.isNull()) - reply.push_back(Pair("result", NullUniValue)); + reply.pushKV("result", NullUniValue); else - reply.push_back(Pair("result", result)); - reply.push_back(Pair("error", error)); - reply.push_back(Pair("id", id)); + reply.pushKV("result", result); + reply.pushKV("error", error); + reply.pushKV("id", id); return reply; } @@ -60,8 +60,8 @@ std::string JSONRPCReply(const UniValue& result, const UniValue& error, const Un UniValue JSONRPCError(int code, const std::string& message) { UniValue error(UniValue::VOBJ); - error.push_back(Pair("code", code)); - error.push_back(Pair("message", message)); + error.pushKV("code", code); + error.pushKV("message", message); return error; } diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index 5b7d603966..20644277d7 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -37,52 +37,52 @@ void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fInclud std::vector addresses; int nRequired; - out.push_back(Pair("asm", scriptPubKey.ToString())); + out.pushKV("asm", scriptPubKey.ToString()); if (fIncludeHex) - out.push_back(Pair("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end()))); + out.pushKV("hex", HexStr(scriptPubKey.begin(), scriptPubKey.end())); if (!ExtractDestinations(scriptPubKey, type, addresses, nRequired)) { - out.push_back(Pair("type", GetTxnOutputType(type))); + out.pushKV("type", GetTxnOutputType(type)); return; } - out.push_back(Pair("reqSigs", nRequired)); - out.push_back(Pair("type", GetTxnOutputType(type))); + out.pushKV("reqSigs", nRequired); + out.pushKV("type", GetTxnOutputType(type)); UniValue a(UniValue::VARR); for (const CTxDestination& addr : addresses) a.push_back(CBitcoinAddress(addr).ToString()); - out.push_back(Pair("addresses", a)); + out.pushKV("addresses", a); } void PoSBlockInfoToJSON(const uint256 hashBlock, int64_t nTime, int height, UniValue& entry) { - entry.push_back(Pair("posblockhash", hashBlock.GetHex())); - entry.push_back(Pair("time", nTime)); - entry.push_back(Pair("height", height)); - entry.push_back(Pair("isauditsuccessful", nTime > 0? "true":"false")); + entry.pushKV("posblockhash", hashBlock.GetHex()); + entry.pushKV("time", nTime); + entry.pushKV("height", height); + entry.pushKV("isauditsuccessful", nTime > 0? "true":"false"); } void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) { - entry.push_back(Pair("txid", tx.GetHash().GetHex())); - entry.push_back(Pair("version", tx.nVersion)); - entry.push_back(Pair("size", (int)::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION))); - entry.push_back(Pair("locktime", (int64_t)tx.nLockTime)); - entry.push_back(Pair("txfee", ValueFromAmount(tx.nTxFee))); + entry.pushKV("txid", tx.GetHash().GetHex()); + entry.pushKV("version", tx.nVersion); + entry.pushKV("size", (int)::GetSerializeSize(tx, SER_NETWORK, PROTOCOL_VERSION)); + entry.pushKV("locktime", (int64_t)tx.nLockTime); + entry.pushKV("txfee", ValueFromAmount(tx.nTxFee)); if (tx.hasPaymentID && pwalletMain->IsMine(tx)) { - entry.push_back(Pair("paymentid", tx.paymentID)); + entry.pushKV("paymentid", tx.paymentID); } - entry.push_back(Pair("txType", (int64_t)tx.txType)); + entry.pushKV("txType", (int64_t)tx.txType); #ifdef ENABLE_WALLET LOCK(pwalletMain->cs_wallet); - entry.push_back(Pair("direction", pwalletMain->GetTransactionType(tx))); + entry.pushKV("direction", pwalletMain->GetTransactionType(tx)); #endif UniValue vin(UniValue::VARR); for (const CTxIn& txin : tx.vin) { UniValue in(UniValue::VOBJ); if (tx.IsCoinBase()) - in.push_back(Pair("coinbase", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); + in.pushKV("coinbase", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())); else { { //decoys @@ -92,8 +92,8 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) allDecoys.insert(allDecoys.begin(), txin.prevout); for (size_t i = 0; i < allDecoys.size(); i++) { UniValue decoy(UniValue::VOBJ); - decoy.push_back(Pair("txid", allDecoys[i].hash.GetHex())); - decoy.push_back(Pair("vout", (int64_t)allDecoys[i].n)); + decoy.pushKV("txid", allDecoys[i].hash.GetHex()); + decoy.pushKV("vout", (int64_t)allDecoys[i].n); #ifdef ENABLE_WALLET std::map::const_iterator mi = pwalletMain->mapWallet.find(allDecoys[i].hash); if (mi != pwalletMain->mapWallet.end()) { @@ -108,49 +108,49 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) CKey blind; pwalletMain->RevealTxOutAmount(prev, prev.vout[allDecoys[i].n], decodedAmount, blind); if (pwalletMain->IsLocked()) { - decoy.push_back(Pair("decoded_amount", "Wallet is Locked")); + decoy.pushKV("decoded_amount", "Wallet is Locked"); } else { - decoy.push_back(Pair("decoded_amount", ValueFromAmount(decodedAmount))); + decoy.pushKV("decoded_amount", ValueFromAmount(decodedAmount)); } - decoy.push_back(Pair("isMine", true)); + decoy.pushKV("isMine", true); } } } else { - decoy.push_back(Pair("isMine", false)); + decoy.pushKV("isMine", false); } } } #endif decoys.push_back(decoy); } - in.push_back(Pair("decoys", decoys)); + in.pushKV("decoys", decoys); } UniValue o(UniValue::VOBJ); - o.push_back(Pair("asm", txin.scriptSig.ToString())); - o.push_back(Pair("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); - in.push_back(Pair("scriptSig", o)); + o.pushKV("asm", txin.scriptSig.ToString()); + o.pushKV("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())); + in.pushKV("scriptSig", o); } - in.push_back(Pair("sequence", (int64_t)txin.nSequence)); - in.push_back(Pair("keyimage", txin.keyImage.GetHex())); - in.push_back(Pair("ringsize", (int64_t) (txin.decoys.size() + 1))); + in.pushKV("sequence", (int64_t)txin.nSequence); + in.pushKV("keyimage", txin.keyImage.GetHex()); + in.pushKV("ringsize", (int64_t) (txin.decoys.size() + 1)); vin.push_back(in); } - entry.push_back(Pair("vin", vin)); + entry.pushKV("vin", vin); UniValue vout(UniValue::VARR); for (unsigned int i = 0; i < tx.vout.size(); i++) { const CTxOut& txout = tx.vout[i]; UniValue out(UniValue::VOBJ); - out.push_back(Pair("value", ValueFromAmount(txout.nValue))); - out.push_back(Pair("n", (int64_t)i)); + out.pushKV("value", ValueFromAmount(txout.nValue)); + out.pushKV("n", (int64_t)i); UniValue o(UniValue::VOBJ); ScriptPubKeyToJSON(txout.scriptPubKey, o, true); - out.push_back(Pair("scriptPubKey", o)); - out.push_back(Pair("encoded_amount", txout.maskValue.amount.GetHex())); - out.push_back(Pair("encoded_mask", txout.maskValue.mask.GetHex())); + out.pushKV("scriptPubKey", o); + out.pushKV("encoded_amount", txout.maskValue.amount.GetHex()); + out.pushKV("encoded_mask", txout.maskValue.mask.GetHex()); CPubKey txPubKey(txout.txPub); - out.push_back(Pair("txpubkey", txPubKey.GetHex())); - out.push_back(Pair("commitment", HexStr(txout.commitment.begin(), txout.commitment.end()))); + out.pushKV("txpubkey", txPubKey.GetHex()); + out.pushKV("commitment", HexStr(txout.commitment.begin(), txout.commitment.end())); #ifdef ENABLE_WALLET if (pwalletMain->IsMine(txout)) { @@ -166,32 +166,32 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) pBlind = blind.begin(); } if (pwalletMain->IsLocked()) { - out.push_back(Pair("decoded_amount", "Wallet is Locked")); + out.pushKV("decoded_amount", "Wallet is Locked"); } else { - out.push_back(Pair("decoded_amount", ValueFromAmount(decodedAmount))); + out.pushKV("decoded_amount", ValueFromAmount(decodedAmount)); } - out.push_back(Pair("isMine", true)); + out.pushKV("isMine", true); } else { - out.push_back(Pair("isMine", false)); + out.pushKV("isMine", false); } #endif vout.push_back(out); } - entry.push_back(Pair("vout", vout)); + entry.pushKV("vout", vout); if (!hashBlock.IsNull()) { - entry.push_back(Pair("blockhash", hashBlock.GetHex())); + entry.pushKV("blockhash", hashBlock.GetHex()); BlockMap::iterator mi = mapBlockIndex.find(hashBlock); if (mi != mapBlockIndex.end() && (*mi).second) { CBlockIndex* pindex = (*mi).second; if (chainActive.Contains(pindex)) { - entry.push_back(Pair("confirmations", 1 + chainActive.Height() - pindex->nHeight)); - entry.push_back(Pair("time", pindex->GetBlockTime())); - entry.push_back(Pair("blocktime", pindex->GetBlockTime())); + entry.pushKV("confirmations", 1 + chainActive.Height() - pindex->nHeight); + entry.pushKV("time", pindex->GetBlockTime()); + entry.pushKV("blocktime", pindex->GetBlockTime()); } else - entry.push_back(Pair("confirmations", 0)); + entry.pushKV("confirmations", 0); } } } @@ -242,10 +242,10 @@ UniValue getrawtransactionbyblockheight(const UniValue& params, bool fHelp) std::string strHex = EncodeHexTx(tx); hexs.push_back(strHex); } - result.push_back(Pair("hexs", hexs)); - result.push_back(Pair("blockhash", block.GetHash().GetHex())); - result.push_back(Pair("confirmations", chainActive.Height() - nHeight + 1)); - result.push_back(Pair("blocktime", block.GetBlockTime())); + result.pushKV("hexs", hexs); + result.pushKV("blockhash", block.GetHash().GetHex()); + result.pushKV("confirmations", chainActive.Height() - nHeight + 1); + result.pushKV("blocktime", block.GetBlockTime()); return result; } @@ -365,7 +365,7 @@ UniValue getrawtransaction(const UniValue& params, bool fHelp) } UniValue result(UniValue::VOBJ); - if (blockindex) result.push_back(Pair("in_active_chain", in_active_chain)); + if (blockindex) result.pushKV("in_active_chain", in_active_chain); TxToJSON(tx, hash_block, result); return result; } @@ -452,27 +452,27 @@ UniValue listunspent(const UniValue& params, bool fHelp) CAmount nValue = pwalletMain->getCTxOutValue(*out.tx, out.tx->vout[out.i]); const CScript& pk = out.tx->vout[out.i].scriptPubKey; UniValue entry(UniValue::VOBJ); - entry.push_back(Pair("txid", out.tx->GetHash().GetHex())); - entry.push_back(Pair("vout", out.i)); + entry.pushKV("txid", out.tx->GetHash().GetHex()); + entry.pushKV("vout", out.i); CTxDestination address; if (ExtractDestination(out.tx->vout[out.i].scriptPubKey, address)) { - entry.push_back(Pair("address", CBitcoinAddress(address).ToString())); + entry.pushKV("address", CBitcoinAddress(address).ToString()); if (pwalletMain->mapAddressBook.count(address)) - entry.push_back(Pair("account", pwalletMain->mapAddressBook[address].name)); + entry.pushKV("account", pwalletMain->mapAddressBook[address].name); } - entry.push_back(Pair("scriptPubKey", HexStr(pk.begin(), pk.end()))); + entry.pushKV("scriptPubKey", HexStr(pk.begin(), pk.end())); if (pk.IsPayToScriptHash()) { CTxDestination address; if (ExtractDestination(pk, address)) { const CScriptID& hash = boost::get(address); CScript redeemScript; if (pwalletMain->GetCScript(hash, redeemScript)) - entry.push_back(Pair("redeemScript", HexStr(redeemScript.begin(), redeemScript.end()))); + entry.pushKV("redeemScript", HexStr(redeemScript.begin(), redeemScript.end())); } } - entry.push_back(Pair("amount", ValueFromAmount(nValue))); - entry.push_back(Pair("confirmations", out.nDepth)); - entry.push_back(Pair("spendable", out.fSpendable)); + entry.pushKV("amount", ValueFromAmount(nValue)); + entry.pushKV("confirmations", out.nDepth); + entry.pushKV("spendable", out.fSpendable); results.push_back(entry); } @@ -549,7 +549,7 @@ UniValue getunspentcount(const UniValue& params, bool fHelp) ++count; } UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("unspentcount", count)); + obj.pushKV("unspentcount", count); return obj; } #endif @@ -755,7 +755,7 @@ UniValue decodescript(const UniValue& params, bool fHelp) } ScriptPubKeyToJSON(script, r, false); - r.push_back(Pair("p2sh", CBitcoinAddress(CScriptID(script)).ToString())); + r.pushKV("p2sh", CBitcoinAddress(CScriptID(script)).ToString()); return r; } @@ -763,11 +763,11 @@ UniValue decodescript(const UniValue& params, bool fHelp) static void TxInErrorToJSON(const CTxIn& txin, UniValue& vErrorsRet, const std::string& strMessage) { UniValue entry(UniValue::VOBJ); - entry.push_back(Pair("txid", txin.prevout.hash.ToString())); - entry.push_back(Pair("vout", (uint64_t)txin.prevout.n)); - entry.push_back(Pair("scriptSig", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); - entry.push_back(Pair("sequence", (uint64_t)txin.nSequence)); - entry.push_back(Pair("error", strMessage)); + entry.pushKV("txid", txin.prevout.hash.ToString()); + entry.pushKV("vout", (uint64_t)txin.prevout.n); + entry.pushKV("scriptSig", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())); + entry.pushKV("sequence", (uint64_t)txin.nSequence); + entry.pushKV("error", strMessage); vErrorsRet.push_back(entry); } @@ -1015,10 +1015,10 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp) bool fComplete = vErrors.empty(); UniValue result(UniValue::VOBJ); - result.push_back(Pair("hex", EncodeHexTx(mergedTx))); - result.push_back(Pair("complete", fComplete)); + result.pushKV("hex", EncodeHexTx(mergedTx)); + result.pushKV("complete", fComplete); if (!vErrors.empty()) { - result.push_back(Pair("errors", vErrors)); + result.pushKV("errors", vErrors); } return result; diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 75c2457310..a3a5cc21b0 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -25,13 +25,12 @@ #include #include #include -#include #include #include #include // for to_upper() #include - +#include // for unique_ptr static bool fRPCRunning = false; static bool fRPCInWarmup = true; @@ -40,9 +39,8 @@ static RecursiveMutex cs_rpcWarmup; /* Timer-creating functions */ static RPCTimerInterface* timerInterface = NULL; -/* Map of name to timer. - * @note Can be changed to std::unique_ptr when C++11 */ -static std::map > deadlineTimers; +/* Map of name to timer. */ +static std::map > deadlineTimers; static struct CRPCSignals { boost::signals2::signal Started; @@ -51,22 +49,18 @@ static struct CRPCSignals { boost::signals2::signal PostCommand; } g_rpcSignals; -void RPCServer::OnStarted(boost::function slot) { +void RPCServer::OnStarted(std::function slot) { g_rpcSignals.Started.connect(slot); } -void RPCServer::OnStopped(boost::function slot) { +void RPCServer::OnStopped(std::function slot) { g_rpcSignals.Stopped.connect(slot); } -void RPCServer::OnPreCommand(boost::function slot) { +void RPCServer::OnPreCommand(std::function slot) { g_rpcSignals.PreCommand.connect(boost::bind(slot, _1)); } -void RPCServer::OnPostCommand(boost::function slot) { - g_rpcSignals.PostCommand.connect(boost::bind(slot, _1)); -} - void RPCTypeCheck(const UniValue ¶ms, const std::list& typesExpected, bool fAllowNull) { unsigned int i = 0; for (UniValue::VType t : typesExpected) { @@ -624,13 +618,12 @@ void RPCUnsetTimerInterface(RPCTimerInterface *iface) { timerInterface = NULL; } -void RPCRunLater(const std::string &name, boost::function func, int64_t nSeconds) { +void RPCRunLater(const std::string &name, std::function func, int64_t nSeconds) { if (!timerInterface) throw JSONRPCError(RPC_INTERNAL_ERROR, "No timer handler registered for RPC"); deadlineTimers.erase(name); LogPrint(BCLog::RPC, "queue run of timer %s in %i seconds (using %s)\n", name, nSeconds, timerInterface->Name()); - deadlineTimers.insert( - std::make_pair(name, boost::shared_ptr(timerInterface->NewTimer(func, nSeconds * 1000)))); + deadlineTimers.emplace(name, std::unique_ptr(timerInterface->NewTimer(func, nSeconds * 1000))); } const CRPCTable tableRPC; diff --git a/src/rpc/server.h b/src/rpc/server.h index d880e15ba7..65ebb14997 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -17,18 +17,16 @@ #include #include -#include - #include class CRPCCommand; namespace RPCServer { - void OnStarted(boost::function slot); - void OnStopped(boost::function slot); - void OnPreCommand(boost::function slot); - void OnPostCommand(boost::function slot); + void OnStarted(std::function slot); + void OnStopped(std::function slot); + void OnPreCommand(std::function slot); + void OnPostCommand(std::function slot); } class CBlockIndex; @@ -97,7 +95,7 @@ class RPCTimerInterface * This is needed to cope with the case in which there is no HTTP server, but * only GUI RPC console, and to break the dependency of pcserver on httprpc. */ - virtual RPCTimerBase* NewTimer(boost::function& func, int64_t millis) = 0; + virtual RPCTimerBase* NewTimer(std::function& func, int64_t millis) = 0; }; /** Set factory function for timers */ @@ -111,7 +109,7 @@ void RPCUnsetTimerInterface(RPCTimerInterface *iface); * Run func nSeconds from now. * Overrides previous timer (if any). */ -void RPCRunLater(const std::string& name, boost::function func, int64_t nSeconds); +void RPCRunLater(const std::string& name, std::function func, int64_t nSeconds); typedef UniValue(*rpcfn_type)(const UniValue& params, bool fHelp); @@ -171,7 +169,6 @@ extern bool ParseBool(const UniValue& o, std::string strKey); extern int64_t nWalletUnlockTime; extern CAmount AmountFromValue(const UniValue& value); extern UniValue ValueFromAmount(const CAmount& amount); -extern double GetDifficulty(const CBlockIndex* blockindex = NULL); extern std::string HelpRequiringPassphrase(); extern std::string HelpExampleCli(std::string methodname, std::string args); extern std::string HelpExampleRpc(std::string methodname, std::string args); @@ -362,6 +359,5 @@ bool StartRPC(); void InterruptRPC(); void StopRPC(); std::string JSONRPCExecBatch(const UniValue& vReq); -void RPCNotifyBlockChange(bool fInitialDownload, const CBlockIndex* pindex); #endif // BITCOIN_RPCSERVER_H diff --git a/src/scheduler.h b/src/scheduler.h index f06031715e..f322d30beb 100644 --- a/src/scheduler.h +++ b/src/scheduler.h @@ -9,10 +9,9 @@ // // NOTE: -// boost::thread / boost::function / boost::chrono should be ported to -// std::thread / std::function / std::chrono when we support C++11. +// boost::thread / boost::chrono should be ported to std::thread / std::chrono +// when we support C++11. // -#include #include #include #include @@ -40,7 +39,7 @@ class CScheduler { ~CScheduler(); - typedef boost::function Function; + typedef std::function Function; // Call func at/after time t void schedule(Function f, boost::chrono::system_clock::time_point t); diff --git a/src/support/events.h b/src/support/events.h new file mode 100644 index 0000000000..90690876ee --- /dev/null +++ b/src/support/events.h @@ -0,0 +1,56 @@ +// Copyright (c) 2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_SUPPORT_EVENTS_H +#define BITCOIN_SUPPORT_EVENTS_H + +#include +#include + +#include +#include + +#define MAKE_RAII(type) \ +/* deleter */\ +struct type##_deleter {\ + void operator()(struct type* ob) {\ + type##_free(ob);\ + }\ +};\ +/* unique ptr typedef */\ +typedef std::unique_ptr raii_##type + +MAKE_RAII(event_base); +MAKE_RAII(event); +MAKE_RAII(evhttp); +MAKE_RAII(evhttp_request); +MAKE_RAII(evhttp_connection); + +inline raii_event_base obtain_event_base() { + auto result = raii_event_base(event_base_new()); + if (!result.get()) + throw std::runtime_error("cannot create event_base"); + return result; +} + +inline raii_event obtain_event(struct event_base* base, evutil_socket_t s, short events, event_callback_fn cb, void* arg) { + return raii_event(event_new(base, s, events, cb, arg)); +} + +inline raii_evhttp obtain_evhttp(struct event_base* base) { + return raii_evhttp(evhttp_new(base)); +} + +inline raii_evhttp_request obtain_evhttp_request(void(*cb)(struct evhttp_request *, void *), void *arg) { + return raii_evhttp_request(evhttp_request_new(cb, arg)); +} + +inline raii_evhttp_connection obtain_evhttp_connection_base(struct event_base* base, std::string host, uint16_t port) { + auto result = raii_evhttp_connection(evhttp_connection_base_new(base, NULL, host.c_str(), port)); + if (!result.get()) + throw std::runtime_error("create connection failed"); + return result; +} + +#endif // BITCOIN_SUPPORT_EVENTS_H diff --git a/src/test/alert_tests.cpp b/src/test/alert_tests.cpp index c43881be20..9910865f4c 100644 --- a/src/test/alert_tests.cpp +++ b/src/test/alert_tests.cpp @@ -9,7 +9,7 @@ #include "chainparams.h" #include "util.h" -#include "test/test_bitcoin.h" +#include "test/test_prcycoin.h" #include diff --git a/src/test/bip32_tests.cpp b/src/test/bip32_tests.cpp index c558ff99f1..1630a6ccb6 100644 --- a/src/test/bip32_tests.cpp +++ b/src/test/bip32_tests.cpp @@ -8,7 +8,7 @@ #include "key.h" #include "uint256.h" #include "util.h" -#include "test/test_bitcoin.h" +#include "test/test_prcycoin.h" #include #include diff --git a/src/test/dbwrapper_tests.cpp b/src/test/dbwrapper_tests.cpp index 90f09379a0..c1671dfca1 100644 --- a/src/test/dbwrapper_tests.cpp +++ b/src/test/dbwrapper_tests.cpp @@ -89,7 +89,7 @@ BOOST_AUTO_TEST_CASE(dbwrapper_iterator) uint256 in2 = GetRandHash(); BOOST_CHECK(dbw.Write(key2, in2)); - boost::scoped_ptr it(const_cast(&dbw)->NewIterator()); + std::unique_ptr it(const_cast(&dbw)->NewIterator()); // Be sure to seek past any earlier key (if it exists) it->Seek(key); diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index 755644f5b1..f58bc30a64 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -10,7 +10,7 @@ #include "uint256.h" #include "util.h" -#include "test/test_bitcoin.h" +#include "test/test_prcycoin.h" #include diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp index e96a35ba47..ad98df60d5 100644 --- a/src/test/net_tests.cpp +++ b/src/test/net_tests.cpp @@ -162,12 +162,12 @@ BOOST_AUTO_TEST_CASE(cnode_simple_test) bool fInboundIn = false; // Test that fFeeler is false by default. - CNode* pnode1 = new CNode(hSocket, addr, pszDest, fInboundIn); + std::unique_ptr pnode1(new CNode(hSocket, addr, pszDest, fInboundIn)); BOOST_CHECK(pnode1->fInbound == false); BOOST_CHECK(pnode1->fFeeler == false); fInboundIn = true; - CNode* pnode2 = new CNode(hSocket, addr, pszDest, fInboundIn); + std::unique_ptr pnode2(new CNode(hSocket, addr, pszDest, fInboundIn)); BOOST_CHECK(pnode2->fInbound == true); BOOST_CHECK(pnode2->fFeeler == false); } diff --git a/src/test/raii_event_tests.cpp b/src/test/raii_event_tests.cpp new file mode 100644 index 0000000000..97363dd353 --- /dev/null +++ b/src/test/raii_event_tests.cpp @@ -0,0 +1,88 @@ +// Copyright (c) 2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include +#include +#include + +#include "support/events.h" + +#include "test/test_prcycoin.h" + +#include + +#include + +static std::map tags; +static std::map orders; +static uint16_t tagSequence = 0; + +static void* tag_malloc(size_t sz) { + void* mem = malloc(sz); + if (!mem) return mem; + tags[mem]++; + orders[mem] = tagSequence++; + return mem; +} + +static void tag_free(void* mem) { + tags[mem]--; + orders[mem] = tagSequence++; + free(mem); +} + +BOOST_FIXTURE_TEST_SUITE(raii_event_tests, BasicTestingSetup) + +BOOST_AUTO_TEST_CASE(raii_event_creation) +{ + event_set_mem_functions(tag_malloc, realloc, tag_free); + + void* base_ptr = NULL; + { + auto base = obtain_event_base(); + base_ptr = (void*)base.get(); + BOOST_CHECK(tags[base_ptr] == 1); + } + BOOST_CHECK(tags[base_ptr] == 0); + + void* event_ptr = NULL; + { + auto base = obtain_event_base(); + auto event = obtain_event(base.get(), -1, 0, NULL, NULL); + + base_ptr = (void*)base.get(); + event_ptr = (void*)event.get(); + + BOOST_CHECK(tags[base_ptr] == 1); + BOOST_CHECK(tags[event_ptr] == 1); + } + BOOST_CHECK(tags[base_ptr] == 0); + BOOST_CHECK(tags[event_ptr] == 0); + + event_set_mem_functions(malloc, realloc, free); +} + +BOOST_AUTO_TEST_CASE(raii_event_order) +{ + event_set_mem_functions(tag_malloc, realloc, tag_free); + + void* base_ptr = NULL; + void* event_ptr = NULL; + { + auto base = obtain_event_base(); + auto event = obtain_event(base.get(), -1, 0, NULL, NULL); + + base_ptr = (void*)base.get(); + event_ptr = (void*)event.get(); + + // base should have allocated before event + BOOST_CHECK(orders[base_ptr] < orders[event_ptr]); + } + // base should be freed after event + BOOST_CHECK(orders[base_ptr] > orders[event_ptr]); + + event_set_mem_functions(malloc, realloc, free); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/scriptnum_tests.cpp b/src/test/scriptnum_tests.cpp index 767db678d0..f75b51e202 100644 --- a/src/test/scriptnum_tests.cpp +++ b/src/test/scriptnum_tests.cpp @@ -12,8 +12,10 @@ BOOST_FIXTURE_TEST_SUITE(scriptnum_tests, BasicTestingSetup) -static const long values[] = \ -{ 0, 1, CHAR_MIN, CHAR_MAX, UCHAR_MAX, SHRT_MIN, USHRT_MAX, INT_MIN, INT_MAX, static_castUINT_MAX, LONG_MIN, LONG_MAX }; +/** A selection of numbers that do not trigger int64_t overflow + * when added/subtracted. */ +static const int64_t values[] = { 0, 1, -2, 127, 128, -255, 256, (1LL << 15) - 1, -(1LL << 16), (1LL << 24) - 1, (1LL << 31), 1 - (1LL << 32), 1LL << 40 }; + static const long offsets[] = { 1, 0x79, 0x80, 0x81, 0xFF, 0x7FFF, 0x8000, 0xFFFF, 0x10000}; static bool verify(const CBigNum& bignum, const CScriptNum& scriptnum) diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp index 8a1a3413b0..405c9679bf 100644 --- a/src/torcontrol.cpp +++ b/src/torcontrol.cpp @@ -17,7 +17,6 @@ #include #include -#include #include #include #include @@ -75,8 +74,8 @@ class TorControlReply class TorControlConnection { public: - typedef boost::function ConnectionCB; - typedef boost::function ReplyHandlerCB; + typedef std::function ConnectionCB; + typedef std::function ReplyHandlerCB; /** Create a new TorControlConnection. */ @@ -107,9 +106,9 @@ class TorControlConnection boost::signals2::signal async_handler; private: /** Callback when ready for use */ - boost::function connected; + std::function connected; /** Callback when connection lost */ - boost::function disconnected; + std::function disconnected; /** Libevent event base */ struct event_base *base; /** Connection to control socket */ diff --git a/src/torcontrol.h b/src/torcontrol.h index 977dfe3682..f0b5569caa 100644 --- a/src/torcontrol.h +++ b/src/torcontrol.h @@ -10,7 +10,6 @@ #include -#include #include #include diff --git a/src/txdb.cpp b/src/txdb.cpp index 6cb6acf47e..6ce77cf53f 100644 --- a/src/txdb.cpp +++ b/src/txdb.cpp @@ -113,7 +113,7 @@ bool CCoinsViewDB::GetStats(CCoinsStats& stats) const /* It seems that there are no "const iterators" for LevelDB. Since we only need read operations on it, use a const-cast to get around that restriction. */ - boost::scoped_ptr pcursor(const_cast(&db)->NewIterator()); + std::unique_ptr pcursor(const_cast(&db)->NewIterator()); pcursor->Seek(DB_COINS); CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION); @@ -237,7 +237,7 @@ bool CBlockTreeDB::ReadInt(const std::string& name, int& nValue) bool CBlockTreeDB::LoadBlockIndexGuts() { - boost::scoped_ptr pcursor(NewIterator()); + std::unique_ptr pcursor(NewIterator()); pcursor->Seek(std::make_pair(DB_BLOCK_INDEX, UINT256_ZERO)); diff --git a/src/txmempool.cpp b/src/txmempool.cpp index f7a29d090e..5655d65db4 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -16,6 +16,8 @@ #include +#include +#include CTxMemPoolEntry::CTxMemPoolEntry() : nFee(0), nTxSize(0), nModSize(0), nTime(0), dPriority(0.0) { @@ -226,7 +228,9 @@ class CMinerPolicyEstimator // Insert at most 10 random entries per bucket, otherwise a single block // can dominate an estimate: if (e.size() > 10) { - std::random_shuffle(e.begin(), e.end()); + std::random_device rd; + std::mt19937 g(rd()); + std::shuffle(e.begin(), e.end(), g); e.resize(10); } for (const CTxMemPoolEntry* entry : e) { diff --git a/src/util.cpp b/src/util.cpp index f4b67e23ff..0587df1d04 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -56,17 +56,6 @@ #pragma warning(disable : 4717) #endif -#ifdef _WIN32_WINNT -#undef _WIN32_WINNT -#endif -#define _WIN32_WINNT 0x0501 - -#ifdef _WIN32_IE -#undef _WIN32_IE -#endif -#define _WIN32_IE 0x0501 - -#define WIN32_LEAN_AND_MEAN 1 #ifndef NOMINMAX #define NOMINMAX #endif diff --git a/src/util.h b/src/util.h index bdc944e876..b8fd70253d 100644 --- a/src/util.h +++ b/src/util.h @@ -189,4 +189,12 @@ void TraceThread(const char* name, Callable func) fs::path AbsPathForConfigVal(const boost::filesystem::path& path, bool net_specific = true); bool PointHashingSuccessively(const CPubKey& pk, const unsigned char* tweak, unsigned char* out); +//! Substitute for C++14 std::make_unique. +//! DEPRECATED use std::make_unique in new code. +template +std::unique_ptr MakeUnique(Args&&... args) +{ + return std::make_unique(std::forward(args)...); +} + #endif // BITCOIN_UTIL_H diff --git a/src/validationinterface.h b/src/validationinterface.h index 7599165b51..e241d2c4fd 100644 --- a/src/validationinterface.h +++ b/src/validationinterface.h @@ -7,7 +7,6 @@ #define BITCOIN_VALIDATIONINTERFACE_H #include -#include class CBlock; struct CBlockLocator; @@ -33,6 +32,7 @@ class CValidationInterface { protected: virtual void UpdatedBlockTip(const CBlockIndex *pindex) {} virtual void SyncTransaction(const CTransaction &tx, const CBlock *pblock) {} + virtual bool EraseFromWallet(const uint256 &hash) { return false;} virtual void NotifyTransactionLock(const CTransaction &tx) {} virtual void SetBestChain(const CBlockLocator &locator) {} virtual bool UpdatedTransaction(const uint256 &hash) { return false;} @@ -40,7 +40,7 @@ class CValidationInterface { // XX42 virtual void ResendWalletTransactions(int64_t nBestBlockTime) {} virtual void ResendWalletTransactions() {} virtual void BlockChecked(const CBlock&, const CValidationState&) {} -// XX42 virtual void GetScriptForMining(boost::shared_ptr&) {}; +// XX42 virtual void GetScriptForMining(std::shared_ptr&) {}; virtual void ResetRequestCount(const uint256 &hash) {}; friend void ::RegisterValidationInterface(CValidationInterface*); friend void ::UnregisterValidationInterface(CValidationInterface*); @@ -66,7 +66,7 @@ struct CMainSignals { /** Notifies listeners of a block validation result */ boost::signals2::signal BlockChecked; /** Notifies listeners that a key for mining is required (coinbase) */ -// XX42 boost::signals2::signal&)> ScriptForMining; +// XX42 boost::signals2::signal&)> ScriptForMining; /** Notifies listeners that a block has been successfully mined */ boost::signals2::signal BlockFound; }; diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index b35633813a..320f0bf798 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -378,7 +378,7 @@ UniValue dumpwallet(const UniValue& params, bool fHelp) std::sort(vKeyBirth.begin(), vKeyBirth.end()); // produce output - file << strprintf("# Wallet dump created by PRCY %s (%s)\n", CLIENT_BUILD, CLIENT_DATE); + file << strprintf("# Wallet dump created by PRCY%s\n", CLIENT_BUILD); file << strprintf("# * Created on %s\n", EncodeDumpTime(GetTime())); file << strprintf("# * Best block at time of backup was %i (%s),\n", chainActive.Height(), chainActive.Tip()->GetBlockHash().ToString()); file << strprintf("# mined on %s\n", EncodeDumpTime(chainActive.Tip()->GetBlockTime())); @@ -403,7 +403,7 @@ UniValue dumpwallet(const UniValue& params, bool fHelp) file.close(); UniValue reply(UniValue::VOBJ); - reply.push_back(Pair("filename", filepath.string())); + reply.pushKV("filename", filepath.string()); return reply; } @@ -442,8 +442,8 @@ UniValue bip38encrypt(const UniValue& params, bool fHelp) std::string encryptedOut = BIP38_Encrypt(strAddress, strPassphrase, privKey, vchSecret.IsCompressed()); UniValue result(UniValue::VOBJ); - result.push_back(Pair("Addess", strAddress)); - result.push_back(Pair("Encrypted Key", encryptedOut)); + result.pushKV("Addess", strAddress); + result.pushKV("Encrypted Key", encryptedOut); return result; } @@ -476,7 +476,7 @@ UniValue bip38decrypt(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_WALLET_ERROR, "Failed To Decrypt"); UniValue result(UniValue::VOBJ); - result.push_back(Pair("privatekey", HexStr(privKey))); + result.pushKV("privatekey", HexStr(privKey)); CKey key; key.Set(privKey.begin(), privKey.end(), fCompressed); @@ -487,7 +487,7 @@ UniValue bip38decrypt(const UniValue& params, bool fHelp) CPubKey pubkey = key.GetPubKey(); pubkey.IsCompressed(); assert(key.VerifyPubKey(pubkey)); - result.push_back(Pair("Address", CBitcoinAddress(pubkey.GetID()).ToString())); + result.pushKV("Address", CBitcoinAddress(pubkey.GetID()).ToString()); CKeyID vchAddress = pubkey.GetID(); { pwalletMain->MarkDirty(); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index c13b92eac0..75928b90c5 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -52,30 +52,31 @@ void WalletTxToJSON(const CWalletTx& wtx, UniValue& entry) { int confirms = wtx.GetDepthInMainChain(false); int confirmsTotal = GetIXConfirmations(wtx.GetHash()) + confirms; - entry.push_back(Pair("confirmations", confirmsTotal)); - entry.push_back(Pair("bcconfirmations", confirms)); + entry.pushKV("confirmations", confirmsTotal); + entry.pushKV("bcconfirmations", confirms); if (wtx.IsCoinBase() || wtx.IsCoinStake()) - entry.push_back(Pair("generated", true)); + entry.pushKV("generated", true); if (confirms > 0) { - entry.push_back(Pair("blockhash", wtx.hashBlock.GetHex())); - entry.push_back(Pair("blockindex", wtx.nIndex)); - entry.push_back(Pair("blocktime", mapBlockIndex[wtx.hashBlock]->GetBlockTime())); + entry.pushKV("blockhash", wtx.hashBlock.GetHex()); + entry.pushKV("blockheight", mapBlockIndex[wtx.hashBlock]->nHeight); + entry.pushKV("blockindex", wtx.nIndex); + entry.pushKV("blocktime", mapBlockIndex[wtx.hashBlock]->GetBlockTime()); } uint256 hash = wtx.GetHash(); - entry.push_back(Pair("txid", hash.GetHex())); + entry.pushKV("txid", hash.GetHex()); UniValue conflicts(UniValue::VARR); for (const uint256& conflict : wtx.GetConflicts()) conflicts.push_back(conflict.GetHex()); - entry.push_back(Pair("walletconflicts", conflicts)); - entry.push_back(Pair("time", wtx.GetTxTime())); - entry.push_back(Pair("timereceived", (int64_t)wtx.nTimeReceived)); + entry.pushKV("walletconflicts", conflicts); + entry.pushKV("time", wtx.GetTxTime()); + entry.pushKV("timereceived", (int64_t)wtx.nTimeReceived); if (wtx.hasPaymentID && pwalletMain->IsMine(wtx)) { - entry.push_back(Pair("paymentid", wtx.paymentID)); + entry.pushKV("paymentid", wtx.paymentID); } for (const PAIRTYPE(std::string, std::string) & item : wtx.mapValue) - entry.push_back(Pair(item.first, item.second)); + entry.pushKV(item.first, item.second); } std::string AccountFromValue(const UniValue& value) @@ -680,11 +681,11 @@ UniValue getbalances(const UniValue& params, bool fHelp) HelpExampleCli("getbalances", "")); UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("total", ValueFromAmount(pwalletMain->GetBalance()))); - obj.push_back(Pair("spendable", ValueFromAmount(pwalletMain->GetSpendableBalance()))); - obj.push_back(Pair("pending", ValueFromAmount(pwalletMain->GetUnconfirmedBalance()))); - obj.push_back(Pair("immature", ValueFromAmount(pwalletMain->GetImmatureBalance()))); - obj.push_back(Pair("locked", ValueFromAmount(pwalletMain->GetLockedCoins()))); + obj.pushKV("total", ValueFromAmount(pwalletMain->GetBalance())); + obj.pushKV("spendable", ValueFromAmount(pwalletMain->GetSpendableBalance())); + obj.pushKV("pending", ValueFromAmount(pwalletMain->GetUnconfirmedBalance())); + obj.pushKV("immature", ValueFromAmount(pwalletMain->GetImmatureBalance())); + obj.pushKV("locked", ValueFromAmount(pwalletMain->GetLockedCoins())); return obj; } @@ -1040,19 +1041,19 @@ UniValue ListReceived(const UniValue& params, bool fByAccounts) } else { UniValue obj(UniValue::VOBJ); if (fIsWatchonly) - obj.push_back(Pair("involvesWatchonly", true)); - obj.push_back(Pair("address", address.ToString())); - obj.push_back(Pair("account", strAccount)); - obj.push_back(Pair("amount", ValueFromAmount(nAmount))); - obj.push_back(Pair("confirmations", (nConf == std::numeric_limits::max() ? 0 : nConf))); - obj.push_back(Pair("bcconfirmations", (nBCConf == std::numeric_limits::max() ? 0 : nBCConf))); + obj.pushKV("involvesWatchonly", true); + obj.pushKV("address", address.ToString()); + obj.pushKV("account", strAccount); + obj.pushKV("amount", ValueFromAmount(nAmount)); + obj.pushKV("confirmations", (nConf == std::numeric_limits::max() ? 0 : nConf)); + obj.pushKV("bcconfirmations", (nBCConf == std::numeric_limits::max() ? 0 : nBCConf)); UniValue transactions(UniValue::VARR); if (it != mapTally.end()) { for (const uint256& item : (*it).second.txids) { transactions.push_back(item.GetHex()); } } - obj.push_back(Pair("txids", transactions)); + obj.pushKV("txids", transactions); ret.push_back(obj); } } @@ -1064,11 +1065,11 @@ UniValue ListReceived(const UniValue& params, bool fByAccounts) int nBCConf = (*it).second.nBCConf; UniValue obj(UniValue::VOBJ); if ((*it).second.fIsWatchonly) - obj.push_back(Pair("involvesWatchonly", true)); - obj.push_back(Pair("account", (*it).first)); - obj.push_back(Pair("amount", ValueFromAmount(nAmount))); - obj.push_back(Pair("confirmations", (nConf == std::numeric_limits::max() ? 0 : nConf))); - obj.push_back(Pair("bcconfirmations", (nBCConf == std::numeric_limits::max() ? 0 : nBCConf))); + obj.pushKV("involvesWatchonly", true); + obj.pushKV("account", (*it).first); + obj.pushKV("amount", ValueFromAmount(nAmount)); + obj.pushKV("confirmations", (nConf == std::numeric_limits::max() ? 0 : nConf)); + obj.pushKV("bcconfirmations", (nBCConf == std::numeric_limits::max() ? 0 : nBCConf)); ret.push_back(obj); } } @@ -1143,7 +1144,7 @@ static void MaybePushAddress(UniValue & entry, const CTxDestination &dest) { CBitcoinAddress addr; if (addr.Set(dest)) - entry.push_back(Pair("address", addr.ToString())); + entry.pushKV("address", addr.ToString()); } void ListTransactions(const CWalletTx& wtx, const std::string& strAccount, int nMinDepth, bool fLong, UniValue& ret, const isminefilter& filter) @@ -1163,13 +1164,31 @@ void ListTransactions(const CWalletTx& wtx, const std::string& strAccount, int n for (const COutputEntry& s : listSent) { UniValue entry(UniValue::VOBJ); if (involvesWatchonly || (::IsMine(*pwalletMain, s.destination) & ISMINE_WATCH_ONLY)) - entry.push_back(Pair("involvesWatchonly", true)); - entry.push_back(Pair("account", strSentAccount)); + entry.pushKV("involvesWatchonly", true); + entry.pushKV("account", strSentAccount); MaybePushAddress(entry, s.destination); - entry.push_back(Pair("category", "send")); - entry.push_back(Pair("amount", ValueFromAmount(-s.amount))); - entry.push_back(Pair("vout", s.vout)); - entry.push_back(Pair("fee", ValueFromAmount(-nFee))); + + // Calculate amounts for this transaction + CAmount nCredit = wtx.GetCredit(filter); + CAmount nDebit = wtx.GetDebit(filter); + CAmount nNet = (nCredit > nDebit)? (nCredit - nDebit):(nDebit - nCredit); + CAmount nAmountWithoutFee = nNet - nFee; + + if (wtx.IsCoinStake()) { + if (wtx.GetDepthInMainChain() < 1) { + entry.pushKV("category", "orphan"); + } else if (wtx.GetBlocksToMaturity() > 0) { + entry.pushKV("category", "immature"); + } else { + entry.pushKV("category", "generate"); + } + entry.pushKV("amount", ValueFromAmount(nAmountWithoutFee)); + } else { + entry.pushKV("category", "send"); + entry.pushKV("amount", ValueFromAmount(-nAmountWithoutFee)); + } + entry.pushKV("vout", s.vout); + entry.pushKV("fee", ValueFromAmount(-nFee)); if (fLong) WalletTxToJSON(wtx, entry); ret.push_back(entry); @@ -1185,21 +1204,21 @@ void ListTransactions(const CWalletTx& wtx, const std::string& strAccount, int n if (fAllAccounts || (account == strAccount)) { UniValue entry(UniValue::VOBJ); if (involvesWatchonly || (::IsMine(*pwalletMain, r.destination) & ISMINE_WATCH_ONLY)) - entry.push_back(Pair("involvesWatchonly", true)); - entry.push_back(Pair("account", account)); + entry.pushKV("involvesWatchonly", true); + entry.pushKV("account", account); MaybePushAddress(entry, r.destination); if (wtx.IsCoinBase()) { if (wtx.GetDepthInMainChain() < 1) - entry.push_back(Pair("category", "orphan")); + entry.pushKV("category", "orphan"); else if (wtx.GetBlocksToMaturity() > 0) - entry.push_back(Pair("category", "immature")); + entry.pushKV("category", "immature"); else - entry.push_back(Pair("category", "generate")); + entry.pushKV("category", "generate"); } else { - entry.push_back(Pair("category", "receive")); + entry.pushKV("category", "receive"); } - entry.push_back(Pair("amount", ValueFromAmount(r.amount))); - entry.push_back(Pair("vout", r.vout)); + entry.pushKV("amount", ValueFromAmount(r.amount)); + entry.pushKV("vout", r.vout); if (fLong) WalletTxToJSON(wtx, entry); ret.push_back(entry); @@ -1214,12 +1233,12 @@ void AcentryToJSON(const CAccountingEntry& acentry, const std::string& strAccoun if (fAllAccounts || acentry.strAccount == strAccount) { UniValue entry(UniValue::VOBJ); - entry.push_back(Pair("account", acentry.strAccount)); - entry.push_back(Pair("category", "move")); - entry.push_back(Pair("time", acentry.nTime)); - entry.push_back(Pair("amount", ValueFromAmount(acentry.nCreditDebit))); - entry.push_back(Pair("otheraccount", acentry.strOtherAccount)); - entry.push_back(Pair("comment", acentry.strComment)); + entry.pushKV("account", acentry.strAccount); + entry.pushKV("category", "move"); + entry.pushKV("time", acentry.nTime); + entry.pushKV("amount", ValueFromAmount(acentry.nCreditDebit)); + entry.pushKV("otheraccount", acentry.strOtherAccount); + entry.pushKV("comment", acentry.strComment); ret.push_back(entry); } } @@ -1279,8 +1298,6 @@ UniValue listtransactions(const UniValue& params, bool fHelp) "\nList transactions 100 to 120 from the tabby account\n" + HelpExampleCli("listtransactions", "\"tabby\" 20 100") + "\nAs a json rpc call\n" + HelpExampleRpc("listtransactions", "\"tabby\", 20, 100")); - LOCK2(cs_main, pwalletMain->cs_wallet); - std::string strAccount = "*"; if (params.size() > 0) strAccount = params[0].get_str(); @@ -1302,19 +1319,24 @@ UniValue listtransactions(const UniValue& params, bool fHelp) UniValue ret(UniValue::VARR); - const CWallet::TxItems & txOrdered = pwalletMain->wtxOrdered; + { + LOCK2(cs_main, pwalletMain->cs_wallet); + + const CWallet::TxItems& txOrdered = pwalletMain->wtxOrdered; - // iterate backwards until we have nCount items to return: - for (CWallet::TxItems::const_reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it) { - CWalletTx* const pwtx = (*it).second.first; - if (pwtx != 0) - ListTransactions(*pwtx, strAccount, 0, true, ret, filter); - CAccountingEntry* const pacentry = (*it).second.second; - if (pacentry != 0) - AcentryToJSON(*pacentry, strAccount, ret); + // iterate backwards until we have nCount items to return: + for (CWallet::TxItems::const_reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it) { + CWalletTx* const pwtx = (*it).second.first; + if (pwtx != 0) + ListTransactions(*pwtx, strAccount, 0, true, ret, filter); + CAccountingEntry* const pacentry = (*it).second.second; + if (pacentry != 0) + AcentryToJSON(*pacentry, strAccount, ret); - if ((int)ret.size() >= (nCount + nFrom)) break; + if ((int)ret.size() >= (nCount + nFrom)) break; + } } + // ret is newest to oldest if (nFrom > (int)ret.size()) @@ -1322,24 +1344,10 @@ UniValue listtransactions(const UniValue& params, bool fHelp) if ((nFrom + nCount) > (int)ret.size()) nCount = ret.size() - nFrom; - std::vector arrTmp = ret.getValues(); - - std::vector::iterator first = arrTmp.begin(); - std::advance(first, nFrom); - - std::vector::iterator last = arrTmp.begin(); - std::advance(last, nFrom + nCount); - - if (last != arrTmp.end()) arrTmp.erase(last, arrTmp.end()); - if (first != arrTmp.begin()) arrTmp.erase(arrTmp.begin(), first); - - std::reverse(arrTmp.begin(), arrTmp.end()); // Return oldest to newest - - ret.clear(); - ret.setArray(); - ret.push_backV(arrTmp); - - return ret; + const std::vector& txs = ret.getValues(); + UniValue result{UniValue::VARR}; + result.push_backV({ txs.rend() - nFrom - nCount, txs.rend() - nFrom }); // Return oldest to newest + return result; } UniValue listtransactionsbypaymentid(const UniValue& params, bool fHelp) @@ -1393,8 +1401,6 @@ UniValue listtransactionsbypaymentid(const UniValue& params, bool fHelp) "\nList transactions 100 to 120 from the Payment ID\n" + HelpExampleCli("listtransactionsbypaymentid", "123456 20 100") + "\nAs a json rpc call\n" + HelpExampleRpc("listtransactionsbypaymentid", "123456, 20, 100")); - LOCK2(cs_main, pwalletMain->cs_wallet); - std::string strAccount = "*"; uint64_t paymentID = 0; if (params.size() > 0) @@ -1414,19 +1420,24 @@ UniValue listtransactionsbypaymentid(const UniValue& params, bool fHelp) UniValue ret(UniValue::VARR); - const CWallet::TxItems & txOrdered = pwalletMain->wtxOrdered; + { + LOCK2(cs_main, pwalletMain->cs_wallet); - // iterate backwards until we have nCount items to return: - for (CWallet::TxItems::const_reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it) { - CWalletTx* const pwtx = (*it).second.first; - if (pwtx != 0 && (pwtx->hasPaymentID && pwtx->paymentID == paymentID)) - ListTransactions(*pwtx, strAccount, 0, true, ret, filter); - CAccountingEntry* const pacentry = (*it).second.second; - if (pacentry != 0) - AcentryToJSON(*pacentry, strAccount, ret); + const CWallet::TxItems& txOrdered = pwalletMain->wtxOrdered; - if ((int)ret.size() >= (nCount + nFrom)) break; + // iterate backwards until we have nCount items to return: + for (CWallet::TxItems::const_reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it) { + CWalletTx* const pwtx = (*it).second.first; + if (pwtx != 0 && (pwtx->hasPaymentID && pwtx->paymentID == paymentID)) + ListTransactions(*pwtx, strAccount, 0, true, ret, filter); + CAccountingEntry* const pacentry = (*it).second.second; + if (pacentry != 0) + AcentryToJSON(*pacentry, strAccount, ret); + + if ((int)ret.size() >= (nCount + nFrom)) break; + } } + // ret is newest to oldest if (nFrom > (int)ret.size()) @@ -1434,24 +1445,10 @@ UniValue listtransactionsbypaymentid(const UniValue& params, bool fHelp) if ((nFrom + nCount) > (int)ret.size()) nCount = ret.size() - nFrom; - std::vector arrTmp = ret.getValues(); - - std::vector::iterator first = arrTmp.begin(); - std::advance(first, nFrom); - - std::vector::iterator last = arrTmp.begin(); - std::advance(last, nFrom + nCount); - - if (last != arrTmp.end()) arrTmp.erase(last, arrTmp.end()); - if (first != arrTmp.begin()) arrTmp.erase(arrTmp.begin(), first); - - std::reverse(arrTmp.begin(), arrTmp.end()); // Return oldest to newest - - ret.clear(); - ret.setArray(); - ret.push_backV(arrTmp); - - return ret; + const std::vector& txs = ret.getValues(); + UniValue result{UniValue::VARR}; + result.push_backV({ txs.rend() - nFrom - nCount, txs.rend() - nFrom }); // Return oldest to newest + return result; } UniValue listaccounts(const UniValue& params, bool fHelp) @@ -1519,7 +1516,7 @@ UniValue listaccounts(const UniValue& params, bool fHelp) UniValue ret(UniValue::VOBJ); for (const PAIRTYPE(std::string, CAmount) & accountBalance : mapAccountBalances) { - ret.push_back(Pair(accountBalance.first, ValueFromAmount(accountBalance.second))); + ret.pushKV(accountBalance.first, ValueFromAmount(accountBalance.second)); } return ret; } @@ -1601,8 +1598,8 @@ UniValue listsinceblock(const UniValue& params, bool fHelp) uint256 lastblock = pblockLast ? pblockLast->GetBlockHash() : UINT256_ZERO; UniValue ret(UniValue::VOBJ); - ret.push_back(Pair("transactions", transactions)); - ret.push_back(Pair("lastblock", lastblock.GetHex())); + ret.pushKV("transactions", transactions); + ret.pushKV("lastblock", lastblock.GetHex()); return ret; } @@ -1622,6 +1619,7 @@ UniValue gettransaction(const UniValue& params, bool fHelp) " \"confirmations\" : n, (numeric) The number of confirmations\n" " \"bcconfirmations\" : n, (numeric) The number of blockchain confirmations\n" " \"blockhash\" : \"hash\", (string) The block hash\n" + " \"blockheight\" : n, (numeric) The block height\n" " \"blockindex\" : xx, (numeric) The block index\n" " \"blocktime\" : ttt, (numeric) The time in seconds since epoch (1 Jan 1970 GMT)\n" " \"txid\" : \"transactionid\", (string) The transaction id.\n" @@ -1662,18 +1660,18 @@ UniValue gettransaction(const UniValue& params, bool fHelp) CAmount nDebit = wtx.GetDebit(filter); CAmount nNet = (nCredit > nDebit)? (nCredit - nDebit):(nDebit - nCredit); CAmount nFee = wtx.nTxFee; - entry.push_back(Pair("amount", ValueFromAmount(nNet))); + entry.pushKV("amount", ValueFromAmount(nNet - nFee)); if (wtx.IsFromMe(filter)) - entry.push_back(Pair("fee", ValueFromAmount(nFee))); + entry.pushKV("fee", ValueFromAmount(nFee)); WalletTxToJSON(wtx, entry); UniValue details(UniValue::VARR); ListTransactions(wtx, "*", 0, false, details, filter); - entry.push_back(Pair("details", details)); + entry.pushKV("details", details); std::string strHex = EncodeHexTx(static_cast(wtx)); - entry.push_back(Pair("hex", strHex)); + entry.pushKV("hex", strHex); return entry; } @@ -2036,8 +2034,8 @@ UniValue listlockunspent(const UniValue& params, bool fHelp) for (COutPoint& outpt : vOutpts) { UniValue o(UniValue::VOBJ); - o.push_back(Pair("txid", outpt.hash.GetHex())); - o.push_back(Pair("vout", (int)outpt.n)); + o.pushKV("txid", outpt.hash.GetHex()); + o.pushKV("vout", (int)outpt.n); ret.push_back(o); } @@ -2077,9 +2075,14 @@ UniValue getwalletinfo(const UniValue& params, bool fHelp) "\nResult:\n" "{\n" " \"walletversion\": xxxxx, (numeric) the wallet version\n" - " \"balance\": xxxxxxx, (numeric) the total PRCY balance of the wallet\n" - " \"unconfirmed_balance\": xxx, (numeric) the total unconfirmed balance of the wallet in PRCY\n" - " \"immature_balance\": xxxxxx, (numeric) the total immature balance of the wallet in PRCY\n" + " \"balances\": (string) A json array of balances\n" + " {\n" + " \"total\": (numeric) the total balance of the wallet in PRCY\n" + " \"spendable\": (numeric) the total spendable balance of the wallet in PRCY\n" + " \"pending\": (numeric) the total pending balance of the wallet in PRCY\n" + " \"immature\": (numeric) the total immature balance of the wallet in PRCY\n" + " \"locked\": (numeric) the total locked balance of the wallet in PRCY\n" + " },\n" " \"txcount\": xxxxxxx, (numeric) the total number of transactions in the wallet\n" " \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since GMT epoch) of the oldest pre-generated key in the key pool\n" " \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated\n" @@ -2093,17 +2096,21 @@ UniValue getwalletinfo(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("walletversion", pwalletMain->GetVersion())); - obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance()))); - obj.push_back(Pair("unconfirmed_balance", ValueFromAmount(pwalletMain->GetUnconfirmedBalance()))); - obj.push_back(Pair("immature_balance", ValueFromAmount(pwalletMain->GetImmatureBalance()))); - obj.push_back(Pair("txcount", (int)pwalletMain->mapWallet.size())); - obj.push_back(Pair("keypoololdest", pwalletMain->GetOldestKeyPoolTime())); - obj.push_back(Pair("keypoolsize", (int)pwalletMain->GetKeyPoolSize())); + obj.pushKV("walletversion", pwalletMain->GetVersion()); + UniValue balances(UniValue::VOBJ); + balances.pushKV("total", ValueFromAmount(pwalletMain->GetBalance())); + balances.pushKV("spendable", ValueFromAmount(pwalletMain->GetSpendableBalance())); + balances.pushKV("pending", ValueFromAmount(pwalletMain->GetUnconfirmedBalance())); + balances.pushKV("immature", ValueFromAmount(pwalletMain->GetImmatureBalance())); + balances.pushKV("locked", ValueFromAmount(pwalletMain->GetLockedCoins())); + obj.pushKV("balances", balances); + obj.pushKV("txcount", (int)pwalletMain->mapWallet.size()); + obj.pushKV("keypoololdest", pwalletMain->GetOldestKeyPoolTime()); + obj.pushKV("keypoolsize", (int)pwalletMain->GetKeyPoolSize()); if (pwalletMain->IsCrypted()) - obj.push_back(Pair("walletunlocked", !pwalletMain->IsLocked())); - obj.push_back(Pair("unlocked_until", nWalletUnlockTime)); - obj.push_back(Pair("paytxfee", ValueFromAmount(payTxFee.GetFeePerK()))); + obj.pushKV("walletunlocked", !pwalletMain->IsLocked()); + obj.pushKV("unlocked_until", nWalletUnlockTime); + obj.pushKV("paytxfee", ValueFromAmount(payTxFee.GetFeePerK())); return obj; } @@ -2123,7 +2130,7 @@ UniValue gettxcount(const UniValue& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("txcount", (int)pwalletMain->mapWallet.size())); + obj.pushKV("txcount", (int)pwalletMain->mapWallet.size()); return obj; } @@ -2171,8 +2178,8 @@ UniValue reservebalance(const UniValue& params, bool fHelp) } UniValue result(UniValue::VOBJ); - result.push_back(Pair("reserve", (nReserveBalance > 0))); - result.push_back(Pair("amount", ValueFromAmount(nReserveBalance))); + result.pushKV("reserve", (nReserveBalance > 0)); + result.pushKV("amount", ValueFromAmount(nReserveBalance)); return result; } @@ -2207,12 +2214,12 @@ UniValue setstakesplitthreshold(const UniValue& params, bool fHelp) UniValue result(UniValue::VOBJ); pwalletMain->nStakeSplitThreshold = nStakeSplitThreshold; - result.push_back(Pair("threshold", int(pwalletMain->nStakeSplitThreshold))); + result.pushKV("threshold", int(pwalletMain->nStakeSplitThreshold)); if (fFileBacked) { walletdb.WriteStakeSplitThreshold(nStakeSplitThreshold); - result.push_back(Pair("saved", "true")); + result.pushKV("saved", "true"); } else - result.push_back(Pair("saved", "false")); + result.pushKV("saved", "false"); return result; } @@ -2235,7 +2242,6 @@ UniValue getstakesplitthreshold(const UniValue& params, bool fHelp) UniValue autocombinedust(const UniValue& params, bool fHelp) { - if(pwalletMain->fCombineDust){ bool fEnable; if (params.size() >= 1) fEnable = params[0].get_bool(); @@ -2268,28 +2274,23 @@ UniValue autocombinedust(const UniValue& params, bool fHelp) throw std::runtime_error("Changed settings in wallet but failed to save to database\n"); UniValue result(UniValue::VOBJ); - result.push_back(Pair("autocombinedust", params[0].get_bool())); - result.push_back(Pair("amount", int(pwalletMain->nAutoCombineThreshold))); + result.pushKV("autocombinedust", params[0].get_bool()); + result.pushKV("amount", int(pwalletMain->nAutoCombineThreshold)); return result; - } - else{ - throw std::runtime_error( - "autocombinedust is disabled in your prcycoin.conf"); - } } UniValue printMultiSend() { UniValue ret(UniValue::VARR); UniValue act(UniValue::VARR); - act.push_back(Pair("MultiSendStake Activated?", pwalletMain->fMultiSendStake)); - act.push_back(Pair("MultiSendMasternode Activated?", pwalletMain->fMultiSendMasternodeReward)); + act.pushKV("MultiSendStake Activated?", pwalletMain->fMultiSendStake); + act.pushKV("MultiSendMasternode Activated?", pwalletMain->fMultiSendMasternodeReward); ret.push_back(act); if (pwalletMain->vDisabledAddresses.size() >= 1) { UniValue disAdd(UniValue::VOBJ); for (unsigned int i = 0; i < pwalletMain->vDisabledAddresses.size(); i++) { - disAdd.push_back(Pair("Disabled From Sending", pwalletMain->vDisabledAddresses[i])); + disAdd.pushKV("Disabled From Sending", pwalletMain->vDisabledAddresses[i]); } ret.push_back(disAdd); } @@ -2298,8 +2299,8 @@ UniValue printMultiSend() UniValue vMS(UniValue::VOBJ); for (unsigned int i = 0; i < pwalletMain->vMultiSend.size(); i++) { - vMS.push_back(Pair("Address " + std::to_string(i), pwalletMain->vMultiSend[i].first)); - vMS.push_back(Pair("Percent", pwalletMain->vMultiSend[i].second)); + vMS.pushKV("Address " + std::to_string(i), pwalletMain->vMultiSend[i].first); + vMS.pushKV("Percent", pwalletMain->vMultiSend[i].second); } ret.push_back(vMS); @@ -2327,8 +2328,8 @@ UniValue printAddresses() UniValue obj(UniValue::VOBJ); const std::string* strAdd = &(*it).first; const double* nBalance = &(*it).second; - obj.push_back(Pair("Address ", *strAdd)); - obj.push_back(Pair("Balance ", *nBalance)); + obj.pushKV("Address ", *strAdd); + obj.pushKV("Balance ", *nBalance); ret.push_back(obj); } @@ -2368,8 +2369,8 @@ UniValue multisend(const UniValue& params, bool fHelp) pwalletMain->setMultiSendDisabled(); UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("Erased from database", erased)); - obj.push_back(Pair("Erased from RAM", true)); + obj.pushKV("Erased from database", erased); + obj.pushKV("Erased from RAM", true); return obj; } @@ -2381,7 +2382,7 @@ UniValue multisend(const UniValue& params, bool fHelp) pwalletMain->fMultiSendStake = true; if (!walletdb.WriteMSettings(true, pwalletMain->fMultiSendMasternodeReward, pwalletMain->nLastMultiSendHeight)) { UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("error", "MultiSend activated but writing settings to DB failed")); + obj.pushKV("error", "MultiSend activated but writing settings to DB failed"); UniValue arr(UniValue::VARR); arr.push_back(obj); arr.push_back(printMultiSend()); @@ -2400,7 +2401,7 @@ UniValue multisend(const UniValue& params, bool fHelp) if (!walletdb.WriteMSettings(pwalletMain->fMultiSendStake, true, pwalletMain->nLastMultiSendHeight)) { UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("error", "MultiSend activated but writing settings to DB failed")); + obj.pushKV("error", "MultiSend activated but writing settings to DB failed"); UniValue arr(UniValue::VARR); arr.push_back(obj); arr.push_back(printMultiSend()); @@ -2579,13 +2580,13 @@ UniValue createprivacyaccount(const UniValue& params, bool fHelp) i++; continue; } - ret.push_back(Pair("viewpublickey", viewAccount.vchPubKey.GetHex())); + ret.pushKV("viewpublickey", viewAccount.vchPubKey.GetHex()); - ret.push_back(Pair("spendpublickey", spendAccount.vchPubKey.GetHex())); + ret.pushKV("spendpublickey", spendAccount.vchPubKey.GetHex()); std::string stealthAddr; if (pwalletMain->EncodeStealthPublicAddress(viewAccount.vchPubKey, spendAccount.vchPubKey, stealthAddr)) { - ret.push_back(Pair("stealthaddress", stealthAddr)); + ret.pushKV("stealthaddress", stealthAddr); } break; } @@ -2634,8 +2635,8 @@ UniValue generateintegratedaddress(const UniValue& params, bool fHelp) } else { address = pwalletMain->GenerateIntegratedAddressWithRandomPaymentID("masteraccount", paymentID); } - ret.push_back(Pair("integratedaddress", address)); - ret.push_back(Pair("paymentid", paymentID)); + ret.pushKV("integratedaddress", address); + ret.pushKV("paymentid", paymentID); return ret; } @@ -2734,13 +2735,13 @@ UniValue createprivacysubaddress(const UniValue& params, bool fHelp) UniValue ret(UniValue::VOBJ); - ret.push_back(Pair("viewpublickey", account.viewAccount.vchPubKey.GetHex())); + ret.pushKV("viewpublickey", account.viewAccount.vchPubKey.GetHex()); - ret.push_back(Pair("spendpublickey", account.spendAccount.vchPubKey.GetHex())); + ret.pushKV("spendpublickey", account.spendAccount.vchPubKey.GetHex()); std::string stealthAddr; if (pwalletMain->EncodeStealthPublicAddress(account.viewAccount.vchPubKey, account.spendAccount.vchPubKey, stealthAddr)) { - ret.push_back(Pair("stealthaddress", stealthAddr)); + ret.pushKV("stealthaddress", stealthAddr); } return ret; } @@ -2791,10 +2792,10 @@ UniValue decodestealthaddress(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_WALLET_ERROR, "Error: Stealth address is not correctly formatted."); } - ret.push_back(Pair("spendpublickey", spendKey.GetHex())); - ret.push_back(Pair("viewpublickey", viewKey.GetHex())); + ret.pushKV("spendpublickey", spendKey.GetHex()); + ret.pushKV("viewpublickey", viewKey.GetHex()); if (hasPaymentID) { - ret.push_back(Pair("paymentid", paymentID)); + ret.pushKV("paymentid", paymentID); } return ret; @@ -2919,7 +2920,7 @@ UniValue setdecoyconfirmation(const UniValue& params, bool fHelp) } pwalletMain->DecoyConfirmationMinimum = confirmation; UniValue ret(UniValue::VOBJ); - ret.push_back(Pair("decoy_confirmation", confirmation)); + ret.pushKV("decoy_confirmation", confirmation); return ret; } @@ -2939,7 +2940,7 @@ UniValue getdecoyconfirmation(const UniValue& params, bool fHelp) EnsureWallet(); UniValue ret(UniValue::VOBJ); - ret.push_back(Pair("decoy_confirmation", pwalletMain->DecoyConfirmationMinimum)); + ret.pushKV("decoy_confirmation", pwalletMain->DecoyConfirmationMinimum); return ret; } @@ -3011,7 +3012,7 @@ UniValue showtxprivatekeys(const UniValue& params, bool fHelp) { std::string key = params[0].get_str() + std::to_string(i); std::string secret; if (db.ReadTxPrivateKey(key, secret)) { - ret.push_back(Pair(std::to_string(i), secret)); + ret.pushKV(std::to_string(i), secret); } else break; } return ret; @@ -3079,11 +3080,23 @@ UniValue erasewallettransactions(const UniValue& params, bool fHelp) { EnsureWallet(); EnsureWalletIsUnlocked(); + LOCK2(cs_main, pwalletMain->cs_wallet); + CBlockIndex* pindex = chainActive.Tip(); + int initialCount = (int)pwalletMain->mapWallet.size(); + int newCount, removedTxes = 0; - pwalletMain->DeleteWalletTransactions(pindex); + pwalletMain->DeleteWalletTransactions(pindex, false); - return "Done"; + newCount = (int)pwalletMain->mapWallet.size(); + removedTxes = initialCount - newCount; + + UniValue ret(UniValue::VOBJ); + ret.pushKV("initial_utxo_count", initialCount); + ret.pushKV("new_utxo_count", newCount); + ret.pushKV("deleted_utxo_count", removedTxes); + + return ret; } UniValue revealmnemonicphrase(const UniValue& params, bool fHelp) @@ -3129,7 +3142,8 @@ UniValue erasefromwallet(const UniValue& params, bool fHelp) if (!pwalletMain->mapWallet.count(hash)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id"); - pwalletMain->EraseFromWallet(hash); + if (!pwalletMain->mapWallet.count(hash)) + return "Failed to delete transaction"; return "Done"; } diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp index d324b111df..a917639daa 100644 --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -20,6 +20,7 @@ // we repeat those tests this many times and only complain if all iterations of the test fail #define RANDOM_REPEATS 5 +std::vector> wtxn; typedef std::set > CoinSet; extern CWallet* pwalletMain; @@ -81,21 +82,21 @@ static void add_coin(const CAmount& nValue, int nAge = 6*24, bool fIsFromMe = fa // so stop vin being empty, and cache a non-zero Debit to fake out IsFromMe() tx.vin.resize(1); } - CWalletTx* wtx = new CWalletTx(&wallet, tx); + std::unique_ptr wtx(new CWalletTx(&wallet, MakeTransactionRef(std::move(tx)))); if (fIsFromMe) { wtx->fDebitCached = true; wtx->nDebitCached = 1; } - COutput output(wtx, nInput, nAge, true); + COutput output(wtx.get(), nInput, nAge, true); vCoins.push_back(output); + wtxn.emplace_back(std::move(wtx)); } static void empty_wallet(void) { - for (COutput output : vCoins) - delete output.tx; vCoins.clear(); + wtxn.clear(); } static bool equal_sets(CoinSet a, CoinSet b) diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 39ba4aca21..42188b6d05 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -46,10 +46,11 @@ #include #endif +#include +#include + CWallet* pwalletMain = nullptr; -/** - * Settings - */ +/** Transaction fee set by the user */ CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE); CAmount maxTxFee = DEFAULT_TRANSACTION_MAXFEE; unsigned int nTxConfirmTarget = 1; @@ -897,6 +898,17 @@ unsigned int CWallet::GetSpendDepth(const uint256& hash, unsigned int n) const if (mit != mapWallet.end() && mit->second.GetDepthInMainChain() >= 0) return mit->second.GetDepthInMainChain(); // Spent } + + std::string outString = outpoint.hash.GetHex() + std::to_string(outpoint.n); + CKeyImage ki = outpointToKeyImages[outString]; + if (IsSpentKeyImage(ki.GetHex(), UINT256_ZERO)) { + std::string kiHex = ki.GetHex(); + int confirmations = 0; + if (CheckKeyImageSpendInMainChain(kiHex, confirmations)) { + return confirmations; // Spent + } + } + return 0; } @@ -1319,17 +1331,16 @@ void CWallet::SyncTransaction(const CTransaction& tx, const CBlock* pblock) } } -void CWallet::EraseFromWallet(const uint256& hash) +bool CWallet::EraseFromWallet(const uint256& hash) { if (!fFileBacked) - return; + return false; { LOCK(cs_wallet); if (mapWallet.erase(hash)) - CWalletDB(strWalletFile).EraseTx(hash); - LogPrintf("%s: Erased wtx %s from wallet\n", __func__, hash.GetHex()); + return CWalletDB(strWalletFile).EraseTx(hash); } - return; + return false; } @@ -1597,11 +1608,12 @@ CAmount CWalletTx::GetUnlockedCredit() const CAmount nCredit = 0; uint256 hashTx = GetHash(); + const CAmount collateralAmount = Params().MNCollateralAmt(); for (unsigned int i = 0; i < vout.size(); i++) { const CTxOut& txout = vout[i]; if (pwallet->IsSpent(hashTx, i) || pwallet->IsLockedCoin(hashTx, i)) continue; - if (fMasterNode && pwallet->getCTxOutValue(*this, vout[i]) == Params().MNCollateralAmt()) continue; // do not count MN-like outputs + if (fMasterNode && pwallet->getCTxOutValue(*this, vout[i]) == collateralAmount) continue; // do not count MN-like outputs nCredit += pwallet->GetCredit(*this, txout, ISMINE_SPENDABLE); } @@ -1621,6 +1633,7 @@ CAmount CWalletTx::GetLockedCredit() const CAmount nCredit = 0; uint256 hashTx = GetHash(); + const CAmount collateralAmount = Params().MNCollateralAmt(); for (unsigned int i = 0; i < vout.size(); i++) { const CTxOut& txout = vout[i]; @@ -1632,8 +1645,8 @@ CAmount CWalletTx::GetLockedCredit() const nCredit += pwallet->GetCredit(*this, txout, ISMINE_SPENDABLE); } - // Add masternode collaterals which are handled likc locked coins - else if (fMasterNode && pwallet->getCTxOutValue(*this, vout[i]) == Params().MNCollateralAmt()) { + // Add masternode collaterals which are handled like locked coins + else if (fMasterNode && pwallet->getCTxOutValue(*this, vout[i]) == collateralAmount) { nCredit += pwallet->GetCredit(*this, txout, ISMINE_SPENDABLE); } @@ -1768,6 +1781,25 @@ bool CWalletTx::WriteToDisk(CWalletDB *pwalletdb) return CWalletDB(pwallet->strWalletFile).WriteTx(GetHash(), *this); } +void CWallet::RemoveFromSpends(const uint256& wtxid) +{ + if (mapTxSpends.size() > 0) + { + std::multimap::const_iterator itr = mapTxSpends.cbegin(); + while (itr != mapTxSpends.cend()) + { + if (itr->second == wtxid) + { + itr = mapTxSpends.erase(itr); + } + else + { + ++itr; + } + } + } +} + /** * Reorder the transactions based on block hieght and block index. * Transactions can get out of order when they are deleted and subsequently @@ -1775,22 +1807,29 @@ bool CWalletTx::WriteToDisk(CWalletDB *pwalletdb) */ void CWallet::ReorderWalletTransactions(std::map, CWalletTx*> &mapSorted, int64_t &maxOrderPos) { - LOCK2(cs_main, cs_wallet); + AssertLockHeld(cs_main); + AssertLockHeld(cs_wallet); int maxSortNumber = chainActive.Tip()->nHeight + 1; for (std::map::iterator it = mapWallet.begin(); it != mapWallet.end(); ++it) { CWalletTx* pwtx = &(it->second); - int confirms = pwtx->GetDepthInMainChain(); maxOrderPos = std::max(maxOrderPos, pwtx->nOrderPos); - if (confirms > 0) { - int wtxHeight = mapBlockIndex[pwtx->hashBlock]->nHeight; - auto key = std::make_pair(wtxHeight, pwtx->nIndex); - mapSorted.insert(make_pair(key, pwtx)); - } - else { + if (mapBlockIndex.count(pwtx->hashBlock) > 0) { + auto blockIndex = mapBlockIndex[pwtx->hashBlock]; + if (blockIndex) { + int wtxHeight = blockIndex->nHeight; + auto key = std::make_pair(wtxHeight, pwtx->nIndex); + mapSorted.insert(make_pair(key, pwtx)); + } else { + // handle null blockIndex + auto key = std::make_pair(maxSortNumber, 0); + mapSorted.insert(std::make_pair(key, pwtx)); + maxSortNumber++; + } + } else { auto key = std::make_pair(maxSortNumber, 0); mapSorted.insert(std::make_pair(key, pwtx)); maxSortNumber++; @@ -1803,7 +1842,8 @@ void CWallet::ReorderWalletTransactions(std::map, CWalletTx*> */ void CWallet::UpdateWalletTransactionOrder(std::map, CWalletTx*> &mapSorted, bool resetOrder) { - LOCK2(cs_main, cs_wallet); + AssertLockHeld(cs_main); + AssertLockHeld(cs_wallet); int64_t previousPosition = 0; std::map mapUpdatedTxs; @@ -1839,25 +1879,32 @@ void CWallet::UpdateWalletTransactionOrder(std::map, CWalletT nOrderPosNext = previousPosition++; CWalletDB(strWalletFile).WriteOrderPosNext(nOrderPosNext); LogPrint(BCLog::DELETETX,"Reorder Tx - Total Transactions Reordered %i, Next Position %i\n", mapUpdatedTxs.size(), nOrderPosNext); - } /** * Delete transactions from the Wallet */ -void CWallet::DeleteTransactions(std::vector &removeTxs) +bool CWallet::DeleteTransactions(std::vector &removeTxs, bool fRescan) { - LOCK(cs_wallet); + AssertLockHeld(cs_wallet); + + bool removingTransactions = false; + if (removeTxs.size() > 0) { + removingTransactions = true; + } CWalletDB walletdb(strWalletFile, "r+", false); - for (int i = 0; i< removeTxs.size(); i++) { - if (mapWallet.erase(removeTxs[i])) { - walletdb.EraseTx(removeTxs[i]); + for (int i = 0; i < removeTxs.size(); i++) { + bool fRemoveFromSpends = !(mapWallet.at(removeTxs[i]).IsCoinBase()); + if (EraseFromWallet(removeTxs[i])) { + if (fRemoveFromSpends) { + RemoveFromSpends(removeTxs[i]); + } LogPrint(BCLog::DELETETX,"DeleteTx - Deleting tx %s, %i.\n", removeTxs[i].ToString(),i); } else { - LogPrint(BCLog::DELETETX,"DeleteTx - Deleting tx %failed.\n", removeTxs[i].ToString()); - return; + LogPrint(BCLog::DELETETX,"DeleteTx - Deleting tx %s failed.\n", removeTxs[i].ToString()); + return false; } } @@ -1865,18 +1912,21 @@ void CWallet::DeleteTransactions(std::vector &removeTxs) #ifdef __linux__ malloc_trim(0); #endif + + return removingTransactions; } -void CWallet::DeleteWalletTransactions(const CBlockIndex* pindex) +bool CWallet::DeleteWalletTransactions(const CBlockIndex* pindex, bool fRescan) { - LOCK2(cs_main, cs_wallet); + AssertLockHeld(cs_main); + AssertLockHeld(cs_wallet); int nDeleteAfter = (int)fDeleteTransactionsAfterNBlocks; bool runCompact = false; + bool deletedTransactions = false; auto startTime = GetTime(); if (pindex && fTxDeleteEnabled) { - //Check for acentries - exit function if found { std::list acentries; @@ -1884,7 +1934,7 @@ void CWallet::DeleteWalletTransactions(const CBlockIndex* pindex) walletdb.ListAccountCreditDebit("*", acentries); if (acentries.size() > 0) { LogPrintf("deletetx not compatible to account entries\n"); - return; + return false; } } //delete transactions @@ -1996,7 +2046,7 @@ void CWallet::DeleteWalletTransactions(const CBlockIndex* pindex) LogPrint(BCLog::DELETETX,"DeleteTx - Time to Select %s\n", DateTimeStrFormat("%H:%M:%S", selectTime - reorderTime)); //Delete Transactions from wallet - DeleteTransactions(removeTxs); + deletedTransactions = DeleteTransactions(removeTxs, fRescan); auto deleteTime = GetTime(); LogPrint(BCLog::DELETETX,"DeleteTx - Time to Delete %s\n", DateTimeStrFormat("%H:%M:%S", deleteTime - selectTime)); @@ -2009,6 +2059,8 @@ void CWallet::DeleteWalletTransactions(const CBlockIndex* pindex) auto totalTime = GetTime(); LogPrint(BCLog::DELETETX,"DeleteTx - Time to Run Total Function %s\n", DateTimeStrFormat("%H:%M:%S", totalTime - startTime)); } + + return deletedTransactions; } /** @@ -2051,6 +2103,11 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate, b if (AddToWalletIfInvolvingMe(tx, &block, fUpdate)) ret++; } + + //Delete Transactions + if (pindex->nHeight % fDeleteInterval == 0) + while(DeleteWalletTransactions(pindex, true)) {} + pindex = chainActive.Next(pindex); if (GetTime() >= nNow + 60) { nNow = GetTime(); @@ -2062,6 +2119,8 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate, b } } ShowProgress(_("Rescanning... Please do not interrupt this process as it could lead to a corrupt wallet."), 100); // hide progress dialog in GUI + //Delete transactions + while(DeleteWalletTransactions(chainActive.Tip(), true)) {} } return ret; } @@ -2436,6 +2495,7 @@ bool CWallet::AvailableCoins( if (IsLocked()) return false; vCoins.clear(); const bool fCoinsSelected = (coinControl != nullptr) && coinControl->HasSelected(); + const CAmount collateralAmount = Params().MNCollateralAmt(); { LOCK2(cs_main, cs_wallet); @@ -2455,7 +2515,7 @@ bool CWallet::AvailableCoins( bool found = false; CAmount value = getCTxOutValue(*pcoin, pcoin->vout[i]); if (nCoinType == ONLY_5000) { - found = value == Params().MNCollateralAmt(); + found = value == collateralAmount; } else { COutPoint outpoint(pcoin->GetHash(), i); if (IsCollateralized(outpoint)) { @@ -2568,6 +2628,9 @@ bool CWallet::SelectStakeCoins(std::list >& listInp std::vector vCoins; AvailableCoins(vCoins, true, NULL, false, STAKABLE_COINS); CAmount nAmountSelected = 0; + const CAmount collateralAmount = Params().MNCollateralAmt(); + const CAmount minStakingAmount = Params().MinimumStakeAmount(); + if (GetBoolArg("-prcystake", true)) { for (const COutput &out : vCoins) { //make sure not to outrun target amount @@ -2576,11 +2639,11 @@ bool CWallet::SelectStakeCoins(std::list >& listInp continue; //check that it is above Minimum Stake Amount - if (value < Params().MinimumStakeAmount()) + if (value < minStakingAmount) continue; //check that it is not MN Collateral - if (value == Params().MNCollateralAmt()) { + if (value == collateralAmount) { COutPoint outpoint(out.tx->GetHash(), out.i); if (IsCollateralized(outpoint)) { continue; @@ -2611,6 +2674,8 @@ bool CWallet::SelectStakeCoins(std::list >& listInp bool CWallet::MintableCoins() { CAmount nBalance = GetBalance(); + const CAmount collateralAmount = Params().MNCollateralAmt(); + const CAmount minStakingAmount = Params().MinimumStakeAmount(); // Regular PRCY if (nBalance > 0) { @@ -2630,7 +2695,7 @@ bool CWallet::MintableCoins() //check that it is not MN Collateral bool isCollateral = false; - if (nVal == Params().MNCollateralAmt()) { + if (nVal == collateralAmount) { COutPoint outpoint(out.tx->GetHash(), out.i); if (IsCollateralized(outpoint)) { isCollateral = true; @@ -2638,7 +2703,7 @@ bool CWallet::MintableCoins() } //nTxTime <= nTime: only stake with UTXOs that are received before nTime time - if (Params().IsRegTestNet() || (GetAdjustedTime() > Params().StakeMinAge() + nTxTime && nVal >= Params().MinimumStakeAmount() && !isCollateral)) + if (Params().IsRegTestNet() || (GetAdjustedTime() > Params().StakeMinAge() + nTxTime && nVal >= minStakingAmount && !isCollateral)) return true; } } @@ -2652,7 +2717,9 @@ StakingStatusError CWallet::StakingCoinStatus(CAmount& minFee, CAmount& maxFee) maxFee = 0; SetRingSize(0); CAmount nBalance = GetBalance(); + const CAmount collateralAmount = Params().MNCollateralAmt(); const CAmount minStakingAmount = Params().MinimumStakeAmount(); + if (IsMasternodeController()) { nBalance = GetSpendableBalance(); } @@ -2695,7 +2762,7 @@ StakingStatusError CWallet::StakingCoinStatus(CAmount& minFee, CAmount& maxFee) continue; } CAmount value = getCTxOutValue(*pcoin, pcoin->vout[i]); - if (value == Params().MNCollateralAmt()) { + if (value == collateralAmount) { COutPoint outpoint(wtxid, i); if (IsCollateralized(outpoint)) { continue; @@ -2810,7 +2877,9 @@ bool CWallet::SelectCoinsMinConf(bool needFee, CAmount& feeNeeded, int ringSize, CAmount nTotalLower = 0; std::string s = ""; - random_shuffle(vCoins.begin(), vCoins.end(), GetRandInt); + std::random_device rd; + std::mt19937 g(rd()); + std::shuffle(vCoins.begin(), vCoins.end(), g); for (const COutput& output : vCoins) { if (!output.fSpendable) @@ -3174,7 +3243,7 @@ bool CWallet::CreateTransactionBulletProof(const CKey& txPrivDes, const CPubKey& CPubKey sharedSec; ECDHInfo::ComputeSharedSec(txPrivDes, recipientViewKey, sharedSec); EncodeTxOutAmount(txout, txout.nValue, sharedSec.begin()); - txNew.vout.push_back(txout); + txNew.vout.emplace_back(txout); nBytes += ::GetSerializeSize(*(CTxOut*)&txout, SER_NETWORK, PROTOCOL_VERSION); } @@ -3357,7 +3426,7 @@ bool CWallet::CreateTransaction(const std::vector >& strFailReason = _("Transaction amount too small"); return false; } - txNew.vout.push_back(txout); + txNew.vout.emplace_back(txout); } } else //UTXO Splitter Transaction { @@ -5342,7 +5411,7 @@ bool CWallet::SendAll(std::string des, CWalletTx& wtxNew, bool inclLocked) CPubKey sharedSec; ECDHInfo::ComputeSharedSec(wtxNew.txPrivM, pubViewKey, sharedSec); EncodeTxOutAmount(txout, txout.nValue, sharedSec.begin()); - txNew.vout.push_back(txout); + txNew.vout.emplace_back(txout); txNew.nTxFee = nFeeNeeded; //Fill vin @@ -5603,7 +5672,7 @@ bool CWallet::CreateSweepingTransaction(CAmount target, CAmount threshold, uint3 CPubKey sharedSec; ECDHInfo::ComputeSharedSec(wtxNew.txPrivM, pubViewKey, sharedSec); EncodeTxOutAmount(txout, txout.nValue, sharedSec.begin()); - txNew.vout.push_back(txout); + txNew.vout.emplace_back(txout); //nBytes += ::GetSerializeSize(*(CTxOut*)&txout, SER_NETWORK, PROTOCOL_VERSION); txNew.nTxFee = nFeeNeeded; diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index b8baefca2f..7b585a2df0 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -268,6 +268,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface TxSpends mapTxSpends; void AddToSpends(const COutPoint& outpoint, const uint256& wtxid); void AddToSpends(const uint256& wtxid); + void RemoveFromSpends(const uint256& wtxid); void SyncMetaData(std::pair); @@ -476,11 +477,11 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface bool AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletDB* pwalletdb); void SyncTransaction(const CTransaction& tx, const CBlock* pblock); bool AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate); - void EraseFromWallet(const uint256& hash); + bool EraseFromWallet(const uint256& hash); void ReorderWalletTransactions(std::map, CWalletTx*> &mapSorted, int64_t &maxOrderPos); void UpdateWalletTransactionOrder(std::map, CWalletTx*> &mapSorted, bool resetOrder); - void DeleteTransactions(std::vector &removeTxs); - void DeleteWalletTransactions(const CBlockIndex* pindex); + bool DeleteTransactions(std::vector &removeTxs, bool fRescan = false); + bool DeleteWalletTransactions(const CBlockIndex* pindex, bool fRescan = false); int ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false, bool fromStartup = false, int height = -1); void ReacceptWalletTransactions(); void ResendWalletTransactions(); diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 8d79aae0d1..b4909bfa84 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -17,7 +17,6 @@ #include "wallet/wallet.h" #include -#include #include #include @@ -463,6 +462,69 @@ void CWalletDB::ListAccountCreditDebit(const std::string& strAccount, std::list< pcursor->close(); } +DBErrors CWalletDB::ReorderTransactions(CWallet* pwallet) +{ + LOCK(pwallet->cs_wallet); + // Old wallets didn't have any defined order for transactions + // Probably a bad idea to change the output of this + + // First: get all CWalletTx and CAccountingEntry into a sorted-by-time multimap. + typedef std::pair TxPair; + typedef std::multimap TxItems; + TxItems txByTime; + + for (std::map::iterator it = pwallet->mapWallet.begin(); it != pwallet->mapWallet.end(); ++it) { + CWalletTx* wtx = &((*it).second); + txByTime.insert(std::make_pair(wtx->nTimeReceived, TxPair(wtx, (CAccountingEntry*)0))); + } + std::list acentries; + ListAccountCreditDebit("", acentries); + for (CAccountingEntry& entry : acentries) { + txByTime.insert(std::make_pair(entry.nTime, TxPair((CWalletTx*)0, &entry))); + } + + int64_t& nOrderPosNext = pwallet->nOrderPosNext; + nOrderPosNext = 0; + std::vector nOrderPosOffsets; + for (TxItems::iterator it = txByTime.begin(); it != txByTime.end(); ++it) { + CWalletTx* const pwtx = (*it).second.first; + CAccountingEntry* const pacentry = (*it).second.second; + int64_t& nOrderPos = (pwtx != 0) ? pwtx->nOrderPos : pacentry->nOrderPos; + + if (nOrderPos == -1) { + nOrderPos = nOrderPosNext++; + nOrderPosOffsets.push_back(nOrderPos); + + if (pwtx) { + if (!WriteTx(pwtx->GetHash(), *pwtx)) + return DB_LOAD_FAIL; + } else if (!WriteAccountingEntry(pacentry->nEntryNo, *pacentry)) + return DB_LOAD_FAIL; + } else { + int64_t nOrderPosOff = 0; + for (const int64_t& nOffsetStart : nOrderPosOffsets) { + if (nOrderPos >= nOffsetStart) + ++nOrderPosOff; + } + nOrderPos += nOrderPosOff; + nOrderPosNext = std::max(nOrderPosNext, nOrderPos + 1); + + if (!nOrderPosOff) + continue; + + // Since we're changing the order, write it back + if (pwtx) { + if (!WriteTx(pwtx->GetHash(), *pwtx)) + return DB_LOAD_FAIL; + } else if (!WriteAccountingEntry(pacentry->nEntryNo, *pacentry)) + return DB_LOAD_FAIL; + } + } + WriteOrderPosNext(nOrderPosNext); + + return DB_LOAD_OK; +} + class CWalletScanState { public: @@ -1153,7 +1215,7 @@ bool CWalletDB::Recover(CDBEnv& dbenv, std::string filename, bool fOnlyKeys) LogPrintf("Salvage(aggressive) found %u records\n", salvagedData.size()); bool fSuccess = allOK; - boost::scoped_ptr pdbCopy(new Db(dbenv.dbenv, 0)); + std::unique_ptr pdbCopy(new Db(dbenv.dbenv, 0)); int ret = pdbCopy->open(NULL, // Txn pointer filename.c_str(), // Filename "main", // Logical db name diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index 8d0325cb4b..a60d76b7ab 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -179,6 +179,7 @@ class CWalletDB : public CDB CAmount GetAccountCreditDebit(const std::string& strAccount); void ListAccountCreditDebit(const std::string& strAccount, std::list& acentries); + DBErrors ReorderTransactions(CWallet* pwallet); DBErrors LoadWallet(CWallet* pwallet); DBErrors FindWalletTx(CWallet* pwallet, std::vector& vTxHash, std::vector& vWtx); DBErrors ZapWalletTx(CWallet* pwallet, std::vector& vWtx); diff --git a/version.txt b/version.txt deleted file mode 100644 index df5bd0ff56..0000000000 --- a/version.txt +++ /dev/null @@ -1 +0,0 @@ -2.0.0.6