mirror of
				https://github.com/Xahau/xahaud.git
				synced 2025-11-04 10:45:50 +00:00 
			
		
		
		
	Merge remote-tracking branch 'origin/dev' into nd-add-colored-file-2025-07-25
# Conflicts: # src/test/unit_test/SuiteJournal.h
This commit is contained in:
		@@ -14,6 +14,18 @@ inputs:
 | 
			
		||||
    description: 'How to check compiler for changes'
 | 
			
		||||
    required: false
 | 
			
		||||
    default: 'content'
 | 
			
		||||
  is_main_branch:
 | 
			
		||||
    description: 'Whether the current branch is the main branch'
 | 
			
		||||
    required: false
 | 
			
		||||
    default: 'false'
 | 
			
		||||
  main_cache_dir:
 | 
			
		||||
    description: 'Path to the main branch cache directory'
 | 
			
		||||
    required: false
 | 
			
		||||
    default: '~/.ccache-main'
 | 
			
		||||
  current_cache_dir:
 | 
			
		||||
    description: 'Path to the current branch cache directory'
 | 
			
		||||
    required: false
 | 
			
		||||
    default: '~/.ccache-current'
 | 
			
		||||
 | 
			
		||||
runs:
 | 
			
		||||
  using: 'composite'
 | 
			
		||||
@@ -21,11 +33,31 @@ runs:
 | 
			
		||||
    - name: Configure ccache
 | 
			
		||||
      shell: bash
 | 
			
		||||
      run: |
 | 
			
		||||
        # Create cache directories
 | 
			
		||||
        mkdir -p ${{ inputs.main_cache_dir }} ${{ inputs.current_cache_dir }}
 | 
			
		||||
        
 | 
			
		||||
        # Set compiler check globally
 | 
			
		||||
        ccache -o compiler_check=${{ inputs.compiler_check }}
 | 
			
		||||
        
 | 
			
		||||
        # Use a single config file location
 | 
			
		||||
        mkdir -p ~/.ccache
 | 
			
		||||
        export CONF_PATH="${CCACHE_CONFIGPATH:-${CCACHE_DIR:-$HOME/.ccache}/ccache.conf}"
 | 
			
		||||
        mkdir -p $(dirname "$CONF_PATH")
 | 
			
		||||
        export CONF_PATH="$HOME/.ccache/ccache.conf"
 | 
			
		||||
        
 | 
			
		||||
        # Apply common settings
 | 
			
		||||
        echo "max_size = ${{ inputs.max_size }}" > "$CONF_PATH"
 | 
			
		||||
        echo "hash_dir = ${{ inputs.hash_dir }}" >> "$CONF_PATH"
 | 
			
		||||
        echo "compiler_check = ${{ inputs.compiler_check }}" >> "$CONF_PATH"
 | 
			
		||||
        
 | 
			
		||||
        if [ "${{ inputs.is_main_branch }}" == "true" ]; then
 | 
			
		||||
          # Main branch: use main branch cache
 | 
			
		||||
          ccache --set-config=cache_dir="${{ inputs.main_cache_dir }}"
 | 
			
		||||
          echo "CCACHE_DIR=${{ inputs.main_cache_dir }}" >> $GITHUB_ENV
 | 
			
		||||
        else
 | 
			
		||||
          # Feature branch: use current branch cache with main as secondary
 | 
			
		||||
          ccache --set-config=cache_dir="${{ inputs.current_cache_dir }}"
 | 
			
		||||
          ccache --set-config=secondary_storage="file:${{ inputs.main_cache_dir }}"
 | 
			
		||||
          echo "CCACHE_DIR=${{ inputs.current_cache_dir }}" >> $GITHUB_ENV
 | 
			
		||||
        fi
 | 
			
		||||
        
 | 
			
		||||
        ccache -p # Print config for verification
 | 
			
		||||
        ccache -z # Zero statistics before the build
 | 
			
		||||
							
								
								
									
										32
									
								
								.github/actions/xahau-ga-build/action.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										32
									
								
								.github/actions/xahau-ga-build/action.yml
									
									
									
									
										vendored
									
									
								
							@@ -48,18 +48,28 @@ runs:
 | 
			
		||||
        SAFE_BRANCH=$(echo "${{ github.ref_name }}" | tr -c 'a-zA-Z0-9_.-' '-')
 | 
			
		||||
        echo "name=${SAFE_BRANCH}" >> $GITHUB_OUTPUT
 | 
			
		||||
 | 
			
		||||
    - name: Restore ccache directory
 | 
			
		||||
    - name: Restore ccache directory for default branch
 | 
			
		||||
      if: inputs.ccache_enabled == 'true'
 | 
			
		||||
      id: ccache-restore
 | 
			
		||||
      uses: actions/cache/restore@v4
 | 
			
		||||
      with:
 | 
			
		||||
        path: ~/.ccache
 | 
			
		||||
        path: ~/.ccache-main
 | 
			
		||||
        key: ${{ runner.os }}-ccache-v${{ inputs.cache_version }}-${{ inputs.compiler-id }}-${{ inputs.configuration }}-${{ inputs.main_branch }}
 | 
			
		||||
        restore-keys: |
 | 
			
		||||
          ${{ runner.os }}-ccache-v${{ inputs.cache_version }}-${{ inputs.compiler-id }}-${{ inputs.configuration }}-
 | 
			
		||||
          ${{ runner.os }}-ccache-v${{ inputs.cache_version }}-${{ inputs.compiler-id }}-
 | 
			
		||||
 | 
			
		||||
    - name: Restore ccache directory for current branch
 | 
			
		||||
      if: inputs.ccache_enabled == 'true' && steps.safe-branch.outputs.name != inputs.main_branch
 | 
			
		||||
      id: ccache-restore-current-branch
 | 
			
		||||
      uses: actions/cache/restore@v4
 | 
			
		||||
      with:
 | 
			
		||||
        path: ~/.ccache-current
 | 
			
		||||
        key: ${{ runner.os }}-ccache-v${{ inputs.cache_version }}-${{ inputs.compiler-id }}-${{ inputs.configuration }}-${{ steps.safe-branch.outputs.name }}
 | 
			
		||||
        restore-keys: |
 | 
			
		||||
          ${{ runner.os }}-ccache-v${{ inputs.cache_version }}-${{ inputs.compiler-id }}-${{ inputs.configuration }}-${{ inputs.main_branch }}
 | 
			
		||||
          ${{ runner.os }}-ccache-v${{ inputs.cache_version }}-${{ inputs.compiler-id }}-${{ inputs.configuration }}-
 | 
			
		||||
          ${{ runner.os }}-ccache-v${{ inputs.cache_version }}-${{ inputs.compiler-id }}-
 | 
			
		||||
          ${{ runner.os }}-ccache-v${{ inputs.cache_version }}-
 | 
			
		||||
 | 
			
		||||
    - name: Configure project
 | 
			
		||||
      shell: bash
 | 
			
		||||
@@ -76,6 +86,7 @@ runs:
 | 
			
		||||
          export CXX="${{ inputs.cxx }}"
 | 
			
		||||
        fi
 | 
			
		||||
        
 | 
			
		||||
        
 | 
			
		||||
        # Configure ccache launcher args
 | 
			
		||||
        CCACHE_ARGS=""
 | 
			
		||||
        if [ "${{ inputs.ccache_enabled }}" = "true" ]; then
 | 
			
		||||
@@ -100,9 +111,16 @@ runs:
 | 
			
		||||
      shell: bash
 | 
			
		||||
      run: ccache -s
 | 
			
		||||
 | 
			
		||||
    - name: Save ccache directory
 | 
			
		||||
      if: inputs.ccache_enabled == 'true'
 | 
			
		||||
    - name: Save ccache directory for default branch
 | 
			
		||||
      if: always() && inputs.ccache_enabled == 'true' && steps.safe-branch.outputs.name == inputs.main_branch
 | 
			
		||||
      uses: actions/cache/save@v4
 | 
			
		||||
      with:
 | 
			
		||||
        path: ~/.ccache
 | 
			
		||||
        key: ${{ steps.ccache-restore.outputs.cache-primary-key }}
 | 
			
		||||
        path: ~/.ccache-main
 | 
			
		||||
        key: ${{ steps.ccache-restore.outputs.cache-primary-key }}
 | 
			
		||||
 | 
			
		||||
    - name: Save ccache directory for current branch
 | 
			
		||||
      if: always() && inputs.ccache_enabled == 'true' && steps.safe-branch.outputs.name != inputs.main_branch
 | 
			
		||||
      uses: actions/cache/save@v4
 | 
			
		||||
      with:
 | 
			
		||||
        path: ~/.ccache-current
 | 
			
		||||
        key: ${{ steps.ccache-restore-current-branch.outputs.cache-primary-key }}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										29
									
								
								.github/actions/xahau-ga-dependencies/action.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										29
									
								
								.github/actions/xahau-ga-dependencies/action.yml
									
									
									
									
										vendored
									
									
								
							@@ -42,6 +42,26 @@ runs:
 | 
			
		||||
        SAFE_BRANCH=$(echo "${{ github.ref_name }}" | tr -c 'a-zA-Z0-9_.-' '-')
 | 
			
		||||
        echo "name=${SAFE_BRANCH}" >> $GITHUB_OUTPUT
 | 
			
		||||
 | 
			
		||||
    - name: Check conanfile changes
 | 
			
		||||
      if: inputs.cache_enabled == 'true'
 | 
			
		||||
      id: check-conanfile-changes
 | 
			
		||||
      shell: bash
 | 
			
		||||
      run: |
 | 
			
		||||
        # Check if we're on the main branch
 | 
			
		||||
        if [ "${{ github.ref_name }}" == "${{ inputs.main_branch }}" ]; then
 | 
			
		||||
          echo "should-save-conan-cache=true" >> $GITHUB_OUTPUT
 | 
			
		||||
        else
 | 
			
		||||
          # Fetch main branch for comparison
 | 
			
		||||
          git fetch origin ${{ inputs.main_branch }}
 | 
			
		||||
          
 | 
			
		||||
          # Check if conanfile.txt or conanfile.py has changed compared to main branch
 | 
			
		||||
          if git diff --quiet origin/${{ inputs.main_branch }}..HEAD -- '**/conanfile.txt' '**/conanfile.py'; then
 | 
			
		||||
            echo "should-save-conan-cache=false" >> $GITHUB_OUTPUT
 | 
			
		||||
          else
 | 
			
		||||
            echo "should-save-conan-cache=true" >> $GITHUB_OUTPUT
 | 
			
		||||
          fi
 | 
			
		||||
        fi
 | 
			
		||||
 | 
			
		||||
    - name: Restore Conan cache
 | 
			
		||||
      if: inputs.cache_enabled == 'true'
 | 
			
		||||
      id: cache-restore-conan
 | 
			
		||||
@@ -54,13 +74,12 @@ runs:
 | 
			
		||||
        restore-keys: |
 | 
			
		||||
          ${{ runner.os }}-conan-v${{ inputs.cache_version }}-${{ inputs.compiler-id }}-${{ hashFiles('**/conanfile.txt', '**/conanfile.py') }}-
 | 
			
		||||
          ${{ runner.os }}-conan-v${{ inputs.cache_version }}-${{ inputs.compiler-id }}-
 | 
			
		||||
          ${{ runner.os }}-conan-v${{ inputs.cache_version }}-
 | 
			
		||||
 | 
			
		||||
    - name: Export custom recipes
 | 
			
		||||
      shell: bash
 | 
			
		||||
      run: |
 | 
			
		||||
        conan export external/snappy snappy/1.1.9@
 | 
			
		||||
        conan export external/soci soci/4.0.3@
 | 
			
		||||
        conan export external/snappy snappy/1.1.10@xahaud/stable
 | 
			
		||||
        conan export external/soci soci/4.0.3@xahaud/stable
 | 
			
		||||
 | 
			
		||||
    - name: Install dependencies
 | 
			
		||||
      shell: bash
 | 
			
		||||
@@ -77,10 +96,10 @@ runs:
 | 
			
		||||
          ..
 | 
			
		||||
 | 
			
		||||
    - name: Save Conan cache
 | 
			
		||||
      if: inputs.cache_enabled == 'true' && steps.cache-restore-conan.outputs.cache-hit != 'true'
 | 
			
		||||
      if: always() && inputs.cache_enabled == 'true' && steps.cache-restore-conan.outputs.cache-hit != 'true' && steps.check-conanfile-changes.outputs.should-save-conan-cache == 'true'
 | 
			
		||||
      uses: actions/cache/save@v4
 | 
			
		||||
      with:
 | 
			
		||||
        path: |
 | 
			
		||||
          ~/.conan
 | 
			
		||||
          ~/.conan2
 | 
			
		||||
        key: ${{ steps.cache-restore-conan.outputs.cache-primary-key }}
 | 
			
		||||
        key: ${{ steps.cache-restore-conan.outputs.cache-primary-key }}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										12
									
								
								.github/workflows/build-in-docker.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								.github/workflows/build-in-docker.yml
									
									
									
									
										vendored
									
									
								
							@@ -32,19 +32,9 @@ jobs:
 | 
			
		||||
          clean: true
 | 
			
		||||
          fetch-depth: 2 # Only get the last 2 commits, to avoid fetching all history
 | 
			
		||||
 | 
			
		||||
  checkpatterns:
 | 
			
		||||
    runs-on: [self-hosted, vanity]
 | 
			
		||||
    needs: checkout
 | 
			
		||||
    defaults:
 | 
			
		||||
      run:
 | 
			
		||||
        working-directory: ${{ needs.checkout.outputs.checkout_path }}
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: Check for suspicious patterns
 | 
			
		||||
        run: /bin/bash suspicious_patterns.sh
 | 
			
		||||
 | 
			
		||||
  build:
 | 
			
		||||
    runs-on: [self-hosted, vanity]
 | 
			
		||||
    needs: [checkpatterns, checkout]
 | 
			
		||||
    needs: [checkout]
 | 
			
		||||
    defaults:
 | 
			
		||||
      run:
 | 
			
		||||
        working-directory: ${{ needs.checkout.outputs.checkout_path }}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										5
									
								
								.github/workflows/xahau-ga-macos.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								.github/workflows/xahau-ga-macos.yml
									
									
									
									
										vendored
									
									
								
							@@ -5,6 +5,8 @@ on:
 | 
			
		||||
    branches: ["dev", "candidate", "release"]
 | 
			
		||||
  pull_request:
 | 
			
		||||
    branches: ["dev", "candidate", "release"]
 | 
			
		||||
  schedule:
 | 
			
		||||
    - cron: '0 0 * * *'
 | 
			
		||||
 | 
			
		||||
concurrency:
 | 
			
		||||
  group: ${{ github.workflow }}-${{ github.ref }}
 | 
			
		||||
@@ -74,6 +76,7 @@ jobs:
 | 
			
		||||
          max_size: 2G
 | 
			
		||||
          hash_dir: true
 | 
			
		||||
          compiler_check: content
 | 
			
		||||
          is_main_branch: ${{ github.ref_name == env.MAIN_BRANCH_NAME }}
 | 
			
		||||
 | 
			
		||||
      - name: Check environment
 | 
			
		||||
        run: |
 | 
			
		||||
@@ -113,4 +116,4 @@ jobs:
 | 
			
		||||
 | 
			
		||||
      - name: Test
 | 
			
		||||
        run: |
 | 
			
		||||
          ${{ env.build_dir }}/rippled --unittest --unittest-jobs $(nproc)
 | 
			
		||||
          ${{ env.build_dir }}/rippled --unittest --unittest-jobs $(nproc)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										22
									
								
								.github/workflows/xahau-ga-nix.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										22
									
								
								.github/workflows/xahau-ga-nix.yml
									
									
									
									
										vendored
									
									
								
							@@ -5,6 +5,8 @@ on:
 | 
			
		||||
    branches: ["dev", "candidate", "release"]
 | 
			
		||||
  pull_request:
 | 
			
		||||
    branches: ["dev", "candidate", "release"]
 | 
			
		||||
  schedule:
 | 
			
		||||
    - cron: '0 0 * * *'
 | 
			
		||||
 | 
			
		||||
concurrency:
 | 
			
		||||
  group: ${{ github.workflow }}-${{ github.ref }}
 | 
			
		||||
@@ -22,13 +24,14 @@ jobs:
 | 
			
		||||
        configuration: [Debug]
 | 
			
		||||
        include:
 | 
			
		||||
          - compiler: gcc
 | 
			
		||||
            cc: gcc-11
 | 
			
		||||
            cxx: g++-11
 | 
			
		||||
            compiler_id: gcc-11
 | 
			
		||||
            cc: gcc-13
 | 
			
		||||
            cxx: g++-13
 | 
			
		||||
            compiler_id: gcc-13
 | 
			
		||||
            compiler_version: 13
 | 
			
		||||
    env:
 | 
			
		||||
      build_dir: .build
 | 
			
		||||
      # Bump this number to invalidate all caches globally.
 | 
			
		||||
      CACHE_VERSION: 1
 | 
			
		||||
      CACHE_VERSION: 2
 | 
			
		||||
      MAIN_BRANCH_NAME: dev
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: Checkout
 | 
			
		||||
@@ -47,6 +50,7 @@ jobs:
 | 
			
		||||
          max_size: 2G
 | 
			
		||||
          hash_dir: true
 | 
			
		||||
          compiler_check: content
 | 
			
		||||
          is_main_branch: ${{ github.ref_name == env.MAIN_BRANCH_NAME }}
 | 
			
		||||
 | 
			
		||||
      - name: Configure Conan
 | 
			
		||||
        run: |
 | 
			
		||||
@@ -58,12 +62,8 @@ jobs:
 | 
			
		||||
          conan profile update env.CXX=/usr/bin/${{ matrix.cxx }} default
 | 
			
		||||
          conan profile update conf.tools.build:compiler_executables='{"c": "/usr/bin/${{ matrix.cc }}", "cpp": "/usr/bin/${{ matrix.cxx }}"}' default
 | 
			
		||||
 | 
			
		||||
          # Set correct compiler version based on matrix.compiler
 | 
			
		||||
          if [ "${{ matrix.compiler }}" = "gcc" ]; then
 | 
			
		||||
            conan profile update settings.compiler.version=11 default
 | 
			
		||||
          elif [ "${{ matrix.compiler }}" = "clang" ]; then
 | 
			
		||||
            conan profile update settings.compiler.version=14 default
 | 
			
		||||
          fi
 | 
			
		||||
          # Set compiler version from matrix
 | 
			
		||||
          conan profile update settings.compiler.version=${{ matrix.compiler_version }} default
 | 
			
		||||
          # Display profile for verification
 | 
			
		||||
          conan profile show default
 | 
			
		||||
 | 
			
		||||
@@ -120,4 +120,4 @@ jobs:
 | 
			
		||||
          else
 | 
			
		||||
             echo "Error: rippled executable not found in ${{ env.build_dir }}"
 | 
			
		||||
             exit 1
 | 
			
		||||
          fi
 | 
			
		||||
          fi
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										5
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -24,6 +24,11 @@ bin/project-cache.jam
 | 
			
		||||
 | 
			
		||||
build/docker
 | 
			
		||||
 | 
			
		||||
# Ignore release builder files
 | 
			
		||||
.env
 | 
			
		||||
release-build
 | 
			
		||||
cmake-*.tar.gz
 | 
			
		||||
 | 
			
		||||
# Ignore object files.
 | 
			
		||||
*.o
 | 
			
		||||
build
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								BUILD.md
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								BUILD.md
									
									
									
									
									
								
							@@ -117,14 +117,14 @@ can't build earlier Boost versions.
 | 
			
		||||
   which allows you to statically link it with GCC, if you want.
 | 
			
		||||
 | 
			
		||||
   ```
 | 
			
		||||
   conan export external/snappy snappy/1.1.9@
 | 
			
		||||
   conan export external/snappy snappy/1.1.10@xahaud/stable
 | 
			
		||||
   ```
 | 
			
		||||
 | 
			
		||||
5. Export our [Conan recipe for SOCI](./external/soci).
 | 
			
		||||
   It patches their CMake to correctly import its dependencies.
 | 
			
		||||
 | 
			
		||||
   ```
 | 
			
		||||
   conan export external/soci soci/4.0.3@
 | 
			
		||||
   conan export external/soci soci/4.0.3@xahaud/stable
 | 
			
		||||
   ```
 | 
			
		||||
 | 
			
		||||
### Build and Test
 | 
			
		||||
 
 | 
			
		||||
@@ -561,7 +561,6 @@ target_sources (rippled PRIVATE
 | 
			
		||||
  src/ripple/nodestore/backend/CassandraFactory.cpp
 | 
			
		||||
  src/ripple/nodestore/backend/RWDBFactory.cpp
 | 
			
		||||
  src/ripple/nodestore/backend/MemoryFactory.cpp
 | 
			
		||||
  src/ripple/nodestore/backend/FlatmapFactory.cpp
 | 
			
		||||
  src/ripple/nodestore/backend/NuDBFactory.cpp
 | 
			
		||||
  src/ripple/nodestore/backend/NullFactory.cpp
 | 
			
		||||
  src/ripple/nodestore/backend/RocksDBFactory.cpp
 | 
			
		||||
@@ -1008,6 +1007,11 @@ if (tests)
 | 
			
		||||
         subdir: resource
 | 
			
		||||
    #]===============================]
 | 
			
		||||
    src/test/resource/Logic_test.cpp
 | 
			
		||||
    #[===============================[
 | 
			
		||||
       test sources:
 | 
			
		||||
         subdir: rdb
 | 
			
		||||
    #]===============================]
 | 
			
		||||
    src/test/rdb/RelationalDatabase_test.cpp
 | 
			
		||||
    #[===============================[
 | 
			
		||||
       test sources:
 | 
			
		||||
         subdir: rpc
 | 
			
		||||
@@ -1081,6 +1085,11 @@ target_link_libraries (rippled
 | 
			
		||||
  Ripple::opts
 | 
			
		||||
  Ripple::libs
 | 
			
		||||
  Ripple::xrpl_core
 | 
			
		||||
  # Workaround for a Conan 1.x bug that prevents static linking of libstdc++
 | 
			
		||||
  # when a dependency (snappy) modifies system_libs. See the comment in
 | 
			
		||||
  # external/snappy/conanfile.py for a full explanation.
 | 
			
		||||
  # This is likely not strictly necessary, but listed explicitly as a good practice.
 | 
			
		||||
  m
 | 
			
		||||
  )
 | 
			
		||||
exclude_if_included (rippled)
 | 
			
		||||
# define a macro for tests that might need to
 | 
			
		||||
 
 | 
			
		||||
@@ -1,33 +0,0 @@
 | 
			
		||||
#[===================================================================[
 | 
			
		||||
   NIH prefix path..this is where we will download
 | 
			
		||||
   and build any ExternalProjects, and they will hopefully
 | 
			
		||||
   survive across build directory deletion (manual cleans)
 | 
			
		||||
#]===================================================================]
 | 
			
		||||
 | 
			
		||||
string (REGEX REPLACE "[ \\/%]+" "_" gen_for_path ${CMAKE_GENERATOR})
 | 
			
		||||
string (TOLOWER ${gen_for_path} gen_for_path)
 | 
			
		||||
# HACK: trying to shorten paths for windows CI (which hits 260 MAXPATH easily)
 | 
			
		||||
# @see:  https://issues.jenkins-ci.org/browse/JENKINS-38706?focusedCommentId=339847
 | 
			
		||||
string (REPLACE "visual_studio" "vs" gen_for_path ${gen_for_path})
 | 
			
		||||
if (NOT DEFINED NIH_CACHE_ROOT)
 | 
			
		||||
  if (DEFINED ENV{NIH_CACHE_ROOT})
 | 
			
		||||
    set (NIH_CACHE_ROOT $ENV{NIH_CACHE_ROOT})
 | 
			
		||||
  else ()
 | 
			
		||||
    set (NIH_CACHE_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/.nih_c")
 | 
			
		||||
  endif ()
 | 
			
		||||
endif ()
 | 
			
		||||
set (nih_cache_path
 | 
			
		||||
  "${NIH_CACHE_ROOT}/${gen_for_path}/${CMAKE_CXX_COMPILER_ID}_${CMAKE_CXX_COMPILER_VERSION}")
 | 
			
		||||
if (NOT is_multiconfig)
 | 
			
		||||
  set (nih_cache_path "${nih_cache_path}/${CMAKE_BUILD_TYPE}")
 | 
			
		||||
endif ()
 | 
			
		||||
file(TO_CMAKE_PATH "${nih_cache_path}" nih_cache_path)
 | 
			
		||||
message (STATUS "NIH-EP cache path: ${nih_cache_path}")
 | 
			
		||||
## two convenience variables:
 | 
			
		||||
set (ep_lib_prefix ${CMAKE_STATIC_LIBRARY_PREFIX})
 | 
			
		||||
set (ep_lib_suffix ${CMAKE_STATIC_LIBRARY_SUFFIX})
 | 
			
		||||
 | 
			
		||||
# this is a setting for FetchContent and needs to be
 | 
			
		||||
# a cache variable
 | 
			
		||||
# https://cmake.org/cmake/help/latest/module/FetchContent.html#populating-the-content
 | 
			
		||||
set (FETCHCONTENT_BASE_DIR ${nih_cache_path} CACHE STRING "" FORCE)
 | 
			
		||||
@@ -1,52 +0,0 @@
 | 
			
		||||
find_package(Boost 1.83 REQUIRED
 | 
			
		||||
  COMPONENTS
 | 
			
		||||
    chrono
 | 
			
		||||
    container
 | 
			
		||||
    context
 | 
			
		||||
    coroutine
 | 
			
		||||
    date_time
 | 
			
		||||
    filesystem
 | 
			
		||||
    program_options
 | 
			
		||||
    regex
 | 
			
		||||
    system
 | 
			
		||||
    thread
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
add_library(ripple_boost INTERFACE)
 | 
			
		||||
add_library(Ripple::boost ALIAS ripple_boost)
 | 
			
		||||
if(XCODE)
 | 
			
		||||
  target_include_directories(ripple_boost BEFORE INTERFACE ${Boost_INCLUDE_DIRS})
 | 
			
		||||
  target_compile_options(ripple_boost INTERFACE --system-header-prefix="boost/")
 | 
			
		||||
else()
 | 
			
		||||
  target_include_directories(ripple_boost SYSTEM BEFORE INTERFACE ${Boost_INCLUDE_DIRS})
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
target_link_libraries(ripple_boost
 | 
			
		||||
  INTERFACE
 | 
			
		||||
    Boost::boost
 | 
			
		||||
    Boost::chrono
 | 
			
		||||
    Boost::container
 | 
			
		||||
    Boost::coroutine
 | 
			
		||||
    Boost::date_time
 | 
			
		||||
    Boost::filesystem
 | 
			
		||||
    Boost::program_options
 | 
			
		||||
    Boost::regex
 | 
			
		||||
    Boost::system
 | 
			
		||||
    Boost::iostreams
 | 
			
		||||
    Boost::thread)
 | 
			
		||||
if(Boost_COMPILER)
 | 
			
		||||
  target_link_libraries(ripple_boost INTERFACE Boost::disable_autolinking)
 | 
			
		||||
endif()
 | 
			
		||||
if(san AND is_clang)
 | 
			
		||||
  # TODO: gcc does not support -fsanitize-blacklist...can we do something else
 | 
			
		||||
  # for gcc ?
 | 
			
		||||
  if(NOT Boost_INCLUDE_DIRS AND TARGET Boost::headers)
 | 
			
		||||
    get_target_property(Boost_INCLUDE_DIRS Boost::headers INTERFACE_INCLUDE_DIRECTORIES)
 | 
			
		||||
  endif()
 | 
			
		||||
  message(STATUS "Adding [${Boost_INCLUDE_DIRS}] to sanitizer blacklist")
 | 
			
		||||
  file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/san_bl.txt "src:${Boost_INCLUDE_DIRS}/*")
 | 
			
		||||
  target_compile_options(opts
 | 
			
		||||
    INTERFACE
 | 
			
		||||
      # ignore boost headers for sanitizing
 | 
			
		||||
      -fsanitize-blacklist=${CMAKE_CURRENT_BINARY_DIR}/san_bl.txt)
 | 
			
		||||
endif()
 | 
			
		||||
@@ -1,22 +0,0 @@
 | 
			
		||||
find_package(Protobuf 3.8)
 | 
			
		||||
 | 
			
		||||
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/proto_gen)
 | 
			
		||||
set(ccbd ${CMAKE_CURRENT_BINARY_DIR})
 | 
			
		||||
set(CMAKE_CURRENT_BINARY_DIR ${CMAKE_BINARY_DIR}/proto_gen)
 | 
			
		||||
protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS src/ripple/proto/ripple.proto)
 | 
			
		||||
set(CMAKE_CURRENT_BINARY_DIR ${ccbd})
 | 
			
		||||
 | 
			
		||||
add_library(pbufs STATIC ${PROTO_SRCS} ${PROTO_HDRS})
 | 
			
		||||
target_include_directories(pbufs SYSTEM PUBLIC
 | 
			
		||||
  ${CMAKE_BINARY_DIR}/proto_gen
 | 
			
		||||
  ${CMAKE_BINARY_DIR}/proto_gen/src/ripple/proto
 | 
			
		||||
)
 | 
			
		||||
target_link_libraries(pbufs protobuf::libprotobuf)
 | 
			
		||||
target_compile_options(pbufs
 | 
			
		||||
  PUBLIC
 | 
			
		||||
    $<$<BOOL:${XCODE}>:
 | 
			
		||||
      --system-header-prefix="google/protobuf"
 | 
			
		||||
      -Wno-deprecated-dynamic-exception-spec
 | 
			
		||||
    >
 | 
			
		||||
)
 | 
			
		||||
add_library(Ripple::pbufs ALIAS pbufs)
 | 
			
		||||
@@ -1,62 +0,0 @@
 | 
			
		||||
find_package(gRPC 1.23)
 | 
			
		||||
 | 
			
		||||
#[=================================[
 | 
			
		||||
   generate protobuf sources for
 | 
			
		||||
   grpc defs and bundle into a
 | 
			
		||||
   static lib
 | 
			
		||||
#]=================================]
 | 
			
		||||
set(GRPC_GEN_DIR "${CMAKE_BINARY_DIR}/proto_gen_grpc")
 | 
			
		||||
file(MAKE_DIRECTORY ${GRPC_GEN_DIR})
 | 
			
		||||
set(GRPC_PROTO_SRCS)
 | 
			
		||||
set(GRPC_PROTO_HDRS)
 | 
			
		||||
set(GRPC_PROTO_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/src/ripple/proto/org")
 | 
			
		||||
file(GLOB_RECURSE GRPC_DEFINITION_FILES LIST_DIRECTORIES false "${GRPC_PROTO_ROOT}/*.proto")
 | 
			
		||||
foreach(file ${GRPC_DEFINITION_FILES})
 | 
			
		||||
  get_filename_component(_abs_file ${file} ABSOLUTE)
 | 
			
		||||
  get_filename_component(_abs_dir ${_abs_file} DIRECTORY)
 | 
			
		||||
  get_filename_component(_basename ${file} NAME_WE)
 | 
			
		||||
  get_filename_component(_proto_inc ${GRPC_PROTO_ROOT} DIRECTORY) # updir one level
 | 
			
		||||
  file(RELATIVE_PATH _rel_root_file ${_proto_inc} ${_abs_file})
 | 
			
		||||
  get_filename_component(_rel_root_dir ${_rel_root_file} DIRECTORY)
 | 
			
		||||
  file(RELATIVE_PATH _rel_dir ${CMAKE_CURRENT_SOURCE_DIR} ${_abs_dir})
 | 
			
		||||
 | 
			
		||||
  set(src_1 "${GRPC_GEN_DIR}/${_rel_root_dir}/${_basename}.grpc.pb.cc")
 | 
			
		||||
  set(src_2 "${GRPC_GEN_DIR}/${_rel_root_dir}/${_basename}.pb.cc")
 | 
			
		||||
  set(hdr_1 "${GRPC_GEN_DIR}/${_rel_root_dir}/${_basename}.grpc.pb.h")
 | 
			
		||||
  set(hdr_2 "${GRPC_GEN_DIR}/${_rel_root_dir}/${_basename}.pb.h")
 | 
			
		||||
  add_custom_command(
 | 
			
		||||
    OUTPUT ${src_1} ${src_2} ${hdr_1} ${hdr_2}
 | 
			
		||||
    COMMAND protobuf::protoc
 | 
			
		||||
    ARGS --grpc_out=${GRPC_GEN_DIR}
 | 
			
		||||
         --cpp_out=${GRPC_GEN_DIR}
 | 
			
		||||
         --plugin=protoc-gen-grpc=$<TARGET_FILE:gRPC::grpc_cpp_plugin>
 | 
			
		||||
         -I ${_proto_inc} -I ${_rel_dir}
 | 
			
		||||
         ${_abs_file}
 | 
			
		||||
    DEPENDS ${_abs_file} protobuf::protoc gRPC::grpc_cpp_plugin
 | 
			
		||||
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
 | 
			
		||||
    COMMENT "Running gRPC C++ protocol buffer compiler on ${file}"
 | 
			
		||||
    VERBATIM)
 | 
			
		||||
    set_source_files_properties(${src_1} ${src_2} ${hdr_1} ${hdr_2} PROPERTIES GENERATED TRUE)
 | 
			
		||||
    list(APPEND GRPC_PROTO_SRCS ${src_1} ${src_2})
 | 
			
		||||
    list(APPEND GRPC_PROTO_HDRS ${hdr_1} ${hdr_2})
 | 
			
		||||
endforeach()
 | 
			
		||||
 | 
			
		||||
add_library(grpc_pbufs STATIC ${GRPC_PROTO_SRCS} ${GRPC_PROTO_HDRS})
 | 
			
		||||
#target_include_directories(grpc_pbufs PRIVATE src)
 | 
			
		||||
target_include_directories(grpc_pbufs SYSTEM PUBLIC ${GRPC_GEN_DIR})
 | 
			
		||||
target_link_libraries(grpc_pbufs
 | 
			
		||||
  "gRPC::grpc++"
 | 
			
		||||
  # libgrpc is missing references.
 | 
			
		||||
  absl::random_random
 | 
			
		||||
)
 | 
			
		||||
target_compile_options(grpc_pbufs
 | 
			
		||||
  PRIVATE
 | 
			
		||||
    $<$<BOOL:${MSVC}>:-wd4065>
 | 
			
		||||
    $<$<NOT:$<BOOL:${MSVC}>>:-Wno-deprecated-declarations>
 | 
			
		||||
  PUBLIC
 | 
			
		||||
    $<$<BOOL:${MSVC}>:-wd4996>
 | 
			
		||||
    $<$<BOOL:${XCODE}>:
 | 
			
		||||
      --system-header-prefix="google/protobuf"
 | 
			
		||||
      -Wno-deprecated-dynamic-exception-spec
 | 
			
		||||
    >)
 | 
			
		||||
add_library(Ripple::grpc_pbufs ALIAS grpc_pbufs)
 | 
			
		||||
@@ -1,51 +1,3 @@
 | 
			
		||||
#[===================================================================[
 | 
			
		||||
   NIH dep: boost
 | 
			
		||||
#]===================================================================]
 | 
			
		||||
if((NOT DEFINED BOOST_ROOT) AND(DEFINED ENV{BOOST_ROOT}))
 | 
			
		||||
  set(BOOST_ROOT $ENV{BOOST_ROOT})
 | 
			
		||||
endif()
 | 
			
		||||
if((NOT DEFINED BOOST_LIBRARYDIR) AND(DEFINED ENV{BOOST_LIBRARYDIR}))
 | 
			
		||||
  set(BOOST_LIBRARYDIR $ENV{BOOST_LIBRARYDIR})
 | 
			
		||||
endif()
 | 
			
		||||
file(TO_CMAKE_PATH "${BOOST_ROOT}" BOOST_ROOT)
 | 
			
		||||
if(WIN32 OR CYGWIN)
 | 
			
		||||
  # Workaround for MSVC having two boost versions - x86 and x64 on same PC in stage folders
 | 
			
		||||
  if((NOT DEFINED BOOST_LIBRARYDIR) AND (DEFINED BOOST_ROOT))
 | 
			
		||||
    if(IS_DIRECTORY ${BOOST_ROOT}/stage64/lib)
 | 
			
		||||
      set(BOOST_LIBRARYDIR ${BOOST_ROOT}/stage64/lib)
 | 
			
		||||
    elseif(IS_DIRECTORY ${BOOST_ROOT}/stage/lib)
 | 
			
		||||
      set(BOOST_LIBRARYDIR ${BOOST_ROOT}/stage/lib)
 | 
			
		||||
    elseif(IS_DIRECTORY ${BOOST_ROOT}/lib)
 | 
			
		||||
      set(BOOST_LIBRARYDIR ${BOOST_ROOT}/lib)
 | 
			
		||||
    else()
 | 
			
		||||
      message(WARNING "Did not find expected boost library dir. "
 | 
			
		||||
        "Defaulting to ${BOOST_ROOT}")
 | 
			
		||||
      set(BOOST_LIBRARYDIR ${BOOST_ROOT})
 | 
			
		||||
    endif()
 | 
			
		||||
  endif()
 | 
			
		||||
endif()
 | 
			
		||||
message(STATUS "BOOST_ROOT: ${BOOST_ROOT}")
 | 
			
		||||
message(STATUS "BOOST_LIBRARYDIR: ${BOOST_LIBRARYDIR}")
 | 
			
		||||
 | 
			
		||||
# uncomment the following as needed to debug FindBoost issues:
 | 
			
		||||
#set(Boost_DEBUG ON)
 | 
			
		||||
 | 
			
		||||
#[=========================================================[
 | 
			
		||||
   boost dynamic libraries don't trivially support @rpath
 | 
			
		||||
   linking right now (cmake's default), so just force
 | 
			
		||||
   static linking for macos, or if requested on linux by flag
 | 
			
		||||
#]=========================================================]
 | 
			
		||||
if(static)
 | 
			
		||||
  set(Boost_USE_STATIC_LIBS ON)
 | 
			
		||||
endif()
 | 
			
		||||
set(Boost_USE_MULTITHREADED ON)
 | 
			
		||||
if(static AND NOT APPLE)
 | 
			
		||||
  set(Boost_USE_STATIC_RUNTIME ON)
 | 
			
		||||
else()
 | 
			
		||||
  set(Boost_USE_STATIC_RUNTIME OFF)
 | 
			
		||||
endif()
 | 
			
		||||
# TBD:
 | 
			
		||||
# Boost_USE_DEBUG_RUNTIME:  When ON, uses Boost libraries linked against the
 | 
			
		||||
find_package(Boost 1.86 REQUIRED
 | 
			
		||||
  COMPONENTS
 | 
			
		||||
    chrono
 | 
			
		||||
@@ -57,12 +9,12 @@ find_package(Boost 1.86 REQUIRED
 | 
			
		||||
    program_options
 | 
			
		||||
    regex
 | 
			
		||||
    system
 | 
			
		||||
    iostreams
 | 
			
		||||
    thread)
 | 
			
		||||
    thread
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
add_library(ripple_boost INTERFACE)
 | 
			
		||||
add_library(Ripple::boost ALIAS ripple_boost)
 | 
			
		||||
if(is_xcode)
 | 
			
		||||
if(XCODE)
 | 
			
		||||
  target_include_directories(ripple_boost BEFORE INTERFACE ${Boost_INCLUDE_DIRS})
 | 
			
		||||
  target_compile_options(ripple_boost INTERFACE --system-header-prefix="boost/")
 | 
			
		||||
else()
 | 
			
		||||
@@ -77,10 +29,10 @@ target_link_libraries(ripple_boost
 | 
			
		||||
    Boost::coroutine
 | 
			
		||||
    Boost::date_time
 | 
			
		||||
    Boost::filesystem
 | 
			
		||||
    Boost::iostreams
 | 
			
		||||
    Boost::program_options
 | 
			
		||||
    Boost::regex
 | 
			
		||||
    Boost::system
 | 
			
		||||
    Boost::iostreams
 | 
			
		||||
    Boost::thread)
 | 
			
		||||
if(Boost_COMPILER)
 | 
			
		||||
  target_link_libraries(ripple_boost INTERFACE Boost::disable_autolinking)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,28 +0,0 @@
 | 
			
		||||
#[===================================================================[
 | 
			
		||||
   NIH dep: ed25519-donna
 | 
			
		||||
#]===================================================================]
 | 
			
		||||
 | 
			
		||||
add_library (ed25519-donna STATIC
 | 
			
		||||
  src/ed25519-donna/ed25519.c)
 | 
			
		||||
target_include_directories (ed25519-donna
 | 
			
		||||
  PUBLIC
 | 
			
		||||
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
 | 
			
		||||
    $<INSTALL_INTERFACE:include>
 | 
			
		||||
  PRIVATE
 | 
			
		||||
    ${CMAKE_CURRENT_SOURCE_DIR}/src/ed25519-donna)
 | 
			
		||||
#[=========================================================[
 | 
			
		||||
   NOTE for macos:
 | 
			
		||||
   https://github.com/floodyberry/ed25519-donna/issues/29
 | 
			
		||||
   our source for ed25519-donna-portable.h has been
 | 
			
		||||
   patched to workaround this.
 | 
			
		||||
#]=========================================================]
 | 
			
		||||
target_link_libraries (ed25519-donna PUBLIC OpenSSL::SSL)
 | 
			
		||||
add_library (NIH::ed25519-donna ALIAS ed25519-donna)
 | 
			
		||||
target_link_libraries (ripple_libs INTERFACE NIH::ed25519-donna)
 | 
			
		||||
#[===========================[
 | 
			
		||||
   headers installation
 | 
			
		||||
#]===========================]
 | 
			
		||||
install (
 | 
			
		||||
  FILES
 | 
			
		||||
    src/ed25519-donna/ed25519.h
 | 
			
		||||
  DESTINATION include/ed25519-donna)
 | 
			
		||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,47 +0,0 @@
 | 
			
		||||
# - Try to find jemalloc
 | 
			
		||||
# Once done this will define
 | 
			
		||||
#  JEMALLOC_FOUND - System has jemalloc
 | 
			
		||||
#  JEMALLOC_INCLUDE_DIRS - The jemalloc include directories
 | 
			
		||||
#  JEMALLOC_LIBRARIES - The libraries needed to use jemalloc
 | 
			
		||||
 | 
			
		||||
if(NOT USE_BUNDLED_JEMALLOC)
 | 
			
		||||
  find_package(PkgConfig)
 | 
			
		||||
  if (PKG_CONFIG_FOUND)
 | 
			
		||||
    pkg_check_modules(PC_JEMALLOC QUIET jemalloc)
 | 
			
		||||
  endif()
 | 
			
		||||
else()
 | 
			
		||||
  set(PC_JEMALLOC_INCLUDEDIR)
 | 
			
		||||
  set(PC_JEMALLOC_INCLUDE_DIRS)
 | 
			
		||||
  set(PC_JEMALLOC_LIBDIR)
 | 
			
		||||
  set(PC_JEMALLOC_LIBRARY_DIRS)
 | 
			
		||||
  set(LIMIT_SEARCH NO_DEFAULT_PATH)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
set(JEMALLOC_DEFINITIONS ${PC_JEMALLOC_CFLAGS_OTHER})
 | 
			
		||||
 | 
			
		||||
find_path(JEMALLOC_INCLUDE_DIR jemalloc/jemalloc.h
 | 
			
		||||
          PATHS ${PC_JEMALLOC_INCLUDEDIR} ${PC_JEMALLOC_INCLUDE_DIRS}
 | 
			
		||||
          ${LIMIT_SEARCH})
 | 
			
		||||
 | 
			
		||||
# If we're asked to use static linkage, add libjemalloc.a as a preferred library name.
 | 
			
		||||
if(JEMALLOC_USE_STATIC)
 | 
			
		||||
  list(APPEND JEMALLOC_NAMES
 | 
			
		||||
    "${CMAKE_STATIC_LIBRARY_PREFIX}jemalloc${CMAKE_STATIC_LIBRARY_SUFFIX}")
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
list(APPEND JEMALLOC_NAMES jemalloc)
 | 
			
		||||
 | 
			
		||||
find_library(JEMALLOC_LIBRARY NAMES ${JEMALLOC_NAMES}
 | 
			
		||||
  HINTS ${PC_JEMALLOC_LIBDIR} ${PC_JEMALLOC_LIBRARY_DIRS}
 | 
			
		||||
  ${LIMIT_SEARCH})
 | 
			
		||||
 | 
			
		||||
set(JEMALLOC_LIBRARIES ${JEMALLOC_LIBRARY})
 | 
			
		||||
set(JEMALLOC_INCLUDE_DIRS ${JEMALLOC_INCLUDE_DIR})
 | 
			
		||||
 | 
			
		||||
include(FindPackageHandleStandardArgs)
 | 
			
		||||
# handle the QUIETLY and REQUIRED arguments and set JEMALLOC_FOUND to TRUE
 | 
			
		||||
# if all listed variables are TRUE
 | 
			
		||||
find_package_handle_standard_args(JeMalloc DEFAULT_MSG
 | 
			
		||||
  JEMALLOC_LIBRARY JEMALLOC_INCLUDE_DIR)
 | 
			
		||||
 | 
			
		||||
mark_as_advanced(JEMALLOC_INCLUDE_DIR JEMALLOC_LIBRARY)
 | 
			
		||||
@@ -1,22 +0,0 @@
 | 
			
		||||
find_package (PkgConfig REQUIRED)
 | 
			
		||||
pkg_search_module (libarchive_PC QUIET libarchive>=3.4.3)
 | 
			
		||||
 | 
			
		||||
if(static)
 | 
			
		||||
  set(LIBARCHIVE_LIB libarchive.a)
 | 
			
		||||
else()
 | 
			
		||||
  set(LIBARCHIVE_LIB archive)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
find_library (archive
 | 
			
		||||
  NAMES ${LIBARCHIVE_LIB}
 | 
			
		||||
  HINTS
 | 
			
		||||
    ${libarchive_PC_LIBDIR}
 | 
			
		||||
    ${libarchive_PC_LIBRARY_DIRS}
 | 
			
		||||
  NO_DEFAULT_PATH)
 | 
			
		||||
 | 
			
		||||
find_path (LIBARCHIVE_INCLUDE_DIR
 | 
			
		||||
  NAMES archive.h
 | 
			
		||||
  HINTS
 | 
			
		||||
    ${libarchive_PC_INCLUDEDIR}
 | 
			
		||||
    ${libarchive_PC_INCLUDEDIRS}
 | 
			
		||||
  NO_DEFAULT_PATH)
 | 
			
		||||
@@ -1,24 +0,0 @@
 | 
			
		||||
find_package (PkgConfig)
 | 
			
		||||
if (PKG_CONFIG_FOUND)
 | 
			
		||||
  pkg_search_module (lz4_PC QUIET liblz4>=1.9)
 | 
			
		||||
endif ()
 | 
			
		||||
 | 
			
		||||
if(static)
 | 
			
		||||
  set(LZ4_LIB liblz4.a)
 | 
			
		||||
else()
 | 
			
		||||
  set(LZ4_LIB lz4.so)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
find_library (lz4
 | 
			
		||||
  NAMES ${LZ4_LIB}
 | 
			
		||||
  HINTS
 | 
			
		||||
    ${lz4_PC_LIBDIR}
 | 
			
		||||
    ${lz4_PC_LIBRARY_DIRS}
 | 
			
		||||
  NO_DEFAULT_PATH)
 | 
			
		||||
 | 
			
		||||
find_path (LZ4_INCLUDE_DIR
 | 
			
		||||
  NAMES lz4.h
 | 
			
		||||
  HINTS
 | 
			
		||||
    ${lz4_PC_INCLUDEDIR}
 | 
			
		||||
    ${lz4_PC_INCLUDEDIRS}
 | 
			
		||||
  NO_DEFAULT_PATH)
 | 
			
		||||
@@ -1,24 +0,0 @@
 | 
			
		||||
find_package (PkgConfig)
 | 
			
		||||
if (PKG_CONFIG_FOUND)
 | 
			
		||||
  pkg_search_module (secp256k1_PC QUIET libsecp256k1)
 | 
			
		||||
endif ()
 | 
			
		||||
 | 
			
		||||
if(static)
 | 
			
		||||
  set(SECP256K1_LIB libsecp256k1.a)
 | 
			
		||||
else()
 | 
			
		||||
  set(SECP256K1_LIB secp256k1)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
find_library(secp256k1
 | 
			
		||||
  NAMES ${SECP256K1_LIB}
 | 
			
		||||
  HINTS
 | 
			
		||||
    ${secp256k1_PC_LIBDIR}
 | 
			
		||||
    ${secp256k1_PC_LIBRARY_PATHS}
 | 
			
		||||
  NO_DEFAULT_PATH)
 | 
			
		||||
 | 
			
		||||
find_path (SECP256K1_INCLUDE_DIR
 | 
			
		||||
  NAMES secp256k1.h
 | 
			
		||||
  HINTS
 | 
			
		||||
    ${secp256k1_PC_INCLUDEDIR}
 | 
			
		||||
    ${secp256k1_PC_INCLUDEDIRS}
 | 
			
		||||
  NO_DEFAULT_PATH)
 | 
			
		||||
@@ -1,24 +0,0 @@
 | 
			
		||||
find_package (PkgConfig)
 | 
			
		||||
if (PKG_CONFIG_FOUND)
 | 
			
		||||
  pkg_search_module (snappy_PC QUIET snappy>=1.1.7)
 | 
			
		||||
endif ()
 | 
			
		||||
 | 
			
		||||
if(static)
 | 
			
		||||
  set(SNAPPY_LIB libsnappy.a)
 | 
			
		||||
else()
 | 
			
		||||
  set(SNAPPY_LIB libsnappy.so)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
find_library (snappy
 | 
			
		||||
  NAMES ${SNAPPY_LIB}
 | 
			
		||||
  HINTS
 | 
			
		||||
    ${snappy_PC_LIBDIR}
 | 
			
		||||
    ${snappy_PC_LIBRARY_DIRS}
 | 
			
		||||
  NO_DEFAULT_PATH)
 | 
			
		||||
 | 
			
		||||
find_path (SNAPPY_INCLUDE_DIR
 | 
			
		||||
  NAMES snappy.h
 | 
			
		||||
  HINTS
 | 
			
		||||
    ${snappy_PC_INCLUDEDIR}
 | 
			
		||||
    ${snappy_PC_INCLUDEDIRS}
 | 
			
		||||
  NO_DEFAULT_PATH)
 | 
			
		||||
@@ -1,19 +0,0 @@
 | 
			
		||||
find_package (PkgConfig)
 | 
			
		||||
if (PKG_CONFIG_FOUND)
 | 
			
		||||
  # TBD - currently no soci pkgconfig
 | 
			
		||||
  #pkg_search_module (soci_PC QUIET libsoci_core>=3.2)
 | 
			
		||||
endif ()
 | 
			
		||||
 | 
			
		||||
if(static)
 | 
			
		||||
  set(SOCI_LIB libsoci.a)
 | 
			
		||||
else()
 | 
			
		||||
  set(SOCI_LIB libsoci_core.so)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
find_library (soci
 | 
			
		||||
  NAMES ${SOCI_LIB})
 | 
			
		||||
 | 
			
		||||
find_path (SOCI_INCLUDE_DIR
 | 
			
		||||
  NAMES soci/soci.h)
 | 
			
		||||
 | 
			
		||||
message("SOCI FOUND AT: ${SOCI_LIB}")
 | 
			
		||||
@@ -1,24 +0,0 @@
 | 
			
		||||
find_package (PkgConfig)
 | 
			
		||||
if (PKG_CONFIG_FOUND)
 | 
			
		||||
  pkg_search_module (sqlite_PC QUIET sqlite3>=3.26.0)
 | 
			
		||||
endif ()
 | 
			
		||||
 | 
			
		||||
if(static)
 | 
			
		||||
  set(SQLITE_LIB libsqlite3.a)
 | 
			
		||||
else()
 | 
			
		||||
  set(SQLITE_LIB sqlite3.so)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
find_library (sqlite3
 | 
			
		||||
  NAMES ${SQLITE_LIB}
 | 
			
		||||
  HINTS
 | 
			
		||||
    ${sqlite_PC_LIBDIR}
 | 
			
		||||
    ${sqlite_PC_LIBRARY_DIRS}
 | 
			
		||||
  NO_DEFAULT_PATH)
 | 
			
		||||
 | 
			
		||||
find_path (SQLITE_INCLUDE_DIR
 | 
			
		||||
  NAMES sqlite3.h
 | 
			
		||||
  HINTS
 | 
			
		||||
    ${sqlite_PC_INCLUDEDIR}
 | 
			
		||||
    ${sqlite_PC_INCLUDEDIRS}
 | 
			
		||||
  NO_DEFAULT_PATH)
 | 
			
		||||
@@ -1,163 +0,0 @@
 | 
			
		||||
#[===================================================================[
 | 
			
		||||
   NIH dep: libarchive
 | 
			
		||||
#]===================================================================]
 | 
			
		||||
 | 
			
		||||
option (local_libarchive "use local build of libarchive." OFF)
 | 
			
		||||
add_library (archive_lib UNKNOWN IMPORTED GLOBAL)
 | 
			
		||||
 | 
			
		||||
if (NOT local_libarchive)
 | 
			
		||||
  if (NOT WIN32)
 | 
			
		||||
    find_package(libarchive_pc REQUIRED)
 | 
			
		||||
  endif ()
 | 
			
		||||
  if (archive)
 | 
			
		||||
    message (STATUS "Found libarchive using pkg-config. Using ${archive}.")
 | 
			
		||||
    set_target_properties (archive_lib PROPERTIES
 | 
			
		||||
      IMPORTED_LOCATION_DEBUG
 | 
			
		||||
        ${archive}
 | 
			
		||||
      IMPORTED_LOCATION_RELEASE
 | 
			
		||||
        ${archive}
 | 
			
		||||
      INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
        ${LIBARCHIVE_INCLUDE_DIR})
 | 
			
		||||
      # pkg-config can return extra info for static lib linking
 | 
			
		||||
      # this is probably needed/useful generally, but apply
 | 
			
		||||
      # to APPLE for now (mostly for homebrew)
 | 
			
		||||
      if (APPLE AND static AND libarchive_PC_STATIC_LIBRARIES)
 | 
			
		||||
        message(STATUS "NOTE: libarchive static libs: ${libarchive_PC_STATIC_LIBRARIES}")
 | 
			
		||||
        # also, APPLE seems to need iconv...maybe linux does too (TBD)
 | 
			
		||||
        target_link_libraries (archive_lib
 | 
			
		||||
          INTERFACE iconv ${libarchive_PC_STATIC_LIBRARIES})
 | 
			
		||||
      endif ()
 | 
			
		||||
  else ()
 | 
			
		||||
    ## now try searching using the minimal find module that cmake provides
 | 
			
		||||
    find_package(LibArchive 3.4.3 QUIET)
 | 
			
		||||
    if (LibArchive_FOUND)
 | 
			
		||||
      if (static)
 | 
			
		||||
        # find module doesn't find static libs currently, so we re-search
 | 
			
		||||
        get_filename_component(_loc ${LibArchive_LIBRARY} DIRECTORY)
 | 
			
		||||
        find_library(_la_static
 | 
			
		||||
          NAMES libarchive.a archive_static.lib archive.lib
 | 
			
		||||
          PATHS ${_loc})
 | 
			
		||||
        if (_la_static)
 | 
			
		||||
          set (_la_lib ${_la_static})
 | 
			
		||||
        else ()
 | 
			
		||||
          message (WARNING "unable to find libarchive static lib - switching to local build")
 | 
			
		||||
          set (local_libarchive ON CACHE BOOL "" FORCE)
 | 
			
		||||
        endif ()
 | 
			
		||||
      else ()
 | 
			
		||||
        set (_la_lib ${LibArchive_LIBRARY})
 | 
			
		||||
      endif ()
 | 
			
		||||
      if (NOT local_libarchive)
 | 
			
		||||
        message (STATUS "Found libarchive using module/config. Using ${_la_lib}.")
 | 
			
		||||
        set_target_properties (archive_lib PROPERTIES
 | 
			
		||||
          IMPORTED_LOCATION_DEBUG
 | 
			
		||||
            ${_la_lib}
 | 
			
		||||
          IMPORTED_LOCATION_RELEASE
 | 
			
		||||
            ${_la_lib}
 | 
			
		||||
          INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
            ${LibArchive_INCLUDE_DIRS})
 | 
			
		||||
      endif ()
 | 
			
		||||
    else ()
 | 
			
		||||
      set (local_libarchive ON CACHE BOOL "" FORCE)
 | 
			
		||||
    endif ()
 | 
			
		||||
  endif ()
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
if (local_libarchive)
 | 
			
		||||
  set (lib_post "")
 | 
			
		||||
  if (MSVC)
 | 
			
		||||
    set (lib_post "_static")
 | 
			
		||||
  endif ()
 | 
			
		||||
  ExternalProject_Add (libarchive
 | 
			
		||||
    PREFIX ${nih_cache_path}
 | 
			
		||||
    GIT_REPOSITORY https://github.com/libarchive/libarchive.git
 | 
			
		||||
    GIT_TAG v3.4.3
 | 
			
		||||
    CMAKE_ARGS
 | 
			
		||||
      # passing the compiler seems to be needed for windows CI, sadly
 | 
			
		||||
      -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
 | 
			
		||||
      -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
 | 
			
		||||
      $<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:-DCMAKE_VERBOSE_MAKEFILE=ON>
 | 
			
		||||
      -DCMAKE_DEBUG_POSTFIX=_d
 | 
			
		||||
      $<$<NOT:$<BOOL:${is_multiconfig}>>:-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}>
 | 
			
		||||
      -DENABLE_LZ4=ON
 | 
			
		||||
      -ULZ4_*
 | 
			
		||||
      -DLZ4_INCLUDE_DIR=$<JOIN:$<TARGET_PROPERTY:lz4_lib,INTERFACE_INCLUDE_DIRECTORIES>,::>
 | 
			
		||||
      # because we are building a static lib, this lz4 library doesn't
 | 
			
		||||
      # actually matter since you can't generally link static libs to other static
 | 
			
		||||
      # libs. The include files are needed, but the library itself is not (until
 | 
			
		||||
      # we link our application, at which point we use the lz4 we built above).
 | 
			
		||||
      # nonetheless, we need to provide a library to libarchive else it will
 | 
			
		||||
      # NOT include lz4 support when configuring
 | 
			
		||||
      -DLZ4_LIBRARY=$<IF:$<CONFIG:Debug>,$<TARGET_PROPERTY:lz4_lib,IMPORTED_LOCATION_DEBUG>,$<TARGET_PROPERTY:lz4_lib,IMPORTED_LOCATION_RELEASE>>
 | 
			
		||||
      -DENABLE_WERROR=OFF
 | 
			
		||||
      -DENABLE_TAR=OFF
 | 
			
		||||
      -DENABLE_TAR_SHARED=OFF
 | 
			
		||||
      -DENABLE_INSTALL=ON
 | 
			
		||||
      -DENABLE_NETTLE=OFF
 | 
			
		||||
      -DENABLE_OPENSSL=OFF
 | 
			
		||||
      -DENABLE_LZO=OFF
 | 
			
		||||
      -DENABLE_LZMA=OFF
 | 
			
		||||
      -DENABLE_ZLIB=OFF
 | 
			
		||||
      -DENABLE_BZip2=OFF
 | 
			
		||||
      -DENABLE_LIBXML2=OFF
 | 
			
		||||
      -DENABLE_EXPAT=OFF
 | 
			
		||||
      -DENABLE_PCREPOSIX=OFF
 | 
			
		||||
      -DENABLE_LibGCC=OFF
 | 
			
		||||
      -DENABLE_CNG=OFF
 | 
			
		||||
      -DENABLE_CPIO=OFF
 | 
			
		||||
      -DENABLE_CPIO_SHARED=OFF
 | 
			
		||||
      -DENABLE_CAT=OFF
 | 
			
		||||
      -DENABLE_CAT_SHARED=OFF
 | 
			
		||||
      -DENABLE_XATTR=OFF
 | 
			
		||||
      -DENABLE_ACL=OFF
 | 
			
		||||
      -DENABLE_ICONV=OFF
 | 
			
		||||
      -DENABLE_TEST=OFF
 | 
			
		||||
      -DENABLE_COVERAGE=OFF
 | 
			
		||||
      $<$<BOOL:${MSVC}>:
 | 
			
		||||
        "-DCMAKE_C_FLAGS=-GR -Gd -fp:precise -FS -MP"
 | 
			
		||||
        "-DCMAKE_C_FLAGS_DEBUG=-MTd"
 | 
			
		||||
        "-DCMAKE_C_FLAGS_RELEASE=-MT"
 | 
			
		||||
      >
 | 
			
		||||
    LIST_SEPARATOR ::
 | 
			
		||||
    LOG_BUILD ON
 | 
			
		||||
    LOG_CONFIGURE ON
 | 
			
		||||
    BUILD_COMMAND
 | 
			
		||||
      ${CMAKE_COMMAND}
 | 
			
		||||
      --build .
 | 
			
		||||
      --config $<CONFIG>
 | 
			
		||||
      --target archive_static
 | 
			
		||||
      --parallel ${ep_procs}
 | 
			
		||||
      $<$<BOOL:${is_multiconfig}>:
 | 
			
		||||
        COMMAND
 | 
			
		||||
          ${CMAKE_COMMAND} -E copy
 | 
			
		||||
            <BINARY_DIR>/libarchive/$<CONFIG>/${ep_lib_prefix}archive${lib_post}$<$<CONFIG:Debug>:_d>${ep_lib_suffix}
 | 
			
		||||
            <BINARY_DIR>/libarchive
 | 
			
		||||
        >
 | 
			
		||||
    TEST_COMMAND ""
 | 
			
		||||
    INSTALL_COMMAND ""
 | 
			
		||||
    DEPENDS lz4_lib
 | 
			
		||||
    BUILD_BYPRODUCTS
 | 
			
		||||
      <BINARY_DIR>/libarchive/${ep_lib_prefix}archive${lib_post}${ep_lib_suffix}
 | 
			
		||||
      <BINARY_DIR>/libarchive/${ep_lib_prefix}archive${lib_post}_d${ep_lib_suffix}
 | 
			
		||||
  )
 | 
			
		||||
  ExternalProject_Get_Property (libarchive BINARY_DIR)
 | 
			
		||||
  ExternalProject_Get_Property (libarchive SOURCE_DIR)
 | 
			
		||||
  if (CMAKE_VERBOSE_MAKEFILE)
 | 
			
		||||
    print_ep_logs (libarchive)
 | 
			
		||||
  endif ()
 | 
			
		||||
  file (MAKE_DIRECTORY ${SOURCE_DIR}/libarchive)
 | 
			
		||||
  set_target_properties (archive_lib PROPERTIES
 | 
			
		||||
    IMPORTED_LOCATION_DEBUG
 | 
			
		||||
      ${BINARY_DIR}/libarchive/${ep_lib_prefix}archive${lib_post}_d${ep_lib_suffix}
 | 
			
		||||
    IMPORTED_LOCATION_RELEASE
 | 
			
		||||
      ${BINARY_DIR}/libarchive/${ep_lib_prefix}archive${lib_post}${ep_lib_suffix}
 | 
			
		||||
    INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
      ${SOURCE_DIR}/libarchive
 | 
			
		||||
    INTERFACE_COMPILE_DEFINITIONS
 | 
			
		||||
      LIBARCHIVE_STATIC)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
add_dependencies (archive_lib libarchive)
 | 
			
		||||
target_link_libraries (archive_lib INTERFACE lz4_lib)
 | 
			
		||||
target_link_libraries (ripple_libs INTERFACE archive_lib)
 | 
			
		||||
exclude_if_included (libarchive)
 | 
			
		||||
exclude_if_included (archive_lib)
 | 
			
		||||
@@ -1,79 +0,0 @@
 | 
			
		||||
#[===================================================================[
 | 
			
		||||
   NIH dep: lz4
 | 
			
		||||
#]===================================================================]
 | 
			
		||||
 | 
			
		||||
add_library (lz4_lib STATIC IMPORTED GLOBAL)
 | 
			
		||||
 | 
			
		||||
if (NOT WIN32)
 | 
			
		||||
  find_package(lz4)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
if(lz4)
 | 
			
		||||
  set_target_properties (lz4_lib PROPERTIES
 | 
			
		||||
    IMPORTED_LOCATION_DEBUG
 | 
			
		||||
      ${lz4}
 | 
			
		||||
    IMPORTED_LOCATION_RELEASE
 | 
			
		||||
      ${lz4}
 | 
			
		||||
    INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
      ${LZ4_INCLUDE_DIR})
 | 
			
		||||
 | 
			
		||||
else()
 | 
			
		||||
  ExternalProject_Add (lz4
 | 
			
		||||
    PREFIX ${nih_cache_path}
 | 
			
		||||
    GIT_REPOSITORY https://github.com/lz4/lz4.git
 | 
			
		||||
    GIT_TAG v1.9.2
 | 
			
		||||
    SOURCE_SUBDIR contrib/cmake_unofficial
 | 
			
		||||
    CMAKE_ARGS
 | 
			
		||||
      -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
 | 
			
		||||
      -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
 | 
			
		||||
      $<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:-DCMAKE_VERBOSE_MAKEFILE=ON>
 | 
			
		||||
      -DCMAKE_DEBUG_POSTFIX=_d
 | 
			
		||||
      $<$<NOT:$<BOOL:${is_multiconfig}>>:-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}>
 | 
			
		||||
      -DBUILD_STATIC_LIBS=ON
 | 
			
		||||
      -DBUILD_SHARED_LIBS=OFF
 | 
			
		||||
      $<$<BOOL:${MSVC}>:
 | 
			
		||||
        "-DCMAKE_C_FLAGS=-GR -Gd -fp:precise -FS -MP"
 | 
			
		||||
        "-DCMAKE_C_FLAGS_DEBUG=-MTd"
 | 
			
		||||
        "-DCMAKE_C_FLAGS_RELEASE=-MT"
 | 
			
		||||
      >
 | 
			
		||||
    LOG_BUILD ON
 | 
			
		||||
    LOG_CONFIGURE ON
 | 
			
		||||
    BUILD_COMMAND
 | 
			
		||||
      ${CMAKE_COMMAND}
 | 
			
		||||
      --build .
 | 
			
		||||
      --config $<CONFIG>
 | 
			
		||||
      --target lz4_static
 | 
			
		||||
      --parallel ${ep_procs}
 | 
			
		||||
      $<$<BOOL:${is_multiconfig}>:
 | 
			
		||||
        COMMAND
 | 
			
		||||
          ${CMAKE_COMMAND} -E copy
 | 
			
		||||
          <BINARY_DIR>/$<CONFIG>/${ep_lib_prefix}lz4$<$<CONFIG:Debug>:_d>${ep_lib_suffix}
 | 
			
		||||
          <BINARY_DIR>
 | 
			
		||||
        >
 | 
			
		||||
    TEST_COMMAND ""
 | 
			
		||||
    INSTALL_COMMAND ""
 | 
			
		||||
    BUILD_BYPRODUCTS
 | 
			
		||||
      <BINARY_DIR>/${ep_lib_prefix}lz4${ep_lib_suffix}
 | 
			
		||||
      <BINARY_DIR>/${ep_lib_prefix}lz4_d${ep_lib_suffix}
 | 
			
		||||
  )
 | 
			
		||||
  ExternalProject_Get_Property (lz4 BINARY_DIR)
 | 
			
		||||
  ExternalProject_Get_Property (lz4 SOURCE_DIR)
 | 
			
		||||
 | 
			
		||||
  file (MAKE_DIRECTORY ${SOURCE_DIR}/lz4)
 | 
			
		||||
  set_target_properties (lz4_lib PROPERTIES
 | 
			
		||||
    IMPORTED_LOCATION_DEBUG
 | 
			
		||||
      ${BINARY_DIR}/${ep_lib_prefix}lz4_d${ep_lib_suffix}
 | 
			
		||||
    IMPORTED_LOCATION_RELEASE
 | 
			
		||||
      ${BINARY_DIR}/${ep_lib_prefix}lz4${ep_lib_suffix}
 | 
			
		||||
    INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
      ${SOURCE_DIR}/lib)
 | 
			
		||||
 | 
			
		||||
  if (CMAKE_VERBOSE_MAKEFILE)
 | 
			
		||||
    print_ep_logs (lz4)
 | 
			
		||||
  endif ()
 | 
			
		||||
  add_dependencies (lz4_lib lz4)
 | 
			
		||||
  target_link_libraries (ripple_libs INTERFACE lz4_lib)
 | 
			
		||||
  exclude_if_included (lz4)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
exclude_if_included (lz4_lib)
 | 
			
		||||
@@ -1,31 +0,0 @@
 | 
			
		||||
#[===================================================================[
 | 
			
		||||
   NIH dep: nudb
 | 
			
		||||
 | 
			
		||||
   NuDB is header-only, thus is an INTERFACE lib in CMake.
 | 
			
		||||
   TODO: move the library definition into NuDB repo and add
 | 
			
		||||
   proper targets and export/install
 | 
			
		||||
#]===================================================================]
 | 
			
		||||
 | 
			
		||||
if (is_root_project) # NuDB not needed in the case of xrpl_core inclusion build
 | 
			
		||||
  add_library (nudb INTERFACE)
 | 
			
		||||
  FetchContent_Declare(
 | 
			
		||||
    nudb_src
 | 
			
		||||
    GIT_REPOSITORY https://github.com/CPPAlliance/NuDB.git
 | 
			
		||||
    GIT_TAG        2.0.5
 | 
			
		||||
  )
 | 
			
		||||
  FetchContent_GetProperties(nudb_src)
 | 
			
		||||
  if(NOT nudb_src_POPULATED)
 | 
			
		||||
    message (STATUS "Pausing to download NuDB...")
 | 
			
		||||
    FetchContent_Populate(nudb_src)
 | 
			
		||||
  endif()
 | 
			
		||||
 | 
			
		||||
  file(TO_CMAKE_PATH "${nudb_src_SOURCE_DIR}" nudb_src_SOURCE_DIR)
 | 
			
		||||
  # specify as system includes so as to avoid warnings
 | 
			
		||||
  target_include_directories (nudb SYSTEM INTERFACE ${nudb_src_SOURCE_DIR}/include)
 | 
			
		||||
  target_link_libraries (nudb
 | 
			
		||||
    INTERFACE
 | 
			
		||||
      Boost::thread
 | 
			
		||||
      Boost::system)
 | 
			
		||||
  add_library (NIH::nudb ALIAS nudb)
 | 
			
		||||
  target_link_libraries (ripple_libs INTERFACE NIH::nudb)
 | 
			
		||||
endif ()
 | 
			
		||||
@@ -1,48 +0,0 @@
 | 
			
		||||
#[===================================================================[
 | 
			
		||||
   NIH dep: openssl
 | 
			
		||||
#]===================================================================]
 | 
			
		||||
 | 
			
		||||
#[===============================================[
 | 
			
		||||
  OPENSSL_ROOT_DIR is the only variable that
 | 
			
		||||
  FindOpenSSL honors for locating, so convert any
 | 
			
		||||
  OPENSSL_ROOT vars to this
 | 
			
		||||
#]===============================================]
 | 
			
		||||
if (NOT DEFINED OPENSSL_ROOT_DIR)
 | 
			
		||||
  if (DEFINED ENV{OPENSSL_ROOT})
 | 
			
		||||
    set (OPENSSL_ROOT_DIR $ENV{OPENSSL_ROOT})
 | 
			
		||||
  elseif (HOMEBREW)
 | 
			
		||||
    execute_process (COMMAND ${HOMEBREW} --prefix openssl
 | 
			
		||||
      OUTPUT_VARIABLE OPENSSL_ROOT_DIR
 | 
			
		||||
      OUTPUT_STRIP_TRAILING_WHITESPACE)
 | 
			
		||||
  endif ()
 | 
			
		||||
  file (TO_CMAKE_PATH "${OPENSSL_ROOT_DIR}" OPENSSL_ROOT_DIR)
 | 
			
		||||
endif ()
 | 
			
		||||
 | 
			
		||||
if (static)
 | 
			
		||||
  set (OPENSSL_USE_STATIC_LIBS ON)
 | 
			
		||||
endif ()
 | 
			
		||||
set (OPENSSL_MSVC_STATIC_RT ON)
 | 
			
		||||
find_package (OpenSSL 1.1.1 REQUIRED)
 | 
			
		||||
target_link_libraries (ripple_libs
 | 
			
		||||
  INTERFACE
 | 
			
		||||
    OpenSSL::SSL
 | 
			
		||||
    OpenSSL::Crypto)
 | 
			
		||||
# disable SSLv2...this can also be done when building/configuring OpenSSL
 | 
			
		||||
set_target_properties(OpenSSL::SSL PROPERTIES
 | 
			
		||||
    INTERFACE_COMPILE_DEFINITIONS OPENSSL_NO_SSL2)
 | 
			
		||||
#[=========================================================[
 | 
			
		||||
   https://gitlab.kitware.com/cmake/cmake/issues/16885
 | 
			
		||||
   depending on how openssl is built, it might depend
 | 
			
		||||
   on zlib. In fact, the openssl find package should
 | 
			
		||||
   figure this out for us, but it does not currently...
 | 
			
		||||
   so let's add zlib ourselves to the lib list
 | 
			
		||||
   TODO: investigate linking to static zlib for static
 | 
			
		||||
   build option
 | 
			
		||||
#]=========================================================]
 | 
			
		||||
find_package (ZLIB)
 | 
			
		||||
set (has_zlib FALSE)
 | 
			
		||||
if (TARGET ZLIB::ZLIB)
 | 
			
		||||
  set_target_properties(OpenSSL::Crypto PROPERTIES
 | 
			
		||||
    INTERFACE_LINK_LIBRARIES ZLIB::ZLIB)
 | 
			
		||||
  set (has_zlib TRUE)
 | 
			
		||||
endif ()
 | 
			
		||||
@@ -1,70 +0,0 @@
 | 
			
		||||
if(reporting)
 | 
			
		||||
    find_package(PostgreSQL)
 | 
			
		||||
    if(NOT PostgreSQL_FOUND)
 | 
			
		||||
        message("find_package did not find postgres")
 | 
			
		||||
        find_library(postgres NAMES pq libpq libpq-dev pq-dev postgresql-devel)
 | 
			
		||||
        find_path(libpq-fe NAMES libpq-fe.h PATH_SUFFIXES postgresql pgsql include)
 | 
			
		||||
 | 
			
		||||
        if(NOT libpq-fe_FOUND OR NOT postgres_FOUND)
 | 
			
		||||
            message("No system installed Postgres found. Will build")
 | 
			
		||||
            add_library(postgres SHARED IMPORTED GLOBAL)
 | 
			
		||||
            add_library(pgport SHARED IMPORTED GLOBAL)
 | 
			
		||||
            add_library(pgcommon SHARED IMPORTED GLOBAL)
 | 
			
		||||
            ExternalProject_Add(postgres_src
 | 
			
		||||
                PREFIX ${nih_cache_path}
 | 
			
		||||
                GIT_REPOSITORY https://github.com/postgres/postgres.git
 | 
			
		||||
                GIT_TAG REL_14_5
 | 
			
		||||
                CONFIGURE_COMMAND ./configure --without-readline > /dev/null
 | 
			
		||||
                BUILD_COMMAND ${CMAKE_COMMAND} -E env --unset=MAKELEVEL make
 | 
			
		||||
                UPDATE_COMMAND ""
 | 
			
		||||
                BUILD_IN_SOURCE 1
 | 
			
		||||
                INSTALL_COMMAND ""
 | 
			
		||||
                BUILD_BYPRODUCTS
 | 
			
		||||
                    <BINARY_DIR>/src/interfaces/libpq/${ep_lib_prefix}pq.a
 | 
			
		||||
                    <BINARY_DIR>/src/common/${ep_lib_prefix}pgcommon.a
 | 
			
		||||
                    <BINARY_DIR>/src/port/${ep_lib_prefix}pgport.a
 | 
			
		||||
                LOG_BUILD TRUE
 | 
			
		||||
                )
 | 
			
		||||
            ExternalProject_Get_Property (postgres_src SOURCE_DIR)
 | 
			
		||||
            ExternalProject_Get_Property (postgres_src BINARY_DIR)
 | 
			
		||||
 | 
			
		||||
            set (postgres_src_SOURCE_DIR "${SOURCE_DIR}")
 | 
			
		||||
            file (MAKE_DIRECTORY ${postgres_src_SOURCE_DIR})
 | 
			
		||||
            list(APPEND INCLUDE_DIRS
 | 
			
		||||
                ${SOURCE_DIR}/src/include
 | 
			
		||||
                ${SOURCE_DIR}/src/interfaces/libpq
 | 
			
		||||
                )
 | 
			
		||||
            set_target_properties(postgres PROPERTIES
 | 
			
		||||
                IMPORTED_LOCATION
 | 
			
		||||
                    ${BINARY_DIR}/src/interfaces/libpq/${ep_lib_prefix}pq.a
 | 
			
		||||
                INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
                    "${INCLUDE_DIRS}"
 | 
			
		||||
                )
 | 
			
		||||
            set_target_properties(pgcommon PROPERTIES
 | 
			
		||||
                IMPORTED_LOCATION
 | 
			
		||||
                    ${BINARY_DIR}/src/common/${ep_lib_prefix}pgcommon.a
 | 
			
		||||
                INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
                    "${INCLUDE_DIRS}"
 | 
			
		||||
                )
 | 
			
		||||
            set_target_properties(pgport PROPERTIES
 | 
			
		||||
                IMPORTED_LOCATION
 | 
			
		||||
                    ${BINARY_DIR}/src/port/${ep_lib_prefix}pgport.a
 | 
			
		||||
                INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
                    "${INCLUDE_DIRS}"
 | 
			
		||||
                )
 | 
			
		||||
            add_dependencies(postgres postgres_src)
 | 
			
		||||
            add_dependencies(pgcommon postgres_src)
 | 
			
		||||
            add_dependencies(pgport postgres_src)
 | 
			
		||||
            file(TO_CMAKE_PATH "${postgres_src_SOURCE_DIR}" postgres_src_SOURCE_DIR)
 | 
			
		||||
            target_link_libraries(ripple_libs INTERFACE postgres pgcommon pgport)
 | 
			
		||||
        else()
 | 
			
		||||
            message("Found system installed Postgres via find_libary")
 | 
			
		||||
            target_include_directories(ripple_libs INTERFACE ${libpq-fe})
 | 
			
		||||
            target_link_libraries(ripple_libs INTERFACE ${postgres})
 | 
			
		||||
        endif()
 | 
			
		||||
    else()
 | 
			
		||||
        message("Found system installed Postgres via find_package")
 | 
			
		||||
        target_include_directories(ripple_libs INTERFACE ${PostgreSQL_INCLUDE_DIRS})
 | 
			
		||||
        target_link_libraries(ripple_libs INTERFACE ${PostgreSQL_LIBRARIES})
 | 
			
		||||
    endif()
 | 
			
		||||
endif()
 | 
			
		||||
@@ -1,155 +1,22 @@
 | 
			
		||||
#[===================================================================[
 | 
			
		||||
   import protobuf (lib and compiler) and create a lib
 | 
			
		||||
   from our proto message definitions. If the system protobuf
 | 
			
		||||
   is not found, fallback on EP to download and build a version
 | 
			
		||||
   from official source.
 | 
			
		||||
#]===================================================================]
 | 
			
		||||
find_package(Protobuf 3.8)
 | 
			
		||||
 | 
			
		||||
if (static)
 | 
			
		||||
  set (Protobuf_USE_STATIC_LIBS ON)
 | 
			
		||||
endif ()
 | 
			
		||||
find_package (Protobuf 3.8)
 | 
			
		||||
if (is_multiconfig)
 | 
			
		||||
    set(protobuf_protoc_lib ${Protobuf_PROTOC_LIBRARIES})
 | 
			
		||||
else ()
 | 
			
		||||
    string(TOUPPER ${CMAKE_BUILD_TYPE} upper_cmake_build_type)
 | 
			
		||||
    set(protobuf_protoc_lib ${Protobuf_PROTOC_LIBRARY_${upper_cmake_build_type}})
 | 
			
		||||
endif ()
 | 
			
		||||
if (local_protobuf OR NOT (Protobuf_FOUND AND Protobuf_PROTOC_EXECUTABLE AND protobuf_protoc_lib))
 | 
			
		||||
  include (GNUInstallDirs)
 | 
			
		||||
  message (STATUS "using local protobuf build.")
 | 
			
		||||
  set(protobuf_reqs Protobuf_PROTOC_EXECUTABLE protobuf_protoc_lib)
 | 
			
		||||
  foreach(lib ${protobuf_reqs})
 | 
			
		||||
    if(NOT ${lib})
 | 
			
		||||
      message(STATUS "Couldn't find ${lib}")
 | 
			
		||||
    endif()
 | 
			
		||||
  endforeach()
 | 
			
		||||
  if (WIN32)
 | 
			
		||||
    # protobuf prepends lib even on windows
 | 
			
		||||
    set (pbuf_lib_pre "lib")
 | 
			
		||||
  else ()
 | 
			
		||||
    set (pbuf_lib_pre ${ep_lib_prefix})
 | 
			
		||||
  endif ()
 | 
			
		||||
  # for the external project build of protobuf, we currently ignore the
 | 
			
		||||
  # static option and always build static libs here. This is consistent
 | 
			
		||||
  # with our other EP builds. Dynamic libs in an EP would add complexity
 | 
			
		||||
  # because we'd need to get them into the runtime path, and probably
 | 
			
		||||
  # install them.
 | 
			
		||||
  ExternalProject_Add (protobuf_src
 | 
			
		||||
    PREFIX ${nih_cache_path}
 | 
			
		||||
    GIT_REPOSITORY https://github.com/protocolbuffers/protobuf.git
 | 
			
		||||
    GIT_TAG v3.8.0
 | 
			
		||||
    SOURCE_SUBDIR cmake
 | 
			
		||||
    CMAKE_ARGS
 | 
			
		||||
      -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
 | 
			
		||||
      -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
 | 
			
		||||
      -DCMAKE_INSTALL_PREFIX=<BINARY_DIR>/_installed_
 | 
			
		||||
      -Dprotobuf_BUILD_TESTS=OFF
 | 
			
		||||
      -Dprotobuf_BUILD_EXAMPLES=OFF
 | 
			
		||||
      -Dprotobuf_BUILD_PROTOC_BINARIES=ON
 | 
			
		||||
      -Dprotobuf_MSVC_STATIC_RUNTIME=ON
 | 
			
		||||
      -DBUILD_SHARED_LIBS=OFF
 | 
			
		||||
      -Dprotobuf_BUILD_SHARED_LIBS=OFF
 | 
			
		||||
      -DCMAKE_DEBUG_POSTFIX=_d
 | 
			
		||||
      -Dprotobuf_DEBUG_POSTFIX=_d
 | 
			
		||||
      -Dprotobuf_WITH_ZLIB=$<IF:$<BOOL:${has_zlib}>,ON,OFF>
 | 
			
		||||
      $<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:-DCMAKE_VERBOSE_MAKEFILE=ON>
 | 
			
		||||
      $<$<BOOL:${unity}>:-DCMAKE_UNITY_BUILD=ON}>
 | 
			
		||||
      $<$<NOT:$<BOOL:${is_multiconfig}>>:-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}>
 | 
			
		||||
      $<$<BOOL:${MSVC}>:
 | 
			
		||||
	"-DCMAKE_CXX_FLAGS=-GR -Gd -fp:precise -FS -EHa -MP"
 | 
			
		||||
      >
 | 
			
		||||
    LOG_BUILD ON
 | 
			
		||||
    LOG_CONFIGURE ON
 | 
			
		||||
    BUILD_COMMAND
 | 
			
		||||
      ${CMAKE_COMMAND}
 | 
			
		||||
      --build .
 | 
			
		||||
      --config $<CONFIG>
 | 
			
		||||
      --parallel ${ep_procs}
 | 
			
		||||
    TEST_COMMAND ""
 | 
			
		||||
    INSTALL_COMMAND
 | 
			
		||||
      ${CMAKE_COMMAND} -E env --unset=DESTDIR ${CMAKE_COMMAND} --build . --config $<CONFIG> --target install
 | 
			
		||||
    BUILD_BYPRODUCTS
 | 
			
		||||
      <BINARY_DIR>/_installed_/${CMAKE_INSTALL_LIBDIR}/${pbuf_lib_pre}protobuf${ep_lib_suffix}
 | 
			
		||||
      <BINARY_DIR>/_installed_/${CMAKE_INSTALL_LIBDIR}/${pbuf_lib_pre}protobuf_d${ep_lib_suffix}
 | 
			
		||||
      <BINARY_DIR>/_installed_/${CMAKE_INSTALL_LIBDIR}/${pbuf_lib_pre}protoc${ep_lib_suffix}
 | 
			
		||||
      <BINARY_DIR>/_installed_/${CMAKE_INSTALL_LIBDIR}/${pbuf_lib_pre}protoc_d${ep_lib_suffix}
 | 
			
		||||
      <BINARY_DIR>/_installed_/bin/protoc${CMAKE_EXECUTABLE_SUFFIX}
 | 
			
		||||
  )
 | 
			
		||||
  ExternalProject_Get_Property (protobuf_src BINARY_DIR)
 | 
			
		||||
  ExternalProject_Get_Property (protobuf_src SOURCE_DIR)
 | 
			
		||||
  if (CMAKE_VERBOSE_MAKEFILE)
 | 
			
		||||
    print_ep_logs (protobuf_src)
 | 
			
		||||
  endif ()
 | 
			
		||||
  exclude_if_included (protobuf_src)
 | 
			
		||||
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/proto_gen)
 | 
			
		||||
set(ccbd ${CMAKE_CURRENT_BINARY_DIR})
 | 
			
		||||
set(CMAKE_CURRENT_BINARY_DIR ${CMAKE_BINARY_DIR}/proto_gen)
 | 
			
		||||
protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS src/ripple/proto/ripple.proto)
 | 
			
		||||
set(CMAKE_CURRENT_BINARY_DIR ${ccbd})
 | 
			
		||||
 | 
			
		||||
  if (NOT TARGET protobuf::libprotobuf)
 | 
			
		||||
    add_library (protobuf::libprotobuf STATIC IMPORTED GLOBAL)
 | 
			
		||||
  endif ()
 | 
			
		||||
  file (MAKE_DIRECTORY ${BINARY_DIR}/_installed_/include)
 | 
			
		||||
  set_target_properties (protobuf::libprotobuf PROPERTIES
 | 
			
		||||
    IMPORTED_LOCATION_DEBUG
 | 
			
		||||
      ${BINARY_DIR}/_installed_/${CMAKE_INSTALL_LIBDIR}/${pbuf_lib_pre}protobuf_d${ep_lib_suffix}
 | 
			
		||||
    IMPORTED_LOCATION_RELEASE
 | 
			
		||||
      ${BINARY_DIR}/_installed_/${CMAKE_INSTALL_LIBDIR}/${pbuf_lib_pre}protobuf${ep_lib_suffix}
 | 
			
		||||
    INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
      ${BINARY_DIR}/_installed_/include)
 | 
			
		||||
  add_dependencies (protobuf::libprotobuf protobuf_src)
 | 
			
		||||
  exclude_if_included (protobuf::libprotobuf)
 | 
			
		||||
 | 
			
		||||
  if (NOT TARGET protobuf::libprotoc)
 | 
			
		||||
    add_library (protobuf::libprotoc STATIC IMPORTED GLOBAL)
 | 
			
		||||
  endif ()
 | 
			
		||||
  set_target_properties (protobuf::libprotoc PROPERTIES
 | 
			
		||||
    IMPORTED_LOCATION_DEBUG
 | 
			
		||||
      ${BINARY_DIR}/_installed_/${CMAKE_INSTALL_LIBDIR}/${pbuf_lib_pre}protoc_d${ep_lib_suffix}
 | 
			
		||||
    IMPORTED_LOCATION_RELEASE
 | 
			
		||||
      ${BINARY_DIR}/_installed_/${CMAKE_INSTALL_LIBDIR}/${pbuf_lib_pre}protoc${ep_lib_suffix}
 | 
			
		||||
    INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
      ${BINARY_DIR}/_installed_/include)
 | 
			
		||||
  add_dependencies (protobuf::libprotoc protobuf_src)
 | 
			
		||||
  exclude_if_included (protobuf::libprotoc)
 | 
			
		||||
 | 
			
		||||
  if (NOT TARGET protobuf::protoc)
 | 
			
		||||
    add_executable (protobuf::protoc IMPORTED)
 | 
			
		||||
    exclude_if_included (protobuf::protoc)
 | 
			
		||||
  endif ()
 | 
			
		||||
  set_target_properties (protobuf::protoc PROPERTIES
 | 
			
		||||
    IMPORTED_LOCATION "${BINARY_DIR}/_installed_/bin/protoc${CMAKE_EXECUTABLE_SUFFIX}")
 | 
			
		||||
  add_dependencies (protobuf::protoc protobuf_src)
 | 
			
		||||
else ()
 | 
			
		||||
  if (NOT TARGET protobuf::protoc)
 | 
			
		||||
    if (EXISTS "${Protobuf_PROTOC_EXECUTABLE}")
 | 
			
		||||
      add_executable (protobuf::protoc IMPORTED)
 | 
			
		||||
      set_target_properties (protobuf::protoc PROPERTIES
 | 
			
		||||
        IMPORTED_LOCATION "${Protobuf_PROTOC_EXECUTABLE}")
 | 
			
		||||
    else ()
 | 
			
		||||
      message (FATAL_ERROR "Protobuf import failed")
 | 
			
		||||
    endif ()
 | 
			
		||||
  endif ()
 | 
			
		||||
endif ()
 | 
			
		||||
 | 
			
		||||
file (MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/proto_gen)
 | 
			
		||||
set (save_CBD ${CMAKE_CURRENT_BINARY_DIR})
 | 
			
		||||
set (CMAKE_CURRENT_BINARY_DIR ${CMAKE_BINARY_DIR}/proto_gen)
 | 
			
		||||
protobuf_generate_cpp (
 | 
			
		||||
  PROTO_SRCS
 | 
			
		||||
  PROTO_HDRS
 | 
			
		||||
  src/ripple/proto/ripple.proto)
 | 
			
		||||
set (CMAKE_CURRENT_BINARY_DIR ${save_CBD})
 | 
			
		||||
 | 
			
		||||
add_library (pbufs STATIC ${PROTO_SRCS} ${PROTO_HDRS})
 | 
			
		||||
 | 
			
		||||
target_include_directories (pbufs PRIVATE src)
 | 
			
		||||
target_include_directories (pbufs
 | 
			
		||||
  SYSTEM PUBLIC ${CMAKE_BINARY_DIR}/proto_gen)
 | 
			
		||||
target_link_libraries (pbufs protobuf::libprotobuf)
 | 
			
		||||
target_compile_options (pbufs
 | 
			
		||||
add_library(pbufs STATIC ${PROTO_SRCS} ${PROTO_HDRS})
 | 
			
		||||
target_include_directories(pbufs SYSTEM PUBLIC
 | 
			
		||||
  ${CMAKE_BINARY_DIR}/proto_gen
 | 
			
		||||
  ${CMAKE_BINARY_DIR}/proto_gen/src/ripple/proto
 | 
			
		||||
)
 | 
			
		||||
target_link_libraries(pbufs protobuf::libprotobuf)
 | 
			
		||||
target_compile_options(pbufs
 | 
			
		||||
  PUBLIC
 | 
			
		||||
    $<$<BOOL:${is_xcode}>:
 | 
			
		||||
    $<$<BOOL:${XCODE}>:
 | 
			
		||||
      --system-header-prefix="google/protobuf"
 | 
			
		||||
      -Wno-deprecated-dynamic-exception-spec
 | 
			
		||||
    >)
 | 
			
		||||
add_library (Ripple::pbufs ALIAS pbufs)
 | 
			
		||||
target_link_libraries (ripple_libs INTERFACE Ripple::pbufs)
 | 
			
		||||
exclude_if_included (pbufs)
 | 
			
		||||
    >
 | 
			
		||||
)
 | 
			
		||||
add_library(Ripple::pbufs ALIAS pbufs)
 | 
			
		||||
@@ -1,177 +0,0 @@
 | 
			
		||||
#[===================================================================[
 | 
			
		||||
   NIH dep: rocksdb
 | 
			
		||||
#]===================================================================]
 | 
			
		||||
 | 
			
		||||
add_library (rocksdb_lib UNKNOWN IMPORTED GLOBAL)
 | 
			
		||||
set_target_properties (rocksdb_lib
 | 
			
		||||
  PROPERTIES INTERFACE_COMPILE_DEFINITIONS RIPPLE_ROCKSDB_AVAILABLE=1)
 | 
			
		||||
 | 
			
		||||
option (local_rocksdb "use local build of rocksdb." OFF)
 | 
			
		||||
if (NOT local_rocksdb)
 | 
			
		||||
  find_package (RocksDB 6.27 QUIET CONFIG)
 | 
			
		||||
  if (TARGET RocksDB::rocksdb)
 | 
			
		||||
    message (STATUS "Found RocksDB using config.")
 | 
			
		||||
    get_target_property (_rockslib_l RocksDB::rocksdb IMPORTED_LOCATION_DEBUG)
 | 
			
		||||
    if (_rockslib_l)
 | 
			
		||||
      set_target_properties (rocksdb_lib PROPERTIES IMPORTED_LOCATION_DEBUG ${_rockslib_l})
 | 
			
		||||
    endif ()
 | 
			
		||||
    get_target_property (_rockslib_l RocksDB::rocksdb IMPORTED_LOCATION_RELEASE)
 | 
			
		||||
    if (_rockslib_l)
 | 
			
		||||
      set_target_properties (rocksdb_lib PROPERTIES IMPORTED_LOCATION_RELEASE ${_rockslib_l})
 | 
			
		||||
    endif ()
 | 
			
		||||
    get_target_property (_rockslib_l RocksDB::rocksdb IMPORTED_LOCATION)
 | 
			
		||||
    if (_rockslib_l)
 | 
			
		||||
      set_target_properties (rocksdb_lib PROPERTIES IMPORTED_LOCATION ${_rockslib_l})
 | 
			
		||||
    endif ()
 | 
			
		||||
    get_target_property (_rockslib_i RocksDB::rocksdb INTERFACE_INCLUDE_DIRECTORIES)
 | 
			
		||||
    if (_rockslib_i)
 | 
			
		||||
      set_target_properties (rocksdb_lib PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${_rockslib_i})
 | 
			
		||||
    endif ()
 | 
			
		||||
    target_link_libraries (ripple_libs INTERFACE RocksDB::rocksdb)
 | 
			
		||||
  else ()
 | 
			
		||||
    # using a find module with rocksdb is difficult because
 | 
			
		||||
    # you have no idea how it was configured (transitive dependencies).
 | 
			
		||||
    # the code below will generally find rocksdb using the module, but
 | 
			
		||||
    # will then result in linker errors for static linkage since the
 | 
			
		||||
    # transitive dependencies are unknown. force local build here for now, but leave the code as
 | 
			
		||||
    # a placeholder for future investigation.
 | 
			
		||||
    if (static)
 | 
			
		||||
      set (local_rocksdb ON CACHE BOOL "" FORCE)
 | 
			
		||||
      # TBD if there is some way to extract transitive deps..then:
 | 
			
		||||
      #set (RocksDB_USE_STATIC ON)
 | 
			
		||||
    else ()
 | 
			
		||||
      find_package (RocksDB 6.27 MODULE)
 | 
			
		||||
      if (ROCKSDB_FOUND)
 | 
			
		||||
        if (RocksDB_LIBRARY_DEBUG)
 | 
			
		||||
          set_target_properties (rocksdb_lib PROPERTIES IMPORTED_LOCATION_DEBUG ${RocksDB_LIBRARY_DEBUG})
 | 
			
		||||
        endif ()
 | 
			
		||||
        set_target_properties (rocksdb_lib PROPERTIES IMPORTED_LOCATION_RELEASE ${RocksDB_LIBRARIES})
 | 
			
		||||
        set_target_properties (rocksdb_lib PROPERTIES IMPORTED_LOCATION ${RocksDB_LIBRARIES})
 | 
			
		||||
        set_target_properties (rocksdb_lib PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${RocksDB_INCLUDE_DIRS})
 | 
			
		||||
      else ()
 | 
			
		||||
        set (local_rocksdb ON CACHE BOOL "" FORCE)
 | 
			
		||||
      endif ()
 | 
			
		||||
    endif ()
 | 
			
		||||
  endif ()
 | 
			
		||||
endif ()
 | 
			
		||||
 | 
			
		||||
if (local_rocksdb)
 | 
			
		||||
  message (STATUS "Using local build of RocksDB.")
 | 
			
		||||
  ExternalProject_Add (rocksdb
 | 
			
		||||
    PREFIX ${nih_cache_path}
 | 
			
		||||
    GIT_REPOSITORY https://github.com/facebook/rocksdb.git
 | 
			
		||||
    GIT_TAG v6.27.3
 | 
			
		||||
    PATCH_COMMAND
 | 
			
		||||
      # only used by windows build
 | 
			
		||||
      ${CMAKE_COMMAND} -E copy_if_different
 | 
			
		||||
      ${CMAKE_CURRENT_SOURCE_DIR}/Builds/CMake/rocks_thirdparty.inc
 | 
			
		||||
      <SOURCE_DIR>/thirdparty.inc
 | 
			
		||||
    COMMAND
 | 
			
		||||
      # fixup their build version file to keep the values
 | 
			
		||||
      # from changing always
 | 
			
		||||
      ${CMAKE_COMMAND} -E copy_if_different
 | 
			
		||||
      ${CMAKE_CURRENT_SOURCE_DIR}/Builds/CMake/rocksdb_build_version.cc.in
 | 
			
		||||
      <SOURCE_DIR>/util/build_version.cc.in
 | 
			
		||||
    CMAKE_ARGS
 | 
			
		||||
      -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
 | 
			
		||||
      -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
 | 
			
		||||
      $<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:-DCMAKE_VERBOSE_MAKEFILE=ON>
 | 
			
		||||
      $<$<BOOL:${unity}>:-DCMAKE_UNITY_BUILD=ON}>
 | 
			
		||||
      -DCMAKE_DEBUG_POSTFIX=_d
 | 
			
		||||
      $<$<NOT:$<BOOL:${is_multiconfig}>>:-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}>
 | 
			
		||||
      -DBUILD_SHARED_LIBS=OFF
 | 
			
		||||
      -DCMAKE_POSITION_INDEPENDENT_CODE=ON
 | 
			
		||||
      -DWITH_JEMALLOC=$<IF:$<BOOL:${jemalloc}>,ON,OFF>
 | 
			
		||||
      -DWITH_SNAPPY=ON
 | 
			
		||||
      -DWITH_LZ4=ON
 | 
			
		||||
      -DWITH_ZLIB=OFF
 | 
			
		||||
      -DUSE_RTTI=ON
 | 
			
		||||
      -DWITH_ZSTD=OFF
 | 
			
		||||
      -DWITH_GFLAGS=OFF
 | 
			
		||||
      -DWITH_BZ2=OFF
 | 
			
		||||
      -ULZ4_*
 | 
			
		||||
      -Ulz4_*
 | 
			
		||||
      -Dlz4_INCLUDE_DIRS=$<JOIN:$<TARGET_PROPERTY:lz4_lib,INTERFACE_INCLUDE_DIRECTORIES>,::>
 | 
			
		||||
      -Dlz4_LIBRARIES=$<IF:$<CONFIG:Debug>,$<TARGET_PROPERTY:lz4_lib,IMPORTED_LOCATION_DEBUG>,$<TARGET_PROPERTY:lz4_lib,IMPORTED_LOCATION_RELEASE>>
 | 
			
		||||
      -Dlz4_FOUND=ON
 | 
			
		||||
      -USNAPPY_*
 | 
			
		||||
      -Usnappy_*
 | 
			
		||||
      -USnappy_*
 | 
			
		||||
      -Dsnappy_INCLUDE_DIRS=$<JOIN:$<TARGET_PROPERTY:snappy_lib,INTERFACE_INCLUDE_DIRECTORIES>,::>
 | 
			
		||||
      -Dsnappy_LIBRARIES=$<IF:$<CONFIG:Debug>,$<TARGET_PROPERTY:snappy_lib,IMPORTED_LOCATION_DEBUG>,$<TARGET_PROPERTY:snappy_lib,IMPORTED_LOCATION_RELEASE>>
 | 
			
		||||
      -Dsnappy_FOUND=ON
 | 
			
		||||
      -DSnappy_INCLUDE_DIRS=$<JOIN:$<TARGET_PROPERTY:snappy_lib,INTERFACE_INCLUDE_DIRECTORIES>,::>
 | 
			
		||||
      -DSnappy_LIBRARIES=$<IF:$<CONFIG:Debug>,$<TARGET_PROPERTY:snappy_lib,IMPORTED_LOCATION_DEBUG>,$<TARGET_PROPERTY:snappy_lib,IMPORTED_LOCATION_RELEASE>>
 | 
			
		||||
      -DSnappy_FOUND=ON
 | 
			
		||||
      -DWITH_MD_LIBRARY=OFF
 | 
			
		||||
      -DWITH_RUNTIME_DEBUG=$<IF:$<CONFIG:Debug>,ON,OFF>
 | 
			
		||||
      -DFAIL_ON_WARNINGS=OFF
 | 
			
		||||
      -DWITH_ASAN=OFF
 | 
			
		||||
      -DWITH_TSAN=OFF
 | 
			
		||||
      -DWITH_UBSAN=OFF
 | 
			
		||||
      -DWITH_NUMA=OFF
 | 
			
		||||
      -DWITH_TBB=OFF
 | 
			
		||||
      -DWITH_WINDOWS_UTF8_FILENAMES=OFF
 | 
			
		||||
      -DWITH_XPRESS=OFF
 | 
			
		||||
      -DPORTABLE=ON
 | 
			
		||||
      -DFORCE_SSE42=OFF
 | 
			
		||||
      -DDISABLE_STALL_NOTIF=OFF
 | 
			
		||||
      -DOPTDBG=ON
 | 
			
		||||
      -DROCKSDB_LITE=OFF
 | 
			
		||||
      -DWITH_FALLOCATE=ON
 | 
			
		||||
      -DWITH_LIBRADOS=OFF
 | 
			
		||||
      -DWITH_JNI=OFF
 | 
			
		||||
      -DROCKSDB_INSTALL_ON_WINDOWS=OFF
 | 
			
		||||
      -DWITH_TESTS=OFF
 | 
			
		||||
      -DWITH_TOOLS=OFF
 | 
			
		||||
      $<$<BOOL:${MSVC}>:
 | 
			
		||||
        "-DCMAKE_CXX_FLAGS=-GR -Gd -fp:precise -FS -MP /DNDEBUG"
 | 
			
		||||
      >
 | 
			
		||||
      $<$<NOT:$<BOOL:${MSVC}>>:
 | 
			
		||||
        "-DCMAKE_CXX_FLAGS=-DNDEBUG"
 | 
			
		||||
      >
 | 
			
		||||
    LOG_BUILD ON
 | 
			
		||||
    LOG_CONFIGURE ON
 | 
			
		||||
    BUILD_COMMAND
 | 
			
		||||
      ${CMAKE_COMMAND}
 | 
			
		||||
      --build .
 | 
			
		||||
      --config $<CONFIG>
 | 
			
		||||
      --parallel ${ep_procs}
 | 
			
		||||
      $<$<BOOL:${is_multiconfig}>:
 | 
			
		||||
        COMMAND
 | 
			
		||||
          ${CMAKE_COMMAND} -E copy
 | 
			
		||||
          <BINARY_DIR>/$<CONFIG>/${ep_lib_prefix}rocksdb$<$<CONFIG:Debug>:_d>${ep_lib_suffix}
 | 
			
		||||
          <BINARY_DIR>
 | 
			
		||||
        >
 | 
			
		||||
    LIST_SEPARATOR ::
 | 
			
		||||
    TEST_COMMAND ""
 | 
			
		||||
    INSTALL_COMMAND ""
 | 
			
		||||
    DEPENDS snappy_lib lz4_lib
 | 
			
		||||
    BUILD_BYPRODUCTS
 | 
			
		||||
      <BINARY_DIR>/${ep_lib_prefix}rocksdb${ep_lib_suffix}
 | 
			
		||||
      <BINARY_DIR>/${ep_lib_prefix}rocksdb_d${ep_lib_suffix}
 | 
			
		||||
  )
 | 
			
		||||
  ExternalProject_Get_Property (rocksdb BINARY_DIR)
 | 
			
		||||
  ExternalProject_Get_Property (rocksdb SOURCE_DIR)
 | 
			
		||||
  if (CMAKE_VERBOSE_MAKEFILE)
 | 
			
		||||
    print_ep_logs (rocksdb)
 | 
			
		||||
  endif ()
 | 
			
		||||
  file (MAKE_DIRECTORY ${SOURCE_DIR}/include)
 | 
			
		||||
  set_target_properties (rocksdb_lib PROPERTIES
 | 
			
		||||
    IMPORTED_LOCATION_DEBUG
 | 
			
		||||
      ${BINARY_DIR}/${ep_lib_prefix}rocksdb_d${ep_lib_suffix}
 | 
			
		||||
    IMPORTED_LOCATION_RELEASE
 | 
			
		||||
      ${BINARY_DIR}/${ep_lib_prefix}rocksdb${ep_lib_suffix}
 | 
			
		||||
    INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
      ${SOURCE_DIR}/include)
 | 
			
		||||
  add_dependencies (rocksdb_lib rocksdb)
 | 
			
		||||
  exclude_if_included (rocksdb)
 | 
			
		||||
endif ()
 | 
			
		||||
 | 
			
		||||
target_link_libraries (rocksdb_lib
 | 
			
		||||
  INTERFACE
 | 
			
		||||
    snappy_lib
 | 
			
		||||
    lz4_lib
 | 
			
		||||
    $<$<BOOL:${MSVC}>:rpcrt4>)
 | 
			
		||||
exclude_if_included (rocksdb_lib)
 | 
			
		||||
target_link_libraries (ripple_libs INTERFACE rocksdb_lib)
 | 
			
		||||
@@ -1,58 +0,0 @@
 | 
			
		||||
#[===================================================================[
 | 
			
		||||
   NIH dep: secp256k1
 | 
			
		||||
#]===================================================================]
 | 
			
		||||
 | 
			
		||||
add_library (secp256k1_lib STATIC IMPORTED GLOBAL)
 | 
			
		||||
 | 
			
		||||
if (NOT WIN32)
 | 
			
		||||
  find_package(secp256k1)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
if(secp256k1)
 | 
			
		||||
  set_target_properties (secp256k1_lib PROPERTIES
 | 
			
		||||
    IMPORTED_LOCATION_DEBUG
 | 
			
		||||
      ${secp256k1}
 | 
			
		||||
    IMPORTED_LOCATION_RELEASE
 | 
			
		||||
      ${secp256k1}
 | 
			
		||||
    INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
      ${SECP256K1_INCLUDE_DIR})
 | 
			
		||||
 | 
			
		||||
  add_library (secp256k1 ALIAS secp256k1_lib)
 | 
			
		||||
  add_library (NIH::secp256k1 ALIAS secp256k1_lib)
 | 
			
		||||
 | 
			
		||||
else()
 | 
			
		||||
  set(INSTALL_SECP256K1 true)
 | 
			
		||||
 | 
			
		||||
  add_library (secp256k1 STATIC
 | 
			
		||||
    src/secp256k1/src/secp256k1.c)
 | 
			
		||||
  target_compile_definitions (secp256k1
 | 
			
		||||
    PRIVATE
 | 
			
		||||
      USE_NUM_NONE
 | 
			
		||||
      USE_FIELD_10X26
 | 
			
		||||
      USE_FIELD_INV_BUILTIN
 | 
			
		||||
      USE_SCALAR_8X32
 | 
			
		||||
      USE_SCALAR_INV_BUILTIN)
 | 
			
		||||
  target_include_directories (secp256k1
 | 
			
		||||
    PUBLIC
 | 
			
		||||
      $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
 | 
			
		||||
      $<INSTALL_INTERFACE:include>
 | 
			
		||||
    PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/secp256k1)
 | 
			
		||||
  target_compile_options (secp256k1
 | 
			
		||||
    PRIVATE
 | 
			
		||||
      $<$<BOOL:${MSVC}>:-wd4319>
 | 
			
		||||
      $<$<NOT:$<BOOL:${MSVC}>>:
 | 
			
		||||
        -Wno-deprecated-declarations
 | 
			
		||||
        -Wno-unused-function
 | 
			
		||||
      >
 | 
			
		||||
      $<$<BOOL:${is_gcc}>:-Wno-nonnull-compare>)
 | 
			
		||||
  target_link_libraries (ripple_libs INTERFACE NIH::secp256k1)
 | 
			
		||||
#[===========================[
 | 
			
		||||
     headers installation
 | 
			
		||||
#]===========================]
 | 
			
		||||
  install (
 | 
			
		||||
    FILES
 | 
			
		||||
      src/secp256k1/include/secp256k1.h
 | 
			
		||||
  DESTINATION include/secp256k1/include)
 | 
			
		||||
 | 
			
		||||
  add_library (NIH::secp256k1 ALIAS secp256k1)
 | 
			
		||||
endif()
 | 
			
		||||
@@ -1,77 +0,0 @@
 | 
			
		||||
#[===================================================================[
 | 
			
		||||
   NIH dep: snappy
 | 
			
		||||
#]===================================================================]
 | 
			
		||||
 | 
			
		||||
add_library (snappy_lib STATIC IMPORTED GLOBAL)
 | 
			
		||||
 | 
			
		||||
if (NOT WIN32)
 | 
			
		||||
  find_package(snappy)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
if(snappy)
 | 
			
		||||
  set_target_properties (snappy_lib PROPERTIES
 | 
			
		||||
    IMPORTED_LOCATION_DEBUG
 | 
			
		||||
      ${snappy}
 | 
			
		||||
    IMPORTED_LOCATION_RELEASE
 | 
			
		||||
      ${snappy}
 | 
			
		||||
    INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
    ${SNAPPY_INCLUDE_DIR})
 | 
			
		||||
 | 
			
		||||
else()
 | 
			
		||||
  ExternalProject_Add (snappy
 | 
			
		||||
    PREFIX ${nih_cache_path}
 | 
			
		||||
    GIT_REPOSITORY https://github.com/google/snappy.git
 | 
			
		||||
    GIT_TAG 1.1.7
 | 
			
		||||
    CMAKE_ARGS
 | 
			
		||||
      -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
 | 
			
		||||
      -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
 | 
			
		||||
      $<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:-DCMAKE_VERBOSE_MAKEFILE=ON>
 | 
			
		||||
      -DCMAKE_DEBUG_POSTFIX=_d
 | 
			
		||||
      $<$<NOT:$<BOOL:${is_multiconfig}>>:-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}>
 | 
			
		||||
      -DBUILD_SHARED_LIBS=OFF
 | 
			
		||||
      -DCMAKE_POSITION_INDEPENDENT_CODE=ON
 | 
			
		||||
      -DSNAPPY_BUILD_TESTS=OFF
 | 
			
		||||
      $<$<BOOL:${MSVC}>:
 | 
			
		||||
        "-DCMAKE_CXX_FLAGS=-GR -Gd -fp:precise -FS -EHa -MP"
 | 
			
		||||
        "-DCMAKE_CXX_FLAGS_DEBUG=-MTd"
 | 
			
		||||
        "-DCMAKE_CXX_FLAGS_RELEASE=-MT"
 | 
			
		||||
      >
 | 
			
		||||
    LOG_BUILD ON
 | 
			
		||||
    LOG_CONFIGURE ON
 | 
			
		||||
    BUILD_COMMAND
 | 
			
		||||
      ${CMAKE_COMMAND}
 | 
			
		||||
      --build .
 | 
			
		||||
      --config $<CONFIG>
 | 
			
		||||
      --parallel ${ep_procs}
 | 
			
		||||
      $<$<BOOL:${is_multiconfig}>:
 | 
			
		||||
        COMMAND
 | 
			
		||||
          ${CMAKE_COMMAND} -E copy
 | 
			
		||||
          <BINARY_DIR>/$<CONFIG>/${ep_lib_prefix}snappy$<$<CONFIG:Debug>:_d>${ep_lib_suffix}
 | 
			
		||||
          <BINARY_DIR>
 | 
			
		||||
        >
 | 
			
		||||
    TEST_COMMAND ""
 | 
			
		||||
    INSTALL_COMMAND
 | 
			
		||||
      ${CMAKE_COMMAND} -E copy_if_different <BINARY_DIR>/config.h <BINARY_DIR>/snappy-stubs-public.h <SOURCE_DIR>
 | 
			
		||||
    BUILD_BYPRODUCTS
 | 
			
		||||
      <BINARY_DIR>/${ep_lib_prefix}snappy${ep_lib_suffix}
 | 
			
		||||
      <BINARY_DIR>/${ep_lib_prefix}snappy_d${ep_lib_suffix}
 | 
			
		||||
  )
 | 
			
		||||
  ExternalProject_Get_Property (snappy BINARY_DIR)
 | 
			
		||||
  ExternalProject_Get_Property (snappy SOURCE_DIR)
 | 
			
		||||
  if (CMAKE_VERBOSE_MAKEFILE)
 | 
			
		||||
    print_ep_logs (snappy)
 | 
			
		||||
  endif ()
 | 
			
		||||
  file (MAKE_DIRECTORY ${SOURCE_DIR}/snappy)
 | 
			
		||||
  set_target_properties (snappy_lib PROPERTIES
 | 
			
		||||
    IMPORTED_LOCATION_DEBUG
 | 
			
		||||
      ${BINARY_DIR}/${ep_lib_prefix}snappy_d${ep_lib_suffix}
 | 
			
		||||
    IMPORTED_LOCATION_RELEASE
 | 
			
		||||
      ${BINARY_DIR}/${ep_lib_prefix}snappy${ep_lib_suffix}
 | 
			
		||||
    INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
      ${SOURCE_DIR})
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
add_dependencies (snappy_lib snappy)
 | 
			
		||||
target_link_libraries (ripple_libs INTERFACE snappy_lib)
 | 
			
		||||
exclude_if_included (snappy)
 | 
			
		||||
exclude_if_included (snappy_lib)
 | 
			
		||||
@@ -1,165 +0,0 @@
 | 
			
		||||
#[===================================================================[
 | 
			
		||||
   NIH dep: soci
 | 
			
		||||
#]===================================================================]
 | 
			
		||||
 | 
			
		||||
foreach (_comp core empty sqlite3)
 | 
			
		||||
  add_library ("soci_${_comp}" STATIC IMPORTED GLOBAL)
 | 
			
		||||
endforeach ()
 | 
			
		||||
 | 
			
		||||
if (NOT WIN32)
 | 
			
		||||
  find_package(soci)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
if (soci)
 | 
			
		||||
  foreach (_comp core empty sqlite3)
 | 
			
		||||
    set_target_properties ("soci_${_comp}" PROPERTIES
 | 
			
		||||
      IMPORTED_LOCATION_DEBUG
 | 
			
		||||
        ${soci}
 | 
			
		||||
      IMPORTED_LOCATION_RELEASE
 | 
			
		||||
        ${soci}
 | 
			
		||||
      INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
        ${SOCI_INCLUDE_DIR})
 | 
			
		||||
  endforeach ()
 | 
			
		||||
 | 
			
		||||
else()
 | 
			
		||||
  set (soci_lib_pre ${ep_lib_prefix})
 | 
			
		||||
  set (soci_lib_post "")
 | 
			
		||||
  if (WIN32)
 | 
			
		||||
    # for some reason soci on windows still prepends lib (non-standard)
 | 
			
		||||
    set (soci_lib_pre lib)
 | 
			
		||||
    # this version in the name might change if/when we change versions of soci
 | 
			
		||||
    set (soci_lib_post "_4_0")
 | 
			
		||||
  endif ()
 | 
			
		||||
  get_target_property (_boost_incs Boost::date_time INTERFACE_INCLUDE_DIRECTORIES)
 | 
			
		||||
  get_target_property (_boost_dt Boost::date_time IMPORTED_LOCATION)
 | 
			
		||||
  if (NOT _boost_dt)
 | 
			
		||||
    get_target_property (_boost_dt Boost::date_time IMPORTED_LOCATION_RELEASE)
 | 
			
		||||
  endif ()
 | 
			
		||||
  if (NOT _boost_dt)
 | 
			
		||||
    get_target_property (_boost_dt Boost::date_time IMPORTED_LOCATION_DEBUG)
 | 
			
		||||
  endif ()
 | 
			
		||||
 | 
			
		||||
  ExternalProject_Add (soci
 | 
			
		||||
    PREFIX ${nih_cache_path}
 | 
			
		||||
    GIT_REPOSITORY https://github.com/SOCI/soci.git
 | 
			
		||||
    GIT_TAG 04e1870294918d20761736743bb6136314c42dd5
 | 
			
		||||
    # We had an issue with soci integer range checking for boost::optional
 | 
			
		||||
    # and needed to remove the exception that SOCI throws in this case.
 | 
			
		||||
    # This is *probably* a bug in SOCI, but has never been investigated more
 | 
			
		||||
    # nor reported to the maintainers.
 | 
			
		||||
    # This cmake script comments out the lines in question.
 | 
			
		||||
    # This patch process is likely fragile and should be reviewed carefully
 | 
			
		||||
    # whenever we update the GIT_TAG above.
 | 
			
		||||
    PATCH_COMMAND
 | 
			
		||||
      ${CMAKE_COMMAND} -D RIPPLED_SOURCE=${CMAKE_CURRENT_SOURCE_DIR}
 | 
			
		||||
        -P ${CMAKE_CURRENT_SOURCE_DIR}/Builds/CMake/soci_patch.cmake
 | 
			
		||||
    CMAKE_ARGS
 | 
			
		||||
      -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
 | 
			
		||||
      -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
 | 
			
		||||
      $<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:-DCMAKE_VERBOSE_MAKEFILE=ON>
 | 
			
		||||
      $<$<BOOL:${CMAKE_TOOLCHAIN_FILE}>:-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}>
 | 
			
		||||
      $<$<BOOL:${VCPKG_TARGET_TRIPLET}>:-DVCPKG_TARGET_TRIPLET=${VCPKG_TARGET_TRIPLET}>
 | 
			
		||||
      $<$<BOOL:${unity}>:-DCMAKE_UNITY_BUILD=ON}>
 | 
			
		||||
      -DCMAKE_PREFIX_PATH=${CMAKE_BINARY_DIR}/sqlite3
 | 
			
		||||
      -DCMAKE_MODULE_PATH=${CMAKE_CURRENT_SOURCE_DIR}/Builds/CMake
 | 
			
		||||
      -DCMAKE_INCLUDE_PATH=$<JOIN:$<TARGET_PROPERTY:sqlite,INTERFACE_INCLUDE_DIRECTORIES>,::>
 | 
			
		||||
      -DCMAKE_LIBRARY_PATH=${sqlite_BINARY_DIR}
 | 
			
		||||
      -DCMAKE_DEBUG_POSTFIX=_d
 | 
			
		||||
      $<$<NOT:$<BOOL:${is_multiconfig}>>:-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}>
 | 
			
		||||
      -DSOCI_CXX_C11=ON
 | 
			
		||||
      -DSOCI_STATIC=ON
 | 
			
		||||
      -DSOCI_LIBDIR=lib
 | 
			
		||||
      -DSOCI_SHARED=OFF
 | 
			
		||||
      -DSOCI_TESTS=OFF
 | 
			
		||||
      # hacks to workaround the fact that soci doesn't currently use
 | 
			
		||||
      # boost imported targets in its cmake. If they switch to
 | 
			
		||||
      # proper imported targets, this next line can be removed
 | 
			
		||||
      # (as well as the get_property above that sets _boost_incs)
 | 
			
		||||
      -DBoost_INCLUDE_DIRS=$<JOIN:${_boost_incs},::>
 | 
			
		||||
      -DBoost_INCLUDE_DIR=$<JOIN:${_boost_incs},::>
 | 
			
		||||
      -DBOOST_ROOT=${BOOST_ROOT}
 | 
			
		||||
      -DWITH_BOOST=ON
 | 
			
		||||
      -DBoost_FOUND=ON
 | 
			
		||||
      -DBoost_NO_BOOST_CMAKE=ON
 | 
			
		||||
      -DBoost_DATE_TIME_FOUND=ON
 | 
			
		||||
      -DSOCI_HAVE_BOOST=ON
 | 
			
		||||
      -DSOCI_HAVE_BOOST_DATE_TIME=ON
 | 
			
		||||
      -DBoost_DATE_TIME_LIBRARY=${_boost_dt}
 | 
			
		||||
      -DSOCI_DB2=OFF
 | 
			
		||||
      -DSOCI_FIREBIRD=OFF
 | 
			
		||||
      -DSOCI_MYSQL=OFF
 | 
			
		||||
      -DSOCI_ODBC=OFF
 | 
			
		||||
      -DSOCI_ORACLE=OFF
 | 
			
		||||
      -DSOCI_POSTGRESQL=OFF
 | 
			
		||||
      -DSOCI_SQLITE3=ON
 | 
			
		||||
      -DSQLITE3_INCLUDE_DIR=$<JOIN:$<TARGET_PROPERTY:sqlite,INTERFACE_INCLUDE_DIRECTORIES>,::>
 | 
			
		||||
      -DSQLITE3_LIBRARY=$<IF:$<CONFIG:Debug>,$<TARGET_PROPERTY:sqlite,IMPORTED_LOCATION_DEBUG>,$<TARGET_PROPERTY:sqlite,IMPORTED_LOCATION_RELEASE>>
 | 
			
		||||
      $<$<BOOL:${APPLE}>:-DCMAKE_FIND_FRAMEWORK=LAST>
 | 
			
		||||
      $<$<BOOL:${MSVC}>:
 | 
			
		||||
        "-DCMAKE_CXX_FLAGS=-GR -Gd -fp:precise -FS -EHa -MP"
 | 
			
		||||
        "-DCMAKE_CXX_FLAGS_DEBUG=-MTd"
 | 
			
		||||
        "-DCMAKE_CXX_FLAGS_RELEASE=-MT"
 | 
			
		||||
      >
 | 
			
		||||
      $<$<NOT:$<BOOL:${MSVC}>>:
 | 
			
		||||
        "-DCMAKE_CXX_FLAGS=-Wno-deprecated-declarations"
 | 
			
		||||
      >
 | 
			
		||||
      # SEE: https://github.com/SOCI/soci/issues/640
 | 
			
		||||
      $<$<AND:$<BOOL:${is_gcc}>,$<VERSION_GREATER_EQUAL:${CMAKE_CXX_COMPILER_VERSION},8>>:
 | 
			
		||||
        "-DCMAKE_CXX_FLAGS=-Wno-deprecated-declarations -Wno-error=format-overflow -Wno-format-overflow -Wno-error=format-truncation"
 | 
			
		||||
      >
 | 
			
		||||
    LIST_SEPARATOR ::
 | 
			
		||||
    LOG_BUILD ON
 | 
			
		||||
    LOG_CONFIGURE ON
 | 
			
		||||
    BUILD_COMMAND
 | 
			
		||||
      ${CMAKE_COMMAND}
 | 
			
		||||
      --build .
 | 
			
		||||
      --config $<CONFIG>
 | 
			
		||||
      --parallel ${ep_procs}
 | 
			
		||||
      $<$<BOOL:${is_multiconfig}>:
 | 
			
		||||
        COMMAND
 | 
			
		||||
          ${CMAKE_COMMAND} -E copy
 | 
			
		||||
          <BINARY_DIR>/lib/$<CONFIG>/${soci_lib_pre}soci_core${soci_lib_post}$<$<CONFIG:Debug>:_d>${ep_lib_suffix}
 | 
			
		||||
          <BINARY_DIR>/lib/$<CONFIG>/${soci_lib_pre}soci_empty${soci_lib_post}$<$<CONFIG:Debug>:_d>${ep_lib_suffix}
 | 
			
		||||
          <BINARY_DIR>/lib/$<CONFIG>/${soci_lib_pre}soci_sqlite3${soci_lib_post}$<$<CONFIG:Debug>:_d>${ep_lib_suffix}
 | 
			
		||||
          <BINARY_DIR>/lib
 | 
			
		||||
        >
 | 
			
		||||
    TEST_COMMAND ""
 | 
			
		||||
    INSTALL_COMMAND ""
 | 
			
		||||
    DEPENDS sqlite
 | 
			
		||||
    BUILD_BYPRODUCTS
 | 
			
		||||
      <BINARY_DIR>/lib/${soci_lib_pre}soci_core${soci_lib_post}${ep_lib_suffix}
 | 
			
		||||
      <BINARY_DIR>/lib/${soci_lib_pre}soci_core${soci_lib_post}_d${ep_lib_suffix}
 | 
			
		||||
      <BINARY_DIR>/lib/${soci_lib_pre}soci_empty${soci_lib_post}${ep_lib_suffix}
 | 
			
		||||
      <BINARY_DIR>/lib/${soci_lib_pre}soci_empty${soci_lib_post}_d${ep_lib_suffix}
 | 
			
		||||
      <BINARY_DIR>/lib/${soci_lib_pre}soci_sqlite3${soci_lib_post}${ep_lib_suffix}
 | 
			
		||||
      <BINARY_DIR>/lib/${soci_lib_pre}soci_sqlite3${soci_lib_post}_d${ep_lib_suffix}
 | 
			
		||||
  )
 | 
			
		||||
  ExternalProject_Get_Property (soci BINARY_DIR)
 | 
			
		||||
  ExternalProject_Get_Property (soci SOURCE_DIR)
 | 
			
		||||
  if (CMAKE_VERBOSE_MAKEFILE)
 | 
			
		||||
    print_ep_logs (soci)
 | 
			
		||||
  endif ()
 | 
			
		||||
  file (MAKE_DIRECTORY ${SOURCE_DIR}/include)
 | 
			
		||||
  file (MAKE_DIRECTORY ${BINARY_DIR}/include)
 | 
			
		||||
  foreach (_comp core empty sqlite3)
 | 
			
		||||
    set_target_properties ("soci_${_comp}" PROPERTIES
 | 
			
		||||
      IMPORTED_LOCATION_DEBUG
 | 
			
		||||
        ${BINARY_DIR}/lib/${soci_lib_pre}soci_${_comp}${soci_lib_post}_d${ep_lib_suffix}
 | 
			
		||||
      IMPORTED_LOCATION_RELEASE
 | 
			
		||||
        ${BINARY_DIR}/lib/${soci_lib_pre}soci_${_comp}${soci_lib_post}${ep_lib_suffix}
 | 
			
		||||
      INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
        "${SOURCE_DIR}/include;${BINARY_DIR}/include")
 | 
			
		||||
    add_dependencies ("soci_${_comp}" soci) # something has to depend on the ExternalProject to trigger it
 | 
			
		||||
    target_link_libraries (ripple_libs INTERFACE "soci_${_comp}")
 | 
			
		||||
    if (NOT _comp STREQUAL "core")
 | 
			
		||||
      target_link_libraries ("soci_${_comp}" INTERFACE soci_core)
 | 
			
		||||
    endif ()
 | 
			
		||||
  endforeach ()
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
foreach (_comp core empty sqlite3)
 | 
			
		||||
  exclude_if_included ("soci_${_comp}")
 | 
			
		||||
endforeach ()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
exclude_if_included (soci)
 | 
			
		||||
@@ -1,93 +0,0 @@
 | 
			
		||||
#[===================================================================[
 | 
			
		||||
   NIH dep: sqlite
 | 
			
		||||
#]===================================================================]
 | 
			
		||||
 | 
			
		||||
add_library (sqlite STATIC IMPORTED GLOBAL)
 | 
			
		||||
 | 
			
		||||
if (NOT WIN32)
 | 
			
		||||
  find_package(sqlite)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if(sqlite3)
 | 
			
		||||
  set_target_properties (sqlite PROPERTIES
 | 
			
		||||
    IMPORTED_LOCATION_DEBUG
 | 
			
		||||
      ${sqlite3}
 | 
			
		||||
    IMPORTED_LOCATION_RELEASE
 | 
			
		||||
      ${sqlite3}
 | 
			
		||||
    INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
    ${SQLITE_INCLUDE_DIR})
 | 
			
		||||
 | 
			
		||||
else()
 | 
			
		||||
  ExternalProject_Add (sqlite3
 | 
			
		||||
    PREFIX ${nih_cache_path}
 | 
			
		||||
    # sqlite doesn't use git, but it provides versioned tarballs
 | 
			
		||||
    URL https://www.sqlite.org/2018/sqlite-amalgamation-3260000.zip
 | 
			
		||||
      http://www.sqlite.org/2018/sqlite-amalgamation-3260000.zip
 | 
			
		||||
      https://www2.sqlite.org/2018/sqlite-amalgamation-3260000.zip
 | 
			
		||||
      http://www2.sqlite.org/2018/sqlite-amalgamation-3260000.zip
 | 
			
		||||
    # ^^^ version is apparent in the URL:  3260000 => 3.26.0
 | 
			
		||||
    URL_HASH SHA256=de5dcab133aa339a4cf9e97c40aa6062570086d6085d8f9ad7bc6ddf8a52096e
 | 
			
		||||
    # Don't need to worry about MITM attacks too much because the download
 | 
			
		||||
    # is checked against a strong hash
 | 
			
		||||
    TLS_VERIFY false
 | 
			
		||||
    # we wrote a very simple CMake file to build sqlite
 | 
			
		||||
    # so that's what we copy here so that we can build with
 | 
			
		||||
    # CMake. sqlite doesn't generally provided a build system
 | 
			
		||||
    # for the single amalgamation source file.
 | 
			
		||||
    PATCH_COMMAND
 | 
			
		||||
      ${CMAKE_COMMAND} -E copy_if_different
 | 
			
		||||
      ${CMAKE_CURRENT_SOURCE_DIR}/Builds/CMake/CMake_sqlite3.txt
 | 
			
		||||
      <SOURCE_DIR>/CMakeLists.txt
 | 
			
		||||
    CMAKE_ARGS
 | 
			
		||||
      -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
 | 
			
		||||
      -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
 | 
			
		||||
      $<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:-DCMAKE_VERBOSE_MAKEFILE=ON>
 | 
			
		||||
      -DCMAKE_DEBUG_POSTFIX=_d
 | 
			
		||||
      $<$<NOT:$<BOOL:${is_multiconfig}>>:-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}>
 | 
			
		||||
      $<$<BOOL:${MSVC}>:
 | 
			
		||||
        "-DCMAKE_C_FLAGS=-GR -Gd -fp:precise -FS -MP"
 | 
			
		||||
        "-DCMAKE_C_FLAGS_DEBUG=-MTd"
 | 
			
		||||
        "-DCMAKE_C_FLAGS_RELEASE=-MT"
 | 
			
		||||
      >
 | 
			
		||||
    LOG_BUILD ON
 | 
			
		||||
    LOG_CONFIGURE ON
 | 
			
		||||
    BUILD_COMMAND
 | 
			
		||||
      ${CMAKE_COMMAND}
 | 
			
		||||
      --build .
 | 
			
		||||
      --config $<CONFIG>
 | 
			
		||||
      --parallel ${ep_procs}
 | 
			
		||||
      $<$<BOOL:${is_multiconfig}>:
 | 
			
		||||
        COMMAND
 | 
			
		||||
          ${CMAKE_COMMAND} -E copy
 | 
			
		||||
            <BINARY_DIR>/$<CONFIG>/${ep_lib_prefix}sqlite3$<$<CONFIG:Debug>:_d>${ep_lib_suffix}
 | 
			
		||||
            <BINARY_DIR>
 | 
			
		||||
        >
 | 
			
		||||
    TEST_COMMAND ""
 | 
			
		||||
    INSTALL_COMMAND ""
 | 
			
		||||
    BUILD_BYPRODUCTS
 | 
			
		||||
      <BINARY_DIR>/${ep_lib_prefix}sqlite3${ep_lib_suffix}
 | 
			
		||||
      <BINARY_DIR>/${ep_lib_prefix}sqlite3_d${ep_lib_suffix}
 | 
			
		||||
  )
 | 
			
		||||
  ExternalProject_Get_Property (sqlite3 BINARY_DIR)
 | 
			
		||||
  ExternalProject_Get_Property (sqlite3 SOURCE_DIR)
 | 
			
		||||
  if (CMAKE_VERBOSE_MAKEFILE)
 | 
			
		||||
    print_ep_logs (sqlite3)
 | 
			
		||||
  endif ()
 | 
			
		||||
 | 
			
		||||
  set_target_properties (sqlite PROPERTIES
 | 
			
		||||
    IMPORTED_LOCATION_DEBUG
 | 
			
		||||
      ${BINARY_DIR}/${ep_lib_prefix}sqlite3_d${ep_lib_suffix}
 | 
			
		||||
    IMPORTED_LOCATION_RELEASE
 | 
			
		||||
      ${BINARY_DIR}/${ep_lib_prefix}sqlite3${ep_lib_suffix}
 | 
			
		||||
    INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
      ${SOURCE_DIR})
 | 
			
		||||
 | 
			
		||||
  add_dependencies (sqlite sqlite3)
 | 
			
		||||
  exclude_if_included (sqlite3)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
target_link_libraries (sqlite INTERFACE $<$<NOT:$<BOOL:${MSVC}>>:dl>)
 | 
			
		||||
target_link_libraries (ripple_libs INTERFACE sqlite)
 | 
			
		||||
exclude_if_included (sqlite)
 | 
			
		||||
set(sqlite_BINARY_DIR ${BINARY_DIR})
 | 
			
		||||
@@ -1,84 +1 @@
 | 
			
		||||
#[===================================================================[
 | 
			
		||||
 NIH dep: wasmedge: web assembly runtime for hooks.
 | 
			
		||||
#]===================================================================]
 | 
			
		||||
 | 
			
		||||
find_package(Curses)
 | 
			
		||||
if(CURSES_FOUND)
 | 
			
		||||
  include_directories(${CURSES_INCLUDE_DIR})
 | 
			
		||||
  target_link_libraries(ripple_libs INTERFACE ${CURSES_LIBRARY})
 | 
			
		||||
else()
 | 
			
		||||
  message(WARNING "CURSES library not found... (only important for mac builds)")
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
find_package(LLVM REQUIRED CONFIG)
 | 
			
		||||
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
 | 
			
		||||
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
 | 
			
		||||
ExternalProject_Add (wasmedge_src
 | 
			
		||||
  PREFIX ${nih_cache_path}
 | 
			
		||||
  GIT_REPOSITORY https://github.com/WasmEdge/WasmEdge.git
 | 
			
		||||
  GIT_TAG 0.11.2
 | 
			
		||||
  CMAKE_ARGS
 | 
			
		||||
    -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
 | 
			
		||||
    -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
 | 
			
		||||
    $<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:-DCMAKE_VERBOSE_MAKEFILE=ON>
 | 
			
		||||
    -DCMAKE_DEBUG_POSTFIX=_d
 | 
			
		||||
    -DWASMEDGE_BUILD_SHARED_LIB=OFF
 | 
			
		||||
    -DWASMEDGE_BUILD_STATIC_LIB=ON
 | 
			
		||||
    -DWASMEDGE_BUILD_AOT_RUNTIME=ON
 | 
			
		||||
    -DWASMEDGE_FORCE_DISABLE_LTO=ON
 | 
			
		||||
    -DWASMEDGE_LINK_LLVM_STATIC=ON
 | 
			
		||||
    -DWASMEDGE_LINK_TOOLS_STATIC=ON
 | 
			
		||||
    -DWASMEDGE_BUILD_PLUGINS=OFF
 | 
			
		||||
    -DCMAKE_POSITION_INDEPENDENT_CODE=ON
 | 
			
		||||
    -DLLVM_DIR=${LLVM_DIR}
 | 
			
		||||
    -DLLVM_LIBRARY_DIR=${LLVM_LIBRARY_DIR}
 | 
			
		||||
    -DLLVM_ENABLE_TERMINFO=OFF
 | 
			
		||||
    $<$<NOT:$<BOOL:${is_multiconfig}>>:-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}>
 | 
			
		||||
    $<$<BOOL:${MSVC}>:
 | 
			
		||||
      "-DCMAKE_C_FLAGS=-GR -Gd -fp:precise -FS -MP -march=native"
 | 
			
		||||
      "-DCMAKE_C_FLAGS_DEBUG=-MTd"
 | 
			
		||||
      "-DCMAKE_C_FLAGS_RELEASE=-MT"
 | 
			
		||||
    >  
 | 
			
		||||
  LOG_CONFIGURE ON
 | 
			
		||||
  LOG_BUILD ON
 | 
			
		||||
  LOG_CONFIGURE ON
 | 
			
		||||
  COMMAND
 | 
			
		||||
    pwd
 | 
			
		||||
  BUILD_COMMAND
 | 
			
		||||
    ${CMAKE_COMMAND}
 | 
			
		||||
    --build .
 | 
			
		||||
    --config $<CONFIG>
 | 
			
		||||
    $<$<VERSION_GREATER_EQUAL:${CMAKE_VERSION},3.12>:--parallel ${ep_procs}>
 | 
			
		||||
  TEST_COMMAND ""
 | 
			
		||||
  INSTALL_COMMAND ""
 | 
			
		||||
  BUILD_BYPRODUCTS
 | 
			
		||||
      <BINARY_DIR>/lib/api/libwasmedge.a
 | 
			
		||||
)
 | 
			
		||||
add_library (wasmedge STATIC IMPORTED GLOBAL)
 | 
			
		||||
ExternalProject_Get_Property (wasmedge_src BINARY_DIR)
 | 
			
		||||
ExternalProject_Get_Property (wasmedge_src SOURCE_DIR)
 | 
			
		||||
set (wasmedge_src_BINARY_DIR "${BINARY_DIR}")
 | 
			
		||||
add_dependencies (wasmedge wasmedge_src)
 | 
			
		||||
execute_process(
 | 
			
		||||
    COMMAND
 | 
			
		||||
        mkdir -p "${wasmedge_src_BINARY_DIR}/include/api"
 | 
			
		||||
)
 | 
			
		||||
set_target_properties (wasmedge PROPERTIES
 | 
			
		||||
  IMPORTED_LOCATION_DEBUG
 | 
			
		||||
    "${wasmedge_src_BINARY_DIR}/lib/api/libwasmedge.a"
 | 
			
		||||
  IMPORTED_LOCATION_RELEASE
 | 
			
		||||
    "${wasmedge_src_BINARY_DIR}/lib/api/libwasmedge.a"
 | 
			
		||||
  INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
    "${wasmedge_src_BINARY_DIR}/include/api/"
 | 
			
		||||
)
 | 
			
		||||
target_link_libraries (ripple_libs INTERFACE wasmedge)
 | 
			
		||||
#RH NOTE: some compilers / versions of some libraries need these, most don't
 | 
			
		||||
 | 
			
		||||
find_library(XAR_LIBRARY NAMES xar)
 | 
			
		||||
if(XAR_LIBRARY)
 | 
			
		||||
  target_link_libraries(ripple_libs INTERFACE ${XAR_LIBRARY})
 | 
			
		||||
else()
 | 
			
		||||
  message(WARNING "xar library not found... (only important for mac builds)")
 | 
			
		||||
endif()
 | 
			
		||||
add_library (wasmedge::wasmedge ALIAS wasmedge)
 | 
			
		||||
find_package(wasmedge REQUIRED)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,167 +0,0 @@
 | 
			
		||||
if(reporting)
 | 
			
		||||
    find_library(cassandra NAMES cassandra)
 | 
			
		||||
    if(NOT cassandra)
 | 
			
		||||
 | 
			
		||||
        message("System installed Cassandra cpp driver not found. Will build")
 | 
			
		||||
 | 
			
		||||
        find_library(zlib NAMES zlib1g-dev zlib-devel zlib z)
 | 
			
		||||
        if(NOT zlib)
 | 
			
		||||
            message("zlib not found. will build")
 | 
			
		||||
            add_library(zlib STATIC IMPORTED GLOBAL)
 | 
			
		||||
            ExternalProject_Add(zlib_src
 | 
			
		||||
                PREFIX ${nih_cache_path}
 | 
			
		||||
                GIT_REPOSITORY https://github.com/madler/zlib.git
 | 
			
		||||
                GIT_TAG v1.2.12
 | 
			
		||||
                INSTALL_COMMAND ""
 | 
			
		||||
                BUILD_BYPRODUCTS <BINARY_DIR>/${ep_lib_prefix}z.a
 | 
			
		||||
                LOG_BUILD TRUE
 | 
			
		||||
                LOG_CONFIGURE TRUE
 | 
			
		||||
                )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            ExternalProject_Get_Property (zlib_src SOURCE_DIR)
 | 
			
		||||
            ExternalProject_Get_Property (zlib_src BINARY_DIR)
 | 
			
		||||
            set (zlib_src_SOURCE_DIR "${SOURCE_DIR}")
 | 
			
		||||
            file (MAKE_DIRECTORY ${zlib_src_SOURCE_DIR}/include)
 | 
			
		||||
 | 
			
		||||
            set_target_properties (zlib PROPERTIES
 | 
			
		||||
                IMPORTED_LOCATION
 | 
			
		||||
                ${BINARY_DIR}/${ep_lib_prefix}z.a
 | 
			
		||||
                INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
                ${SOURCE_DIR}/include)
 | 
			
		||||
            add_dependencies(zlib zlib_src)
 | 
			
		||||
 | 
			
		||||
            file(TO_CMAKE_PATH "${zlib_src_SOURCE_DIR}" zlib_src_SOURCE_DIR)
 | 
			
		||||
        endif()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        find_library(krb5 NAMES krb5-dev libkrb5-dev)
 | 
			
		||||
 | 
			
		||||
        if(NOT krb5)
 | 
			
		||||
            message("krb5 not found. will build")
 | 
			
		||||
            add_library(krb5 STATIC IMPORTED GLOBAL)
 | 
			
		||||
            ExternalProject_Add(krb5_src
 | 
			
		||||
                PREFIX ${nih_cache_path}
 | 
			
		||||
                GIT_REPOSITORY https://github.com/krb5/krb5.git
 | 
			
		||||
                GIT_TAG krb5-1.20-final
 | 
			
		||||
                UPDATE_COMMAND ""
 | 
			
		||||
                CONFIGURE_COMMAND autoreconf src && CFLAGS=-fcommon ./src/configure --enable-static --disable-shared > /dev/null
 | 
			
		||||
                BUILD_IN_SOURCE 1
 | 
			
		||||
                BUILD_COMMAND make
 | 
			
		||||
                INSTALL_COMMAND ""
 | 
			
		||||
                BUILD_BYPRODUCTS <SOURCE_DIR>/lib/${ep_lib_prefix}krb5.a
 | 
			
		||||
                LOG_BUILD TRUE
 | 
			
		||||
                )
 | 
			
		||||
 | 
			
		||||
            ExternalProject_Get_Property (krb5_src SOURCE_DIR)
 | 
			
		||||
            ExternalProject_Get_Property (krb5_src BINARY_DIR)
 | 
			
		||||
            set (krb5_src_SOURCE_DIR "${SOURCE_DIR}")
 | 
			
		||||
            file (MAKE_DIRECTORY ${krb5_src_SOURCE_DIR}/include)
 | 
			
		||||
 | 
			
		||||
            set_target_properties (krb5 PROPERTIES
 | 
			
		||||
                IMPORTED_LOCATION
 | 
			
		||||
                ${BINARY_DIR}/lib/${ep_lib_prefix}krb5.a
 | 
			
		||||
                INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
                ${SOURCE_DIR}/include)
 | 
			
		||||
            add_dependencies(krb5 krb5_src)
 | 
			
		||||
 | 
			
		||||
            file(TO_CMAKE_PATH "${krb5_src_SOURCE_DIR}" krb5_src_SOURCE_DIR)
 | 
			
		||||
        endif()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        find_library(libuv1 NAMES uv1 libuv1 liubuv1-dev libuv1:amd64)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        if(NOT libuv1)
 | 
			
		||||
            message("libuv1 not found, will build")
 | 
			
		||||
            add_library(libuv1 STATIC IMPORTED GLOBAL)
 | 
			
		||||
            ExternalProject_Add(libuv_src
 | 
			
		||||
                PREFIX ${nih_cache_path}
 | 
			
		||||
                GIT_REPOSITORY https://github.com/libuv/libuv.git
 | 
			
		||||
                GIT_TAG v1.44.2
 | 
			
		||||
                INSTALL_COMMAND ""
 | 
			
		||||
                BUILD_BYPRODUCTS <BINARY_DIR>/${ep_lib_prefix}uv_a.a
 | 
			
		||||
                LOG_BUILD TRUE
 | 
			
		||||
                LOG_CONFIGURE TRUE
 | 
			
		||||
                )
 | 
			
		||||
 | 
			
		||||
            ExternalProject_Get_Property (libuv_src SOURCE_DIR)
 | 
			
		||||
            ExternalProject_Get_Property (libuv_src BINARY_DIR)
 | 
			
		||||
            set (libuv_src_SOURCE_DIR "${SOURCE_DIR}")
 | 
			
		||||
            file (MAKE_DIRECTORY ${libuv_src_SOURCE_DIR}/include)
 | 
			
		||||
 | 
			
		||||
            set_target_properties (libuv1 PROPERTIES
 | 
			
		||||
                IMPORTED_LOCATION
 | 
			
		||||
                ${BINARY_DIR}/${ep_lib_prefix}uv_a.a
 | 
			
		||||
                INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
                ${SOURCE_DIR}/include)
 | 
			
		||||
            add_dependencies(libuv1 libuv_src)
 | 
			
		||||
 | 
			
		||||
            file(TO_CMAKE_PATH "${libuv_src_SOURCE_DIR}" libuv_src_SOURCE_DIR)
 | 
			
		||||
        endif()
 | 
			
		||||
 | 
			
		||||
        add_library (cassandra STATIC IMPORTED GLOBAL)
 | 
			
		||||
        ExternalProject_Add(cassandra_src
 | 
			
		||||
            PREFIX ${nih_cache_path}
 | 
			
		||||
            GIT_REPOSITORY https://github.com/datastax/cpp-driver.git
 | 
			
		||||
            GIT_TAG 2.16.2
 | 
			
		||||
            CMAKE_ARGS
 | 
			
		||||
            -DLIBUV_ROOT_DIR=${BINARY_DIR}
 | 
			
		||||
            -DLIBUV_LIBARY=${BINARY_DIR}/libuv_a.a
 | 
			
		||||
            -DLIBUV_INCLUDE_DIR=${SOURCE_DIR}/include
 | 
			
		||||
            -DCASS_BUILD_STATIC=ON
 | 
			
		||||
            -DCASS_BUILD_SHARED=OFF
 | 
			
		||||
            -DOPENSSL_ROOT_DIR=/opt/local/openssl
 | 
			
		||||
            INSTALL_COMMAND ""
 | 
			
		||||
            BUILD_BYPRODUCTS <BINARY_DIR>/${ep_lib_prefix}cassandra_static.a
 | 
			
		||||
            LOG_BUILD TRUE
 | 
			
		||||
            LOG_CONFIGURE TRUE
 | 
			
		||||
            )
 | 
			
		||||
 | 
			
		||||
        ExternalProject_Get_Property (cassandra_src SOURCE_DIR)
 | 
			
		||||
        ExternalProject_Get_Property (cassandra_src BINARY_DIR)
 | 
			
		||||
        set (cassandra_src_SOURCE_DIR "${SOURCE_DIR}")
 | 
			
		||||
        file (MAKE_DIRECTORY ${cassandra_src_SOURCE_DIR}/include)
 | 
			
		||||
 | 
			
		||||
        set_target_properties (cassandra PROPERTIES
 | 
			
		||||
            IMPORTED_LOCATION
 | 
			
		||||
            ${BINARY_DIR}/${ep_lib_prefix}cassandra_static.a
 | 
			
		||||
            INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
            ${SOURCE_DIR}/include)
 | 
			
		||||
        add_dependencies(cassandra cassandra_src)
 | 
			
		||||
 | 
			
		||||
        if(NOT libuv1)
 | 
			
		||||
            ExternalProject_Add_StepDependencies(cassandra_src build libuv1)
 | 
			
		||||
            target_link_libraries(cassandra INTERFACE libuv1)
 | 
			
		||||
        else()
 | 
			
		||||
            target_link_libraries(cassandra INTERFACE ${libuv1})
 | 
			
		||||
        endif()
 | 
			
		||||
        if(NOT krb5)
 | 
			
		||||
 | 
			
		||||
            ExternalProject_Add_StepDependencies(cassandra_src build krb5)
 | 
			
		||||
            target_link_libraries(cassandra INTERFACE krb5)
 | 
			
		||||
        else()
 | 
			
		||||
            target_link_libraries(cassandra INTERFACE ${krb5})
 | 
			
		||||
        endif()
 | 
			
		||||
 | 
			
		||||
        if(NOT zlib)
 | 
			
		||||
            ExternalProject_Add_StepDependencies(cassandra_src build zlib)
 | 
			
		||||
            target_link_libraries(cassandra INTERFACE zlib)
 | 
			
		||||
        else()
 | 
			
		||||
            target_link_libraries(cassandra INTERFACE ${zlib})
 | 
			
		||||
        endif()
 | 
			
		||||
 | 
			
		||||
        file(TO_CMAKE_PATH "${cassandra_src_SOURCE_DIR}" cassandra_src_SOURCE_DIR)
 | 
			
		||||
        target_link_libraries(ripple_libs INTERFACE cassandra)
 | 
			
		||||
    else()
 | 
			
		||||
        message("Found system installed cassandra cpp driver")
 | 
			
		||||
 | 
			
		||||
        find_path(cassandra_includes NAMES cassandra.h REQUIRED)
 | 
			
		||||
        target_link_libraries (ripple_libs INTERFACE ${cassandra})
 | 
			
		||||
        target_include_directories(ripple_libs INTERFACE ${cassandra_includes})
 | 
			
		||||
    endif()
 | 
			
		||||
 | 
			
		||||
    exclude_if_included (cassandra)
 | 
			
		||||
endif()
 | 
			
		||||
@@ -1,18 +0,0 @@
 | 
			
		||||
#[===================================================================[
 | 
			
		||||
   NIH dep: date
 | 
			
		||||
 | 
			
		||||
   the main library is header-only, thus is an INTERFACE lib in CMake.
 | 
			
		||||
 | 
			
		||||
   NOTE: this has been accepted into c++20 so can likely be replaced
 | 
			
		||||
   when we update to that standard
 | 
			
		||||
#]===================================================================]
 | 
			
		||||
 | 
			
		||||
find_package (date QUIET)
 | 
			
		||||
if (NOT TARGET date::date)
 | 
			
		||||
  FetchContent_Declare(
 | 
			
		||||
    hh_date_src
 | 
			
		||||
    GIT_REPOSITORY https://github.com/HowardHinnant/date.git
 | 
			
		||||
    GIT_TAG        fc4cf092f9674f2670fb9177edcdee870399b829
 | 
			
		||||
  )
 | 
			
		||||
  FetchContent_MakeAvailable(hh_date_src)
 | 
			
		||||
endif ()
 | 
			
		||||
@@ -1,324 +1,15 @@
 | 
			
		||||
 | 
			
		||||
# currently linking to unsecure versions...if we switch, we'll
 | 
			
		||||
# need to add ssl as a link dependency to the grpc targets
 | 
			
		||||
option (use_secure_grpc "use TLS version of grpc libs." OFF)
 | 
			
		||||
if (use_secure_grpc)
 | 
			
		||||
  set (grpc_suffix "")
 | 
			
		||||
else ()
 | 
			
		||||
  set (grpc_suffix "_unsecure")
 | 
			
		||||
endif ()
 | 
			
		||||
 | 
			
		||||
find_package (gRPC 1.23 CONFIG QUIET)
 | 
			
		||||
if (TARGET gRPC::gpr AND NOT local_grpc)
 | 
			
		||||
  get_target_property (_grpc_l gRPC::gpr IMPORTED_LOCATION_DEBUG)
 | 
			
		||||
  if (NOT _grpc_l)
 | 
			
		||||
    get_target_property (_grpc_l gRPC::gpr IMPORTED_LOCATION_RELEASE)
 | 
			
		||||
  endif ()
 | 
			
		||||
  if (NOT _grpc_l)
 | 
			
		||||
    get_target_property (_grpc_l gRPC::gpr IMPORTED_LOCATION)
 | 
			
		||||
  endif ()
 | 
			
		||||
  message (STATUS "Found cmake config for gRPC. Using ${_grpc_l}.")
 | 
			
		||||
else ()
 | 
			
		||||
  find_package (PkgConfig QUIET)
 | 
			
		||||
  if (PKG_CONFIG_FOUND)
 | 
			
		||||
    pkg_check_modules (grpc QUIET "grpc${grpc_suffix}>=1.25" "grpc++${grpc_suffix}" gpr)
 | 
			
		||||
  endif ()
 | 
			
		||||
 | 
			
		||||
  if (grpc_FOUND)
 | 
			
		||||
    message (STATUS "Found gRPC using pkg-config. Using ${grpc_gpr_PREFIX}.")
 | 
			
		||||
  endif ()
 | 
			
		||||
 | 
			
		||||
  add_executable (gRPC::grpc_cpp_plugin IMPORTED)
 | 
			
		||||
  exclude_if_included (gRPC::grpc_cpp_plugin)
 | 
			
		||||
 | 
			
		||||
  if (grpc_FOUND AND NOT local_grpc)
 | 
			
		||||
    # use installed grpc (via pkg-config)
 | 
			
		||||
    macro (add_imported_grpc libname_)
 | 
			
		||||
      if (static)
 | 
			
		||||
        set (_search "${CMAKE_STATIC_LIBRARY_PREFIX}${libname_}${CMAKE_STATIC_LIBRARY_SUFFIX}")
 | 
			
		||||
      else ()
 | 
			
		||||
        set (_search "${CMAKE_SHARED_LIBRARY_PREFIX}${libname_}${CMAKE_SHARED_LIBRARY_SUFFIX}")
 | 
			
		||||
      endif()
 | 
			
		||||
      find_library(_found_${libname_}
 | 
			
		||||
        NAMES ${_search}
 | 
			
		||||
        HINTS ${grpc_LIBRARY_DIRS})
 | 
			
		||||
      if (_found_${libname_})
 | 
			
		||||
        message (STATUS "importing ${libname_} as ${_found_${libname_}}")
 | 
			
		||||
      else ()
 | 
			
		||||
        message (FATAL_ERROR "using pkg-config for grpc, can't find ${_search}")
 | 
			
		||||
      endif ()
 | 
			
		||||
      add_library ("gRPC::${libname_}" STATIC IMPORTED GLOBAL)
 | 
			
		||||
      set_target_properties ("gRPC::${libname_}" PROPERTIES IMPORTED_LOCATION ${_found_${libname_}})
 | 
			
		||||
      if (grpc_INCLUDE_DIRS)
 | 
			
		||||
        set_target_properties ("gRPC::${libname_}" PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${grpc_INCLUDE_DIRS})
 | 
			
		||||
      endif ()
 | 
			
		||||
      target_link_libraries (ripple_libs INTERFACE "gRPC::${libname_}")
 | 
			
		||||
      exclude_if_included ("gRPC::${libname_}")
 | 
			
		||||
    endmacro ()
 | 
			
		||||
 | 
			
		||||
    set_target_properties (gRPC::grpc_cpp_plugin PROPERTIES
 | 
			
		||||
        IMPORTED_LOCATION "${grpc_gpr_PREFIX}/bin/grpc_cpp_plugin${CMAKE_EXECUTABLE_SUFFIX}")
 | 
			
		||||
 | 
			
		||||
    pkg_check_modules (cares QUIET libcares)
 | 
			
		||||
    if (cares_FOUND)
 | 
			
		||||
      if (static)
 | 
			
		||||
        set (_search "${CMAKE_STATIC_LIBRARY_PREFIX}cares${CMAKE_STATIC_LIBRARY_SUFFIX}")
 | 
			
		||||
        set (_prefix cares_STATIC)
 | 
			
		||||
        set (_static STATIC)
 | 
			
		||||
      else ()
 | 
			
		||||
        set (_search "${CMAKE_SHARED_LIBRARY_PREFIX}cares${CMAKE_SHARED_LIBRARY_SUFFIX}")
 | 
			
		||||
        set (_prefix cares)
 | 
			
		||||
        set (_static)
 | 
			
		||||
      endif()
 | 
			
		||||
      find_library(_location NAMES ${_search} HINTS ${cares_LIBRARY_DIRS})
 | 
			
		||||
      if (NOT _location)
 | 
			
		||||
        message (FATAL_ERROR "using pkg-config for grpc, can't find c-ares")
 | 
			
		||||
      endif ()
 | 
			
		||||
      if(${_location} MATCHES "\\.a$")
 | 
			
		||||
        add_library(c-ares::cares STATIC IMPORTED GLOBAL)
 | 
			
		||||
      else()
 | 
			
		||||
        add_library(c-ares::cares SHARED IMPORTED GLOBAL)
 | 
			
		||||
      endif()      
 | 
			
		||||
      set_target_properties (c-ares::cares PROPERTIES
 | 
			
		||||
        IMPORTED_LOCATION ${_location}
 | 
			
		||||
        INTERFACE_INCLUDE_DIRECTORIES "${${_prefix}_INCLUDE_DIRS}"
 | 
			
		||||
        INTERFACE_LINK_OPTIONS "${${_prefix}_LDFLAGS}"
 | 
			
		||||
      )
 | 
			
		||||
      exclude_if_included (c-ares::cares)
 | 
			
		||||
    else ()
 | 
			
		||||
      message (FATAL_ERROR "using pkg-config for grpc, can't find c-ares")
 | 
			
		||||
    endif ()
 | 
			
		||||
  else ()
 | 
			
		||||
    #[===========================[
 | 
			
		||||
       c-ares (grpc requires)
 | 
			
		||||
    #]===========================]
 | 
			
		||||
    ExternalProject_Add (c-ares_src
 | 
			
		||||
      PREFIX ${nih_cache_path}
 | 
			
		||||
      GIT_REPOSITORY https://github.com/c-ares/c-ares.git
 | 
			
		||||
      GIT_TAG cares-1_15_0
 | 
			
		||||
      CMAKE_ARGS
 | 
			
		||||
        -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
 | 
			
		||||
        $<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:-DCMAKE_VERBOSE_MAKEFILE=ON>
 | 
			
		||||
        -DCMAKE_DEBUG_POSTFIX=_d
 | 
			
		||||
        $<$<NOT:$<BOOL:${is_multiconfig}>>:-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}>
 | 
			
		||||
        -DCMAKE_INSTALL_PREFIX=<BINARY_DIR>/_installed_
 | 
			
		||||
        -DCARES_SHARED=OFF
 | 
			
		||||
        -DCARES_STATIC=ON
 | 
			
		||||
        -DCARES_STATIC_PIC=ON
 | 
			
		||||
        -DCARES_INSTALL=ON
 | 
			
		||||
        -DCARES_MSVC_STATIC_RUNTIME=ON
 | 
			
		||||
        $<$<BOOL:${MSVC}>:
 | 
			
		||||
          "-DCMAKE_C_FLAGS=-GR -Gd -fp:precise -FS -MP"
 | 
			
		||||
        >
 | 
			
		||||
      LOG_BUILD ON
 | 
			
		||||
      LOG_CONFIGURE ON
 | 
			
		||||
      BUILD_COMMAND
 | 
			
		||||
        ${CMAKE_COMMAND}
 | 
			
		||||
          --build .
 | 
			
		||||
          --config $<CONFIG>
 | 
			
		||||
          --parallel ${ep_procs}
 | 
			
		||||
      TEST_COMMAND ""
 | 
			
		||||
      INSTALL_COMMAND
 | 
			
		||||
        ${CMAKE_COMMAND} -E env --unset=DESTDIR ${CMAKE_COMMAND} --build . --config $<CONFIG> --target install
 | 
			
		||||
      BUILD_BYPRODUCTS
 | 
			
		||||
        <BINARY_DIR>/_installed_/lib/${ep_lib_prefix}cares${ep_lib_suffix}
 | 
			
		||||
        <BINARY_DIR>/_installed_/lib/${ep_lib_prefix}cares_d${ep_lib_suffix}
 | 
			
		||||
    )
 | 
			
		||||
    exclude_if_included (c-ares_src)
 | 
			
		||||
    ExternalProject_Get_Property (c-ares_src BINARY_DIR)
 | 
			
		||||
    set (cares_binary_dir "${BINARY_DIR}")
 | 
			
		||||
 | 
			
		||||
    add_library (c-ares::cares STATIC IMPORTED GLOBAL)
 | 
			
		||||
    file (MAKE_DIRECTORY ${BINARY_DIR}/_installed_/include)
 | 
			
		||||
    set_target_properties (c-ares::cares PROPERTIES
 | 
			
		||||
      IMPORTED_LOCATION_DEBUG
 | 
			
		||||
        ${BINARY_DIR}/_installed_/lib/${ep_lib_prefix}cares_d${ep_lib_suffix}
 | 
			
		||||
      IMPORTED_LOCATION_RELEASE
 | 
			
		||||
        ${BINARY_DIR}/_installed_/lib/${ep_lib_prefix}cares${ep_lib_suffix}
 | 
			
		||||
      INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
        ${BINARY_DIR}/_installed_/include)
 | 
			
		||||
    add_dependencies (c-ares::cares c-ares_src)
 | 
			
		||||
    exclude_if_included (c-ares::cares)
 | 
			
		||||
 | 
			
		||||
    if (NOT has_zlib)
 | 
			
		||||
      #[===========================[
 | 
			
		||||
         zlib (grpc requires)
 | 
			
		||||
      #]===========================]
 | 
			
		||||
      if (MSVC)
 | 
			
		||||
        set (zlib_debug_postfix "d") # zlib cmake sets this internally for MSVC, so we really don't have a choice
 | 
			
		||||
        set (zlib_base "zlibstatic")
 | 
			
		||||
      else ()
 | 
			
		||||
        set (zlib_debug_postfix "_d")
 | 
			
		||||
        set (zlib_base "z")
 | 
			
		||||
      endif ()
 | 
			
		||||
      ExternalProject_Add (zlib_src
 | 
			
		||||
        PREFIX ${nih_cache_path}
 | 
			
		||||
        GIT_REPOSITORY https://github.com/madler/zlib.git
 | 
			
		||||
        GIT_TAG v1.2.11
 | 
			
		||||
        CMAKE_ARGS
 | 
			
		||||
          -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
 | 
			
		||||
          $<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:-DCMAKE_VERBOSE_MAKEFILE=ON>
 | 
			
		||||
          -DCMAKE_DEBUG_POSTFIX=${zlib_debug_postfix}
 | 
			
		||||
          $<$<NOT:$<BOOL:${is_multiconfig}>>:-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}>
 | 
			
		||||
          -DCMAKE_INSTALL_PREFIX=<BINARY_DIR>/_installed_
 | 
			
		||||
          -DBUILD_SHARED_LIBS=OFF
 | 
			
		||||
          $<$<BOOL:${MSVC}>:
 | 
			
		||||
            "-DCMAKE_C_FLAGS=-GR -Gd -fp:precise -FS -MP"
 | 
			
		||||
            "-DCMAKE_C_FLAGS_DEBUG=-MTd"
 | 
			
		||||
            "-DCMAKE_C_FLAGS_RELEASE=-MT"
 | 
			
		||||
          >
 | 
			
		||||
        LOG_BUILD ON
 | 
			
		||||
        LOG_CONFIGURE ON
 | 
			
		||||
        BUILD_COMMAND
 | 
			
		||||
          ${CMAKE_COMMAND}
 | 
			
		||||
            --build .
 | 
			
		||||
            --config $<CONFIG>
 | 
			
		||||
            --parallel ${ep_procs}
 | 
			
		||||
        TEST_COMMAND ""
 | 
			
		||||
        INSTALL_COMMAND
 | 
			
		||||
          ${CMAKE_COMMAND} -E env --unset=DESTDIR ${CMAKE_COMMAND} --build . --config $<CONFIG> --target install
 | 
			
		||||
        BUILD_BYPRODUCTS
 | 
			
		||||
          <BINARY_DIR>/_installed_/lib/${ep_lib_prefix}${zlib_base}${ep_lib_suffix}
 | 
			
		||||
          <BINARY_DIR>/_installed_/lib/${ep_lib_prefix}${zlib_base}${zlib_debug_postfix}${ep_lib_suffix}
 | 
			
		||||
      )
 | 
			
		||||
      exclude_if_included (zlib_src)
 | 
			
		||||
      ExternalProject_Get_Property (zlib_src BINARY_DIR)
 | 
			
		||||
      set (zlib_binary_dir "${BINARY_DIR}")
 | 
			
		||||
 | 
			
		||||
      add_library (ZLIB::ZLIB STATIC IMPORTED GLOBAL)
 | 
			
		||||
      file (MAKE_DIRECTORY ${BINARY_DIR}/_installed_/include)
 | 
			
		||||
      set_target_properties (ZLIB::ZLIB PROPERTIES
 | 
			
		||||
        IMPORTED_LOCATION_DEBUG
 | 
			
		||||
          ${BINARY_DIR}/_installed_/lib/${ep_lib_prefix}${zlib_base}${zlib_debug_postfix}${ep_lib_suffix}
 | 
			
		||||
        IMPORTED_LOCATION_RELEASE
 | 
			
		||||
          ${BINARY_DIR}/_installed_/lib/${ep_lib_prefix}${zlib_base}${ep_lib_suffix}
 | 
			
		||||
        INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
          ${BINARY_DIR}/_installed_/include)
 | 
			
		||||
      add_dependencies (ZLIB::ZLIB zlib_src)
 | 
			
		||||
      exclude_if_included (ZLIB::ZLIB)
 | 
			
		||||
    endif ()
 | 
			
		||||
 | 
			
		||||
    #[===========================[
 | 
			
		||||
       grpc
 | 
			
		||||
    #]===========================]
 | 
			
		||||
    ExternalProject_Add (grpc_src
 | 
			
		||||
      PREFIX ${nih_cache_path}
 | 
			
		||||
      GIT_REPOSITORY https://github.com/grpc/grpc.git
 | 
			
		||||
      GIT_TAG v1.25.0
 | 
			
		||||
      CMAKE_ARGS
 | 
			
		||||
        -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
 | 
			
		||||
        -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
 | 
			
		||||
        -DCMAKE_CXX_STANDARD=17
 | 
			
		||||
        $<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:-DCMAKE_VERBOSE_MAKEFILE=ON>
 | 
			
		||||
        $<$<BOOL:${CMAKE_TOOLCHAIN_FILE}>:-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}>
 | 
			
		||||
        $<$<BOOL:${VCPKG_TARGET_TRIPLET}>:-DVCPKG_TARGET_TRIPLET=${VCPKG_TARGET_TRIPLET}>
 | 
			
		||||
        $<$<BOOL:${unity}>:-DCMAKE_UNITY_BUILD=ON}>
 | 
			
		||||
        -DCMAKE_DEBUG_POSTFIX=_d
 | 
			
		||||
        $<$<NOT:$<BOOL:${is_multiconfig}>>:-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}>
 | 
			
		||||
        -DgRPC_BUILD_TESTS=OFF
 | 
			
		||||
        -DgRPC_BENCHMARK_PROVIDER=""
 | 
			
		||||
        -DgRPC_BUILD_CSHARP_EXT=OFF
 | 
			
		||||
        -DgRPC_MSVC_STATIC_RUNTIME=ON
 | 
			
		||||
        -DgRPC_INSTALL=OFF
 | 
			
		||||
        -DgRPC_CARES_PROVIDER=package
 | 
			
		||||
        -Dc-ares_DIR=${cares_binary_dir}/_installed_/lib/cmake/c-ares
 | 
			
		||||
        -DgRPC_SSL_PROVIDER=package
 | 
			
		||||
        -DOPENSSL_ROOT_DIR=${OPENSSL_ROOT_DIR}
 | 
			
		||||
        -DgRPC_PROTOBUF_PROVIDER=package
 | 
			
		||||
        -DProtobuf_USE_STATIC_LIBS=$<IF:$<AND:$<BOOL:${Protobuf_FOUND}>,$<NOT:$<BOOL:${static}>>>,OFF,ON>
 | 
			
		||||
        -DProtobuf_INCLUDE_DIR=$<JOIN:$<TARGET_PROPERTY:protobuf::libprotobuf,INTERFACE_INCLUDE_DIRECTORIES>,:_:>
 | 
			
		||||
        -DProtobuf_LIBRARY=$<IF:$<CONFIG:Debug>,$<TARGET_PROPERTY:protobuf::libprotobuf,IMPORTED_LOCATION_DEBUG>,$<TARGET_PROPERTY:protobuf::libprotobuf,IMPORTED_LOCATION_RELEASE>>
 | 
			
		||||
        -DProtobuf_PROTOC_LIBRARY=$<IF:$<CONFIG:Debug>,$<TARGET_PROPERTY:protobuf::libprotoc,IMPORTED_LOCATION_DEBUG>,$<TARGET_PROPERTY:protobuf::libprotoc,IMPORTED_LOCATION_RELEASE>>
 | 
			
		||||
        -DProtobuf_PROTOC_EXECUTABLE=$<TARGET_PROPERTY:protobuf::protoc,IMPORTED_LOCATION>
 | 
			
		||||
        -DgRPC_ZLIB_PROVIDER=package
 | 
			
		||||
        $<$<NOT:$<BOOL:${has_zlib}>>:-DZLIB_ROOT=${zlib_binary_dir}/_installed_>
 | 
			
		||||
        $<$<BOOL:${MSVC}>:
 | 
			
		||||
          "-DCMAKE_CXX_FLAGS=-GR -Gd -fp:precise -FS -EHa -MP"
 | 
			
		||||
          "-DCMAKE_C_FLAGS=-GR -Gd -fp:precise -FS -MP"
 | 
			
		||||
        >
 | 
			
		||||
      LOG_BUILD ON
 | 
			
		||||
      LOG_CONFIGURE ON
 | 
			
		||||
      BUILD_COMMAND
 | 
			
		||||
        ${CMAKE_COMMAND}
 | 
			
		||||
        --build .
 | 
			
		||||
        --config $<CONFIG>
 | 
			
		||||
        --parallel ${ep_procs}
 | 
			
		||||
        $<$<BOOL:${is_multiconfig}>:
 | 
			
		||||
          COMMAND
 | 
			
		||||
            ${CMAKE_COMMAND} -E copy
 | 
			
		||||
            <BINARY_DIR>/$<CONFIG>/${ep_lib_prefix}grpc${grpc_suffix}$<$<CONFIG:Debug>:_d>${ep_lib_suffix}
 | 
			
		||||
            <BINARY_DIR>/$<CONFIG>/${ep_lib_prefix}grpc++${grpc_suffix}$<$<CONFIG:Debug>:_d>${ep_lib_suffix}
 | 
			
		||||
            <BINARY_DIR>/$<CONFIG>/${ep_lib_prefix}address_sorting$<$<CONFIG:Debug>:_d>${ep_lib_suffix}
 | 
			
		||||
            <BINARY_DIR>/$<CONFIG>/${ep_lib_prefix}gpr$<$<CONFIG:Debug>:_d>${ep_lib_suffix}
 | 
			
		||||
            <BINARY_DIR>/$<CONFIG>/grpc_cpp_plugin${CMAKE_EXECUTABLE_SUFFIX}
 | 
			
		||||
            <BINARY_DIR>
 | 
			
		||||
          >
 | 
			
		||||
      LIST_SEPARATOR :_:
 | 
			
		||||
      TEST_COMMAND ""
 | 
			
		||||
      INSTALL_COMMAND ""
 | 
			
		||||
      DEPENDS c-ares_src
 | 
			
		||||
      BUILD_BYPRODUCTS
 | 
			
		||||
        <BINARY_DIR>/${ep_lib_prefix}grpc${grpc_suffix}${ep_lib_suffix}
 | 
			
		||||
        <BINARY_DIR>/${ep_lib_prefix}grpc${grpc_suffix}_d${ep_lib_suffix}
 | 
			
		||||
        <BINARY_DIR>/${ep_lib_prefix}grpc++${grpc_suffix}${ep_lib_suffix}
 | 
			
		||||
        <BINARY_DIR>/${ep_lib_prefix}grpc++${grpc_suffix}_d${ep_lib_suffix}
 | 
			
		||||
        <BINARY_DIR>/${ep_lib_prefix}address_sorting${ep_lib_suffix}
 | 
			
		||||
        <BINARY_DIR>/${ep_lib_prefix}address_sorting_d${ep_lib_suffix}
 | 
			
		||||
        <BINARY_DIR>/${ep_lib_prefix}gpr${ep_lib_suffix}
 | 
			
		||||
        <BINARY_DIR>/${ep_lib_prefix}gpr_d${ep_lib_suffix}
 | 
			
		||||
        <BINARY_DIR>/grpc_cpp_plugin${CMAKE_EXECUTABLE_SUFFIX}
 | 
			
		||||
    )
 | 
			
		||||
    if (TARGET protobuf_src)
 | 
			
		||||
      ExternalProject_Add_StepDependencies(grpc_src build protobuf_src)
 | 
			
		||||
    endif ()
 | 
			
		||||
    exclude_if_included (grpc_src)
 | 
			
		||||
    ExternalProject_Get_Property (grpc_src BINARY_DIR)
 | 
			
		||||
    ExternalProject_Get_Property (grpc_src SOURCE_DIR)
 | 
			
		||||
    set (grpc_binary_dir "${BINARY_DIR}")
 | 
			
		||||
    set (grpc_source_dir "${SOURCE_DIR}")
 | 
			
		||||
    if (CMAKE_VERBOSE_MAKEFILE)
 | 
			
		||||
      print_ep_logs (grpc_src)
 | 
			
		||||
    endif ()
 | 
			
		||||
    file (MAKE_DIRECTORY ${SOURCE_DIR}/include)
 | 
			
		||||
 | 
			
		||||
    macro (add_imported_grpc libname_)
 | 
			
		||||
      add_library ("gRPC::${libname_}" STATIC IMPORTED GLOBAL)
 | 
			
		||||
      set_target_properties ("gRPC::${libname_}" PROPERTIES
 | 
			
		||||
        IMPORTED_LOCATION_DEBUG
 | 
			
		||||
          ${grpc_binary_dir}/${ep_lib_prefix}${libname_}_d${ep_lib_suffix}
 | 
			
		||||
        IMPORTED_LOCATION_RELEASE
 | 
			
		||||
          ${grpc_binary_dir}/${ep_lib_prefix}${libname_}${ep_lib_suffix}
 | 
			
		||||
        INTERFACE_INCLUDE_DIRECTORIES
 | 
			
		||||
          ${grpc_source_dir}/include)
 | 
			
		||||
      add_dependencies ("gRPC::${libname_}" grpc_src)
 | 
			
		||||
      target_link_libraries (ripple_libs INTERFACE "gRPC::${libname_}")
 | 
			
		||||
      exclude_if_included ("gRPC::${libname_}")
 | 
			
		||||
    endmacro ()
 | 
			
		||||
 | 
			
		||||
    set_target_properties (gRPC::grpc_cpp_plugin PROPERTIES
 | 
			
		||||
        IMPORTED_LOCATION "${grpc_binary_dir}/grpc_cpp_plugin${CMAKE_EXECUTABLE_SUFFIX}")
 | 
			
		||||
    add_dependencies (gRPC::grpc_cpp_plugin grpc_src)
 | 
			
		||||
  endif ()
 | 
			
		||||
 | 
			
		||||
  add_imported_grpc (gpr)
 | 
			
		||||
  add_imported_grpc ("grpc${grpc_suffix}")
 | 
			
		||||
  add_imported_grpc ("grpc++${grpc_suffix}")
 | 
			
		||||
  add_imported_grpc (address_sorting)
 | 
			
		||||
 | 
			
		||||
  target_link_libraries ("gRPC::grpc${grpc_suffix}" INTERFACE c-ares::cares gRPC::gpr gRPC::address_sorting ZLIB::ZLIB)
 | 
			
		||||
  target_link_libraries ("gRPC::grpc++${grpc_suffix}" INTERFACE "gRPC::grpc${grpc_suffix}" gRPC::gpr)
 | 
			
		||||
endif ()
 | 
			
		||||
find_package(gRPC 1.23)
 | 
			
		||||
 | 
			
		||||
#[=================================[
 | 
			
		||||
   generate protobuf sources for
 | 
			
		||||
   grpc defs and bundle into a
 | 
			
		||||
   static lib
 | 
			
		||||
#]=================================]
 | 
			
		||||
set (GRPC_GEN_DIR "${CMAKE_BINARY_DIR}/proto_gen_grpc")
 | 
			
		||||
file (MAKE_DIRECTORY ${GRPC_GEN_DIR})
 | 
			
		||||
set (GRPC_PROTO_SRCS)
 | 
			
		||||
set (GRPC_PROTO_HDRS)
 | 
			
		||||
set (GRPC_PROTO_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/src/ripple/proto/org")
 | 
			
		||||
set(GRPC_GEN_DIR "${CMAKE_BINARY_DIR}/proto_gen_grpc")
 | 
			
		||||
file(MAKE_DIRECTORY ${GRPC_GEN_DIR})
 | 
			
		||||
set(GRPC_PROTO_SRCS)
 | 
			
		||||
set(GRPC_PROTO_HDRS)
 | 
			
		||||
set(GRPC_PROTO_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/src/ripple/proto/org")
 | 
			
		||||
file(GLOB_RECURSE GRPC_DEFINITION_FILES LIST_DIRECTORIES false "${GRPC_PROTO_ROOT}/*.proto")
 | 
			
		||||
foreach(file ${GRPC_DEFINITION_FILES})
 | 
			
		||||
  get_filename_component(_abs_file ${file} ABSOLUTE)
 | 
			
		||||
@@ -329,10 +20,10 @@ foreach(file ${GRPC_DEFINITION_FILES})
 | 
			
		||||
  get_filename_component(_rel_root_dir ${_rel_root_file} DIRECTORY)
 | 
			
		||||
  file(RELATIVE_PATH _rel_dir ${CMAKE_CURRENT_SOURCE_DIR} ${_abs_dir})
 | 
			
		||||
 | 
			
		||||
  set (src_1 "${GRPC_GEN_DIR}/${_rel_root_dir}/${_basename}.grpc.pb.cc")
 | 
			
		||||
  set (src_2 "${GRPC_GEN_DIR}/${_rel_root_dir}/${_basename}.pb.cc")
 | 
			
		||||
  set (hdr_1 "${GRPC_GEN_DIR}/${_rel_root_dir}/${_basename}.grpc.pb.h")
 | 
			
		||||
  set (hdr_2 "${GRPC_GEN_DIR}/${_rel_root_dir}/${_basename}.pb.h")
 | 
			
		||||
  set(src_1 "${GRPC_GEN_DIR}/${_rel_root_dir}/${_basename}.grpc.pb.cc")
 | 
			
		||||
  set(src_2 "${GRPC_GEN_DIR}/${_rel_root_dir}/${_basename}.pb.cc")
 | 
			
		||||
  set(hdr_1 "${GRPC_GEN_DIR}/${_rel_root_dir}/${_basename}.grpc.pb.h")
 | 
			
		||||
  set(hdr_2 "${GRPC_GEN_DIR}/${_rel_root_dir}/${_basename}.pb.h")
 | 
			
		||||
  add_custom_command(
 | 
			
		||||
    OUTPUT ${src_1} ${src_2} ${hdr_1} ${hdr_2}
 | 
			
		||||
    COMMAND protobuf::protoc
 | 
			
		||||
@@ -350,20 +41,22 @@ foreach(file ${GRPC_DEFINITION_FILES})
 | 
			
		||||
    list(APPEND GRPC_PROTO_HDRS ${hdr_1} ${hdr_2})
 | 
			
		||||
endforeach()
 | 
			
		||||
 | 
			
		||||
add_library (grpc_pbufs STATIC ${GRPC_PROTO_SRCS} ${GRPC_PROTO_HDRS})
 | 
			
		||||
#target_include_directories (grpc_pbufs PRIVATE src)
 | 
			
		||||
target_include_directories (grpc_pbufs SYSTEM PUBLIC ${GRPC_GEN_DIR})
 | 
			
		||||
target_link_libraries (grpc_pbufs protobuf::libprotobuf "gRPC::grpc++${grpc_suffix}")
 | 
			
		||||
target_compile_options (grpc_pbufs
 | 
			
		||||
add_library(grpc_pbufs STATIC ${GRPC_PROTO_SRCS} ${GRPC_PROTO_HDRS})
 | 
			
		||||
#target_include_directories(grpc_pbufs PRIVATE src)
 | 
			
		||||
target_include_directories(grpc_pbufs SYSTEM PUBLIC ${GRPC_GEN_DIR})
 | 
			
		||||
target_link_libraries(grpc_pbufs
 | 
			
		||||
  "gRPC::grpc++"
 | 
			
		||||
  # libgrpc is missing references.
 | 
			
		||||
  absl::random_random
 | 
			
		||||
)
 | 
			
		||||
target_compile_options(grpc_pbufs
 | 
			
		||||
  PRIVATE
 | 
			
		||||
    $<$<BOOL:${MSVC}>:-wd4065>
 | 
			
		||||
    $<$<NOT:$<BOOL:${MSVC}>>:-Wno-deprecated-declarations>
 | 
			
		||||
  PUBLIC
 | 
			
		||||
    $<$<BOOL:${MSVC}>:-wd4996>
 | 
			
		||||
    $<$<BOOL:${is_xcode}>:
 | 
			
		||||
    $<$<BOOL:${XCODE}>:
 | 
			
		||||
      --system-header-prefix="google/protobuf"
 | 
			
		||||
      -Wno-deprecated-dynamic-exception-spec
 | 
			
		||||
    >)
 | 
			
		||||
add_library (Ripple::grpc_pbufs ALIAS grpc_pbufs)
 | 
			
		||||
target_link_libraries (ripple_libs INTERFACE Ripple::grpc_pbufs)
 | 
			
		||||
exclude_if_included (grpc_pbufs)
 | 
			
		||||
add_library(Ripple::grpc_pbufs ALIAS grpc_pbufs)
 | 
			
		||||
@@ -186,6 +186,10 @@ test.protocol > ripple.crypto
 | 
			
		||||
test.protocol > ripple.json
 | 
			
		||||
test.protocol > ripple.protocol
 | 
			
		||||
test.protocol > test.toplevel
 | 
			
		||||
test.rdb > ripple.app
 | 
			
		||||
test.rdb > ripple.core
 | 
			
		||||
test.rdb > test.jtx
 | 
			
		||||
test.rdb > test.toplevel
 | 
			
		||||
test.resource > ripple.basics
 | 
			
		||||
test.resource > ripple.beast
 | 
			
		||||
test.resource > ripple.resource
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										137
									
								
								CMakeLists.txt
									
									
									
									
									
								
							
							
						
						
									
										137
									
								
								CMakeLists.txt
									
									
									
									
									
								
							@@ -75,11 +75,6 @@ if(CMAKE_TOOLCHAIN_FILE)
 | 
			
		||||
  endif()
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
if (NOT USE_CONAN)
 | 
			
		||||
  list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/Builds/CMake")
 | 
			
		||||
  list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/Builds/CMake/deps")
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
include (CheckCXXCompilerFlag)
 | 
			
		||||
include (FetchContent)
 | 
			
		||||
include (ExternalProject)
 | 
			
		||||
@@ -92,9 +87,7 @@ endif ()
 | 
			
		||||
include(RippledSanity)
 | 
			
		||||
include(RippledVersion)
 | 
			
		||||
include(RippledSettings)
 | 
			
		||||
if (NOT USE_CONAN)
 | 
			
		||||
  include(RippledNIH)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
# this check has to remain in the top-level cmake
 | 
			
		||||
# because of the early return statement
 | 
			
		||||
if (packages_only)
 | 
			
		||||
@@ -106,86 +99,64 @@ endif ()
 | 
			
		||||
include(RippledCompiler)
 | 
			
		||||
include(RippledInterface)
 | 
			
		||||
 | 
			
		||||
###
 | 
			
		||||
if (NOT USE_CONAN)
 | 
			
		||||
  add_subdirectory(src/secp256k1)
 | 
			
		||||
  add_subdirectory(src/ed25519-donna)
 | 
			
		||||
  include(deps/Boost)
 | 
			
		||||
  include(deps/OpenSSL)
 | 
			
		||||
  # include(deps/Secp256k1)
 | 
			
		||||
  # include(deps/Ed25519-donna)
 | 
			
		||||
  include(deps/Lz4)
 | 
			
		||||
  include(deps/Libarchive)
 | 
			
		||||
  include(deps/Sqlite)
 | 
			
		||||
  include(deps/Soci)
 | 
			
		||||
  include(deps/Snappy)
 | 
			
		||||
  include(deps/Rocksdb)
 | 
			
		||||
  include(deps/Nudb)
 | 
			
		||||
  include(deps/date)
 | 
			
		||||
  include(deps/Protobuf)
 | 
			
		||||
  include(deps/gRPC)
 | 
			
		||||
  include(deps/cassandra)
 | 
			
		||||
  include(deps/Postgres)
 | 
			
		||||
  include(deps/WasmEdge)
 | 
			
		||||
else()
 | 
			
		||||
  include(conan/Boost)
 | 
			
		||||
  find_package(OpenSSL 1.1.1 REQUIRED)
 | 
			
		||||
  set_target_properties(OpenSSL::SSL PROPERTIES
 | 
			
		||||
    INTERFACE_COMPILE_DEFINITIONS OPENSSL_NO_SSL2
 | 
			
		||||
include(deps/Boost)
 | 
			
		||||
find_package(OpenSSL 1.1.1 REQUIRED)
 | 
			
		||||
set_target_properties(OpenSSL::SSL PROPERTIES
 | 
			
		||||
  INTERFACE_COMPILE_DEFINITIONS OPENSSL_NO_SSL2
 | 
			
		||||
)
 | 
			
		||||
add_subdirectory(src/secp256k1)
 | 
			
		||||
add_subdirectory(src/ed25519-donna)
 | 
			
		||||
find_package(lz4 REQUIRED)
 | 
			
		||||
# Target names with :: are not allowed in a generator expression.
 | 
			
		||||
# We need to pull the include directories and imported location properties
 | 
			
		||||
# from separate targets.
 | 
			
		||||
find_package(LibArchive REQUIRED)
 | 
			
		||||
find_package(SOCI REQUIRED)
 | 
			
		||||
find_package(SQLite3 REQUIRED)
 | 
			
		||||
find_package(Snappy REQUIRED)
 | 
			
		||||
# find_package(wasmedge REQUIRED)
 | 
			
		||||
option(rocksdb "Enable RocksDB" ON)
 | 
			
		||||
if(rocksdb)
 | 
			
		||||
  find_package(RocksDB REQUIRED)
 | 
			
		||||
  set_target_properties(RocksDB::rocksdb PROPERTIES
 | 
			
		||||
    INTERFACE_COMPILE_DEFINITIONS RIPPLE_ROCKSDB_AVAILABLE=1
 | 
			
		||||
  )
 | 
			
		||||
  add_subdirectory(src/secp256k1)
 | 
			
		||||
  add_subdirectory(src/ed25519-donna)
 | 
			
		||||
  find_package(lz4 REQUIRED)
 | 
			
		||||
  # Target names with :: are not allowed in a generator expression.
 | 
			
		||||
  # We need to pull the include directories and imported location properties
 | 
			
		||||
  # from separate targets.
 | 
			
		||||
  find_package(LibArchive REQUIRED)
 | 
			
		||||
  find_package(SOCI REQUIRED)
 | 
			
		||||
  find_package(SQLite3 REQUIRED)
 | 
			
		||||
  find_package(Snappy REQUIRED)
 | 
			
		||||
  find_package(wasmedge REQUIRED)
 | 
			
		||||
  option(rocksdb "Enable RocksDB" ON)
 | 
			
		||||
  if(rocksdb)
 | 
			
		||||
    find_package(RocksDB REQUIRED)
 | 
			
		||||
    set_target_properties(RocksDB::rocksdb PROPERTIES
 | 
			
		||||
      INTERFACE_COMPILE_DEFINITIONS RIPPLE_ROCKSDB_AVAILABLE=1
 | 
			
		||||
    )
 | 
			
		||||
    target_link_libraries(ripple_libs INTERFACE RocksDB::rocksdb)
 | 
			
		||||
  endif()
 | 
			
		||||
  find_package(nudb REQUIRED)
 | 
			
		||||
  find_package(date REQUIRED)
 | 
			
		||||
  include(conan/Protobuf)
 | 
			
		||||
  include(conan/gRPC)
 | 
			
		||||
    if(TARGET nudb::core)
 | 
			
		||||
    set(nudb nudb::core)
 | 
			
		||||
  elseif(TARGET NuDB::nudb)
 | 
			
		||||
    set(nudb NuDB::nudb)
 | 
			
		||||
  else()
 | 
			
		||||
    message(FATAL_ERROR "unknown nudb target")
 | 
			
		||||
  endif()
 | 
			
		||||
  target_link_libraries(ripple_libs INTERFACE ${nudb})
 | 
			
		||||
  target_link_libraries(ripple_libs INTERFACE RocksDB::rocksdb)
 | 
			
		||||
endif()
 | 
			
		||||
find_package(nudb REQUIRED)
 | 
			
		||||
find_package(date REQUIRED)
 | 
			
		||||
include(deps/Protobuf)
 | 
			
		||||
include(deps/gRPC)
 | 
			
		||||
include(deps/WasmEdge) 
 | 
			
		||||
  if(TARGET nudb::core)
 | 
			
		||||
  set(nudb nudb::core)
 | 
			
		||||
elseif(TARGET NuDB::nudb)
 | 
			
		||||
  set(nudb NuDB::nudb)
 | 
			
		||||
else()
 | 
			
		||||
  message(FATAL_ERROR "unknown nudb target")
 | 
			
		||||
endif()
 | 
			
		||||
target_link_libraries(ripple_libs INTERFACE ${nudb})
 | 
			
		||||
 | 
			
		||||
  if(reporting)
 | 
			
		||||
    find_package(cassandra-cpp-driver REQUIRED)
 | 
			
		||||
    find_package(PostgreSQL REQUIRED)
 | 
			
		||||
    target_link_libraries(ripple_libs INTERFACE
 | 
			
		||||
      cassandra-cpp-driver::cassandra-cpp-driver
 | 
			
		||||
      PostgreSQL::PostgreSQL
 | 
			
		||||
    )
 | 
			
		||||
  endif()
 | 
			
		||||
if(reporting)
 | 
			
		||||
  find_package(cassandra-cpp-driver REQUIRED)
 | 
			
		||||
  find_package(PostgreSQL REQUIRED)
 | 
			
		||||
  target_link_libraries(ripple_libs INTERFACE
 | 
			
		||||
    ed25519::ed25519
 | 
			
		||||
    LibArchive::LibArchive
 | 
			
		||||
    lz4::lz4
 | 
			
		||||
    OpenSSL::Crypto
 | 
			
		||||
    OpenSSL::SSL
 | 
			
		||||
    Ripple::grpc_pbufs
 | 
			
		||||
    Ripple::pbufs
 | 
			
		||||
    secp256k1::secp256k1
 | 
			
		||||
    soci::soci
 | 
			
		||||
    SQLite::SQLite3
 | 
			
		||||
    cassandra-cpp-driver::cassandra-cpp-driver
 | 
			
		||||
    PostgreSQL::PostgreSQL
 | 
			
		||||
  )
 | 
			
		||||
endif()
 | 
			
		||||
target_link_libraries(ripple_libs INTERFACE
 | 
			
		||||
  ed25519::ed25519
 | 
			
		||||
  LibArchive::LibArchive
 | 
			
		||||
  lz4::lz4
 | 
			
		||||
  OpenSSL::Crypto
 | 
			
		||||
  OpenSSL::SSL
 | 
			
		||||
  Ripple::grpc_pbufs
 | 
			
		||||
  Ripple::pbufs
 | 
			
		||||
  secp256k1::secp256k1
 | 
			
		||||
  soci::soci
 | 
			
		||||
  SQLite::SQLite3
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
###
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -5,8 +5,6 @@
 | 
			
		||||
# debugging.
 | 
			
		||||
set -ex
 | 
			
		||||
 | 
			
		||||
set -e
 | 
			
		||||
 | 
			
		||||
echo "START INSIDE CONTAINER - CORE"
 | 
			
		||||
 | 
			
		||||
echo "-- BUILD CORES:       $3"
 | 
			
		||||
@@ -27,7 +25,8 @@ if [[ "$?" -ne "0" ]]; then
 | 
			
		||||
  exit 127
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
perl -i -pe "s/^(\\s*)-DBUILD_SHARED_LIBS=OFF/\\1-DBUILD_SHARED_LIBS=OFF\\n\\1-DROCKSDB_BUILD_SHARED=OFF/g" Builds/CMake/deps/Rocksdb.cmake &&
 | 
			
		||||
BUILD_TYPE=Release
 | 
			
		||||
 | 
			
		||||
mv Builds/CMake/deps/WasmEdge.cmake Builds/CMake/deps/WasmEdge.old &&
 | 
			
		||||
echo "find_package(LLVM REQUIRED CONFIG)
 | 
			
		||||
message(STATUS \"Found LLVM \${LLVM_PACKAGE_VERSION}\")
 | 
			
		||||
@@ -38,13 +37,30 @@ target_link_libraries (ripple_libs INTERFACE wasmedge)
 | 
			
		||||
add_library (wasmedge::wasmedge ALIAS wasmedge)
 | 
			
		||||
message(\"WasmEdge DONE\")
 | 
			
		||||
" > Builds/CMake/deps/WasmEdge.cmake &&
 | 
			
		||||
 | 
			
		||||
export LDFLAGS="-static-libstdc++"
 | 
			
		||||
 | 
			
		||||
git config --global --add safe.directory /io &&
 | 
			
		||||
git checkout src/ripple/protocol/impl/BuildInfo.cpp &&
 | 
			
		||||
sed -i s/\"0.0.0\"/\"$(date +%Y).$(date +%-m).$(date +%-d)-$(git rev-parse --abbrev-ref HEAD)+$4\"/g src/ripple/protocol/impl/BuildInfo.cpp &&
 | 
			
		||||
sed -i s/\"0.0.0\"/\"$(date +%Y).$(date +%-m).$(date +%-d)-$(git rev-parse --abbrev-ref HEAD)$(if [ -n "$4" ]; then echo "+$4"; fi)\"/g src/ripple/protocol/impl/BuildInfo.cpp &&
 | 
			
		||||
conan export external/snappy snappy/1.1.10@xahaud/stable &&
 | 
			
		||||
conan export external/soci soci/4.0.3@xahaud/stable &&
 | 
			
		||||
cd release-build &&
 | 
			
		||||
cmake .. -DCMAKE_BUILD_TYPE=Release -DBoost_NO_BOOST_CMAKE=ON -DLLVM_DIR=/usr/lib64/llvm13/lib/cmake/llvm/ -DLLVM_LIBRARY_DIR=/usr/lib64/llvm13/lib/ -DWasmEdge_LIB=/usr/local/lib64/libwasmedge.a &&
 | 
			
		||||
make -j$3 VERBOSE=1 &&
 | 
			
		||||
strip -s rippled &&
 | 
			
		||||
conan install .. --output-folder . --build missing --settings build_type=$BUILD_TYPE &&
 | 
			
		||||
cmake .. -G Ninja \
 | 
			
		||||
  -DCMAKE_BUILD_TYPE=$BUILD_TYPE \
 | 
			
		||||
  -DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake \
 | 
			
		||||
  -DCMAKE_EXE_LINKER_FLAGS="-static-libstdc++" \
 | 
			
		||||
  -DLLVM_DIR=$LLVM_DIR \
 | 
			
		||||
  -DWasmEdge_LIB=$WasmEdge_LIB \
 | 
			
		||||
  -Dxrpld=TRUE \
 | 
			
		||||
  -Dtests=TRUE &&
 | 
			
		||||
ccache -z &&
 | 
			
		||||
ninja -j $3 &&
 | 
			
		||||
ccache -s &&
 | 
			
		||||
strip -s rippled &&	
 | 
			
		||||
mv rippled xahaud &&
 | 
			
		||||
libcheck xahaud &&
 | 
			
		||||
echo "Build host: `hostname`" > release.info &&
 | 
			
		||||
echo "Build date: `date`" >> release.info &&
 | 
			
		||||
echo "Build md5: `md5sum xahaud`" >> release.info &&
 | 
			
		||||
@@ -69,8 +85,8 @@ fi
 | 
			
		||||
cd ..;
 | 
			
		||||
 | 
			
		||||
mv src/ripple/net/impl/RegisterSSLCerts.cpp.old src/ripple/net/impl/RegisterSSLCerts.cpp;
 | 
			
		||||
mv Builds/CMake/deps/Rocksdb.cmake.old Builds/CMake/deps/Rocksdb.cmake;
 | 
			
		||||
mv Builds/CMake/deps/WasmEdge.old Builds/CMake/deps/WasmEdge.cmake;
 | 
			
		||||
 | 
			
		||||
rm src/certs/certbundle.h;
 | 
			
		||||
git checkout src/ripple/protocol/impl/BuildInfo.cpp;
 | 
			
		||||
 | 
			
		||||
echo "END INSIDE CONTAINER - CORE"
 | 
			
		||||
 
 | 
			
		||||
@@ -3,8 +3,6 @@
 | 
			
		||||
# processes launched or upon any unbound variable.
 | 
			
		||||
# We use set -x to print commands before running them to help with
 | 
			
		||||
# debugging.
 | 
			
		||||
set -ex
 | 
			
		||||
 | 
			
		||||
set -e
 | 
			
		||||
 | 
			
		||||
echo "START INSIDE CONTAINER - FULL"
 | 
			
		||||
@@ -16,13 +14,6 @@ echo "-- GITHUB_RUN_NUMBER: $4"
 | 
			
		||||
 | 
			
		||||
umask 0000;
 | 
			
		||||
 | 
			
		||||
echo "Fixing CentOS 7 EOL"
 | 
			
		||||
 | 
			
		||||
sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*
 | 
			
		||||
sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*
 | 
			
		||||
yum clean all
 | 
			
		||||
yum-config-manager --disable centos-sclo-sclo
 | 
			
		||||
 | 
			
		||||
####
 | 
			
		||||
 | 
			
		||||
cd /io;
 | 
			
		||||
@@ -73,92 +64,15 @@ then
 | 
			
		||||
    #endif/g" src/ripple/net/impl/RegisterSSLCerts.cpp &&
 | 
			
		||||
    sed -i "s/#include <ripple\/net\/RegisterSSLCerts.h>/\0\n#include <certs\/certbundle.h>/g" src/ripple/net/impl/RegisterSSLCerts.cpp
 | 
			
		||||
fi
 | 
			
		||||
mkdir -p .nih_c;
 | 
			
		||||
mkdir -p .nih_toolchain;
 | 
			
		||||
cd .nih_toolchain &&
 | 
			
		||||
yum install -y wget lz4 lz4-devel git llvm13-static.x86_64 llvm13-devel.x86_64 devtoolset-10-binutils zlib-static ncurses-static -y \
 | 
			
		||||
  devtoolset-7-gcc-c++ \
 | 
			
		||||
  devtoolset-9-gcc-c++ \
 | 
			
		||||
  devtoolset-10-gcc-c++ \
 | 
			
		||||
  snappy snappy-devel \
 | 
			
		||||
  zlib zlib-devel \
 | 
			
		||||
  lz4-devel \
 | 
			
		||||
  libasan &&
 | 
			
		||||
export PATH=`echo $PATH | sed -E "s/devtoolset-9/devtoolset-7/g"` &&
 | 
			
		||||
echo "-- Install ZStd 1.1.3 --" &&
 | 
			
		||||
yum install epel-release -y &&
 | 
			
		||||
ZSTD_VERSION="1.1.3" &&
 | 
			
		||||
( wget -nc -q -O zstd-${ZSTD_VERSION}.tar.gz https://github.com/facebook/zstd/archive/v${ZSTD_VERSION}.tar.gz; echo "" ) &&
 | 
			
		||||
tar xzvf zstd-${ZSTD_VERSION}.tar.gz &&
 | 
			
		||||
cd zstd-${ZSTD_VERSION} &&
 | 
			
		||||
make -j$3 install &&
 | 
			
		||||
cd .. &&
 | 
			
		||||
echo "-- Install Cmake 3.23.1 --" &&
 | 
			
		||||
pwd &&
 | 
			
		||||
( wget -nc -q https://github.com/Kitware/CMake/releases/download/v3.23.1/cmake-3.23.1-linux-x86_64.tar.gz; echo "" ) &&
 | 
			
		||||
tar -xzf cmake-3.23.1-linux-x86_64.tar.gz -C /hbb/ &&
 | 
			
		||||
echo "-- Install Boost 1.86.0 --" &&
 | 
			
		||||
pwd &&
 | 
			
		||||
( wget -nc -q https://archives.boost.io/release/1.86.0/source/boost_1_86_0.tar.gz; echo "" ) &&
 | 
			
		||||
tar -xzf boost_1_86_0.tar.gz &&
 | 
			
		||||
cd boost_1_86_0 && ./bootstrap.sh && ./b2  link=static -j$3 && ./b2 install &&
 | 
			
		||||
cd ../ &&
 | 
			
		||||
echo "-- Install Protobuf 3.20.0 --" &&
 | 
			
		||||
pwd &&
 | 
			
		||||
( wget -nc -q https://github.com/protocolbuffers/protobuf/releases/download/v3.20.0/protobuf-all-3.20.0.tar.gz; echo "" ) &&
 | 
			
		||||
tar -xzf protobuf-all-3.20.0.tar.gz &&
 | 
			
		||||
cd protobuf-3.20.0/ &&
 | 
			
		||||
./autogen.sh && ./configure --prefix=/usr --disable-shared link=static && make -j$3 && make install &&
 | 
			
		||||
cd .. &&
 | 
			
		||||
echo "-- Build LLD --" &&
 | 
			
		||||
pwd &&
 | 
			
		||||
ln /usr/bin/llvm-config-13 /usr/bin/llvm-config &&
 | 
			
		||||
mv /opt/rh/devtoolset-9/root/usr/bin/ar /opt/rh/devtoolset-9/root/usr/bin/ar-9 &&
 | 
			
		||||
ln /opt/rh/devtoolset-10/root/usr/bin/ar  /opt/rh/devtoolset-9/root/usr/bin/ar &&
 | 
			
		||||
( wget -nc -q https://github.com/llvm/llvm-project/releases/download/llvmorg-13.0.1/lld-13.0.1.src.tar.xz; echo "" ) &&
 | 
			
		||||
( wget -nc -q https://github.com/llvm/llvm-project/releases/download/llvmorg-13.0.1/libunwind-13.0.1.src.tar.xz; echo "" ) &&
 | 
			
		||||
tar -xf lld-13.0.1.src.tar.xz &&
 | 
			
		||||
tar -xf libunwind-13.0.1.src.tar.xz &&
 | 
			
		||||
cp -r libunwind-13.0.1.src/include libunwind-13.0.1.src/src lld-13.0.1.src/ &&
 | 
			
		||||
cd lld-13.0.1.src &&
 | 
			
		||||
rm -rf build CMakeCache.txt &&
 | 
			
		||||
mkdir -p build &&
 | 
			
		||||
cd build &&
 | 
			
		||||
cmake .. -DLLVM_LIBRARY_DIR=/usr/lib64/llvm13/lib/ -DCMAKE_INSTALL_PREFIX=/usr/lib64/llvm13/ -DCMAKE_BUILD_TYPE=Release &&
 | 
			
		||||
make -j$3 install &&
 | 
			
		||||
ln -s /usr/lib64/llvm13/lib/include/lld /usr/include/lld &&
 | 
			
		||||
cp /usr/lib64/llvm13/lib/liblld*.a /usr/local/lib/ &&
 | 
			
		||||
cd ../../ &&
 | 
			
		||||
echo "-- Build WasmEdge --" &&
 | 
			
		||||
( wget -nc -q https://github.com/WasmEdge/WasmEdge/archive/refs/tags/0.11.2.zip; unzip -o 0.11.2.zip; ) &&
 | 
			
		||||
cd WasmEdge-0.11.2 &&
 | 
			
		||||
( mkdir -p build; echo "" ) &&
 | 
			
		||||
cd build &&
 | 
			
		||||
export BOOST_ROOT="/usr/local/src/boost_1_86_0" &&
 | 
			
		||||
export Boost_LIBRARY_DIRS="/usr/local/lib" &&
 | 
			
		||||
export BOOST_INCLUDEDIR="/usr/local/src/boost_1_86_0" &&
 | 
			
		||||
export PATH=`echo $PATH | sed -E "s/devtoolset-7/devtoolset-9/g"` &&
 | 
			
		||||
cmake .. \
 | 
			
		||||
    -DCMAKE_BUILD_TYPE=Release \
 | 
			
		||||
    -DWASMEDGE_BUILD_SHARED_LIB=OFF \
 | 
			
		||||
    -DWASMEDGE_BUILD_STATIC_LIB=ON \
 | 
			
		||||
    -DWASMEDGE_BUILD_AOT_RUNTIME=ON \
 | 
			
		||||
    -DWASMEDGE_FORCE_DISABLE_LTO=ON \
 | 
			
		||||
    -DCMAKE_POSITION_INDEPENDENT_CODE=ON \
 | 
			
		||||
    -DWASMEDGE_LINK_LLVM_STATIC=ON \
 | 
			
		||||
    -DWASMEDGE_BUILD_PLUGINS=OFF \
 | 
			
		||||
    -DWASMEDGE_LINK_TOOLS_STATIC=ON \
 | 
			
		||||
    -DBoost_NO_BOOST_CMAKE=ON -DLLVM_DIR=/usr/lib64/llvm13/lib/cmake/llvm/ -DLLVM_LIBRARY_DIR=/usr/lib64/llvm13/lib/ &&
 | 
			
		||||
make -j$3 install &&
 | 
			
		||||
export PATH=`echo $PATH | sed -E "s/devtoolset-9/devtoolset-10/g"` &&
 | 
			
		||||
cp -r include/api/wasmedge /usr/include/ &&
 | 
			
		||||
cd /io/ &&
 | 
			
		||||
# Environment setup moved to Dockerfile in release-builder.sh
 | 
			
		||||
source /opt/rh/gcc-toolset-11/enable
 | 
			
		||||
export PATH=/usr/local/bin:$PATH
 | 
			
		||||
export CC='ccache gcc' &&
 | 
			
		||||
export CXX='ccache g++' &&
 | 
			
		||||
echo "-- Build Rippled --" &&
 | 
			
		||||
pwd &&
 | 
			
		||||
cp Builds/CMake/deps/Rocksdb.cmake Builds/CMake/deps/Rocksdb.cmake.old &&
 | 
			
		||||
 | 
			
		||||
echo "MOVING TO [ build-core.sh ]"
 | 
			
		||||
cd /io;
 | 
			
		||||
echo "MOVING TO [ build-core.sh ]";
 | 
			
		||||
 | 
			
		||||
printenv > .env.temp;
 | 
			
		||||
cat .env.temp | grep '=' | sed s/\\\(^[^=]\\+=\\\)/\\1\\\"/g|sed s/\$/\\\"/g > .env;
 | 
			
		||||
 
 | 
			
		||||
@@ -1063,14 +1063,16 @@
 | 
			
		||||
#       RWDB is recommended for Validator and Peer nodes that are not required to 
 | 
			
		||||
#       store history.
 | 
			
		||||
#
 | 
			
		||||
#       RWDB maintains its high speed regardless of the amount of history
 | 
			
		||||
#       stored. Online delete should NOT be used instead RWDB will use the 
 | 
			
		||||
#       ledger_history config value to determine how many ledgers to keep in memory.
 | 
			
		||||
#
 | 
			
		||||
#   Required keys for NuDB, RWDB and RocksDB:
 | 
			
		||||
#   Required keys for NuDB and RocksDB:
 | 
			
		||||
#
 | 
			
		||||
#       path                Location to store the database
 | 
			
		||||
#
 | 
			
		||||
#   Required keys for RWDB:
 | 
			
		||||
#
 | 
			
		||||
#       online_delete       Required. RWDB stores data in memory and will
 | 
			
		||||
#                           grow unbounded without online_delete. See the
 | 
			
		||||
#                           online_delete section below.
 | 
			
		||||
#
 | 
			
		||||
#   Required keys for Cassandra:
 | 
			
		||||
#
 | 
			
		||||
#      contact_points       IP of a node in the Cassandra cluster
 | 
			
		||||
@@ -1110,7 +1112,17 @@
 | 
			
		||||
#                           if sufficient IOPS capacity is available.
 | 
			
		||||
#                           Default 0.
 | 
			
		||||
#
 | 
			
		||||
#   Optional keys for NuDB or RocksDB:
 | 
			
		||||
#   online_delete for RWDB, NuDB and RocksDB:
 | 
			
		||||
#
 | 
			
		||||
#       online_delete       Minimum value of 256. Enable automatic purging
 | 
			
		||||
#                           of older ledger information. Maintain at least this
 | 
			
		||||
#                           number of ledger records online. Must be greater
 | 
			
		||||
#                           than or equal to ledger_history.
 | 
			
		||||
#
 | 
			
		||||
#                           REQUIRED for RWDB to prevent out-of-memory errors.
 | 
			
		||||
#                           Optional for NuDB and RocksDB.
 | 
			
		||||
#
 | 
			
		||||
#   Optional keys for NuDB and RocksDB:
 | 
			
		||||
#
 | 
			
		||||
#       earliest_seq        The default is 32570 to match the XRP ledger
 | 
			
		||||
#                           network's earliest allowed sequence. Alternate
 | 
			
		||||
@@ -1120,12 +1132,7 @@
 | 
			
		||||
#                           it must be defined with the same value in both
 | 
			
		||||
#                           sections.
 | 
			
		||||
#
 | 
			
		||||
#       online_delete       Minimum value of 256. Enable automatic purging
 | 
			
		||||
#                           of older ledger information. Maintain at least this
 | 
			
		||||
#                           number of ledger records online. Must be greater
 | 
			
		||||
#                           than or equal to ledger_history. If using RWDB 
 | 
			
		||||
#                           this value is ignored.
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
#       These keys modify the behavior of online_delete, and thus are only
 | 
			
		||||
#       relevant if online_delete is defined and non-zero:
 | 
			
		||||
#
 | 
			
		||||
 
 | 
			
		||||
@@ -32,8 +32,8 @@ class Xrpl(ConanFile):
 | 
			
		||||
        'nudb/2.0.8',
 | 
			
		||||
        'openssl/1.1.1u',
 | 
			
		||||
        'protobuf/3.21.9',
 | 
			
		||||
        'snappy/1.1.10',
 | 
			
		||||
        'soci/4.0.3',
 | 
			
		||||
        'snappy/1.1.10@xahaud/stable',
 | 
			
		||||
        'soci/4.0.3@xahaud/stable',
 | 
			
		||||
        'sqlite3/3.42.0',
 | 
			
		||||
        'zlib/1.3.1',
 | 
			
		||||
        'wasmedge/0.11.2',
 | 
			
		||||
 
 | 
			
		||||
@@ -8,4 +8,4 @@ if [[ "$GITHUB_REPOSITORY" == "" ]]; then
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
echo "Mounting $(pwd)/io in ubuntu and running unit tests"
 | 
			
		||||
docker run --rm -i -v $(pwd):/io -e BUILD_CORES=$BUILD_CORES ubuntu sh -c '/io/release-build/xahaud --unittest-jobs $BUILD_CORES -u'
 | 
			
		||||
docker run --rm -i -v $(pwd):/io --platform=linux/amd64 -e BUILD_CORES=$BUILD_CORES ubuntu sh -c '/io/release-build/xahaud --unittest-jobs $BUILD_CORES -u'
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										11
									
								
								external/snappy/conanfile.py
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										11
									
								
								external/snappy/conanfile.py
									
									
									
									
										vendored
									
									
								
							@@ -77,9 +77,14 @@ class SnappyConan(ConanFile):
 | 
			
		||||
        self.cpp_info.set_property("cmake_target_name", "Snappy::snappy")
 | 
			
		||||
        # TODO: back to global scope in conan v2 once cmake_find_package* generators removed
 | 
			
		||||
        self.cpp_info.components["snappylib"].libs = ["snappy"]
 | 
			
		||||
        if not self.options.shared:
 | 
			
		||||
            if self.settings.os in ["Linux", "FreeBSD"]:
 | 
			
		||||
                self.cpp_info.components["snappylib"].system_libs.append("m")
 | 
			
		||||
        # The following block is commented out as a workaround for a bug in the
 | 
			
		||||
        # Conan 1.x CMakeDeps generator. Including system_libs ("m") here
 | 
			
		||||
        # incorrectly triggers a heuristic that adds a dynamic link to `stdc++`
 | 
			
		||||
        # (-lstdc++), preventing a fully static build.
 | 
			
		||||
        # This behavior is expected to be corrected in Conan 2.
 | 
			
		||||
        # if not self.options.shared:
 | 
			
		||||
        #     if self.settings.os in ["Linux", "FreeBSD"]:
 | 
			
		||||
        #         self.cpp_info.components["snappylib"].system_libs.append("m")
 | 
			
		||||
 | 
			
		||||
        # TODO: to remove in conan v2 once cmake_find_package* generators removed
 | 
			
		||||
        self.cpp_info.names["cmake_find_package"] = "Snappy"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								external/soci/conanfile.py
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								external/soci/conanfile.py
									
									
									
									
										vendored
									
									
								
							@@ -154,7 +154,7 @@ class SociConan(ConanFile):
 | 
			
		||||
        self.cpp_info.components["soci_core"].set_property("cmake_target_name", "SOCI::soci_core{}".format(target_suffix))
 | 
			
		||||
        self.cpp_info.components["soci_core"].libs = ["{}soci_core{}".format(lib_prefix, lib_suffix)]
 | 
			
		||||
        if self.options.with_boost:
 | 
			
		||||
            self.cpp_info.components["soci_core"].requires.append("boost::boost")
 | 
			
		||||
            self.cpp_info.components["soci_core"].requires.append("boost::headers")
 | 
			
		||||
 | 
			
		||||
        # soci_empty
 | 
			
		||||
        if self.options.empty:
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,8 @@
 | 
			
		||||
#!/bin/bash -u
 | 
			
		||||
#!/bin/bash 
 | 
			
		||||
# We use set -e and bash with -u to bail on first non zero exit code of any
 | 
			
		||||
# processes launched or upon any unbound variable.
 | 
			
		||||
# We use set -x to print commands before running them to help with
 | 
			
		||||
# debugging.
 | 
			
		||||
set -ex
 | 
			
		||||
 | 
			
		||||
echo "START BUILDING (HOST)"
 | 
			
		||||
 | 
			
		||||
@@ -14,7 +13,7 @@ BUILD_CORES=$(echo "scale=0 ; `nproc` / 1.337" | bc)
 | 
			
		||||
 | 
			
		||||
if [[ "$GITHUB_REPOSITORY" == "" ]]; then
 | 
			
		||||
  #Default
 | 
			
		||||
  BUILD_CORES=8
 | 
			
		||||
  BUILD_CORES=${BUILD_CORES:-8} 
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Ensure still works outside of GH Actions by setting these to /dev/null
 | 
			
		||||
@@ -46,29 +45,166 @@ fi
 | 
			
		||||
 | 
			
		||||
STATIC_CONTAINER=$(docker ps -a | grep $CONTAINER_NAME |wc -l)
 | 
			
		||||
 | 
			
		||||
CACHE_VOLUME_NAME="xahau-release-builder-cache"
 | 
			
		||||
 | 
			
		||||
# if [[ "$STATIC_CONTAINER" -gt "0" && "$GITHUB_REPOSITORY" != "" ]]; then
 | 
			
		||||
if false; then
 | 
			
		||||
  echo "Static container, execute in static container to have max. cache"
 | 
			
		||||
  docker start $CONTAINER_NAME
 | 
			
		||||
  docker exec -i $CONTAINER_NAME /hbb_exe/activate-exec bash -x /io/build-core.sh "$GITHUB_REPOSITORY" "$GITHUB_SHA" "$BUILD_CORES" "$GITHUB_RUN_NUMBER"
 | 
			
		||||
  docker exec -i $CONTAINER_NAME /hbb_exe/activate-exec bash -c "source /opt/rh/gcc-toolset-11/enable && bash -x /io/build-core.sh '$GITHUB_REPOSITORY' '$GITHUB_SHA' '$BUILD_CORES' '$GITHUB_RUN_NUMBER'"
 | 
			
		||||
  docker stop $CONTAINER_NAME
 | 
			
		||||
else
 | 
			
		||||
  echo "No static container, build on temp container"
 | 
			
		||||
  rm -rf release-build;
 | 
			
		||||
  mkdir -p release-build;
 | 
			
		||||
 | 
			
		||||
  docker volume create $CACHE_VOLUME_NAME
 | 
			
		||||
 | 
			
		||||
  # Create inline Dockerfile with environment setup for build-full.sh
 | 
			
		||||
  DOCKERFILE_CONTENT=$(cat <<'DOCKERFILE_EOF'
 | 
			
		||||
FROM ghcr.io/phusion/holy-build-box:4.0.1-amd64
 | 
			
		||||
 | 
			
		||||
ARG BUILD_CORES=8
 | 
			
		||||
 | 
			
		||||
# Enable repositories and install dependencies
 | 
			
		||||
RUN /hbb_exe/activate-exec bash -c "dnf install -y epel-release && \
 | 
			
		||||
    dnf config-manager --set-enabled powertools || dnf config-manager --set-enabled crb && \
 | 
			
		||||
    dnf install -y --enablerepo=devel \
 | 
			
		||||
        wget git \
 | 
			
		||||
        gcc-toolset-11-gcc-c++ gcc-toolset-11-binutils gcc-toolset-11-libatomic-devel \
 | 
			
		||||
        lz4 lz4-devel \
 | 
			
		||||
        ncurses-static ncurses-devel \
 | 
			
		||||
        snappy snappy-devel \
 | 
			
		||||
        zlib zlib-devel zlib-static \
 | 
			
		||||
        libasan \
 | 
			
		||||
        python3 python3-pip \
 | 
			
		||||
        ccache \
 | 
			
		||||
        ninja-build \
 | 
			
		||||
        patch \
 | 
			
		||||
        glibc-devel glibc-static \
 | 
			
		||||
        libxml2-devel \
 | 
			
		||||
        autoconf \
 | 
			
		||||
        automake \
 | 
			
		||||
        texinfo \
 | 
			
		||||
        libtool \
 | 
			
		||||
        llvm14-static llvm14-devel && \
 | 
			
		||||
    dnf clean all"
 | 
			
		||||
 | 
			
		||||
# Install Conan and CMake
 | 
			
		||||
RUN /hbb_exe/activate-exec pip3 install "conan==1.66.0" && \
 | 
			
		||||
    /hbb_exe/activate-exec wget -q https://github.com/Kitware/CMake/releases/download/v3.23.1/cmake-3.23.1-linux-x86_64.tar.gz -O cmake.tar.gz && \
 | 
			
		||||
    mkdir cmake && \
 | 
			
		||||
    tar -xzf cmake.tar.gz --strip-components=1 -C cmake && \
 | 
			
		||||
    rm cmake.tar.gz
 | 
			
		||||
 | 
			
		||||
# Install Boost 1.86.0
 | 
			
		||||
RUN /hbb_exe/activate-exec bash -c "cd /tmp && \
 | 
			
		||||
    wget -q https://archives.boost.io/release/1.86.0/source/boost_1_86_0.tar.gz -O boost.tar.gz && \
 | 
			
		||||
    mkdir boost && \
 | 
			
		||||
    tar -xzf boost.tar.gz --strip-components=1 -C boost && \
 | 
			
		||||
    cd boost && \
 | 
			
		||||
    ./bootstrap.sh && \
 | 
			
		||||
    ./b2 link=static -j${BUILD_CORES} && \
 | 
			
		||||
    ./b2 install && \
 | 
			
		||||
    cd /tmp && \
 | 
			
		||||
    rm -rf boost boost.tar.gz"
 | 
			
		||||
 | 
			
		||||
ENV BOOST_ROOT=/usr/local/src/boost_1_86_0
 | 
			
		||||
ENV Boost_LIBRARY_DIRS=/usr/local/lib
 | 
			
		||||
ENV BOOST_INCLUDEDIR=/usr/local/src/boost_1_86_0
 | 
			
		||||
 | 
			
		||||
ENV CMAKE_EXE_LINKER_FLAGS="-static-libstdc++"
 | 
			
		||||
 | 
			
		||||
ENV LLVM_DIR=/usr/lib64/llvm14/lib/cmake/llvm
 | 
			
		||||
ENV WasmEdge_LIB=/usr/local/lib64/libwasmedge.a
 | 
			
		||||
 | 
			
		||||
ENV CC='ccache gcc'
 | 
			
		||||
ENV CXX='ccache g++'
 | 
			
		||||
 | 
			
		||||
# Install LLD
 | 
			
		||||
RUN /hbb_exe/activate-exec bash -c "source /opt/rh/gcc-toolset-11/enable && \
 | 
			
		||||
    cd /tmp && \
 | 
			
		||||
    wget -q https://github.com/llvm/llvm-project/releases/download/llvmorg-14.0.3/lld-14.0.3.src.tar.xz && \
 | 
			
		||||
    wget -q https://github.com/llvm/llvm-project/releases/download/llvmorg-14.0.3/libunwind-14.0.3.src.tar.xz && \
 | 
			
		||||
    tar -xf lld-14.0.3.src.tar.xz && \
 | 
			
		||||
    tar -xf libunwind-14.0.3.src.tar.xz && \
 | 
			
		||||
    cp -r libunwind-14.0.3.src/include libunwind-14.0.3.src/src lld-14.0.3.src/ && \
 | 
			
		||||
    cd lld-14.0.3.src && \
 | 
			
		||||
    mkdir -p build && cd build && \
 | 
			
		||||
    cmake .. \
 | 
			
		||||
        -DLLVM_LIBRARY_DIR=/usr/lib64/llvm14/lib/ \
 | 
			
		||||
        -DCMAKE_INSTALL_PREFIX=/usr/lib64/llvm14/ \
 | 
			
		||||
        -DCMAKE_BUILD_TYPE=Release \
 | 
			
		||||
        -DCMAKE_EXE_LINKER_FLAGS=\"\$CMAKE_EXE_LINKER_FLAGS\" && \
 | 
			
		||||
    make -j${BUILD_CORES} install && \
 | 
			
		||||
    ln -s /usr/lib64/llvm14/lib/include/lld /usr/include/lld && \
 | 
			
		||||
    cp /usr/lib64/llvm14/lib/liblld*.a /usr/local/lib/ && \
 | 
			
		||||
    cd /tmp && rm -rf lld-* libunwind-*"
 | 
			
		||||
 | 
			
		||||
# Build and install WasmEdge (static version)
 | 
			
		||||
# Note: Conan only provides WasmEdge with shared library linking.
 | 
			
		||||
# For a fully static build, we need to manually install:
 | 
			
		||||
# * Boost: Static C++ libraries for filesystem and system operations (built from source above)
 | 
			
		||||
# * LLVM: Static LLVM libraries for WebAssembly compilation (installed via llvm14-static package)
 | 
			
		||||
# * LLD: Static linker to produce the final static binary (built from source above)
 | 
			
		||||
# These were installed above to enable WASMEDGE_LINK_LLVM_STATIC=ON
 | 
			
		||||
RUN cd /tmp && \
 | 
			
		||||
    ( wget -nc -q https://github.com/WasmEdge/WasmEdge/archive/refs/tags/0.11.2.zip; unzip -o 0.11.2.zip; ) && \
 | 
			
		||||
    cd WasmEdge-0.11.2 && \
 | 
			
		||||
    ( mkdir -p build; echo "" ) && \
 | 
			
		||||
    cd build && \
 | 
			
		||||
    /hbb_exe/activate-exec bash -c "source /opt/rh/gcc-toolset-11/enable && \
 | 
			
		||||
    ln -sf /opt/rh/gcc-toolset-11/root/usr/bin/ar /usr/bin/ar && \
 | 
			
		||||
    cmake .. \
 | 
			
		||||
        -DCMAKE_BUILD_TYPE=Release \
 | 
			
		||||
        -DCMAKE_INSTALL_PREFIX=/usr/local \
 | 
			
		||||
        -DCMAKE_POSITION_INDEPENDENT_CODE=ON \
 | 
			
		||||
        -DWASMEDGE_BUILD_SHARED_LIB=OFF \
 | 
			
		||||
        -DWASMEDGE_BUILD_STATIC_LIB=ON \
 | 
			
		||||
        -DWASMEDGE_BUILD_AOT_RUNTIME=ON \
 | 
			
		||||
        -DWASMEDGE_FORCE_DISABLE_LTO=ON \
 | 
			
		||||
        -DWASMEDGE_LINK_LLVM_STATIC=ON \
 | 
			
		||||
        -DWASMEDGE_BUILD_PLUGINS=OFF \
 | 
			
		||||
        -DWASMEDGE_LINK_TOOLS_STATIC=ON \
 | 
			
		||||
        -DBoost_NO_BOOST_CMAKE=ON \
 | 
			
		||||
        -DCMAKE_EXE_LINKER_FLAGS=\"\$CMAKE_EXE_LINKER_FLAGS\" \
 | 
			
		||||
        && \
 | 
			
		||||
    make -j${BUILD_CORES} install" && \
 | 
			
		||||
    cp -r include/api/wasmedge /usr/include/ && \
 | 
			
		||||
    cd /tmp && rm -rf WasmEdge* 0.11.2.zip
 | 
			
		||||
 | 
			
		||||
# Set environment variables
 | 
			
		||||
ENV PATH=/usr/local/bin:$PATH
 | 
			
		||||
 | 
			
		||||
# Configure ccache and Conan
 | 
			
		||||
RUN /hbb_exe/activate-exec bash -c "ccache -M 10G && \
 | 
			
		||||
    ccache -o cache_dir=/cache/ccache && \
 | 
			
		||||
    ccache -o compiler_check=content && \
 | 
			
		||||
    conan config set storage.path=/cache/conan && \
 | 
			
		||||
    (conan profile new default --detect || true) && \
 | 
			
		||||
    conan profile update settings.compiler.libcxx=libstdc++11 default && \
 | 
			
		||||
    conan profile update settings.compiler.cppstd=20 default"
 | 
			
		||||
 | 
			
		||||
DOCKERFILE_EOF
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
  # Build custom Docker image
 | 
			
		||||
  IMAGE_NAME="xahaud-builder:latest"
 | 
			
		||||
  echo "Building custom Docker image with dependencies..."
 | 
			
		||||
  echo "$DOCKERFILE_CONTENT" | docker build --build-arg BUILD_CORES="$BUILD_CORES" -t "$IMAGE_NAME" - || exit 1
 | 
			
		||||
 | 
			
		||||
  if [[ "$GITHUB_REPOSITORY" == "" ]]; then
 | 
			
		||||
    # Non GH, local building
 | 
			
		||||
    echo "Non-GH runner, local building, temp container"
 | 
			
		||||
    docker run -i --user 0:$(id -g) --rm -v /data/builds:/data/builds -v `pwd`:/io --network host ghcr.io/foobarwidget/holy-build-box-x64 /hbb_exe/activate-exec bash -x /io/build-full.sh "$GITHUB_REPOSITORY" "$GITHUB_SHA" "$BUILD_CORES" "$GITHUB_RUN_NUMBER"
 | 
			
		||||
    docker run -i --user 0:$(id -g) --rm -v /data/builds:/data/builds -v `pwd`:/io -v "$CACHE_VOLUME_NAME":/cache --network host "$IMAGE_NAME" /hbb_exe/activate-exec bash -c "source /opt/rh/gcc-toolset-11/enable && bash -x /io/build-full.sh '$GITHUB_REPOSITORY' '$GITHUB_SHA' '$BUILD_CORES' '$GITHUB_RUN_NUMBER'"
 | 
			
		||||
  else
 | 
			
		||||
    # GH Action, runner
 | 
			
		||||
    echo "GH Action, runner, clean & re-create create persistent container"
 | 
			
		||||
    docker rm -f $CONTAINER_NAME
 | 
			
		||||
    echo "echo 'Stopping container: $CONTAINER_NAME'" >> "$JOB_CLEANUP_SCRIPT"
 | 
			
		||||
    echo "docker stop --time=15 \"$CONTAINER_NAME\" || echo 'Failed to stop container or container not running'" >> "$JOB_CLEANUP_SCRIPT"
 | 
			
		||||
    docker run -di --user 0:$(id -g) --name $CONTAINER_NAME -v /data/builds:/data/builds -v `pwd`:/io --network host ghcr.io/foobarwidget/holy-build-box-x64 /hbb_exe/activate-exec bash
 | 
			
		||||
    docker exec -i $CONTAINER_NAME /hbb_exe/activate-exec bash -x /io/build-full.sh "$GITHUB_REPOSITORY" "$GITHUB_SHA" "$BUILD_CORES" "$GITHUB_RUN_NUMBER"
 | 
			
		||||
    docker run -di --user 0:$(id -g) --name $CONTAINER_NAME -v /data/builds:/data/builds -v `pwd`:/io -v "$CACHE_VOLUME_NAME":/cache --network host "$IMAGE_NAME" /hbb_exe/activate-exec bash
 | 
			
		||||
    docker exec -i $CONTAINER_NAME /hbb_exe/activate-exec bash -c "source /opt/rh/gcc-toolset-11/enable && bash -x /io/build-full.sh '$GITHUB_REPOSITORY' '$GITHUB_SHA' '$BUILD_CORES' '$GITHUB_RUN_NUMBER'"
 | 
			
		||||
    docker stop $CONTAINER_NAME
 | 
			
		||||
  fi
 | 
			
		||||
fi
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,4 @@
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <map>
 | 
			
		||||
#include <set>
 | 
			
		||||
#include <string>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,851 +0,0 @@
 | 
			
		||||
#ifndef RIPPLE_APP_RDB_BACKEND_FLATMAPDATABASE_H_INCLUDED
 | 
			
		||||
#define RIPPLE_APP_RDB_BACKEND_FLATMAPDATABASE_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#include <ripple/app/ledger/AcceptedLedger.h>
 | 
			
		||||
#include <ripple/app/ledger/LedgerMaster.h>
 | 
			
		||||
#include <ripple/app/ledger/TransactionMaster.h>
 | 
			
		||||
#include <ripple/app/rdb/backend/SQLiteDatabase.h>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <map>
 | 
			
		||||
#include <mutex>
 | 
			
		||||
#include <optional>
 | 
			
		||||
#include <shared_mutex>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#include <boost/unordered/concurrent_flat_map.hpp>
 | 
			
		||||
 | 
			
		||||
namespace ripple {
 | 
			
		||||
 | 
			
		||||
struct base_uint_hasher
 | 
			
		||||
{
 | 
			
		||||
    using result_type = std::size_t;
 | 
			
		||||
 | 
			
		||||
    result_type
 | 
			
		||||
    operator()(base_uint<256> const& value) const
 | 
			
		||||
    {
 | 
			
		||||
        return hardened_hash<>{}(value);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    result_type
 | 
			
		||||
    operator()(AccountID const& value) const
 | 
			
		||||
    {
 | 
			
		||||
        return hardened_hash<>{}(value);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class FlatmapDatabase : public SQLiteDatabase
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
    struct LedgerData
 | 
			
		||||
    {
 | 
			
		||||
        LedgerInfo info;
 | 
			
		||||
        boost::unordered::
 | 
			
		||||
            concurrent_flat_map<uint256, AccountTx, base_uint_hasher>
 | 
			
		||||
                transactions;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    struct AccountTxData
 | 
			
		||||
    {
 | 
			
		||||
        boost::unordered::
 | 
			
		||||
            concurrent_flat_map<std::pair<uint32_t, uint32_t>, AccountTx>
 | 
			
		||||
                transactions;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    Application& app_;
 | 
			
		||||
 | 
			
		||||
    boost::unordered::concurrent_flat_map<LedgerIndex, LedgerData> ledgers_;
 | 
			
		||||
    boost::unordered::
 | 
			
		||||
        concurrent_flat_map<uint256, LedgerIndex, base_uint_hasher>
 | 
			
		||||
            ledgerHashToSeq_;
 | 
			
		||||
    boost::unordered::concurrent_flat_map<uint256, AccountTx, base_uint_hasher>
 | 
			
		||||
        transactionMap_;
 | 
			
		||||
    boost::unordered::
 | 
			
		||||
        concurrent_flat_map<AccountID, AccountTxData, base_uint_hasher>
 | 
			
		||||
            accountTxMap_;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    FlatmapDatabase(Application& app, Config const& config, JobQueue& jobQueue)
 | 
			
		||||
        : app_(app)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::optional<LedgerIndex>
 | 
			
		||||
    getMinLedgerSeq() override
 | 
			
		||||
    {
 | 
			
		||||
        std::optional<LedgerIndex> minSeq;
 | 
			
		||||
        ledgers_.visit_all([&minSeq](auto const& pair) {
 | 
			
		||||
            if (!minSeq || pair.first < *minSeq)
 | 
			
		||||
            {
 | 
			
		||||
                minSeq = pair.first;
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        return minSeq;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::optional<LedgerIndex>
 | 
			
		||||
    getTransactionsMinLedgerSeq() override
 | 
			
		||||
    {
 | 
			
		||||
        std::optional<LedgerIndex> minSeq;
 | 
			
		||||
        transactionMap_.visit_all([&minSeq](auto const& pair) {
 | 
			
		||||
            LedgerIndex seq = pair.second.second->getLgrSeq();
 | 
			
		||||
            if (!minSeq || seq < *minSeq)
 | 
			
		||||
            {
 | 
			
		||||
                minSeq = seq;
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        return minSeq;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::optional<LedgerIndex>
 | 
			
		||||
    getAccountTransactionsMinLedgerSeq() override
 | 
			
		||||
    {
 | 
			
		||||
        std::optional<LedgerIndex> minSeq;
 | 
			
		||||
        accountTxMap_.visit_all([&minSeq](auto const& pair) {
 | 
			
		||||
            pair.second.transactions.visit_all([&minSeq](auto const& tx) {
 | 
			
		||||
                if (!minSeq || tx.first.first < *minSeq)
 | 
			
		||||
                {
 | 
			
		||||
                    minSeq = tx.first.first;
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
        return minSeq;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::optional<LedgerIndex>
 | 
			
		||||
    getMaxLedgerSeq() override
 | 
			
		||||
    {
 | 
			
		||||
        std::optional<LedgerIndex> maxSeq;
 | 
			
		||||
        ledgers_.visit_all([&maxSeq](auto const& pair) {
 | 
			
		||||
            if (!maxSeq || pair.first > *maxSeq)
 | 
			
		||||
            {
 | 
			
		||||
                maxSeq = pair.first;
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        return maxSeq;
 | 
			
		||||
    }
 | 
			
		||||
    void
 | 
			
		||||
    deleteTransactionByLedgerSeq(LedgerIndex ledgerSeq) override
 | 
			
		||||
    {
 | 
			
		||||
        ledgers_.visit(ledgerSeq, [this](auto& item) {
 | 
			
		||||
            item.second.transactions.visit_all([this](auto const& txPair) {
 | 
			
		||||
                transactionMap_.erase(txPair.first);
 | 
			
		||||
            });
 | 
			
		||||
            item.second.transactions.clear();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        accountTxMap_.visit_all([ledgerSeq](auto& item) {
 | 
			
		||||
            item.second.transactions.erase_if([ledgerSeq](auto const& tx) {
 | 
			
		||||
                return tx.first.first == ledgerSeq;
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void
 | 
			
		||||
    deleteBeforeLedgerSeq(LedgerIndex ledgerSeq) override
 | 
			
		||||
    {
 | 
			
		||||
        ledgers_.erase_if([this, ledgerSeq](auto const& item) {
 | 
			
		||||
            if (item.first < ledgerSeq)
 | 
			
		||||
            {
 | 
			
		||||
                item.second.transactions.visit_all([this](auto const& txPair) {
 | 
			
		||||
                    transactionMap_.erase(txPair.first);
 | 
			
		||||
                });
 | 
			
		||||
                ledgerHashToSeq_.erase(item.second.info.hash);
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        accountTxMap_.visit_all([ledgerSeq](auto& item) {
 | 
			
		||||
            item.second.transactions.erase_if([ledgerSeq](auto const& tx) {
 | 
			
		||||
                return tx.first.first < ledgerSeq;
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void
 | 
			
		||||
    deleteTransactionsBeforeLedgerSeq(LedgerIndex ledgerSeq) override
 | 
			
		||||
    {
 | 
			
		||||
        ledgers_.visit_all([this, ledgerSeq](auto& item) {
 | 
			
		||||
            if (item.first < ledgerSeq)
 | 
			
		||||
            {
 | 
			
		||||
                item.second.transactions.visit_all([this](auto const& txPair) {
 | 
			
		||||
                    transactionMap_.erase(txPair.first);
 | 
			
		||||
                });
 | 
			
		||||
                item.second.transactions.clear();
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        accountTxMap_.visit_all([ledgerSeq](auto& item) {
 | 
			
		||||
            item.second.transactions.erase_if([ledgerSeq](auto const& tx) {
 | 
			
		||||
                return tx.first.first < ledgerSeq;
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void
 | 
			
		||||
    deleteAccountTransactionsBeforeLedgerSeq(LedgerIndex ledgerSeq) override
 | 
			
		||||
    {
 | 
			
		||||
        accountTxMap_.visit_all([ledgerSeq](auto& item) {
 | 
			
		||||
            item.second.transactions.erase_if([ledgerSeq](auto const& tx) {
 | 
			
		||||
                return tx.first.first < ledgerSeq;
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
    std::size_t
 | 
			
		||||
    getTransactionCount() override
 | 
			
		||||
    {
 | 
			
		||||
        return transactionMap_.size();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::size_t
 | 
			
		||||
    getAccountTransactionCount() override
 | 
			
		||||
    {
 | 
			
		||||
        std::size_t count = 0;
 | 
			
		||||
        accountTxMap_.visit_all([&count](auto const& item) {
 | 
			
		||||
            count += item.second.transactions.size();
 | 
			
		||||
        });
 | 
			
		||||
        return count;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    CountMinMax
 | 
			
		||||
    getLedgerCountMinMax() override
 | 
			
		||||
    {
 | 
			
		||||
        CountMinMax result{0, 0, 0};
 | 
			
		||||
        ledgers_.visit_all([&result](auto const& item) {
 | 
			
		||||
            result.numberOfRows++;
 | 
			
		||||
            if (result.minLedgerSequence == 0 ||
 | 
			
		||||
                item.first < result.minLedgerSequence)
 | 
			
		||||
            {
 | 
			
		||||
                result.minLedgerSequence = item.first;
 | 
			
		||||
            }
 | 
			
		||||
            if (item.first > result.maxLedgerSequence)
 | 
			
		||||
            {
 | 
			
		||||
                result.maxLedgerSequence = item.first;
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool
 | 
			
		||||
    saveValidatedLedger(
 | 
			
		||||
        std::shared_ptr<Ledger const> const& ledger,
 | 
			
		||||
        bool current) override
 | 
			
		||||
    {
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            LedgerData ledgerData;
 | 
			
		||||
            ledgerData.info = ledger->info();
 | 
			
		||||
 | 
			
		||||
            auto aLedger = std::make_shared<AcceptedLedger>(ledger, app_);
 | 
			
		||||
            for (auto const& acceptedLedgerTx : *aLedger)
 | 
			
		||||
            {
 | 
			
		||||
                auto const& txn = acceptedLedgerTx->getTxn();
 | 
			
		||||
                auto const& meta = acceptedLedgerTx->getMeta();
 | 
			
		||||
                auto const& id = txn->getTransactionID();
 | 
			
		||||
 | 
			
		||||
                std::string reason;
 | 
			
		||||
                auto accTx = std::make_pair(
 | 
			
		||||
                    std::make_shared<ripple::Transaction>(txn, reason, app_),
 | 
			
		||||
                    std::make_shared<ripple::TxMeta>(meta));
 | 
			
		||||
 | 
			
		||||
                ledgerData.transactions.emplace(id, accTx);
 | 
			
		||||
                transactionMap_.emplace(id, accTx);
 | 
			
		||||
 | 
			
		||||
                for (auto const& account : meta.getAffectedAccounts())
 | 
			
		||||
                {
 | 
			
		||||
                    accountTxMap_.visit(account, [&](auto& data) {
 | 
			
		||||
                        data.second.transactions.emplace(
 | 
			
		||||
                            std::make_pair(
 | 
			
		||||
                                ledger->info().seq,
 | 
			
		||||
                                acceptedLedgerTx->getTxnSeq()),
 | 
			
		||||
                            accTx);
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            ledgers_.emplace(ledger->info().seq, std::move(ledgerData));
 | 
			
		||||
            ledgerHashToSeq_.emplace(ledger->info().hash, ledger->info().seq);
 | 
			
		||||
 | 
			
		||||
            if (current)
 | 
			
		||||
            {
 | 
			
		||||
                auto const cutoffSeq =
 | 
			
		||||
                    ledger->info().seq > app_.config().LEDGER_HISTORY
 | 
			
		||||
                    ? ledger->info().seq - app_.config().LEDGER_HISTORY
 | 
			
		||||
                    : 0;
 | 
			
		||||
 | 
			
		||||
                if (cutoffSeq > 0)
 | 
			
		||||
                {
 | 
			
		||||
                    const std::size_t BATCH_SIZE = 128;
 | 
			
		||||
                    std::size_t deleted = 0;
 | 
			
		||||
 | 
			
		||||
                    ledgers_.erase_if([&](auto const& item) {
 | 
			
		||||
                        if (deleted >= BATCH_SIZE)
 | 
			
		||||
                            return false;
 | 
			
		||||
 | 
			
		||||
                        if (item.first < cutoffSeq)
 | 
			
		||||
                        {
 | 
			
		||||
                            item.second.transactions.visit_all(
 | 
			
		||||
                                [this](auto const& txPair) {
 | 
			
		||||
                                    transactionMap_.erase(txPair.first);
 | 
			
		||||
                                });
 | 
			
		||||
                            ledgerHashToSeq_.erase(item.second.info.hash);
 | 
			
		||||
                            deleted++;
 | 
			
		||||
                            return true;
 | 
			
		||||
                        }
 | 
			
		||||
                        return false;
 | 
			
		||||
                    });
 | 
			
		||||
 | 
			
		||||
                    if (deleted > 0)
 | 
			
		||||
                    {
 | 
			
		||||
                        accountTxMap_.visit_all([cutoffSeq](auto& item) {
 | 
			
		||||
                            item.second.transactions.erase_if(
 | 
			
		||||
                                [cutoffSeq](auto const& tx) {
 | 
			
		||||
                                    return tx.first.first < cutoffSeq;
 | 
			
		||||
                                });
 | 
			
		||||
                        });
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    app_.getLedgerMaster().clearPriorLedgers(cutoffSeq);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        catch (std::exception const&)
 | 
			
		||||
        {
 | 
			
		||||
            deleteTransactionByLedgerSeq(ledger->info().seq);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::optional<LedgerInfo>
 | 
			
		||||
    getLedgerInfoByIndex(LedgerIndex ledgerSeq) override
 | 
			
		||||
    {
 | 
			
		||||
        std::optional<LedgerInfo> result;
 | 
			
		||||
        ledgers_.visit(ledgerSeq, [&result](auto const& item) {
 | 
			
		||||
            result = item.second.info;
 | 
			
		||||
        });
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::optional<LedgerInfo>
 | 
			
		||||
    getNewestLedgerInfo() override
 | 
			
		||||
    {
 | 
			
		||||
        std::optional<LedgerInfo> result;
 | 
			
		||||
        ledgers_.visit_all([&result](auto const& item) {
 | 
			
		||||
            if (!result || item.second.info.seq > result->seq)
 | 
			
		||||
            {
 | 
			
		||||
                result = item.second.info;
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::optional<LedgerInfo>
 | 
			
		||||
    getLimitedOldestLedgerInfo(LedgerIndex ledgerFirstIndex) override
 | 
			
		||||
    {
 | 
			
		||||
        std::optional<LedgerInfo> result;
 | 
			
		||||
        ledgers_.visit_all([&](auto const& item) {
 | 
			
		||||
            if (item.first >= ledgerFirstIndex &&
 | 
			
		||||
                (!result || item.first < result->seq))
 | 
			
		||||
            {
 | 
			
		||||
                result = item.second.info;
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::optional<LedgerInfo>
 | 
			
		||||
    getLimitedNewestLedgerInfo(LedgerIndex ledgerFirstIndex) override
 | 
			
		||||
    {
 | 
			
		||||
        std::optional<LedgerInfo> result;
 | 
			
		||||
        ledgers_.visit_all([&](auto const& item) {
 | 
			
		||||
            if (item.first >= ledgerFirstIndex &&
 | 
			
		||||
                (!result || item.first > result->seq))
 | 
			
		||||
            {
 | 
			
		||||
                result = item.second.info;
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::optional<LedgerInfo>
 | 
			
		||||
    getLedgerInfoByHash(uint256 const& ledgerHash) override
 | 
			
		||||
    {
 | 
			
		||||
        std::optional<LedgerInfo> result;
 | 
			
		||||
        ledgerHashToSeq_.visit(ledgerHash, [this, &result](auto const& item) {
 | 
			
		||||
            ledgers_.visit(item.second, [&result](auto const& item) {
 | 
			
		||||
                result = item.second.info;
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
    uint256
 | 
			
		||||
    getHashByIndex(LedgerIndex ledgerIndex) override
 | 
			
		||||
    {
 | 
			
		||||
        uint256 result;
 | 
			
		||||
        ledgers_.visit(ledgerIndex, [&result](auto const& item) {
 | 
			
		||||
            result = item.second.info.hash;
 | 
			
		||||
        });
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::optional<LedgerHashPair>
 | 
			
		||||
    getHashesByIndex(LedgerIndex ledgerIndex) override
 | 
			
		||||
    {
 | 
			
		||||
        std::optional<LedgerHashPair> result;
 | 
			
		||||
        ledgers_.visit(ledgerIndex, [&result](auto const& item) {
 | 
			
		||||
            result = LedgerHashPair{
 | 
			
		||||
                item.second.info.hash, item.second.info.parentHash};
 | 
			
		||||
        });
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::map<LedgerIndex, LedgerHashPair>
 | 
			
		||||
    getHashesByIndex(LedgerIndex minSeq, LedgerIndex maxSeq) override
 | 
			
		||||
    {
 | 
			
		||||
        std::map<LedgerIndex, LedgerHashPair> result;
 | 
			
		||||
        ledgers_.visit_all([&](auto const& item) {
 | 
			
		||||
            if (item.first >= minSeq && item.first <= maxSeq)
 | 
			
		||||
            {
 | 
			
		||||
                result[item.first] = LedgerHashPair{
 | 
			
		||||
                    item.second.info.hash, item.second.info.parentHash};
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::variant<AccountTx, TxSearched>
 | 
			
		||||
    getTransaction(
 | 
			
		||||
        uint256 const& id,
 | 
			
		||||
        std::optional<ClosedInterval<std::uint32_t>> const& range,
 | 
			
		||||
        error_code_i& ec) override
 | 
			
		||||
    {
 | 
			
		||||
        std::variant<AccountTx, TxSearched> result = TxSearched::unknown;
 | 
			
		||||
        transactionMap_.visit(id, [&](auto const& item) {
 | 
			
		||||
            auto const& tx = item.second;
 | 
			
		||||
            if (!range ||
 | 
			
		||||
                (range->lower() <= tx.second->getLgrSeq() &&
 | 
			
		||||
                 tx.second->getLgrSeq() <= range->upper()))
 | 
			
		||||
            {
 | 
			
		||||
                result = tx;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                result = TxSearched::all;
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool
 | 
			
		||||
    ledgerDbHasSpace(Config const& config) override
 | 
			
		||||
    {
 | 
			
		||||
        return true;  // In-memory database always has space
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool
 | 
			
		||||
    transactionDbHasSpace(Config const& config) override
 | 
			
		||||
    {
 | 
			
		||||
        return true;  // In-memory database always has space
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::uint32_t
 | 
			
		||||
    getKBUsedAll() override
 | 
			
		||||
    {
 | 
			
		||||
        std::uint32_t size = sizeof(*this);
 | 
			
		||||
        size += ledgers_.size() * (sizeof(LedgerIndex) + sizeof(LedgerData));
 | 
			
		||||
        size +=
 | 
			
		||||
            ledgerHashToSeq_.size() * (sizeof(uint256) + sizeof(LedgerIndex));
 | 
			
		||||
        size += transactionMap_.size() * (sizeof(uint256) + sizeof(AccountTx));
 | 
			
		||||
        accountTxMap_.visit_all([&size](auto const& item) {
 | 
			
		||||
            size += sizeof(AccountID) + sizeof(AccountTxData);
 | 
			
		||||
            size += item.second.transactions.size() * sizeof(AccountTx);
 | 
			
		||||
        });
 | 
			
		||||
        return size / 1024;  // Convert to KB
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::uint32_t
 | 
			
		||||
    getKBUsedLedger() override
 | 
			
		||||
    {
 | 
			
		||||
        std::uint32_t size =
 | 
			
		||||
            ledgers_.size() * (sizeof(LedgerIndex) + sizeof(LedgerData));
 | 
			
		||||
        size +=
 | 
			
		||||
            ledgerHashToSeq_.size() * (sizeof(uint256) + sizeof(LedgerIndex));
 | 
			
		||||
        return size / 1024;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::uint32_t
 | 
			
		||||
    getKBUsedTransaction() override
 | 
			
		||||
    {
 | 
			
		||||
        std::uint32_t size =
 | 
			
		||||
            transactionMap_.size() * (sizeof(uint256) + sizeof(AccountTx));
 | 
			
		||||
        accountTxMap_.visit_all([&size](auto const& item) {
 | 
			
		||||
            size += sizeof(AccountID) + sizeof(AccountTxData);
 | 
			
		||||
            size += item.second.transactions.size() * sizeof(AccountTx);
 | 
			
		||||
        });
 | 
			
		||||
        return size / 1024;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void
 | 
			
		||||
    closeLedgerDB() override
 | 
			
		||||
    {
 | 
			
		||||
        // No-op for in-memory database
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void
 | 
			
		||||
    closeTransactionDB() override
 | 
			
		||||
    {
 | 
			
		||||
        // No-op for in-memory database
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~FlatmapDatabase()
 | 
			
		||||
    {
 | 
			
		||||
        // Concurrent maps need visit_all
 | 
			
		||||
        accountTxMap_.visit_all(
 | 
			
		||||
            [](auto& pair) { pair.second.transactions.clear(); });
 | 
			
		||||
        accountTxMap_.clear();
 | 
			
		||||
 | 
			
		||||
        transactionMap_.clear();
 | 
			
		||||
 | 
			
		||||
        ledgers_.visit_all(
 | 
			
		||||
            [](auto& pair) { pair.second.transactions.clear(); });
 | 
			
		||||
        ledgers_.clear();
 | 
			
		||||
 | 
			
		||||
        ledgerHashToSeq_.clear();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::vector<std::shared_ptr<Transaction>>
 | 
			
		||||
    getTxHistory(LedgerIndex startIndex) override
 | 
			
		||||
    {
 | 
			
		||||
        std::vector<std::shared_ptr<Transaction>> result;
 | 
			
		||||
        transactionMap_.visit_all([&](auto const& item) {
 | 
			
		||||
            if (item.second.second->getLgrSeq() >= startIndex)
 | 
			
		||||
            {
 | 
			
		||||
                result.push_back(item.second.first);
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
        std::sort(
 | 
			
		||||
            result.begin(), result.end(), [](auto const& a, auto const& b) {
 | 
			
		||||
                return a->getLedger() > b->getLedger();
 | 
			
		||||
            });
 | 
			
		||||
        if (result.size() > 20)
 | 
			
		||||
        {
 | 
			
		||||
            result.resize(20);
 | 
			
		||||
        }
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
    // Helper function to handle limits
 | 
			
		||||
    template <typename Container>
 | 
			
		||||
    void
 | 
			
		||||
    applyLimit(Container& container, std::size_t limit, bool bUnlimited)
 | 
			
		||||
    {
 | 
			
		||||
        if (!bUnlimited && limit > 0 && container.size() > limit)
 | 
			
		||||
        {
 | 
			
		||||
            container.resize(limit);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    AccountTxs
 | 
			
		||||
    getOldestAccountTxs(AccountTxOptions const& options) override
 | 
			
		||||
    {
 | 
			
		||||
        AccountTxs result;
 | 
			
		||||
        accountTxMap_.visit(options.account, [&](auto const& item) {
 | 
			
		||||
            item.second.transactions.visit_all([&](auto const& tx) {
 | 
			
		||||
                if (tx.first.first >= options.minLedger &&
 | 
			
		||||
                    tx.first.first <= options.maxLedger)
 | 
			
		||||
                {
 | 
			
		||||
                    result.push_back(tx.second);
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
        std::sort(
 | 
			
		||||
            result.begin(), result.end(), [](auto const& a, auto const& b) {
 | 
			
		||||
                return a.second->getLgrSeq() < b.second->getLgrSeq();
 | 
			
		||||
            });
 | 
			
		||||
        applyLimit(result, options.limit, options.bUnlimited);
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    AccountTxs
 | 
			
		||||
    getNewestAccountTxs(AccountTxOptions const& options) override
 | 
			
		||||
    {
 | 
			
		||||
        AccountTxs result;
 | 
			
		||||
        accountTxMap_.visit(options.account, [&](auto const& item) {
 | 
			
		||||
            item.second.transactions.visit_all([&](auto const& tx) {
 | 
			
		||||
                if (tx.first.first >= options.minLedger &&
 | 
			
		||||
                    tx.first.first <= options.maxLedger)
 | 
			
		||||
                {
 | 
			
		||||
                    result.push_back(tx.second);
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
        std::sort(
 | 
			
		||||
            result.begin(), result.end(), [](auto const& a, auto const& b) {
 | 
			
		||||
                return a.second->getLgrSeq() > b.second->getLgrSeq();
 | 
			
		||||
            });
 | 
			
		||||
        applyLimit(result, options.limit, options.bUnlimited);
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    MetaTxsList
 | 
			
		||||
    getOldestAccountTxsB(AccountTxOptions const& options) override
 | 
			
		||||
    {
 | 
			
		||||
        MetaTxsList result;
 | 
			
		||||
        accountTxMap_.visit(options.account, [&](auto const& item) {
 | 
			
		||||
            item.second.transactions.visit_all([&](auto const& tx) {
 | 
			
		||||
                if (tx.first.first >= options.minLedger &&
 | 
			
		||||
                    tx.first.first <= options.maxLedger)
 | 
			
		||||
                {
 | 
			
		||||
                    result.emplace_back(
 | 
			
		||||
                        tx.second.first->getSTransaction()
 | 
			
		||||
                            ->getSerializer()
 | 
			
		||||
                            .peekData(),
 | 
			
		||||
                        tx.second.second->getAsObject()
 | 
			
		||||
                            .getSerializer()
 | 
			
		||||
                            .peekData(),
 | 
			
		||||
                        tx.first.first);
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
        std::sort(
 | 
			
		||||
            result.begin(), result.end(), [](auto const& a, auto const& b) {
 | 
			
		||||
                return std::get<2>(a) < std::get<2>(b);
 | 
			
		||||
            });
 | 
			
		||||
        applyLimit(result, options.limit, options.bUnlimited);
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    MetaTxsList
 | 
			
		||||
    getNewestAccountTxsB(AccountTxOptions const& options) override
 | 
			
		||||
    {
 | 
			
		||||
        MetaTxsList result;
 | 
			
		||||
        accountTxMap_.visit(options.account, [&](auto const& item) {
 | 
			
		||||
            item.second.transactions.visit_all([&](auto const& tx) {
 | 
			
		||||
                if (tx.first.first >= options.minLedger &&
 | 
			
		||||
                    tx.first.first <= options.maxLedger)
 | 
			
		||||
                {
 | 
			
		||||
                    result.emplace_back(
 | 
			
		||||
                        tx.second.first->getSTransaction()
 | 
			
		||||
                            ->getSerializer()
 | 
			
		||||
                            .peekData(),
 | 
			
		||||
                        tx.second.second->getAsObject()
 | 
			
		||||
                            .getSerializer()
 | 
			
		||||
                            .peekData(),
 | 
			
		||||
                        tx.first.first);
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
        std::sort(
 | 
			
		||||
            result.begin(), result.end(), [](auto const& a, auto const& b) {
 | 
			
		||||
                return std::get<2>(a) > std::get<2>(b);
 | 
			
		||||
            });
 | 
			
		||||
        applyLimit(result, options.limit, options.bUnlimited);
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
    std::pair<AccountTxs, std::optional<AccountTxMarker>>
 | 
			
		||||
    oldestAccountTxPage(AccountTxPageOptions const& options) override
 | 
			
		||||
    {
 | 
			
		||||
        AccountTxs result;
 | 
			
		||||
        std::optional<AccountTxMarker> marker;
 | 
			
		||||
 | 
			
		||||
        accountTxMap_.visit(options.account, [&](auto const& item) {
 | 
			
		||||
            std::vector<std::pair<std::pair<uint32_t, uint32_t>, AccountTx>>
 | 
			
		||||
                txs;
 | 
			
		||||
            item.second.transactions.visit_all([&](auto const& tx) {
 | 
			
		||||
                if (tx.first.first >= options.minLedger &&
 | 
			
		||||
                    tx.first.first <= options.maxLedger)
 | 
			
		||||
                {
 | 
			
		||||
                    txs.emplace_back(tx);
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            std::sort(txs.begin(), txs.end(), [](auto const& a, auto const& b) {
 | 
			
		||||
                return a.first < b.first;
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            auto it = txs.begin();
 | 
			
		||||
            if (options.marker)
 | 
			
		||||
            {
 | 
			
		||||
                it = std::find_if(txs.begin(), txs.end(), [&](auto const& tx) {
 | 
			
		||||
                    return tx.first.first == options.marker->ledgerSeq &&
 | 
			
		||||
                        tx.first.second == options.marker->txnSeq;
 | 
			
		||||
                });
 | 
			
		||||
                if (it != txs.end())
 | 
			
		||||
                    ++it;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            for (; it != txs.end() &&
 | 
			
		||||
                 (options.limit == 0 || result.size() < options.limit);
 | 
			
		||||
                 ++it)
 | 
			
		||||
            {
 | 
			
		||||
                result.push_back(it->second);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (it != txs.end())
 | 
			
		||||
            {
 | 
			
		||||
                marker = AccountTxMarker{it->first.first, it->first.second};
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        return {result, marker};
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::pair<AccountTxs, std::optional<AccountTxMarker>>
 | 
			
		||||
    newestAccountTxPage(AccountTxPageOptions const& options) override
 | 
			
		||||
    {
 | 
			
		||||
        AccountTxs result;
 | 
			
		||||
        std::optional<AccountTxMarker> marker;
 | 
			
		||||
 | 
			
		||||
        accountTxMap_.visit(options.account, [&](auto const& item) {
 | 
			
		||||
            std::vector<std::pair<std::pair<uint32_t, uint32_t>, AccountTx>>
 | 
			
		||||
                txs;
 | 
			
		||||
            item.second.transactions.visit_all([&](auto const& tx) {
 | 
			
		||||
                if (tx.first.first >= options.minLedger &&
 | 
			
		||||
                    tx.first.first <= options.maxLedger)
 | 
			
		||||
                {
 | 
			
		||||
                    txs.emplace_back(tx);
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            std::sort(txs.begin(), txs.end(), [](auto const& a, auto const& b) {
 | 
			
		||||
                return a.first > b.first;
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            auto it = txs.begin();
 | 
			
		||||
            if (options.marker)
 | 
			
		||||
            {
 | 
			
		||||
                it = std::find_if(txs.begin(), txs.end(), [&](auto const& tx) {
 | 
			
		||||
                    return tx.first.first == options.marker->ledgerSeq &&
 | 
			
		||||
                        tx.first.second == options.marker->txnSeq;
 | 
			
		||||
                });
 | 
			
		||||
                if (it != txs.end())
 | 
			
		||||
                    ++it;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            for (; it != txs.end() &&
 | 
			
		||||
                 (options.limit == 0 || result.size() < options.limit);
 | 
			
		||||
                 ++it)
 | 
			
		||||
            {
 | 
			
		||||
                result.push_back(it->second);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (it != txs.end())
 | 
			
		||||
            {
 | 
			
		||||
                marker = AccountTxMarker{it->first.first, it->first.second};
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        return {result, marker};
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::pair<MetaTxsList, std::optional<AccountTxMarker>>
 | 
			
		||||
    oldestAccountTxPageB(AccountTxPageOptions const& options) override
 | 
			
		||||
    {
 | 
			
		||||
        MetaTxsList result;
 | 
			
		||||
        std::optional<AccountTxMarker> marker;
 | 
			
		||||
 | 
			
		||||
        accountTxMap_.visit(options.account, [&](auto const& item) {
 | 
			
		||||
            std::vector<std::tuple<uint32_t, uint32_t, AccountTx>> txs;
 | 
			
		||||
            item.second.transactions.visit_all([&](auto const& tx) {
 | 
			
		||||
                if (tx.first.first >= options.minLedger &&
 | 
			
		||||
                    tx.first.first <= options.maxLedger)
 | 
			
		||||
                {
 | 
			
		||||
                    txs.emplace_back(
 | 
			
		||||
                        tx.first.first, tx.first.second, tx.second);
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            std::sort(txs.begin(), txs.end());
 | 
			
		||||
 | 
			
		||||
            auto it = txs.begin();
 | 
			
		||||
            if (options.marker)
 | 
			
		||||
            {
 | 
			
		||||
                it = std::find_if(txs.begin(), txs.end(), [&](auto const& tx) {
 | 
			
		||||
                    return std::get<0>(tx) == options.marker->ledgerSeq &&
 | 
			
		||||
                        std::get<1>(tx) == options.marker->txnSeq;
 | 
			
		||||
                });
 | 
			
		||||
                if (it != txs.end())
 | 
			
		||||
                    ++it;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            for (; it != txs.end() &&
 | 
			
		||||
                 (options.limit == 0 || result.size() < options.limit);
 | 
			
		||||
                 ++it)
 | 
			
		||||
            {
 | 
			
		||||
                const auto& [_, __, tx] = *it;
 | 
			
		||||
                result.emplace_back(
 | 
			
		||||
                    tx.first->getSTransaction()->getSerializer().peekData(),
 | 
			
		||||
                    tx.second->getAsObject().getSerializer().peekData(),
 | 
			
		||||
                    std::get<0>(*it));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (it != txs.end())
 | 
			
		||||
            {
 | 
			
		||||
                marker = AccountTxMarker{std::get<0>(*it), std::get<1>(*it)};
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        return {result, marker};
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::pair<MetaTxsList, std::optional<AccountTxMarker>>
 | 
			
		||||
    newestAccountTxPageB(AccountTxPageOptions const& options) override
 | 
			
		||||
    {
 | 
			
		||||
        MetaTxsList result;
 | 
			
		||||
        std::optional<AccountTxMarker> marker;
 | 
			
		||||
 | 
			
		||||
        accountTxMap_.visit(options.account, [&](auto const& item) {
 | 
			
		||||
            std::vector<std::tuple<uint32_t, uint32_t, AccountTx>> txs;
 | 
			
		||||
            item.second.transactions.visit_all([&](auto const& tx) {
 | 
			
		||||
                if (tx.first.first >= options.minLedger &&
 | 
			
		||||
                    tx.first.first <= options.maxLedger)
 | 
			
		||||
                {
 | 
			
		||||
                    txs.emplace_back(
 | 
			
		||||
                        tx.first.first, tx.first.second, tx.second);
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            std::sort(txs.begin(), txs.end(), std::greater<>());
 | 
			
		||||
 | 
			
		||||
            auto it = txs.begin();
 | 
			
		||||
            if (options.marker)
 | 
			
		||||
            {
 | 
			
		||||
                it = std::find_if(txs.begin(), txs.end(), [&](auto const& tx) {
 | 
			
		||||
                    return std::get<0>(tx) == options.marker->ledgerSeq &&
 | 
			
		||||
                        std::get<1>(tx) == options.marker->txnSeq;
 | 
			
		||||
                });
 | 
			
		||||
                if (it != txs.end())
 | 
			
		||||
                    ++it;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            for (; it != txs.end() &&
 | 
			
		||||
                 (options.limit == 0 || result.size() < options.limit);
 | 
			
		||||
                 ++it)
 | 
			
		||||
            {
 | 
			
		||||
                const auto& [_, __, tx] = *it;
 | 
			
		||||
                result.emplace_back(
 | 
			
		||||
                    tx.first->getSTransaction()->getSerializer().peekData(),
 | 
			
		||||
                    tx.second->getAsObject().getSerializer().peekData(),
 | 
			
		||||
                    std::get<0>(*it));
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (it != txs.end())
 | 
			
		||||
            {
 | 
			
		||||
                marker = AccountTxMarker{std::get<0>(*it), std::get<1>(*it)};
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        return {result, marker};
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// Factory function
 | 
			
		||||
std::unique_ptr<SQLiteDatabase>
 | 
			
		||||
getFlatmapDatabase(Application& app, Config const& config, JobQueue& jobQueue)
 | 
			
		||||
{
 | 
			
		||||
    return std::make_unique<FlatmapDatabase>(app, config, jobQueue);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}  // namespace ripple
 | 
			
		||||
#endif  // RIPPLE_APP_RDB_BACKEND_FLATMAPDATABASE_H_INCLUDED
 | 
			
		||||
@@ -28,9 +28,8 @@ private:
 | 
			
		||||
 | 
			
		||||
    struct AccountTxData
 | 
			
		||||
    {
 | 
			
		||||
        AccountTxs transactions;
 | 
			
		||||
        std::map<uint32_t, std::map<uint32_t, size_t>>
 | 
			
		||||
            ledgerTxMap;  // ledgerSeq -> txSeq -> index in transactions
 | 
			
		||||
        std::map<uint32_t, std::vector<AccountTx>>
 | 
			
		||||
            ledgerTxMap;  // ledgerSeq -> vector of transactions
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    Application& app_;
 | 
			
		||||
@@ -65,9 +64,12 @@ public:
 | 
			
		||||
            return {};
 | 
			
		||||
 | 
			
		||||
        std::shared_lock<std::shared_mutex> lock(mutex_);
 | 
			
		||||
        if (transactionMap_.empty())
 | 
			
		||||
            return std::nullopt;
 | 
			
		||||
        return transactionMap_.begin()->second.second->getLgrSeq();
 | 
			
		||||
        for (const auto& [ledgerSeq, ledgerData] : ledgers_)
 | 
			
		||||
        {
 | 
			
		||||
            if (!ledgerData.transactions.empty())
 | 
			
		||||
                return ledgerSeq;
 | 
			
		||||
        }
 | 
			
		||||
        return std::nullopt;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::optional<LedgerIndex>
 | 
			
		||||
@@ -163,14 +165,6 @@ public:
 | 
			
		||||
            {
 | 
			
		||||
                txIt = accountData.ledgerTxMap.erase(txIt);
 | 
			
		||||
            }
 | 
			
		||||
            accountData.transactions.erase(
 | 
			
		||||
                std::remove_if(
 | 
			
		||||
                    accountData.transactions.begin(),
 | 
			
		||||
                    accountData.transactions.end(),
 | 
			
		||||
                    [ledgerSeq](const AccountTx& tx) {
 | 
			
		||||
                        return tx.second->getLgrSeq() < ledgerSeq;
 | 
			
		||||
                    }),
 | 
			
		||||
                accountData.transactions.end());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    std::size_t
 | 
			
		||||
@@ -193,7 +187,10 @@ public:
 | 
			
		||||
        std::size_t count = 0;
 | 
			
		||||
        for (const auto& [_, accountData] : accountTxMap_)
 | 
			
		||||
        {
 | 
			
		||||
            count += accountData.transactions.size();
 | 
			
		||||
            for (const auto& [_, txVector] : accountData.ledgerTxMap)
 | 
			
		||||
            {
 | 
			
		||||
                count += txVector.size();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return count;
 | 
			
		||||
    }
 | 
			
		||||
@@ -293,10 +290,7 @@ public:
 | 
			
		||||
                        accountTxMap_[account] = AccountTxData();
 | 
			
		||||
 | 
			
		||||
                    auto& accountData = accountTxMap_[account];
 | 
			
		||||
                    accountData.transactions.push_back(accTx);
 | 
			
		||||
                    accountData
 | 
			
		||||
                        .ledgerTxMap[seq][acceptedLedgerTx->getTxnSeq()] =
 | 
			
		||||
                        accountData.transactions.size() - 1;
 | 
			
		||||
                    accountData.ledgerTxMap[seq].push_back(accTx);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                app_.getMasterTransaction().inLedger(
 | 
			
		||||
@@ -451,59 +445,108 @@ public:
 | 
			
		||||
        return true;  // In-memory database always has space
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Red-black tree node overhead per map entry
 | 
			
		||||
    static constexpr size_t MAP_NODE_OVERHEAD = 40;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    std::uint64_t
 | 
			
		||||
    getBytesUsedLedger_unlocked() const
 | 
			
		||||
    {
 | 
			
		||||
        std::uint64_t size = 0;
 | 
			
		||||
 | 
			
		||||
        // Count structural overhead of ledger storage including map node
 | 
			
		||||
        // overhead Note: sizeof(LedgerData) includes the map container for
 | 
			
		||||
        // transactions, but not the actual transaction data
 | 
			
		||||
        size += ledgers_.size() *
 | 
			
		||||
            (sizeof(LedgerIndex) + sizeof(LedgerData) + MAP_NODE_OVERHEAD);
 | 
			
		||||
 | 
			
		||||
        // Add the transaction map nodes inside each ledger (ledger's view of
 | 
			
		||||
        // its transactions)
 | 
			
		||||
        for (const auto& [_, ledgerData] : ledgers_)
 | 
			
		||||
        {
 | 
			
		||||
            size += ledgerData.transactions.size() *
 | 
			
		||||
                (sizeof(uint256) + sizeof(AccountTx) + MAP_NODE_OVERHEAD);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Count the ledger hash to sequence lookup map
 | 
			
		||||
        size += ledgerHashToSeq_.size() *
 | 
			
		||||
            (sizeof(uint256) + sizeof(LedgerIndex) + MAP_NODE_OVERHEAD);
 | 
			
		||||
 | 
			
		||||
        return size;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::uint64_t
 | 
			
		||||
    getBytesUsedTransaction_unlocked() const
 | 
			
		||||
    {
 | 
			
		||||
        if (!useTxTables_)
 | 
			
		||||
            return 0;
 | 
			
		||||
 | 
			
		||||
        std::uint64_t size = 0;
 | 
			
		||||
 | 
			
		||||
        // Count structural overhead of transaction map
 | 
			
		||||
        // sizeof(AccountTx) is just the size of two shared_ptrs (~32 bytes)
 | 
			
		||||
        size += transactionMap_.size() *
 | 
			
		||||
            (sizeof(uint256) + sizeof(AccountTx) + MAP_NODE_OVERHEAD);
 | 
			
		||||
 | 
			
		||||
        // Add actual transaction and metadata data sizes
 | 
			
		||||
        for (const auto& [_, accountTx] : transactionMap_)
 | 
			
		||||
        {
 | 
			
		||||
            if (accountTx.first)
 | 
			
		||||
                size += accountTx.first->getSTransaction()
 | 
			
		||||
                            ->getSerializer()
 | 
			
		||||
                            .peekData()
 | 
			
		||||
                            .size();
 | 
			
		||||
            if (accountTx.second)
 | 
			
		||||
                size += accountTx.second->getAsObject()
 | 
			
		||||
                            .getSerializer()
 | 
			
		||||
                            .peekData()
 | 
			
		||||
                            .size();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Count structural overhead of account transaction index
 | 
			
		||||
        // The actual transaction data is already counted above from
 | 
			
		||||
        // transactionMap_
 | 
			
		||||
        for (const auto& [accountId, accountData] : accountTxMap_)
 | 
			
		||||
        {
 | 
			
		||||
            size +=
 | 
			
		||||
                sizeof(accountId) + sizeof(AccountTxData) + MAP_NODE_OVERHEAD;
 | 
			
		||||
            for (const auto& [ledgerSeq, txVector] : accountData.ledgerTxMap)
 | 
			
		||||
            {
 | 
			
		||||
                // Use capacity() to account for actual allocated memory
 | 
			
		||||
                size += sizeof(ledgerSeq) + MAP_NODE_OVERHEAD;
 | 
			
		||||
                size += txVector.capacity() * sizeof(AccountTx);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return size;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    std::uint32_t
 | 
			
		||||
    getKBUsedAll() override
 | 
			
		||||
    {
 | 
			
		||||
        std::shared_lock<std::shared_mutex> lock(mutex_);
 | 
			
		||||
        std::uint32_t size = sizeof(*this);
 | 
			
		||||
        size += ledgers_.size() * (sizeof(LedgerIndex) + sizeof(LedgerData));
 | 
			
		||||
        size +=
 | 
			
		||||
            ledgerHashToSeq_.size() * (sizeof(uint256) + sizeof(LedgerIndex));
 | 
			
		||||
        size += transactionMap_.size() * (sizeof(uint256) + sizeof(AccountTx));
 | 
			
		||||
        for (const auto& [_, accountData] : accountTxMap_)
 | 
			
		||||
        {
 | 
			
		||||
            size += sizeof(AccountID) + sizeof(AccountTxData);
 | 
			
		||||
            size += accountData.transactions.size() * sizeof(AccountTx);
 | 
			
		||||
            for (const auto& [_, innerMap] : accountData.ledgerTxMap)
 | 
			
		||||
            {
 | 
			
		||||
                size += sizeof(uint32_t) +
 | 
			
		||||
                    innerMap.size() * (sizeof(uint32_t) + sizeof(size_t));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return size / 1024;
 | 
			
		||||
 | 
			
		||||
        // Total = base object + ledger infrastructure + transaction data
 | 
			
		||||
        std::uint64_t size = sizeof(*this) + getBytesUsedLedger_unlocked() +
 | 
			
		||||
            getBytesUsedTransaction_unlocked();
 | 
			
		||||
 | 
			
		||||
        return static_cast<std::uint32_t>(size / 1024);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::uint32_t
 | 
			
		||||
    getKBUsedLedger() override
 | 
			
		||||
    {
 | 
			
		||||
        std::shared_lock<std::shared_mutex> lock(mutex_);
 | 
			
		||||
        std::uint32_t size = 0;
 | 
			
		||||
        size += ledgers_.size() * (sizeof(LedgerIndex) + sizeof(LedgerData));
 | 
			
		||||
        size +=
 | 
			
		||||
            ledgerHashToSeq_.size() * (sizeof(uint256) + sizeof(LedgerIndex));
 | 
			
		||||
        return size / 1024;
 | 
			
		||||
        return static_cast<std::uint32_t>(getBytesUsedLedger_unlocked() / 1024);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::uint32_t
 | 
			
		||||
    getKBUsedTransaction() override
 | 
			
		||||
    {
 | 
			
		||||
        if (!useTxTables_)
 | 
			
		||||
            return 0;
 | 
			
		||||
 | 
			
		||||
        std::shared_lock<std::shared_mutex> lock(mutex_);
 | 
			
		||||
        std::uint32_t size = 0;
 | 
			
		||||
        size += transactionMap_.size() * (sizeof(uint256) + sizeof(AccountTx));
 | 
			
		||||
        for (const auto& [_, accountData] : accountTxMap_)
 | 
			
		||||
        {
 | 
			
		||||
            size += sizeof(AccountID) + sizeof(AccountTxData);
 | 
			
		||||
            size += accountData.transactions.size() * sizeof(AccountTx);
 | 
			
		||||
            for (const auto& [_, innerMap] : accountData.ledgerTxMap)
 | 
			
		||||
            {
 | 
			
		||||
                size += sizeof(uint32_t) +
 | 
			
		||||
                    innerMap.size() * (sizeof(uint32_t) + sizeof(size_t));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return size / 1024;
 | 
			
		||||
        return static_cast<std::uint32_t>(
 | 
			
		||||
            getBytesUsedTransaction_unlocked() / 1024);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void
 | 
			
		||||
@@ -605,14 +648,13 @@ public:
 | 
			
		||||
             (options.bUnlimited || result.size() < options.limit);
 | 
			
		||||
             ++txIt)
 | 
			
		||||
        {
 | 
			
		||||
            for (const auto& [txSeq, txIndex] : txIt->second)
 | 
			
		||||
            for (const auto& accountTx : txIt->second)
 | 
			
		||||
            {
 | 
			
		||||
                if (skipped < options.offset)
 | 
			
		||||
                {
 | 
			
		||||
                    ++skipped;
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
                AccountTx const accountTx = accountData.transactions[txIndex];
 | 
			
		||||
                std::uint32_t const inLedger = rangeCheckedCast<std::uint32_t>(
 | 
			
		||||
                    accountTx.second->getLgrSeq());
 | 
			
		||||
                accountTx.first->setStatus(COMMITTED);
 | 
			
		||||
@@ -657,8 +699,7 @@ public:
 | 
			
		||||
                    ++skipped;
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
                AccountTx const accountTx =
 | 
			
		||||
                    accountData.transactions[innerRIt->second];
 | 
			
		||||
                AccountTx const accountTx = *innerRIt;
 | 
			
		||||
                std::uint32_t const inLedger = rangeCheckedCast<std::uint32_t>(
 | 
			
		||||
                    accountTx.second->getLgrSeq());
 | 
			
		||||
                accountTx.first->setLedger(inLedger);
 | 
			
		||||
@@ -692,14 +733,14 @@ public:
 | 
			
		||||
             (options.bUnlimited || result.size() < options.limit);
 | 
			
		||||
             ++txIt)
 | 
			
		||||
        {
 | 
			
		||||
            for (const auto& [txSeq, txIndex] : txIt->second)
 | 
			
		||||
            for (const auto& accountTx : txIt->second)
 | 
			
		||||
            {
 | 
			
		||||
                if (skipped < options.offset)
 | 
			
		||||
                {
 | 
			
		||||
                    ++skipped;
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
                const auto& [txn, txMeta] = accountData.transactions[txIndex];
 | 
			
		||||
                const auto& [txn, txMeta] = accountTx;
 | 
			
		||||
                result.emplace_back(
 | 
			
		||||
                    txn->getSTransaction()->getSerializer().peekData(),
 | 
			
		||||
                    txMeta->getAsObject().getSerializer().peekData(),
 | 
			
		||||
@@ -743,8 +784,7 @@ public:
 | 
			
		||||
                    ++skipped;
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
                const auto& [txn, txMeta] =
 | 
			
		||||
                    accountData.transactions[innerRIt->second];
 | 
			
		||||
                const auto& [txn, txMeta] = *innerRIt;
 | 
			
		||||
                result.emplace_back(
 | 
			
		||||
                    txn->getSTransaction()->getSerializer().peekData(),
 | 
			
		||||
                    txMeta->getAsObject().getSerializer().peekData(),
 | 
			
		||||
@@ -816,11 +856,9 @@ public:
 | 
			
		||||
            for (; txIt != txEnd; ++txIt)
 | 
			
		||||
            {
 | 
			
		||||
                std::uint32_t const ledgerSeq = txIt->first;
 | 
			
		||||
                for (auto seqIt = txIt->second.begin();
 | 
			
		||||
                     seqIt != txIt->second.end();
 | 
			
		||||
                     ++seqIt)
 | 
			
		||||
                std::uint32_t txnSeq = 0;
 | 
			
		||||
                for (const auto& accountTx : txIt->second)
 | 
			
		||||
                {
 | 
			
		||||
                    const auto& [txnSeq, index] = *seqIt;
 | 
			
		||||
                    if (lookingForMarker)
 | 
			
		||||
                    {
 | 
			
		||||
                        if (findLedger == ledgerSeq && findSeq == txnSeq)
 | 
			
		||||
@@ -828,7 +866,10 @@ public:
 | 
			
		||||
                            lookingForMarker = false;
 | 
			
		||||
                        }
 | 
			
		||||
                        else
 | 
			
		||||
                        {
 | 
			
		||||
                            ++txnSeq;
 | 
			
		||||
                            continue;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    else if (numberOfResults == 0)
 | 
			
		||||
                    {
 | 
			
		||||
@@ -837,12 +878,10 @@ public:
 | 
			
		||||
                        return {newmarker, total};
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    Blob rawTxn = accountData.transactions[index]
 | 
			
		||||
                                      .first->getSTransaction()
 | 
			
		||||
                    Blob rawTxn = accountTx.first->getSTransaction()
 | 
			
		||||
                                      ->getSerializer()
 | 
			
		||||
                                      .peekData();
 | 
			
		||||
                    Blob rawMeta = accountData.transactions[index]
 | 
			
		||||
                                       .second->getAsObject()
 | 
			
		||||
                    Blob rawMeta = accountTx.second->getAsObject()
 | 
			
		||||
                                       .getSerializer()
 | 
			
		||||
                                       .peekData();
 | 
			
		||||
 | 
			
		||||
@@ -856,6 +895,7 @@ public:
 | 
			
		||||
                        std::move(rawMeta));
 | 
			
		||||
                    --numberOfResults;
 | 
			
		||||
                    ++total;
 | 
			
		||||
                    ++txnSeq;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -871,11 +911,11 @@ public:
 | 
			
		||||
            for (; rtxIt != rtxEnd; ++rtxIt)
 | 
			
		||||
            {
 | 
			
		||||
                std::uint32_t const ledgerSeq = rtxIt->first;
 | 
			
		||||
                std::uint32_t txnSeq = rtxIt->second.size() - 1;
 | 
			
		||||
                for (auto innerRIt = rtxIt->second.rbegin();
 | 
			
		||||
                     innerRIt != rtxIt->second.rend();
 | 
			
		||||
                     ++innerRIt)
 | 
			
		||||
                {
 | 
			
		||||
                    const auto& [txnSeq, index] = *innerRIt;
 | 
			
		||||
                    if (lookingForMarker)
 | 
			
		||||
                    {
 | 
			
		||||
                        if (findLedger == ledgerSeq && findSeq == txnSeq)
 | 
			
		||||
@@ -883,7 +923,10 @@ public:
 | 
			
		||||
                            lookingForMarker = false;
 | 
			
		||||
                        }
 | 
			
		||||
                        else
 | 
			
		||||
                        {
 | 
			
		||||
                            --txnSeq;
 | 
			
		||||
                            continue;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    else if (numberOfResults == 0)
 | 
			
		||||
                    {
 | 
			
		||||
@@ -892,12 +935,11 @@ public:
 | 
			
		||||
                        return {newmarker, total};
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    Blob rawTxn = accountData.transactions[index]
 | 
			
		||||
                                      .first->getSTransaction()
 | 
			
		||||
                    const auto& accountTx = *innerRIt;
 | 
			
		||||
                    Blob rawTxn = accountTx.first->getSTransaction()
 | 
			
		||||
                                      ->getSerializer()
 | 
			
		||||
                                      .peekData();
 | 
			
		||||
                    Blob rawMeta = accountData.transactions[index]
 | 
			
		||||
                                       .second->getAsObject()
 | 
			
		||||
                    Blob rawMeta = accountTx.second->getAsObject()
 | 
			
		||||
                                       .getSerializer()
 | 
			
		||||
                                       .peekData();
 | 
			
		||||
 | 
			
		||||
@@ -911,6 +953,7 @@ public:
 | 
			
		||||
                        std::move(rawMeta));
 | 
			
		||||
                    --numberOfResults;
 | 
			
		||||
                    ++total;
 | 
			
		||||
                    --txnSeq;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,6 @@
 | 
			
		||||
 | 
			
		||||
#include <ripple/app/main/Application.h>
 | 
			
		||||
#include <ripple/app/rdb/RelationalDatabase.h>
 | 
			
		||||
#include <ripple/app/rdb/backend/FlatmapDatabase.h>
 | 
			
		||||
#include <ripple/app/rdb/backend/RWDBDatabase.h>
 | 
			
		||||
#include <ripple/core/ConfigSections.h>
 | 
			
		||||
#include <ripple/nodestore/DatabaseShard.h>
 | 
			
		||||
@@ -41,7 +40,6 @@ RelationalDatabase::init(
 | 
			
		||||
    bool use_sqlite = false;
 | 
			
		||||
    bool use_postgres = false;
 | 
			
		||||
    bool use_rwdb = false;
 | 
			
		||||
    bool use_flatmap = false;
 | 
			
		||||
 | 
			
		||||
    if (config.reporting())
 | 
			
		||||
    {
 | 
			
		||||
@@ -60,10 +58,6 @@ RelationalDatabase::init(
 | 
			
		||||
            {
 | 
			
		||||
                use_rwdb = true;
 | 
			
		||||
            }
 | 
			
		||||
            else if (boost::iequals(get(rdb_section, "backend"), "flatmap"))
 | 
			
		||||
            {
 | 
			
		||||
                use_flatmap = true;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                Throw<std::runtime_error>(
 | 
			
		||||
@@ -89,10 +83,6 @@ RelationalDatabase::init(
 | 
			
		||||
    {
 | 
			
		||||
        return getRWDBDatabase(app, config, jobQueue);
 | 
			
		||||
    }
 | 
			
		||||
    else if (use_flatmap)
 | 
			
		||||
    {
 | 
			
		||||
        return getFlatmapDatabase(app, config, jobQueue);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return std::unique_ptr<RelationalDatabase>();
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -361,9 +361,7 @@ public:
 | 
			
		||||
             boost::beast::iequals(
 | 
			
		||||
                 get(section(SECTION_RELATIONAL_DB), "backend"), "rwdb")) ||
 | 
			
		||||
            (!section("node_db").empty() &&
 | 
			
		||||
             (boost::beast::iequals(get(section("node_db"), "type"), "rwdb") ||
 | 
			
		||||
              boost::beast::iequals(
 | 
			
		||||
                  get(section("node_db"), "type"), "flatmap")));
 | 
			
		||||
             boost::beast::iequals(get(section("node_db"), "type"), "rwdb"));
 | 
			
		||||
        // RHNOTE: memory type is not selected for here because it breaks
 | 
			
		||||
        // tests
 | 
			
		||||
        return isMem;
 | 
			
		||||
 
 | 
			
		||||
@@ -45,7 +45,6 @@
 | 
			
		||||
 | 
			
		||||
namespace ripple {
 | 
			
		||||
namespace detail {
 | 
			
		||||
 | 
			
		||||
[[nodiscard]] std::uint64_t
 | 
			
		||||
getMemorySize()
 | 
			
		||||
{
 | 
			
		||||
@@ -54,7 +53,6 @@ getMemorySize()
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}  // namespace detail
 | 
			
		||||
}  // namespace ripple
 | 
			
		||||
#endif
 | 
			
		||||
@@ -64,7 +62,6 @@ getMemorySize()
 | 
			
		||||
 | 
			
		||||
namespace ripple {
 | 
			
		||||
namespace detail {
 | 
			
		||||
 | 
			
		||||
[[nodiscard]] std::uint64_t
 | 
			
		||||
getMemorySize()
 | 
			
		||||
{
 | 
			
		||||
@@ -73,7 +70,6 @@ getMemorySize()
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}  // namespace detail
 | 
			
		||||
}  // namespace ripple
 | 
			
		||||
 | 
			
		||||
@@ -85,7 +81,6 @@ getMemorySize()
 | 
			
		||||
 | 
			
		||||
namespace ripple {
 | 
			
		||||
namespace detail {
 | 
			
		||||
 | 
			
		||||
[[nodiscard]] std::uint64_t
 | 
			
		||||
getMemorySize()
 | 
			
		||||
{
 | 
			
		||||
@@ -98,13 +93,11 @@ getMemorySize()
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}  // namespace detail
 | 
			
		||||
}  // namespace ripple
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace ripple {
 | 
			
		||||
 | 
			
		||||
// clang-format off
 | 
			
		||||
// The configurable node sizes are "tiny", "small", "medium", "large", "huge"
 | 
			
		||||
inline constexpr std::array<std::pair<SizedItem, std::array<int, 5>>, 13>
 | 
			
		||||
@@ -1007,6 +1000,23 @@ Config::loadFromString(std::string const& fileContents)
 | 
			
		||||
                "the maximum number of allowed peers (peers_max)");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!RUN_STANDALONE)
 | 
			
		||||
    {
 | 
			
		||||
        auto db_section = section(ConfigSection::nodeDatabase());
 | 
			
		||||
        if (auto type = get(db_section, "type", ""); type == "rwdb")
 | 
			
		||||
        {
 | 
			
		||||
            if (auto delete_interval = get(db_section, "online_delete", 0);
 | 
			
		||||
                delete_interval == 0)
 | 
			
		||||
            {
 | 
			
		||||
                Throw<std::runtime_error>(
 | 
			
		||||
                    "RWDB (in-memory backend) requires online_delete to "
 | 
			
		||||
                    "prevent OOM "
 | 
			
		||||
                    "Exception: standalone mode (used by tests) doesn't need "
 | 
			
		||||
                    "online_delete");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
boost::filesystem::path
 | 
			
		||||
@@ -1071,5 +1081,4 @@ setup_FeeVote(Section const& section)
 | 
			
		||||
    }
 | 
			
		||||
    return setup;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}  // namespace ripple
 | 
			
		||||
 
 | 
			
		||||
@@ -1,235 +0,0 @@
 | 
			
		||||
#include <ripple/basics/contract.h>
 | 
			
		||||
#include <ripple/nodestore/Factory.h>
 | 
			
		||||
#include <ripple/nodestore/Manager.h>
 | 
			
		||||
#include <ripple/nodestore/impl/DecodedBlob.h>
 | 
			
		||||
#include <ripple/nodestore/impl/EncodedBlob.h>
 | 
			
		||||
#include <ripple/nodestore/impl/codec.h>
 | 
			
		||||
#include <boost/beast/core/string.hpp>
 | 
			
		||||
#include <boost/core/ignore_unused.hpp>
 | 
			
		||||
#include <boost/unordered/concurrent_flat_map.hpp>
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <mutex>
 | 
			
		||||
 | 
			
		||||
namespace ripple {
 | 
			
		||||
namespace NodeStore {
 | 
			
		||||
 | 
			
		||||
class FlatmapBackend : public Backend
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
    std::string name_;
 | 
			
		||||
    beast::Journal journal_;
 | 
			
		||||
    bool isOpen_{false};
 | 
			
		||||
 | 
			
		||||
    struct base_uint_hasher
 | 
			
		||||
    {
 | 
			
		||||
        using result_type = std::size_t;
 | 
			
		||||
 | 
			
		||||
        result_type
 | 
			
		||||
        operator()(base_uint<256> const& value) const
 | 
			
		||||
        {
 | 
			
		||||
            return hardened_hash<>{}(value);
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    using DataStore = boost::unordered::concurrent_flat_map<
 | 
			
		||||
        uint256,
 | 
			
		||||
        std::vector<std::uint8_t>,  // Store compressed blob data
 | 
			
		||||
        base_uint_hasher>;
 | 
			
		||||
 | 
			
		||||
    DataStore table_;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    FlatmapBackend(
 | 
			
		||||
        size_t keyBytes,
 | 
			
		||||
        Section const& keyValues,
 | 
			
		||||
        beast::Journal journal)
 | 
			
		||||
        : name_(get(keyValues, "path")), journal_(journal)
 | 
			
		||||
    {
 | 
			
		||||
        boost::ignore_unused(journal_);
 | 
			
		||||
        if (name_.empty())
 | 
			
		||||
            name_ = "node_db";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~FlatmapBackend() override
 | 
			
		||||
    {
 | 
			
		||||
        close();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::string
 | 
			
		||||
    getName() override
 | 
			
		||||
    {
 | 
			
		||||
        return name_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void
 | 
			
		||||
    open(bool createIfMissing) override
 | 
			
		||||
    {
 | 
			
		||||
        if (isOpen_)
 | 
			
		||||
            Throw<std::runtime_error>("already open");
 | 
			
		||||
        isOpen_ = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool
 | 
			
		||||
    isOpen() override
 | 
			
		||||
    {
 | 
			
		||||
        return isOpen_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void
 | 
			
		||||
    close() override
 | 
			
		||||
    {
 | 
			
		||||
        table_.clear();
 | 
			
		||||
        isOpen_ = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Status
 | 
			
		||||
    fetch(void const* key, std::shared_ptr<NodeObject>* pObject) override
 | 
			
		||||
    {
 | 
			
		||||
        if (!isOpen_)
 | 
			
		||||
            return notFound;
 | 
			
		||||
 | 
			
		||||
        uint256 const hash(uint256::fromVoid(key));
 | 
			
		||||
 | 
			
		||||
        bool found = table_.visit(hash, [&](const auto& key_value_pair) {
 | 
			
		||||
            nudb::detail::buffer bf;
 | 
			
		||||
            auto const result = nodeobject_decompress(
 | 
			
		||||
                key_value_pair.second.data(), key_value_pair.second.size(), bf);
 | 
			
		||||
            DecodedBlob decoded(hash.data(), result.first, result.second);
 | 
			
		||||
            if (!decoded.wasOk())
 | 
			
		||||
            {
 | 
			
		||||
                *pObject = nullptr;
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            *pObject = decoded.createObject();
 | 
			
		||||
        });
 | 
			
		||||
        return found ? (*pObject ? ok : dataCorrupt) : notFound;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::pair<std::vector<std::shared_ptr<NodeObject>>, Status>
 | 
			
		||||
    fetchBatch(std::vector<uint256 const*> const& hashes) override
 | 
			
		||||
    {
 | 
			
		||||
        std::vector<std::shared_ptr<NodeObject>> results;
 | 
			
		||||
        results.reserve(hashes.size());
 | 
			
		||||
        for (auto const& h : hashes)
 | 
			
		||||
        {
 | 
			
		||||
            std::shared_ptr<NodeObject> nObj;
 | 
			
		||||
            Status status = fetch(h->begin(), &nObj);
 | 
			
		||||
            if (status != ok)
 | 
			
		||||
                results.push_back({});
 | 
			
		||||
            else
 | 
			
		||||
                results.push_back(nObj);
 | 
			
		||||
        }
 | 
			
		||||
        return {results, ok};
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void
 | 
			
		||||
    store(std::shared_ptr<NodeObject> const& object) override
 | 
			
		||||
    {
 | 
			
		||||
        if (!isOpen_)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        if (!object)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        EncodedBlob encoded(object);
 | 
			
		||||
        nudb::detail::buffer bf;
 | 
			
		||||
        auto const result =
 | 
			
		||||
            nodeobject_compress(encoded.getData(), encoded.getSize(), bf);
 | 
			
		||||
 | 
			
		||||
        std::vector<std::uint8_t> compressed(
 | 
			
		||||
            static_cast<const std::uint8_t*>(result.first),
 | 
			
		||||
            static_cast<const std::uint8_t*>(result.first) + result.second);
 | 
			
		||||
 | 
			
		||||
        table_.insert_or_assign(object->getHash(), std::move(compressed));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void
 | 
			
		||||
    storeBatch(Batch const& batch) override
 | 
			
		||||
    {
 | 
			
		||||
        for (auto const& e : batch)
 | 
			
		||||
            store(e);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void
 | 
			
		||||
    sync() override
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void
 | 
			
		||||
    for_each(std::function<void(std::shared_ptr<NodeObject>)> f) override
 | 
			
		||||
    {
 | 
			
		||||
        if (!isOpen_)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        table_.visit_all([&f](const auto& entry) {
 | 
			
		||||
            nudb::detail::buffer bf;
 | 
			
		||||
            auto const result = nodeobject_decompress(
 | 
			
		||||
                entry.second.data(), entry.second.size(), bf);
 | 
			
		||||
            DecodedBlob decoded(
 | 
			
		||||
                entry.first.data(), result.first, result.second);
 | 
			
		||||
            if (decoded.wasOk())
 | 
			
		||||
                f(decoded.createObject());
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int
 | 
			
		||||
    getWriteLoad() override
 | 
			
		||||
    {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void
 | 
			
		||||
    setDeletePath() override
 | 
			
		||||
    {
 | 
			
		||||
        close();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int
 | 
			
		||||
    fdRequired() const override
 | 
			
		||||
    {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    size_t
 | 
			
		||||
    size() const
 | 
			
		||||
    {
 | 
			
		||||
        return table_.size();
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class FlatmapFactory : public Factory
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    FlatmapFactory()
 | 
			
		||||
    {
 | 
			
		||||
        Manager::instance().insert(*this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~FlatmapFactory() override
 | 
			
		||||
    {
 | 
			
		||||
        Manager::instance().erase(*this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::string
 | 
			
		||||
    getName() const override
 | 
			
		||||
    {
 | 
			
		||||
        return "Flatmap";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::unique_ptr<Backend>
 | 
			
		||||
    createInstance(
 | 
			
		||||
        size_t keyBytes,
 | 
			
		||||
        Section const& keyValues,
 | 
			
		||||
        std::size_t burstSize,
 | 
			
		||||
        Scheduler& scheduler,
 | 
			
		||||
        beast::Journal journal) override
 | 
			
		||||
    {
 | 
			
		||||
        return std::make_unique<FlatmapBackend>(keyBytes, keyValues, journal);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static FlatmapFactory flatmapFactory;
 | 
			
		||||
 | 
			
		||||
}  // namespace NodeStore
 | 
			
		||||
}  // namespace ripple
 | 
			
		||||
@@ -216,6 +216,10 @@ public:
 | 
			
		||||
        }
 | 
			
		||||
        BEAST_EXPECT(store.getLastRotated() == lastRotated);
 | 
			
		||||
 | 
			
		||||
        SQLiteDatabase* const db =
 | 
			
		||||
            dynamic_cast<SQLiteDatabase*>(&env.app().getRelationalDatabase());
 | 
			
		||||
        BEAST_EXPECT(*db->getTransactionsMinLedgerSeq() == 3);
 | 
			
		||||
 | 
			
		||||
        for (auto i = 3; i < deleteInterval + lastRotated; ++i)
 | 
			
		||||
        {
 | 
			
		||||
            ledgers.emplace(
 | 
			
		||||
 
 | 
			
		||||
@@ -321,7 +321,7 @@ public:
 | 
			
		||||
            HSFEE,
 | 
			
		||||
            ter(temMALFORMED));
 | 
			
		||||
 | 
			
		||||
        env(ripple::test::jtx::hook(alice, {{}}, 0),
 | 
			
		||||
        env(ripple::test::jtx::hook(alice, std::vector<Json::Value>{}, 0),
 | 
			
		||||
            M("Must have a non-empty hooks field"),
 | 
			
		||||
            HSFEE,
 | 
			
		||||
            ter(temMALFORMED));
 | 
			
		||||
 
 | 
			
		||||
@@ -1206,6 +1206,97 @@ r.ripple.com:51235
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void
 | 
			
		||||
    testRWDBOnlineDelete()
 | 
			
		||||
    {
 | 
			
		||||
        testcase("RWDB online_delete validation");
 | 
			
		||||
 | 
			
		||||
        // Test 1: RWDB without online_delete in standalone mode (should
 | 
			
		||||
        // succeed)
 | 
			
		||||
        {
 | 
			
		||||
            Config c;
 | 
			
		||||
            std::string toLoad =
 | 
			
		||||
                "[node_db]\n"
 | 
			
		||||
                "type=rwdb\n"
 | 
			
		||||
                "path=main\n";
 | 
			
		||||
            c.setupControl(true, true, true);  // standalone = true
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                c.loadFromString(toLoad);
 | 
			
		||||
                pass();  // Should succeed
 | 
			
		||||
            }
 | 
			
		||||
            catch (std::runtime_error const& e)
 | 
			
		||||
            {
 | 
			
		||||
                fail("Should not throw in standalone mode");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Test 2: RWDB without online_delete NOT in standalone mode (should
 | 
			
		||||
        // throw)
 | 
			
		||||
        {
 | 
			
		||||
            Config c;
 | 
			
		||||
            std::string toLoad =
 | 
			
		||||
                "[node_db]\n"
 | 
			
		||||
                "type=rwdb\n"
 | 
			
		||||
                "path=main\n";
 | 
			
		||||
            c.setupControl(true, true, false);  // standalone = false
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                c.loadFromString(toLoad);
 | 
			
		||||
                fail("Expected exception for RWDB without online_delete");
 | 
			
		||||
            }
 | 
			
		||||
            catch (std::runtime_error const& e)
 | 
			
		||||
            {
 | 
			
		||||
                BEAST_EXPECT(
 | 
			
		||||
                    std::string(e.what()).find(
 | 
			
		||||
                        "RWDB (in-memory backend) requires online_delete") !=
 | 
			
		||||
                    std::string::npos);
 | 
			
		||||
                pass();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Test 3: RWDB with online_delete NOT in standalone mode (should
 | 
			
		||||
        // succeed)
 | 
			
		||||
        {
 | 
			
		||||
            Config c;
 | 
			
		||||
            std::string toLoad =
 | 
			
		||||
                "[node_db]\n"
 | 
			
		||||
                "type=rwdb\n"
 | 
			
		||||
                "path=main\n"
 | 
			
		||||
                "online_delete=256\n";
 | 
			
		||||
            c.setupControl(true, true, false);  // standalone = false
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                c.loadFromString(toLoad);
 | 
			
		||||
                pass();  // Should succeed
 | 
			
		||||
            }
 | 
			
		||||
            catch (std::runtime_error const& e)
 | 
			
		||||
            {
 | 
			
		||||
                fail("Should not throw when online_delete is configured");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Test 4: Non-RWDB without online_delete NOT in standalone mode (should
 | 
			
		||||
        // succeed)
 | 
			
		||||
        {
 | 
			
		||||
            Config c;
 | 
			
		||||
            std::string toLoad =
 | 
			
		||||
                "[node_db]\n"
 | 
			
		||||
                "type=NuDB\n"
 | 
			
		||||
                "path=main\n";
 | 
			
		||||
            c.setupControl(true, true, false);  // standalone = false
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                c.loadFromString(toLoad);
 | 
			
		||||
                pass();  // Should succeed
 | 
			
		||||
            }
 | 
			
		||||
            catch (std::runtime_error const& e)
 | 
			
		||||
            {
 | 
			
		||||
                fail("Should not throw for non-RWDB backends");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void
 | 
			
		||||
    testOverlay()
 | 
			
		||||
    {
 | 
			
		||||
@@ -1295,6 +1386,7 @@ r.ripple.com:51235
 | 
			
		||||
        testComments();
 | 
			
		||||
        testGetters();
 | 
			
		||||
        testAmendment();
 | 
			
		||||
        testRWDBOnlineDelete();
 | 
			
		||||
        testOverlay();
 | 
			
		||||
        testNetworkID();
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										756
									
								
								src/test/rdb/RelationalDatabase_test.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										756
									
								
								src/test/rdb/RelationalDatabase_test.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,756 @@
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
/*
 | 
			
		||||
    This file is part of rippled: https://github.com/ripple/rippled
 | 
			
		||||
    Copyright (c) 2025 Ripple Labs Inc.
 | 
			
		||||
 | 
			
		||||
    Permission to use, copy, modify, and/or distribute this software for any
 | 
			
		||||
    purpose  with  or without fee is hereby granted, provided that the above
 | 
			
		||||
    copyright notice and this permission notice appear in all copies.
 | 
			
		||||
 | 
			
		||||
    THE  SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
			
		||||
    WITH  REGARD  TO  THIS  SOFTWARE  INCLUDING  ALL  IMPLIED  WARRANTIES  OF
 | 
			
		||||
    MERCHANTABILITY  AND  FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
			
		||||
    ANY  SPECIAL ,  DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
			
		||||
    WHATSOEVER  RESULTING  FROM  LOSS  OF USE, DATA OR PROFITS, WHETHER IN AN
 | 
			
		||||
    ACTION  OF  CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 | 
			
		||||
    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
			
		||||
*/
 | 
			
		||||
//==============================================================================
 | 
			
		||||
 | 
			
		||||
#include <ripple/app/rdb/RelationalDatabase.h>
 | 
			
		||||
#include <ripple/app/rdb/backend/SQLiteDatabase.h>
 | 
			
		||||
#include <ripple/core/ConfigSections.h>
 | 
			
		||||
#include <boost/filesystem.hpp>
 | 
			
		||||
#include <chrono>
 | 
			
		||||
#include <test/jtx.h>
 | 
			
		||||
#include <test/jtx/envconfig.h>
 | 
			
		||||
 | 
			
		||||
namespace ripple {
 | 
			
		||||
namespace test {
 | 
			
		||||
 | 
			
		||||
class RelationalDatabase_test : public beast::unit_test::suite
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
    // Helper to get SQLiteDatabase* (works for both SQLite and RWDB since RWDB
 | 
			
		||||
    // inherits from SQLiteDatabase)
 | 
			
		||||
    static SQLiteDatabase*
 | 
			
		||||
    getInterface(Application& app)
 | 
			
		||||
    {
 | 
			
		||||
        return dynamic_cast<SQLiteDatabase*>(&app.getRelationalDatabase());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static SQLiteDatabase*
 | 
			
		||||
    getInterface(RelationalDatabase& db)
 | 
			
		||||
    {
 | 
			
		||||
        return dynamic_cast<SQLiteDatabase*>(&db);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static std::unique_ptr<Config>
 | 
			
		||||
    makeConfig(std::string const& backend)
 | 
			
		||||
    {
 | 
			
		||||
        auto config = test::jtx::envconfig();
 | 
			
		||||
        // Sqlite backend doesn't need a database_path as it will just use
 | 
			
		||||
        // in-memory databases when in standalone mode anyway.
 | 
			
		||||
        config->overwrite(SECTION_RELATIONAL_DB, "backend", backend);
 | 
			
		||||
        return config;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    RelationalDatabase_test() = default;
 | 
			
		||||
 | 
			
		||||
    void
 | 
			
		||||
    testBasicInitialization(
 | 
			
		||||
        std::string const& backend,
 | 
			
		||||
        std::unique_ptr<Config> config)
 | 
			
		||||
    {
 | 
			
		||||
        testcase("Basic initialization and empty database - " + backend);
 | 
			
		||||
 | 
			
		||||
        using namespace test::jtx;
 | 
			
		||||
        Env env(*this, std::move(config));
 | 
			
		||||
        auto& db = env.app().getRelationalDatabase();
 | 
			
		||||
 | 
			
		||||
        // Test empty database state
 | 
			
		||||
        BEAST_EXPECT(db.getMinLedgerSeq() == 2);
 | 
			
		||||
        BEAST_EXPECT(db.getMaxLedgerSeq() == 2);
 | 
			
		||||
        BEAST_EXPECT(db.getNewestLedgerInfo()->seq == 2);
 | 
			
		||||
 | 
			
		||||
        auto* sqliteDb = getInterface(db);
 | 
			
		||||
        BEAST_EXPECT(sqliteDb != nullptr);
 | 
			
		||||
 | 
			
		||||
        if (sqliteDb)
 | 
			
		||||
        {
 | 
			
		||||
            BEAST_EXPECT(!sqliteDb->getTransactionsMinLedgerSeq().has_value());
 | 
			
		||||
            BEAST_EXPECT(
 | 
			
		||||
                !sqliteDb->getAccountTransactionsMinLedgerSeq().has_value());
 | 
			
		||||
 | 
			
		||||
            auto ledgerCount = sqliteDb->getLedgerCountMinMax();
 | 
			
		||||
            BEAST_EXPECT(ledgerCount.numberOfRows == 1);
 | 
			
		||||
            BEAST_EXPECT(ledgerCount.minLedgerSequence == 2);
 | 
			
		||||
            BEAST_EXPECT(ledgerCount.maxLedgerSequence == 2);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void
 | 
			
		||||
    testLedgerSequenceOperations(
 | 
			
		||||
        std::string const& backend,
 | 
			
		||||
        std::unique_ptr<Config> config)
 | 
			
		||||
    {
 | 
			
		||||
        testcase("Ledger sequence operations - " + backend);
 | 
			
		||||
 | 
			
		||||
        using namespace test::jtx;
 | 
			
		||||
        config->LEDGER_HISTORY = 1000;
 | 
			
		||||
 | 
			
		||||
        Env env(*this, std::move(config));
 | 
			
		||||
        auto& db = env.app().getRelationalDatabase();
 | 
			
		||||
 | 
			
		||||
        // Create initial ledger
 | 
			
		||||
        Account alice("alice");
 | 
			
		||||
        env.fund(XRP(10000), alice);
 | 
			
		||||
        env.close();
 | 
			
		||||
 | 
			
		||||
        // Test basic sequence operations
 | 
			
		||||
        auto minSeq = db.getMinLedgerSeq();
 | 
			
		||||
        auto maxSeq = db.getMaxLedgerSeq();
 | 
			
		||||
 | 
			
		||||
        BEAST_EXPECT(minSeq.has_value());
 | 
			
		||||
        BEAST_EXPECT(maxSeq.has_value());
 | 
			
		||||
        BEAST_EXPECT(*minSeq == 2);
 | 
			
		||||
        BEAST_EXPECT(*maxSeq == 3);
 | 
			
		||||
 | 
			
		||||
        // Create more ledgers
 | 
			
		||||
        env(pay(alice, Account("bob"), XRP(1000)));
 | 
			
		||||
        env.close();
 | 
			
		||||
 | 
			
		||||
        env(pay(alice, Account("carol"), XRP(500)));
 | 
			
		||||
        env.close();
 | 
			
		||||
 | 
			
		||||
        // Verify sequence updates
 | 
			
		||||
        minSeq = db.getMinLedgerSeq();
 | 
			
		||||
        maxSeq = db.getMaxLedgerSeq();
 | 
			
		||||
 | 
			
		||||
        BEAST_EXPECT(*minSeq == 2);
 | 
			
		||||
        BEAST_EXPECT(*maxSeq == 5);
 | 
			
		||||
 | 
			
		||||
        auto* sqliteDb = getInterface(db);
 | 
			
		||||
        if (sqliteDb)
 | 
			
		||||
        {
 | 
			
		||||
            auto ledgerCount = sqliteDb->getLedgerCountMinMax();
 | 
			
		||||
            BEAST_EXPECT(ledgerCount.numberOfRows == 4);
 | 
			
		||||
            BEAST_EXPECT(ledgerCount.minLedgerSequence == 2);
 | 
			
		||||
            BEAST_EXPECT(ledgerCount.maxLedgerSequence == 5);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void
 | 
			
		||||
    testLedgerInfoOperations(
 | 
			
		||||
        std::string const& backend,
 | 
			
		||||
        std::unique_ptr<Config> config)
 | 
			
		||||
    {
 | 
			
		||||
        testcase("Ledger info retrieval operations - " + backend);
 | 
			
		||||
 | 
			
		||||
        using namespace test::jtx;
 | 
			
		||||
        config->LEDGER_HISTORY = 1000;
 | 
			
		||||
 | 
			
		||||
        Env env(*this, std::move(config));
 | 
			
		||||
        auto* db = getInterface(env.app());
 | 
			
		||||
 | 
			
		||||
        Account alice("alice");
 | 
			
		||||
        env.fund(XRP(10000), alice);
 | 
			
		||||
        env.close();
 | 
			
		||||
 | 
			
		||||
        // Test getNewestLedgerInfo
 | 
			
		||||
        auto newestLedger = db->getNewestLedgerInfo();
 | 
			
		||||
        BEAST_EXPECT(newestLedger.has_value());
 | 
			
		||||
        BEAST_EXPECT(newestLedger->seq == 3);
 | 
			
		||||
 | 
			
		||||
        // Test getLedgerInfoByIndex
 | 
			
		||||
        auto ledgerByIndex = db->getLedgerInfoByIndex(3);
 | 
			
		||||
        BEAST_EXPECT(ledgerByIndex.has_value());
 | 
			
		||||
        BEAST_EXPECT(ledgerByIndex->seq == 3);
 | 
			
		||||
        BEAST_EXPECT(ledgerByIndex->hash == newestLedger->hash);
 | 
			
		||||
 | 
			
		||||
        // Test getLedgerInfoByHash
 | 
			
		||||
        auto ledgerByHash = db->getLedgerInfoByHash(newestLedger->hash);
 | 
			
		||||
        BEAST_EXPECT(ledgerByHash.has_value());
 | 
			
		||||
        BEAST_EXPECT(ledgerByHash->seq == 3);
 | 
			
		||||
        BEAST_EXPECT(ledgerByHash->hash == newestLedger->hash);
 | 
			
		||||
 | 
			
		||||
        // Test getLimitedOldestLedgerInfo
 | 
			
		||||
        auto oldestLedger = db->getLimitedOldestLedgerInfo(2);
 | 
			
		||||
        BEAST_EXPECT(oldestLedger.has_value());
 | 
			
		||||
        BEAST_EXPECT(oldestLedger->seq == 2);
 | 
			
		||||
 | 
			
		||||
        // Test getLimitedNewestLedgerInfo
 | 
			
		||||
        auto limitedNewest = db->getLimitedNewestLedgerInfo(2);
 | 
			
		||||
        BEAST_EXPECT(limitedNewest.has_value());
 | 
			
		||||
        BEAST_EXPECT(limitedNewest->seq == 3);
 | 
			
		||||
 | 
			
		||||
        // Test invalid queries
 | 
			
		||||
        auto invalidLedger = db->getLedgerInfoByIndex(999);
 | 
			
		||||
        BEAST_EXPECT(!invalidLedger.has_value());
 | 
			
		||||
 | 
			
		||||
        uint256 invalidHash;
 | 
			
		||||
        auto invalidHashLedger = db->getLedgerInfoByHash(invalidHash);
 | 
			
		||||
        BEAST_EXPECT(!invalidHashLedger.has_value());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void
 | 
			
		||||
    testHashOperations(
 | 
			
		||||
        std::string const& backend,
 | 
			
		||||
        std::unique_ptr<Config> config)
 | 
			
		||||
    {
 | 
			
		||||
        testcase("Hash retrieval operations - " + backend);
 | 
			
		||||
 | 
			
		||||
        using namespace test::jtx;
 | 
			
		||||
        config->LEDGER_HISTORY = 1000;
 | 
			
		||||
 | 
			
		||||
        Env env(*this, std::move(config));
 | 
			
		||||
        auto& db = env.app().getRelationalDatabase();
 | 
			
		||||
 | 
			
		||||
        Account alice("alice");
 | 
			
		||||
        env.fund(XRP(10000), alice);
 | 
			
		||||
        env.close();
 | 
			
		||||
 | 
			
		||||
        env(pay(alice, Account("bob"), XRP(1000)));
 | 
			
		||||
        env.close();
 | 
			
		||||
 | 
			
		||||
        // Test getHashByIndex
 | 
			
		||||
        auto hash1 = db.getHashByIndex(3);
 | 
			
		||||
        auto hash2 = db.getHashByIndex(4);
 | 
			
		||||
 | 
			
		||||
        BEAST_EXPECT(hash1 != uint256());
 | 
			
		||||
        BEAST_EXPECT(hash2 != uint256());
 | 
			
		||||
        BEAST_EXPECT(hash1 != hash2);
 | 
			
		||||
 | 
			
		||||
        // Test getHashesByIndex (single)
 | 
			
		||||
        auto hashPair = db.getHashesByIndex(4);
 | 
			
		||||
        BEAST_EXPECT(hashPair.has_value());
 | 
			
		||||
        BEAST_EXPECT(hashPair->ledgerHash == hash2);
 | 
			
		||||
        BEAST_EXPECT(hashPair->parentHash == hash1);
 | 
			
		||||
 | 
			
		||||
        // Test getHashesByIndex (range)
 | 
			
		||||
        auto hashRange = db.getHashesByIndex(3, 4);
 | 
			
		||||
        BEAST_EXPECT(hashRange.size() == 2);
 | 
			
		||||
        BEAST_EXPECT(hashRange[3].ledgerHash == hash1);
 | 
			
		||||
        BEAST_EXPECT(hashRange[4].ledgerHash == hash2);
 | 
			
		||||
        BEAST_EXPECT(hashRange[4].parentHash == hash1);
 | 
			
		||||
 | 
			
		||||
        // Test invalid hash queries
 | 
			
		||||
        auto invalidHash = db.getHashByIndex(999);
 | 
			
		||||
        BEAST_EXPECT(invalidHash == uint256());
 | 
			
		||||
 | 
			
		||||
        auto invalidHashPair = db.getHashesByIndex(999);
 | 
			
		||||
        BEAST_EXPECT(!invalidHashPair.has_value());
 | 
			
		||||
 | 
			
		||||
        auto emptyRange = db.getHashesByIndex(10, 5);  // max < min
 | 
			
		||||
        BEAST_EXPECT(emptyRange.empty());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void
 | 
			
		||||
    testTransactionOperations(
 | 
			
		||||
        std::string const& backend,
 | 
			
		||||
        std::unique_ptr<Config> config)
 | 
			
		||||
    {
 | 
			
		||||
        testcase("Transaction storage and retrieval - " + backend);
 | 
			
		||||
 | 
			
		||||
        using namespace test::jtx;
 | 
			
		||||
        config->LEDGER_HISTORY = 1000;
 | 
			
		||||
 | 
			
		||||
        Env env(*this, std::move(config));
 | 
			
		||||
        auto& db = env.app().getRelationalDatabase();
 | 
			
		||||
 | 
			
		||||
        Account alice("alice");
 | 
			
		||||
        Account bob("bob");
 | 
			
		||||
 | 
			
		||||
        env.fund(XRP(10000), alice, bob);
 | 
			
		||||
        env.close();
 | 
			
		||||
 | 
			
		||||
        auto* sqliteDb = getInterface(db);
 | 
			
		||||
        BEAST_EXPECT(sqliteDb != nullptr);
 | 
			
		||||
 | 
			
		||||
        if (!sqliteDb)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        // Test initial transaction counts after funding
 | 
			
		||||
        auto initialTxCount = sqliteDb->getTransactionCount();
 | 
			
		||||
        auto initialAcctTxCount = sqliteDb->getAccountTransactionCount();
 | 
			
		||||
 | 
			
		||||
        BEAST_EXPECT(initialTxCount == 4);
 | 
			
		||||
        BEAST_EXPECT(initialAcctTxCount == 6);
 | 
			
		||||
 | 
			
		||||
        // Create transactions
 | 
			
		||||
        env(pay(alice, bob, XRP(1000)));
 | 
			
		||||
        env.close();
 | 
			
		||||
 | 
			
		||||
        env(pay(bob, alice, XRP(500)));
 | 
			
		||||
        env.close();
 | 
			
		||||
 | 
			
		||||
        // Test transaction counts after creation
 | 
			
		||||
        auto txCount = sqliteDb->getTransactionCount();
 | 
			
		||||
        auto acctTxCount = sqliteDb->getAccountTransactionCount();
 | 
			
		||||
 | 
			
		||||
        BEAST_EXPECT(txCount == 6);
 | 
			
		||||
        BEAST_EXPECT(acctTxCount == 10);
 | 
			
		||||
 | 
			
		||||
        // Test transaction retrieval
 | 
			
		||||
        uint256 invalidTxId;
 | 
			
		||||
        error_code_i ec;
 | 
			
		||||
        auto invalidTxResult =
 | 
			
		||||
            sqliteDb->getTransaction(invalidTxId, std::nullopt, ec);
 | 
			
		||||
        BEAST_EXPECT(std::holds_alternative<TxSearched>(invalidTxResult));
 | 
			
		||||
 | 
			
		||||
        // Test transaction history
 | 
			
		||||
        auto txHistory = db.getTxHistory(0);
 | 
			
		||||
 | 
			
		||||
        BEAST_EXPECT(!txHistory.empty());
 | 
			
		||||
        BEAST_EXPECT(txHistory.size() == 6);
 | 
			
		||||
 | 
			
		||||
        // Test with valid transaction range
 | 
			
		||||
        auto minSeq = sqliteDb->getTransactionsMinLedgerSeq();
 | 
			
		||||
        auto maxSeq = db.getMaxLedgerSeq();
 | 
			
		||||
 | 
			
		||||
        if (minSeq && maxSeq)
 | 
			
		||||
        {
 | 
			
		||||
            ClosedInterval<std::uint32_t> range(*minSeq, *maxSeq);
 | 
			
		||||
            auto rangeResult = sqliteDb->getTransaction(invalidTxId, range, ec);
 | 
			
		||||
            auto searched = std::get<TxSearched>(rangeResult);
 | 
			
		||||
            BEAST_EXPECT(
 | 
			
		||||
                searched == TxSearched::all || searched == TxSearched::some);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void
 | 
			
		||||
    testAccountTransactionOperations(
 | 
			
		||||
        std::string const& backend,
 | 
			
		||||
        std::unique_ptr<Config> config)
 | 
			
		||||
    {
 | 
			
		||||
        testcase("Account transaction operations - " + backend);
 | 
			
		||||
 | 
			
		||||
        using namespace test::jtx;
 | 
			
		||||
        config->LEDGER_HISTORY = 1000;
 | 
			
		||||
 | 
			
		||||
        Env env(*this, std::move(config));
 | 
			
		||||
        auto& db = env.app().getRelationalDatabase();
 | 
			
		||||
 | 
			
		||||
        Account alice("alice");
 | 
			
		||||
        Account bob("bob");
 | 
			
		||||
        Account carol("carol");
 | 
			
		||||
 | 
			
		||||
        env.fund(XRP(10000), alice, bob, carol);
 | 
			
		||||
        env.close();
 | 
			
		||||
 | 
			
		||||
        auto* sqliteDb = getInterface(db);
 | 
			
		||||
        BEAST_EXPECT(sqliteDb != nullptr);
 | 
			
		||||
 | 
			
		||||
        if (!sqliteDb)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        // Create multiple transactions involving alice
 | 
			
		||||
        env(pay(alice, bob, XRP(1000)));
 | 
			
		||||
        env.close();
 | 
			
		||||
 | 
			
		||||
        env(pay(bob, alice, XRP(500)));
 | 
			
		||||
        env.close();
 | 
			
		||||
 | 
			
		||||
        env(pay(alice, carol, XRP(250)));
 | 
			
		||||
        env.close();
 | 
			
		||||
 | 
			
		||||
        auto minSeq = db.getMinLedgerSeq();
 | 
			
		||||
        auto maxSeq = db.getMaxLedgerSeq();
 | 
			
		||||
 | 
			
		||||
        if (!minSeq || !maxSeq)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        // Test getOldestAccountTxs
 | 
			
		||||
        RelationalDatabase::AccountTxOptions options{
 | 
			
		||||
            alice.id(), *minSeq, *maxSeq, 0, 10, false};
 | 
			
		||||
 | 
			
		||||
        auto oldestTxs = sqliteDb->getOldestAccountTxs(options);
 | 
			
		||||
        BEAST_EXPECT(oldestTxs.size() == 5);
 | 
			
		||||
 | 
			
		||||
        // Test getNewestAccountTxs
 | 
			
		||||
        auto newestTxs = sqliteDb->getNewestAccountTxs(options);
 | 
			
		||||
        BEAST_EXPECT(newestTxs.size() == 5);
 | 
			
		||||
 | 
			
		||||
        // Test binary format versions
 | 
			
		||||
        auto oldestTxsB = sqliteDb->getOldestAccountTxsB(options);
 | 
			
		||||
        BEAST_EXPECT(oldestTxsB.size() == 5);
 | 
			
		||||
 | 
			
		||||
        auto newestTxsB = sqliteDb->getNewestAccountTxsB(options);
 | 
			
		||||
        BEAST_EXPECT(newestTxsB.size() == 5);
 | 
			
		||||
 | 
			
		||||
        // Test with limit
 | 
			
		||||
        options.limit = 1;
 | 
			
		||||
        auto limitedTxs = sqliteDb->getOldestAccountTxs(options);
 | 
			
		||||
        BEAST_EXPECT(limitedTxs.size() == 1);
 | 
			
		||||
 | 
			
		||||
        // Test with offset
 | 
			
		||||
        options.limit = 10;
 | 
			
		||||
        options.offset = 1;
 | 
			
		||||
        auto offsetTxs = sqliteDb->getOldestAccountTxs(options);
 | 
			
		||||
        BEAST_EXPECT(offsetTxs.size() == 4);
 | 
			
		||||
 | 
			
		||||
        // Test with invalid account
 | 
			
		||||
        {
 | 
			
		||||
            Account invalidAccount("invalid");
 | 
			
		||||
            RelationalDatabase::AccountTxOptions invalidOptions{
 | 
			
		||||
                invalidAccount.id(), *minSeq, *maxSeq, 0, 10, false};
 | 
			
		||||
            auto invalidAccountTxs =
 | 
			
		||||
                sqliteDb->getOldestAccountTxs(invalidOptions);
 | 
			
		||||
            BEAST_EXPECT(invalidAccountTxs.empty());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void
 | 
			
		||||
    testAccountTransactionPaging(
 | 
			
		||||
        std::string const& backend,
 | 
			
		||||
        std::unique_ptr<Config> config)
 | 
			
		||||
    {
 | 
			
		||||
        testcase("Account transaction paging operations - " + backend);
 | 
			
		||||
 | 
			
		||||
        using namespace test::jtx;
 | 
			
		||||
        config->LEDGER_HISTORY = 1000;
 | 
			
		||||
 | 
			
		||||
        Env env(*this, std::move(config));
 | 
			
		||||
        auto& db = env.app().getRelationalDatabase();
 | 
			
		||||
 | 
			
		||||
        Account alice("alice");
 | 
			
		||||
        Account bob("bob");
 | 
			
		||||
 | 
			
		||||
        env.fund(XRP(10000), alice, bob);
 | 
			
		||||
        env.close();
 | 
			
		||||
 | 
			
		||||
        auto* sqliteDb = getInterface(db);
 | 
			
		||||
        BEAST_EXPECT(sqliteDb != nullptr);
 | 
			
		||||
        if (!sqliteDb)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        // Create multiple transactions for paging
 | 
			
		||||
        for (int i = 0; i < 5; ++i)
 | 
			
		||||
        {
 | 
			
		||||
            env(pay(alice, bob, XRP(100 + i)));
 | 
			
		||||
            env.close();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        auto minSeq = db.getMinLedgerSeq();
 | 
			
		||||
        auto maxSeq = db.getMaxLedgerSeq();
 | 
			
		||||
 | 
			
		||||
        if (!minSeq || !maxSeq)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        RelationalDatabase::AccountTxPageOptions pageOptions{
 | 
			
		||||
            alice.id(), *minSeq, *maxSeq, std::nullopt, 2, false};
 | 
			
		||||
 | 
			
		||||
        // Test oldestAccountTxPage
 | 
			
		||||
        auto [oldestPage, oldestMarker] =
 | 
			
		||||
            sqliteDb->oldestAccountTxPage(pageOptions);
 | 
			
		||||
 | 
			
		||||
        BEAST_EXPECT(oldestPage.size() == 2);
 | 
			
		||||
        BEAST_EXPECT(oldestMarker.has_value() == true);
 | 
			
		||||
 | 
			
		||||
        // Test newestAccountTxPage
 | 
			
		||||
        auto [newestPage, newestMarker] =
 | 
			
		||||
            sqliteDb->newestAccountTxPage(pageOptions);
 | 
			
		||||
 | 
			
		||||
        BEAST_EXPECT(newestPage.size() == 2);
 | 
			
		||||
        BEAST_EXPECT(newestMarker.has_value() == true);
 | 
			
		||||
 | 
			
		||||
        // Test binary versions
 | 
			
		||||
        auto [oldestPageB, oldestMarkerB] =
 | 
			
		||||
            sqliteDb->oldestAccountTxPageB(pageOptions);
 | 
			
		||||
        BEAST_EXPECT(oldestPageB.size() == 2);
 | 
			
		||||
 | 
			
		||||
        auto [newestPageB, newestMarkerB] =
 | 
			
		||||
            sqliteDb->newestAccountTxPageB(pageOptions);
 | 
			
		||||
        BEAST_EXPECT(newestPageB.size() == 2);
 | 
			
		||||
 | 
			
		||||
        // Test with marker continuation
 | 
			
		||||
        if (oldestMarker.has_value())
 | 
			
		||||
        {
 | 
			
		||||
            pageOptions.marker = oldestMarker;
 | 
			
		||||
            auto [continuedPage, continuedMarker] =
 | 
			
		||||
                sqliteDb->oldestAccountTxPage(pageOptions);
 | 
			
		||||
            BEAST_EXPECT(continuedPage.size() == 2);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void
 | 
			
		||||
    testDeletionOperations(
 | 
			
		||||
        std::string const& backend,
 | 
			
		||||
        std::unique_ptr<Config> config)
 | 
			
		||||
    {
 | 
			
		||||
        testcase("Deletion operations - " + backend);
 | 
			
		||||
 | 
			
		||||
        using namespace test::jtx;
 | 
			
		||||
        config->LEDGER_HISTORY = 1000;
 | 
			
		||||
 | 
			
		||||
        Env env(*this, std::move(config));
 | 
			
		||||
        auto& db = env.app().getRelationalDatabase();
 | 
			
		||||
 | 
			
		||||
        Account alice("alice");
 | 
			
		||||
        Account bob("bob");
 | 
			
		||||
 | 
			
		||||
        env.fund(XRP(10000), alice, bob);
 | 
			
		||||
        env.close();
 | 
			
		||||
 | 
			
		||||
        auto* sqliteDb = getInterface(db);
 | 
			
		||||
        BEAST_EXPECT(sqliteDb != nullptr);
 | 
			
		||||
        if (!sqliteDb)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        // Create multiple ledgers and transactions
 | 
			
		||||
        for (int i = 0; i < 3; ++i)
 | 
			
		||||
        {
 | 
			
		||||
            env(pay(alice, bob, XRP(100 + i)));
 | 
			
		||||
            env.close();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        auto initialTxCount = sqliteDb->getTransactionCount();
 | 
			
		||||
        BEAST_EXPECT(initialTxCount == 7);
 | 
			
		||||
        auto initialAcctTxCount = sqliteDb->getAccountTransactionCount();
 | 
			
		||||
        BEAST_EXPECT(initialAcctTxCount == 12);
 | 
			
		||||
        auto initialLedgerCount = sqliteDb->getLedgerCountMinMax();
 | 
			
		||||
        BEAST_EXPECT(initialLedgerCount.numberOfRows == 5);
 | 
			
		||||
 | 
			
		||||
        auto maxSeq = db.getMaxLedgerSeq();
 | 
			
		||||
        if (!maxSeq || *maxSeq <= 2)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        // Test deleteTransactionByLedgerSeq
 | 
			
		||||
        sqliteDb->deleteTransactionByLedgerSeq(*maxSeq);
 | 
			
		||||
        auto txCountAfterDelete = sqliteDb->getTransactionCount();
 | 
			
		||||
        BEAST_EXPECT(txCountAfterDelete == 6);
 | 
			
		||||
 | 
			
		||||
        // Test deleteTransactionsBeforeLedgerSeq
 | 
			
		||||
        sqliteDb->deleteTransactionsBeforeLedgerSeq(*maxSeq - 1);
 | 
			
		||||
        auto txCountAfterBulkDelete = sqliteDb->getTransactionCount();
 | 
			
		||||
        BEAST_EXPECT(txCountAfterBulkDelete == 1);
 | 
			
		||||
 | 
			
		||||
        // Test deleteAccountTransactionsBeforeLedgerSeq
 | 
			
		||||
        sqliteDb->deleteAccountTransactionsBeforeLedgerSeq(*maxSeq - 1);
 | 
			
		||||
        auto acctTxCountAfterDelete = sqliteDb->getAccountTransactionCount();
 | 
			
		||||
        BEAST_EXPECT(acctTxCountAfterDelete == 4);
 | 
			
		||||
 | 
			
		||||
        // Test deleteBeforeLedgerSeq
 | 
			
		||||
        auto minSeq = db.getMinLedgerSeq();
 | 
			
		||||
        if (minSeq)
 | 
			
		||||
        {
 | 
			
		||||
            sqliteDb->deleteBeforeLedgerSeq(*minSeq + 1);
 | 
			
		||||
            auto ledgerCountAfterDelete = sqliteDb->getLedgerCountMinMax();
 | 
			
		||||
            BEAST_EXPECT(ledgerCountAfterDelete.numberOfRows == 4);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void
 | 
			
		||||
    testDatabaseSpaceOperations(
 | 
			
		||||
        std::string const& backend,
 | 
			
		||||
        std::unique_ptr<Config> config)
 | 
			
		||||
    {
 | 
			
		||||
        testcase("Database space and size operations - " + backend);
 | 
			
		||||
 | 
			
		||||
        using namespace test::jtx;
 | 
			
		||||
        Env env(*this, std::move(config));
 | 
			
		||||
        auto& db = env.app().getRelationalDatabase();
 | 
			
		||||
 | 
			
		||||
        auto* sqliteDb = getInterface(db);
 | 
			
		||||
        BEAST_EXPECT(sqliteDb != nullptr);
 | 
			
		||||
        if (!sqliteDb)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        // Test size queries
 | 
			
		||||
        auto allKB = sqliteDb->getKBUsedAll();
 | 
			
		||||
        auto ledgerKB = sqliteDb->getKBUsedLedger();
 | 
			
		||||
        auto txKB = sqliteDb->getKBUsedTransaction();
 | 
			
		||||
 | 
			
		||||
        if (backend == "rwdb")
 | 
			
		||||
        {
 | 
			
		||||
            // RWDB reports actual data memory (rounded down to KB)
 | 
			
		||||
            // Initially should be < 1KB, so rounds down to 0
 | 
			
		||||
            // Note: These are 0 due to rounding, not because there's literally
 | 
			
		||||
            // no data
 | 
			
		||||
            BEAST_EXPECT(allKB == 0);     // < 1024 bytes rounds to 0 KB
 | 
			
		||||
            BEAST_EXPECT(ledgerKB == 0);  // < 1024 bytes rounds to 0 KB
 | 
			
		||||
            BEAST_EXPECT(txKB == 0);      // < 1024 bytes rounds to 0 KB
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            // SQLite reports cache/engine memory which has overhead even when
 | 
			
		||||
            // empty Just verify the functions return reasonable values
 | 
			
		||||
            BEAST_EXPECT(allKB >= 0);
 | 
			
		||||
            BEAST_EXPECT(ledgerKB >= 0);
 | 
			
		||||
            BEAST_EXPECT(txKB >= 0);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Create some data and verify size increases
 | 
			
		||||
        Account alice("alice");
 | 
			
		||||
        env.fund(XRP(10000), alice);
 | 
			
		||||
        env.close();
 | 
			
		||||
 | 
			
		||||
        auto newAllKB = sqliteDb->getKBUsedAll();
 | 
			
		||||
        auto newLedgerKB = sqliteDb->getKBUsedLedger();
 | 
			
		||||
        auto newTxKB = sqliteDb->getKBUsedTransaction();
 | 
			
		||||
 | 
			
		||||
        if (backend == "rwdb")
 | 
			
		||||
        {
 | 
			
		||||
            // RWDB reports actual data memory
 | 
			
		||||
            // After adding data, should see some increase
 | 
			
		||||
            BEAST_EXPECT(newAllKB >= 1);  // Should have at least 1KB total
 | 
			
		||||
            BEAST_EXPECT(
 | 
			
		||||
                newTxKB >= 0);  // Transactions added (might still be < 1KB)
 | 
			
		||||
            BEAST_EXPECT(
 | 
			
		||||
                newLedgerKB >= 0);  // Ledger data (might still be < 1KB)
 | 
			
		||||
 | 
			
		||||
            // Key relationships
 | 
			
		||||
            BEAST_EXPECT(newAllKB >= newLedgerKB + newTxKB);  // Total >= parts
 | 
			
		||||
            BEAST_EXPECT(newAllKB >= allKB);  // Should increase or stay same
 | 
			
		||||
            BEAST_EXPECT(newTxKB >= txKB);    // Should increase or stay same
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            // SQLite: Memory usage should not decrease after adding data
 | 
			
		||||
            // Values might increase due to cache growth
 | 
			
		||||
            BEAST_EXPECT(newAllKB >= allKB);
 | 
			
		||||
            BEAST_EXPECT(newLedgerKB >= ledgerKB);
 | 
			
		||||
            BEAST_EXPECT(newTxKB >= txKB);
 | 
			
		||||
 | 
			
		||||
            // SQLite's getKBUsedAll is global memory, should be >= parts
 | 
			
		||||
            BEAST_EXPECT(newAllKB >= newLedgerKB);
 | 
			
		||||
            BEAST_EXPECT(newAllKB >= newTxKB);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Test space availability
 | 
			
		||||
        // Both SQLite and RWDB use in-memory databases in standalone mode,
 | 
			
		||||
        // so file-based space checks don't apply to either backend.
 | 
			
		||||
        // Skip these checks for both.
 | 
			
		||||
 | 
			
		||||
        // if (backend == "rwdb")
 | 
			
		||||
        // {
 | 
			
		||||
        //     BEAST_EXPECT(db.ledgerDbHasSpace(env.app().config()));
 | 
			
		||||
        //     BEAST_EXPECT(db.transactionDbHasSpace(env.app().config()));
 | 
			
		||||
        // }
 | 
			
		||||
 | 
			
		||||
        // Test database closure operations (should not throw)
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            sqliteDb->closeLedgerDB();
 | 
			
		||||
            sqliteDb->closeTransactionDB();
 | 
			
		||||
        }
 | 
			
		||||
        catch (std::exception const& e)
 | 
			
		||||
        {
 | 
			
		||||
            BEAST_EXPECT(false);  // Should not throw
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void
 | 
			
		||||
    testTransactionMinLedgerSeq(
 | 
			
		||||
        std::string const& backend,
 | 
			
		||||
        std::unique_ptr<Config> config)
 | 
			
		||||
    {
 | 
			
		||||
        testcase("Transaction minimum ledger sequence tracking - " + backend);
 | 
			
		||||
 | 
			
		||||
        using namespace test::jtx;
 | 
			
		||||
        config->LEDGER_HISTORY = 1000;
 | 
			
		||||
 | 
			
		||||
        Env env(*this, std::move(config));
 | 
			
		||||
        auto& db = env.app().getRelationalDatabase();
 | 
			
		||||
 | 
			
		||||
        auto* sqliteDb = getInterface(db);
 | 
			
		||||
        BEAST_EXPECT(sqliteDb != nullptr);
 | 
			
		||||
        if (!sqliteDb)
 | 
			
		||||
            return;
 | 
			
		||||
 | 
			
		||||
        // Initially should have no transactions
 | 
			
		||||
        BEAST_EXPECT(!sqliteDb->getTransactionsMinLedgerSeq().has_value());
 | 
			
		||||
        BEAST_EXPECT(
 | 
			
		||||
            !sqliteDb->getAccountTransactionsMinLedgerSeq().has_value());
 | 
			
		||||
 | 
			
		||||
        Account alice("alice");
 | 
			
		||||
        Account bob("bob");
 | 
			
		||||
 | 
			
		||||
        env.fund(XRP(10000), alice, bob);
 | 
			
		||||
        env.close();
 | 
			
		||||
 | 
			
		||||
        // Create first transaction
 | 
			
		||||
        env(pay(alice, bob, XRP(1000)));
 | 
			
		||||
        env.close();
 | 
			
		||||
 | 
			
		||||
        auto txMinSeq = sqliteDb->getTransactionsMinLedgerSeq();
 | 
			
		||||
        auto acctTxMinSeq = sqliteDb->getAccountTransactionsMinLedgerSeq();
 | 
			
		||||
        BEAST_EXPECT(txMinSeq.has_value());
 | 
			
		||||
        BEAST_EXPECT(acctTxMinSeq.has_value());
 | 
			
		||||
        BEAST_EXPECT(*txMinSeq == 3);
 | 
			
		||||
        BEAST_EXPECT(*acctTxMinSeq == 3);
 | 
			
		||||
 | 
			
		||||
        // Create more transactions
 | 
			
		||||
        env(pay(bob, alice, XRP(500)));
 | 
			
		||||
        env.close();
 | 
			
		||||
 | 
			
		||||
        env(pay(alice, bob, XRP(250)));
 | 
			
		||||
        env.close();
 | 
			
		||||
 | 
			
		||||
        // Min sequences should remain the same (first transaction ledger)
 | 
			
		||||
        auto newTxMinSeq = sqliteDb->getTransactionsMinLedgerSeq();
 | 
			
		||||
        auto newAcctTxMinSeq = sqliteDb->getAccountTransactionsMinLedgerSeq();
 | 
			
		||||
        BEAST_EXPECT(newTxMinSeq == txMinSeq);
 | 
			
		||||
        BEAST_EXPECT(newAcctTxMinSeq == acctTxMinSeq);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::vector<std::string> static getBackends(std::string const& unittest_arg)
 | 
			
		||||
    {
 | 
			
		||||
        // Valid backends
 | 
			
		||||
        static const std::set<std::string> validBackends = {"sqlite", "rwdb"};
 | 
			
		||||
 | 
			
		||||
        // Default to all valid backends if no arg specified
 | 
			
		||||
        if (unittest_arg.empty())
 | 
			
		||||
            return {validBackends.begin(), validBackends.end()};
 | 
			
		||||
 | 
			
		||||
        std::set<std::string> backends;  // Use set to avoid duplicates
 | 
			
		||||
        std::stringstream ss(unittest_arg);
 | 
			
		||||
        std::string backend;
 | 
			
		||||
 | 
			
		||||
        while (std::getline(ss, backend, ','))
 | 
			
		||||
        {
 | 
			
		||||
            if (!backend.empty())
 | 
			
		||||
            {
 | 
			
		||||
                // Validate backend
 | 
			
		||||
                if (validBackends.contains(backend))
 | 
			
		||||
                {
 | 
			
		||||
                    backends.insert(backend);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Return as vector (sorted due to set)
 | 
			
		||||
        return {backends.begin(), backends.end()};
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void
 | 
			
		||||
    run() override
 | 
			
		||||
    {
 | 
			
		||||
        auto backends = getBackends(arg());
 | 
			
		||||
 | 
			
		||||
        if (backends.empty())
 | 
			
		||||
        {
 | 
			
		||||
            fail("no valid backend specified: '" + arg() + "'");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (auto const& backend : backends)
 | 
			
		||||
        {
 | 
			
		||||
            testBasicInitialization(backend, makeConfig(backend));
 | 
			
		||||
            testLedgerSequenceOperations(backend, makeConfig(backend));
 | 
			
		||||
            testLedgerInfoOperations(backend, makeConfig(backend));
 | 
			
		||||
            testHashOperations(backend, makeConfig(backend));
 | 
			
		||||
            testTransactionOperations(backend, makeConfig(backend));
 | 
			
		||||
            testAccountTransactionOperations(backend, makeConfig(backend));
 | 
			
		||||
            testAccountTransactionPaging(backend, makeConfig(backend));
 | 
			
		||||
            testDeletionOperations(backend, makeConfig(backend));
 | 
			
		||||
            testDatabaseSpaceOperations(backend, makeConfig(backend));
 | 
			
		||||
            testTransactionMinLedgerSeq(backend, makeConfig(backend));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
BEAST_DEFINE_TESTSUITE(RelationalDatabase, rdb, ripple);
 | 
			
		||||
 | 
			
		||||
}  // namespace test
 | 
			
		||||
}  // namespace ripple
 | 
			
		||||
@@ -83,6 +83,8 @@ SuiteJournalSink::write(
 | 
			
		||||
    // Only write the string if the level at least equals the threshold.
 | 
			
		||||
    if (level >= threshold())
 | 
			
		||||
    {
 | 
			
		||||
        // std::endl flushes → sync() → str()/str("") race in shared buffer →
 | 
			
		||||
        // crashes
 | 
			
		||||
        static std::mutex log_mutex;
 | 
			
		||||
        std::lock_guard lock(log_mutex);
 | 
			
		||||
        suite_.log << s << partition_ << text << std::endl;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user