mirror of
				https://github.com/Xahau/xahaud.git
				synced 2025-11-04 02:35:48 +00:00 
			
		
		
		
	Compare commits
	
		
			29 Commits
		
	
	
		
			849d447a20
			...
			9ed20a4f1c
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					9ed20a4f1c | ||
| 
						 | 
					89ffc1969b | ||
| 
						 | 
					79fdafe638 | ||
| 
						 | 
					2a10013dfc | ||
| 
						 | 
					6f148a8ac7 | ||
| 
						 | 
					96222baf5e | ||
| 
						 | 
					74477d2c13 | ||
| 
						 | 
					9378f1a0ad | ||
| 
						 | 
					6fa6a96e3a | ||
| 
						 | 
					b0fcd36bcd | ||
| 
						 | 
					1ec31e79c9 | ||
| 
						 | 
					9c8b005406 | ||
| 
						 | 
					687ccf4203 | ||
| 
						 | 
					83f09fd8ab | ||
| 
						 | 
					15c7ad6f78 | ||
| 
						 | 
					1f12b9ec5a | ||
| 
						 | 
					ad0531ad6c | ||
| 
						 | 
					e580f7cfc0 | ||
| 
						 | 
					094f011006 | ||
| 
						 | 
					39d1c43901 | ||
| 
						 | 
					b3e6a902cb | ||
| 
						 | 
					fa1b93bfd8 | ||
| 
						 | 
					92e3a927fc | ||
| 
						 | 
					8f7ebf0377 | ||
| 
						 | 
					46cf6785ab | ||
| 
						 | 
					3c4c9c87c5 | ||
| 
						 | 
					7a790246fb | ||
| 
						 | 
					1a3d2db8ef | ||
| 
						 | 
					2fc912d54d | 
@@ -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
 | 
			
		||||
							
								
								
									
										82
									
								
								.github/actions/xahau-ga-build/action.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										82
									
								
								.github/actions/xahau-ga-build/action.yml
									
									
									
									
										vendored
									
									
								
							@@ -21,7 +21,7 @@ inputs:
 | 
			
		||||
    required: false
 | 
			
		||||
    default: ''
 | 
			
		||||
  compiler-id:
 | 
			
		||||
    description: 'Unique identifier for compiler/version combination used for cache keys'
 | 
			
		||||
    description: 'Unique identifier: compiler-version-stdlib[-gccversion] (e.g. clang-14-libstdcxx-gcc11, gcc-13-libstdcxx)'
 | 
			
		||||
    required: false
 | 
			
		||||
    default: ''
 | 
			
		||||
  cache_version:
 | 
			
		||||
@@ -36,6 +36,17 @@ inputs:
 | 
			
		||||
    description: 'Main branch name for restore keys'
 | 
			
		||||
    required: false
 | 
			
		||||
    default: 'dev'
 | 
			
		||||
  stdlib:
 | 
			
		||||
    description: 'C++ standard library to use'
 | 
			
		||||
    required: true
 | 
			
		||||
    type: choice
 | 
			
		||||
    options:
 | 
			
		||||
      - libstdcxx
 | 
			
		||||
      - libcxx
 | 
			
		||||
  clang_gcc_toolchain:
 | 
			
		||||
    description: 'GCC version to use for Clang toolchain (e.g. 11, 13)'
 | 
			
		||||
    required: false
 | 
			
		||||
    default: ''
 | 
			
		||||
 | 
			
		||||
runs:
 | 
			
		||||
  using: 'composite'
 | 
			
		||||
@@ -48,18 +59,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,16 +97,54 @@ runs:
 | 
			
		||||
          export CXX="${{ inputs.cxx }}"
 | 
			
		||||
        fi
 | 
			
		||||
        
 | 
			
		||||
        
 | 
			
		||||
        # Configure ccache launcher args
 | 
			
		||||
        CCACHE_ARGS=""
 | 
			
		||||
        if [ "${{ inputs.ccache_enabled }}" = "true" ]; then
 | 
			
		||||
          CCACHE_ARGS="-DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache"
 | 
			
		||||
        fi
 | 
			
		||||
        
 | 
			
		||||
        # Configure C++ standard library if specified
 | 
			
		||||
        # libstdcxx used for clang-14/16 to work around missing lexicographical_compare_three_way in libc++
 | 
			
		||||
        # libcxx can be used with clang-17+ which has full C++20 support
 | 
			
		||||
        # Note: -stdlib flag is Clang-specific, GCC always uses libstdc++
 | 
			
		||||
        CMAKE_CXX_FLAGS=""
 | 
			
		||||
        if [[ "${{ inputs.cxx }}" == clang* ]]; then
 | 
			
		||||
          # Only Clang needs the -stdlib flag
 | 
			
		||||
          if [ "${{ inputs.stdlib }}" = "libstdcxx" ]; then
 | 
			
		||||
            CMAKE_CXX_FLAGS="-stdlib=libstdc++"
 | 
			
		||||
          elif [ "${{ inputs.stdlib }}" = "libcxx" ]; then
 | 
			
		||||
            CMAKE_CXX_FLAGS="-stdlib=libc++"
 | 
			
		||||
          fi
 | 
			
		||||
        fi
 | 
			
		||||
        # GCC always uses libstdc++ and doesn't need/support the -stdlib flag
 | 
			
		||||
        
 | 
			
		||||
        # Configure GCC toolchain for Clang if specified
 | 
			
		||||
        if [ -n "${{ inputs.clang_gcc_toolchain }}" ] && [[ "${{ inputs.cxx }}" == clang* ]]; then
 | 
			
		||||
          # Extract Clang version from compiler executable name (e.g., clang++-14 -> 14)
 | 
			
		||||
          clang_version=$(echo "${{ inputs.cxx }}" | grep -oE '[0-9]+$')
 | 
			
		||||
          
 | 
			
		||||
          # Clang 16+ supports --gcc-install-dir (precise path specification)
 | 
			
		||||
          # Clang <16 only has --gcc-toolchain (uses discovery heuristics)
 | 
			
		||||
          if [ -n "$clang_version" ] && [ "$clang_version" -ge "16" ]; then
 | 
			
		||||
            # Clang 16+ uses --gcc-install-dir (canonical, precise)
 | 
			
		||||
            CMAKE_CXX_FLAGS="$CMAKE_CXX_FLAGS --gcc-install-dir=/usr/lib/gcc/x86_64-linux-gnu/${{ inputs.clang_gcc_toolchain }}"
 | 
			
		||||
          else
 | 
			
		||||
            # Clang 14-15 uses --gcc-toolchain (deprecated but necessary)
 | 
			
		||||
            # Note: This still uses discovery, so we hide newer GCC versions in the workflow
 | 
			
		||||
            CMAKE_CXX_FLAGS="$CMAKE_CXX_FLAGS --gcc-toolchain=/usr"
 | 
			
		||||
          fi
 | 
			
		||||
        fi
 | 
			
		||||
        
 | 
			
		||||
        # Run CMake configure
 | 
			
		||||
        # Note: conanfile.py hardcodes 'build/generators' as the output path.
 | 
			
		||||
        # If we're in a 'build' folder, Conan detects this and uses just 'generators/'
 | 
			
		||||
        # If we're in '.build' (non-standard), Conan adds the full 'build/generators/'
 | 
			
		||||
        # So we get: .build/build/generators/ with our non-standard folder name
 | 
			
		||||
        cmake .. \
 | 
			
		||||
          -G "${{ inputs.generator }}" \
 | 
			
		||||
          $CCACHE_ARGS \
 | 
			
		||||
          ${CMAKE_CXX_FLAGS:+-DCMAKE_CXX_FLAGS="$CMAKE_CXX_FLAGS"} \
 | 
			
		||||
          -DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake \
 | 
			
		||||
          -DCMAKE_BUILD_TYPE=${{ inputs.configuration }}
 | 
			
		||||
 | 
			
		||||
@@ -100,9 +159,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 }}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										42
									
								
								.github/actions/xahau-ga-dependencies/action.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										42
									
								
								.github/actions/xahau-ga-dependencies/action.yml
									
									
									
									
										vendored
									
									
								
							@@ -10,7 +10,7 @@ inputs:
 | 
			
		||||
    required: false
 | 
			
		||||
    default: '.build'
 | 
			
		||||
  compiler-id:
 | 
			
		||||
    description: 'Unique identifier for compiler/version combination used for cache keys'
 | 
			
		||||
    description: 'Unique identifier: compiler-version-stdlib[-gccversion] (e.g. clang-14-libstdcxx-gcc11, gcc-13-libstdcxx)'
 | 
			
		||||
    required: false
 | 
			
		||||
    default: ''
 | 
			
		||||
  cache_version:
 | 
			
		||||
@@ -25,6 +25,13 @@ inputs:
 | 
			
		||||
    description: 'Main branch name for restore keys'
 | 
			
		||||
    required: false
 | 
			
		||||
    default: 'dev'
 | 
			
		||||
  stdlib:
 | 
			
		||||
    description: 'C++ standard library for Conan configuration (note: also in compiler-id)'
 | 
			
		||||
    required: true
 | 
			
		||||
    type: choice
 | 
			
		||||
    options:
 | 
			
		||||
      - libstdcxx
 | 
			
		||||
      - libcxx
 | 
			
		||||
 | 
			
		||||
outputs:
 | 
			
		||||
  cache-hit:
 | 
			
		||||
@@ -42,6 +49,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
 | 
			
		||||
@@ -50,20 +77,23 @@ runs:
 | 
			
		||||
        path: |
 | 
			
		||||
          ~/.conan
 | 
			
		||||
          ~/.conan2
 | 
			
		||||
        # Note: compiler-id format is compiler-version-stdlib[-gccversion]
 | 
			
		||||
        key: ${{ runner.os }}-conan-v${{ inputs.cache_version }}-${{ inputs.compiler-id }}-${{ hashFiles('**/conanfile.txt', '**/conanfile.py') }}-${{ inputs.configuration }}
 | 
			
		||||
        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 --version 1.1.10 --user xahaud --channel stable
 | 
			
		||||
        conan export external/soci --version 4.0.3 --user xahaud --channel stable
 | 
			
		||||
        conan export external/wasmedge --version 0.11.2 --user xahaud --channel stable
 | 
			
		||||
 | 
			
		||||
    - name: Install dependencies
 | 
			
		||||
      shell: bash
 | 
			
		||||
      env:
 | 
			
		||||
        CONAN_REQUEST_TIMEOUT: 180  # Increase timeout to 3 minutes for slow mirrors
 | 
			
		||||
      run: |
 | 
			
		||||
        # Create build directory
 | 
			
		||||
        mkdir -p ${{ inputs.build_dir }}
 | 
			
		||||
@@ -77,10 +107,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 }}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										36
									
								
								.github/workflows/verify-generated-headers.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								.github/workflows/verify-generated-headers.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
			
		||||
name: Verify Generated Hook Headers
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  push:
 | 
			
		||||
  pull_request:
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  verify-generated-headers:
 | 
			
		||||
    strategy:
 | 
			
		||||
      fail-fast: false
 | 
			
		||||
      matrix:
 | 
			
		||||
        include:
 | 
			
		||||
          - target: hook/error.h
 | 
			
		||||
            generator: ./hook/generate_error.sh
 | 
			
		||||
          - target: hook/extern.h
 | 
			
		||||
            generator: ./hook/generate_extern.sh
 | 
			
		||||
          - target: hook/sfcodes.h
 | 
			
		||||
            generator: bash ./hook/generate_sfcodes.sh
 | 
			
		||||
          - target: hook/tts.h
 | 
			
		||||
            generator: ./hook/generate_tts.sh
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    name: ${{ matrix.target }}
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: Checkout repository
 | 
			
		||||
        uses: actions/checkout@v4
 | 
			
		||||
 | 
			
		||||
      - name: Verify ${{ matrix.target }}
 | 
			
		||||
        run: |
 | 
			
		||||
          set -euo pipefail
 | 
			
		||||
          chmod +x hook/generate_*.sh || true
 | 
			
		||||
 | 
			
		||||
          tmp=$(mktemp)
 | 
			
		||||
          trap 'rm -f "$tmp"' EXIT
 | 
			
		||||
 | 
			
		||||
          ${{ matrix.generator }} > "$tmp"
 | 
			
		||||
          diff -u ${{ matrix.target }} "$tmp"
 | 
			
		||||
							
								
								
									
										57
									
								
								.github/workflows/xahau-ga-macos.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										57
									
								
								.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 }}
 | 
			
		||||
@@ -30,9 +32,9 @@ jobs:
 | 
			
		||||
 | 
			
		||||
      - name: Install Conan
 | 
			
		||||
        run: |
 | 
			
		||||
          brew install conan@1
 | 
			
		||||
          # Add Conan 1 to the PATH for this job
 | 
			
		||||
          echo "$(brew --prefix conan@1)/bin" >> $GITHUB_PATH
 | 
			
		||||
          brew install conan
 | 
			
		||||
          # Verify Conan 2 is installed
 | 
			
		||||
          conan --version
 | 
			
		||||
 | 
			
		||||
      - name: Install Coreutils
 | 
			
		||||
        run: |
 | 
			
		||||
@@ -58,12 +60,20 @@ jobs:
 | 
			
		||||
 | 
			
		||||
      - name: Install CMake
 | 
			
		||||
        run: |
 | 
			
		||||
          if which cmake > /dev/null 2>&1; then
 | 
			
		||||
              echo "cmake executable exists"
 | 
			
		||||
              cmake --version
 | 
			
		||||
          else
 | 
			
		||||
              brew install cmake
 | 
			
		||||
          fi
 | 
			
		||||
          # Install CMake 3.x to match local dev environments
 | 
			
		||||
          # With Conan 2 and the policy args passed to CMake, newer versions
 | 
			
		||||
          # can have issues with dependencies that require cmake_minimum_required < 3.5
 | 
			
		||||
          brew uninstall cmake --ignore-dependencies 2>/dev/null || true
 | 
			
		||||
 | 
			
		||||
          # Download and install CMake 3.31.7 directly
 | 
			
		||||
          curl -L https://github.com/Kitware/CMake/releases/download/v3.31.7/cmake-3.31.7-macos-universal.tar.gz -o cmake.tar.gz
 | 
			
		||||
          tar -xzf cmake.tar.gz
 | 
			
		||||
 | 
			
		||||
          # Move the entire CMake.app to /Applications
 | 
			
		||||
          sudo mv cmake-3.31.7-macos-universal/CMake.app /Applications/
 | 
			
		||||
 | 
			
		||||
          echo "/Applications/CMake.app/Contents/bin" >> $GITHUB_PATH
 | 
			
		||||
          /Applications/CMake.app/Contents/bin/cmake --version
 | 
			
		||||
 | 
			
		||||
      - name: Install ccache
 | 
			
		||||
        run: brew install ccache
 | 
			
		||||
@@ -74,6 +84,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: |
 | 
			
		||||
@@ -89,8 +100,30 @@ jobs:
 | 
			
		||||
 | 
			
		||||
      - name: Configure Conan
 | 
			
		||||
        run: |
 | 
			
		||||
          conan profile new default --detect || true # Ignore error if profile exists
 | 
			
		||||
          conan profile update settings.compiler.cppstd=20 default
 | 
			
		||||
          # Create the default profile directory if it doesn't exist
 | 
			
		||||
          mkdir -p ~/.conan2/profiles
 | 
			
		||||
 | 
			
		||||
          # Detect compiler version
 | 
			
		||||
          COMPILER_VERSION=$(clang --version | grep -oE 'version [0-9]+' | grep -oE '[0-9]+')
 | 
			
		||||
 | 
			
		||||
          # Create profile with our specific settings
 | 
			
		||||
          cat > ~/.conan2/profiles/default <<EOF
 | 
			
		||||
          [settings]
 | 
			
		||||
          arch=armv8
 | 
			
		||||
          build_type=Release
 | 
			
		||||
          compiler=apple-clang
 | 
			
		||||
          compiler.cppstd=20
 | 
			
		||||
          compiler.libcxx=libc++
 | 
			
		||||
          compiler.version=${COMPILER_VERSION}
 | 
			
		||||
          os=Macos
 | 
			
		||||
 | 
			
		||||
          [conf]
 | 
			
		||||
          # Workaround for gRPC with newer Apple Clang
 | 
			
		||||
          tools.build:cxxflags=["-Wno-missing-template-arg-list-after-template-kw"]
 | 
			
		||||
          EOF
 | 
			
		||||
 | 
			
		||||
          # Display profile for verification
 | 
			
		||||
          conan profile show
 | 
			
		||||
 | 
			
		||||
      - name: Install dependencies
 | 
			
		||||
        uses: ./.github/actions/xahau-ga-dependencies
 | 
			
		||||
@@ -113,4 +146,4 @@ jobs:
 | 
			
		||||
 | 
			
		||||
      - name: Test
 | 
			
		||||
        run: |
 | 
			
		||||
          ${{ env.build_dir }}/rippled --unittest --unittest-jobs $(nproc)
 | 
			
		||||
          ${{ env.build_dir }}/rippled --unittest --unittest-jobs $(nproc)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										261
									
								
								.github/workflows/xahau-ga-nix.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										261
									
								
								.github/workflows/xahau-ga-nix.yml
									
									
									
									
										vendored
									
									
								
							@@ -5,30 +5,158 @@ on:
 | 
			
		||||
    branches: ["dev", "candidate", "release"]
 | 
			
		||||
  pull_request:
 | 
			
		||||
    branches: ["dev", "candidate", "release"]
 | 
			
		||||
  schedule:
 | 
			
		||||
    - cron: '0 0 * * *'
 | 
			
		||||
 | 
			
		||||
concurrency:
 | 
			
		||||
  group: ${{ github.workflow }}-${{ github.ref }}
 | 
			
		||||
  cancel-in-progress: true
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  build-job:
 | 
			
		||||
  matrix-setup:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    container: python:3-slim
 | 
			
		||||
    outputs:
 | 
			
		||||
      matrix: ${{ steps.set-matrix.outputs.matrix }}
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: Generate build matrix
 | 
			
		||||
        id: set-matrix
 | 
			
		||||
        shell: python
 | 
			
		||||
        run: |
 | 
			
		||||
          import json
 | 
			
		||||
          import os
 | 
			
		||||
          
 | 
			
		||||
          # Full matrix with all 6 compiler configurations
 | 
			
		||||
          # Each configuration includes all parameters needed by the build job
 | 
			
		||||
          full_matrix = [
 | 
			
		||||
              {
 | 
			
		||||
                  "compiler_id": "gcc-11-libstdcxx",
 | 
			
		||||
                  "compiler": "gcc",
 | 
			
		||||
                  "cc": "gcc-11",
 | 
			
		||||
                  "cxx": "g++-11",
 | 
			
		||||
                  "compiler_version": 11,
 | 
			
		||||
                  "stdlib": "libstdcxx",
 | 
			
		||||
                  "configuration": "Debug"
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                  "compiler_id": "gcc-13-libstdcxx",
 | 
			
		||||
                  "compiler": "gcc",
 | 
			
		||||
                  "cc": "gcc-13",
 | 
			
		||||
                  "cxx": "g++-13",
 | 
			
		||||
                  "compiler_version": 13,
 | 
			
		||||
                  "stdlib": "libstdcxx",
 | 
			
		||||
                  "configuration": "Debug"
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                  "compiler_id": "clang-14-libstdcxx-gcc11",
 | 
			
		||||
                  "compiler": "clang",
 | 
			
		||||
                  "cc": "clang-14",
 | 
			
		||||
                  "cxx": "clang++-14",
 | 
			
		||||
                  "compiler_version": 14,
 | 
			
		||||
                  "stdlib": "libstdcxx",
 | 
			
		||||
                  "clang_gcc_toolchain": 11,
 | 
			
		||||
                  "configuration": "Debug"
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                  "compiler_id": "clang-16-libstdcxx-gcc13",
 | 
			
		||||
                  "compiler": "clang",
 | 
			
		||||
                  "cc": "clang-16",
 | 
			
		||||
                  "cxx": "clang++-16",
 | 
			
		||||
                  "compiler_version": 16,
 | 
			
		||||
                  "stdlib": "libstdcxx",
 | 
			
		||||
                  "clang_gcc_toolchain": 13,
 | 
			
		||||
                  "configuration": "Debug"
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                  "compiler_id": "clang-17-libcxx",
 | 
			
		||||
                  "compiler": "clang",
 | 
			
		||||
                  "cc": "clang-17",
 | 
			
		||||
                  "cxx": "clang++-17",
 | 
			
		||||
                  "compiler_version": 17,
 | 
			
		||||
                  "stdlib": "libcxx",
 | 
			
		||||
                  "configuration": "Debug"
 | 
			
		||||
              },
 | 
			
		||||
              {
 | 
			
		||||
                  # Clang 18 - testing if it's faster than Clang 17 with libc++
 | 
			
		||||
                  # Requires patching Conan v1 settings.yml to add version 18
 | 
			
		||||
                  "compiler_id": "clang-18-libcxx",
 | 
			
		||||
                  "compiler": "clang",
 | 
			
		||||
                  "cc": "clang-18",
 | 
			
		||||
                  "cxx": "clang++-18",
 | 
			
		||||
                  "compiler_version": 18,
 | 
			
		||||
                  "stdlib": "libcxx",
 | 
			
		||||
                  "configuration": "Debug"
 | 
			
		||||
              }
 | 
			
		||||
          ]
 | 
			
		||||
          
 | 
			
		||||
          # Minimal matrix for PRs and feature branches
 | 
			
		||||
          minimal_matrix = [
 | 
			
		||||
              full_matrix[1],  # gcc-13 (middle-ground gcc)
 | 
			
		||||
              full_matrix[2]   # clang-14 (mature, stable clang)
 | 
			
		||||
          ]
 | 
			
		||||
          
 | 
			
		||||
          # Determine which matrix to use based on the target branch
 | 
			
		||||
          ref = "${{ github.ref }}"
 | 
			
		||||
          base_ref = "${{ github.base_ref }}"  # For PRs, this is the target branch
 | 
			
		||||
          event_name = "${{ github.event_name }}"
 | 
			
		||||
          commit_message = """${{ github.event.head_commit.message }}"""
 | 
			
		||||
          pr_title = """${{ github.event.pull_request.title }}"""
 | 
			
		||||
          
 | 
			
		||||
          # Debug logging
 | 
			
		||||
          print(f"Event: {event_name}")
 | 
			
		||||
          print(f"Ref: {ref}")
 | 
			
		||||
          print(f"Base ref: {base_ref}")
 | 
			
		||||
          print(f"PR title: {pr_title}")
 | 
			
		||||
          print(f"Commit message: {commit_message}")
 | 
			
		||||
          
 | 
			
		||||
          # Check for override tags in commit message or PR title
 | 
			
		||||
          force_full = "[ci-nix-full-matrix]" in commit_message or "[ci-nix-full-matrix]" in pr_title
 | 
			
		||||
          print(f"Force full matrix: {force_full}")
 | 
			
		||||
          
 | 
			
		||||
          # Check if this is targeting a main branch
 | 
			
		||||
          # For PRs: check base_ref (target branch)
 | 
			
		||||
          # For pushes: check ref (current branch)
 | 
			
		||||
          main_branches = ["refs/heads/dev", "refs/heads/release", "refs/heads/candidate"]
 | 
			
		||||
          
 | 
			
		||||
          if force_full:
 | 
			
		||||
              # Override: always use full matrix if tag is present
 | 
			
		||||
              use_full = True
 | 
			
		||||
          elif event_name == "pull_request":
 | 
			
		||||
              # For PRs, base_ref is just the branch name (e.g., "dev", not "refs/heads/dev")
 | 
			
		||||
              # Check if the PR targets release or candidate (more critical branches)
 | 
			
		||||
              use_full = base_ref in ["release", "candidate"]
 | 
			
		||||
          else:
 | 
			
		||||
              # For pushes, ref is the full reference (e.g., "refs/heads/dev")
 | 
			
		||||
              use_full = ref in main_branches
 | 
			
		||||
          
 | 
			
		||||
          # Select the appropriate matrix
 | 
			
		||||
          if use_full:
 | 
			
		||||
              if force_full:
 | 
			
		||||
                  print(f"Using FULL matrix (6 configs) - forced by [ci-nix-full-matrix] tag")
 | 
			
		||||
              else:
 | 
			
		||||
                  print(f"Using FULL matrix (6 configs) - targeting main branch")
 | 
			
		||||
              matrix = full_matrix
 | 
			
		||||
          else:
 | 
			
		||||
              print(f"Using MINIMAL matrix (2 configs) - feature branch/PR")
 | 
			
		||||
              matrix = minimal_matrix
 | 
			
		||||
          
 | 
			
		||||
          # Output the matrix as JSON
 | 
			
		||||
          output = json.dumps({"include": matrix})
 | 
			
		||||
          with open(os.environ['GITHUB_OUTPUT'], 'a') as f:
 | 
			
		||||
              f.write(f"matrix={output}\n")
 | 
			
		||||
 | 
			
		||||
  build:
 | 
			
		||||
    needs: matrix-setup
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
    outputs:
 | 
			
		||||
      artifact_name: ${{ steps.set-artifact-name.outputs.artifact_name }}
 | 
			
		||||
    strategy:
 | 
			
		||||
      fail-fast: false
 | 
			
		||||
      matrix:
 | 
			
		||||
        compiler: [gcc]
 | 
			
		||||
        configuration: [Debug]
 | 
			
		||||
        include:
 | 
			
		||||
          - compiler: gcc
 | 
			
		||||
            cc: gcc-11
 | 
			
		||||
            cxx: g++-11
 | 
			
		||||
            compiler_id: gcc-11
 | 
			
		||||
      matrix: ${{ fromJSON(needs.matrix-setup.outputs.matrix) }}
 | 
			
		||||
    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
 | 
			
		||||
@@ -38,8 +166,70 @@ jobs:
 | 
			
		||||
        run: |
 | 
			
		||||
          sudo apt-get update
 | 
			
		||||
          sudo apt-get install -y ninja-build ${{ matrix.cc }} ${{ matrix.cxx }} ccache
 | 
			
		||||
          # Install specific Conan version needed
 | 
			
		||||
          pip install --upgrade "conan<2"
 | 
			
		||||
 | 
			
		||||
          # Install the specific GCC version needed for Clang
 | 
			
		||||
          if [ -n "${{ matrix.clang_gcc_toolchain }}" ]; then
 | 
			
		||||
            echo "=== Installing GCC ${{ matrix.clang_gcc_toolchain }} for Clang ==="
 | 
			
		||||
            sudo apt-get install -y gcc-${{ matrix.clang_gcc_toolchain }} g++-${{ matrix.clang_gcc_toolchain }} libstdc++-${{ matrix.clang_gcc_toolchain }}-dev
 | 
			
		||||
 | 
			
		||||
            echo "=== GCC versions available after installation ==="
 | 
			
		||||
            ls -la /usr/lib/gcc/x86_64-linux-gnu/ | grep -E "^d"
 | 
			
		||||
          fi
 | 
			
		||||
 | 
			
		||||
          # For Clang < 16 with --gcc-toolchain, hide newer GCC versions
 | 
			
		||||
          # This is needed because --gcc-toolchain still picks the highest version
 | 
			
		||||
          #
 | 
			
		||||
          # THE GREAT GCC HIDING TRICK (for Clang < 16):
 | 
			
		||||
          # Clang versions before 16 don't have --gcc-install-dir, only --gcc-toolchain
 | 
			
		||||
          # which is deprecated and still uses discovery heuristics that ALWAYS pick
 | 
			
		||||
          # the highest version number. So we play a sneaky game...
 | 
			
		||||
          #
 | 
			
		||||
          # We rename newer GCC versions to very low integers (1, 2, 3...) which makes
 | 
			
		||||
          # Clang think they're ancient GCC versions. Since 11 > 3 > 2 > 1, Clang will
 | 
			
		||||
          # pick GCC 11 over our renamed versions. It's dumb but it works!
 | 
			
		||||
          #
 | 
			
		||||
          # Example: GCC 12→1, GCC 13→2, GCC 14→3, so Clang picks 11 (highest number)
 | 
			
		||||
          if [ -n "${{ matrix.clang_gcc_toolchain }}" ] && [ "${{ matrix.compiler_version }}" -lt "16" ]; then
 | 
			
		||||
            echo "=== Hiding GCC versions newer than ${{ matrix.clang_gcc_toolchain }} for Clang < 16 ==="
 | 
			
		||||
            target_version=${{ matrix.clang_gcc_toolchain }}
 | 
			
		||||
            counter=1  # Start with 1 - these will be seen as "GCC version 1, 2, 3" etc
 | 
			
		||||
            for dir in /usr/lib/gcc/x86_64-linux-gnu/*/; do
 | 
			
		||||
              if [ -d "$dir" ]; then
 | 
			
		||||
                version=$(basename "$dir")
 | 
			
		||||
                # Check if version is numeric and greater than target
 | 
			
		||||
                if [[ "$version" =~ ^[0-9]+$ ]] && [ "$version" -gt "$target_version" ]; then
 | 
			
		||||
                  echo "Hiding GCC $version -> renaming to $counter (will be seen as GCC version $counter)"
 | 
			
		||||
                  # Safety check: ensure target doesn't already exist
 | 
			
		||||
                  if [ ! -e "/usr/lib/gcc/x86_64-linux-gnu/$counter" ]; then
 | 
			
		||||
                    sudo mv "$dir" "/usr/lib/gcc/x86_64-linux-gnu/$counter"
 | 
			
		||||
                  else
 | 
			
		||||
                    echo "ERROR: Cannot rename GCC $version - /usr/lib/gcc/x86_64-linux-gnu/$counter already exists"
 | 
			
		||||
                    exit 1
 | 
			
		||||
                  fi
 | 
			
		||||
                  counter=$((counter + 1))
 | 
			
		||||
                fi
 | 
			
		||||
              fi
 | 
			
		||||
            done
 | 
			
		||||
          fi
 | 
			
		||||
 | 
			
		||||
          # Verify what Clang will use
 | 
			
		||||
          if [ -n "${{ matrix.clang_gcc_toolchain }}" ]; then
 | 
			
		||||
            echo "=== Verifying GCC toolchain selection ==="
 | 
			
		||||
            echo "Available GCC versions:"
 | 
			
		||||
            ls -la /usr/lib/gcc/x86_64-linux-gnu/ | grep -E "^d.*[0-9]+$" || true
 | 
			
		||||
 | 
			
		||||
            echo ""
 | 
			
		||||
            echo "Clang's detected GCC installation:"
 | 
			
		||||
            ${{ matrix.cxx }} -v -E -x c++ /dev/null -o /dev/null 2>&1 | grep "Found candidate GCC installation" || true
 | 
			
		||||
          fi
 | 
			
		||||
 | 
			
		||||
          # Install libc++ dev packages if using libc++ (not needed for libstdc++)
 | 
			
		||||
          if [ "${{ matrix.stdlib }}" = "libcxx" ]; then
 | 
			
		||||
            sudo apt-get install -y libc++-${{ matrix.compiler_version }}-dev libc++abi-${{ matrix.compiler_version }}-dev
 | 
			
		||||
          fi
 | 
			
		||||
 | 
			
		||||
          # Install Conan 2
 | 
			
		||||
          pip install --upgrade "conan>=2.0,<3"
 | 
			
		||||
 | 
			
		||||
      - name: Configure ccache
 | 
			
		||||
        uses: ./.github/actions/xahau-configure-ccache
 | 
			
		||||
@@ -47,25 +237,41 @@ jobs:
 | 
			
		||||
          max_size: 2G
 | 
			
		||||
          hash_dir: true
 | 
			
		||||
          compiler_check: content
 | 
			
		||||
          is_main_branch: ${{ github.ref_name == env.MAIN_BRANCH_NAME }}
 | 
			
		||||
 | 
			
		||||
      - name: Configure Conan
 | 
			
		||||
        run: |
 | 
			
		||||
          conan profile new default --detect || true # Ignore error if profile exists
 | 
			
		||||
          conan profile update settings.compiler.cppstd=20 default
 | 
			
		||||
          conan profile update settings.compiler=${{ matrix.compiler }} default
 | 
			
		||||
          conan profile update settings.compiler.libcxx=libstdc++11 default
 | 
			
		||||
          conan profile update env.CC=/usr/bin/${{ matrix.cc }} default
 | 
			
		||||
          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
 | 
			
		||||
          # Create the default profile directory if it doesn't exist
 | 
			
		||||
          mkdir -p ~/.conan2/profiles
 | 
			
		||||
 | 
			
		||||
          # 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
 | 
			
		||||
          # Determine the correct libcxx based on stdlib parameter
 | 
			
		||||
          if [ "${{ matrix.stdlib }}" = "libcxx" ]; then
 | 
			
		||||
            LIBCXX="libc++"
 | 
			
		||||
          else
 | 
			
		||||
            LIBCXX="libstdc++11"
 | 
			
		||||
          fi
 | 
			
		||||
 | 
			
		||||
          # Create profile with our specific settings
 | 
			
		||||
          cat > ~/.conan2/profiles/default <<EOF
 | 
			
		||||
          [settings]
 | 
			
		||||
          arch=x86_64
 | 
			
		||||
          build_type=${{ matrix.configuration }}
 | 
			
		||||
          compiler=${{ matrix.compiler }}
 | 
			
		||||
          compiler.cppstd=20
 | 
			
		||||
          compiler.libcxx=${LIBCXX}
 | 
			
		||||
          compiler.version=${{ matrix.compiler_version }}
 | 
			
		||||
          os=Linux
 | 
			
		||||
 | 
			
		||||
          [buildenv]
 | 
			
		||||
          CC=/usr/bin/${{ matrix.cc }}
 | 
			
		||||
          CXX=/usr/bin/${{ matrix.cxx }}
 | 
			
		||||
 | 
			
		||||
          [conf]
 | 
			
		||||
          tools.build:compiler_executables={"c": "/usr/bin/${{ matrix.cc }}", "cpp": "/usr/bin/${{ matrix.cxx }}"}
 | 
			
		||||
          EOF
 | 
			
		||||
 | 
			
		||||
          # Display profile for verification
 | 
			
		||||
          conan profile show default
 | 
			
		||||
          conan profile show
 | 
			
		||||
 | 
			
		||||
      - name: Check environment
 | 
			
		||||
        run: |
 | 
			
		||||
@@ -87,6 +293,7 @@ jobs:
 | 
			
		||||
          compiler-id: ${{ matrix.compiler_id }}
 | 
			
		||||
          cache_version: ${{ env.CACHE_VERSION }}
 | 
			
		||||
          main_branch: ${{ env.MAIN_BRANCH_NAME }}
 | 
			
		||||
          stdlib: ${{ matrix.stdlib }}
 | 
			
		||||
 | 
			
		||||
      - name: Build
 | 
			
		||||
        uses: ./.github/actions/xahau-ga-build
 | 
			
		||||
@@ -99,6 +306,8 @@ jobs:
 | 
			
		||||
          compiler-id: ${{ matrix.compiler_id }}
 | 
			
		||||
          cache_version: ${{ env.CACHE_VERSION }}
 | 
			
		||||
          main_branch: ${{ env.MAIN_BRANCH_NAME }}
 | 
			
		||||
          stdlib: ${{ matrix.stdlib }}
 | 
			
		||||
          clang_gcc_toolchain: ${{ matrix.clang_gcc_toolchain || '' }}
 | 
			
		||||
 | 
			
		||||
      - name: Set artifact name
 | 
			
		||||
        id: set-artifact-name
 | 
			
		||||
@@ -120,4 +329,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
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							@@ -8,6 +8,6 @@
 | 
			
		||||
    "editor.semanticHighlighting.enabled": true,
 | 
			
		||||
    "editor.tabSize": 4,
 | 
			
		||||
    "editor.defaultFormatter": "xaver.clang-format",
 | 
			
		||||
    "editor.formatOnSave": false
 | 
			
		||||
    "editor.formatOnSave": true
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										72
									
								
								BUILD.md
									
									
									
									
									
								
							
							
						
						
									
										72
									
								
								BUILD.md
									
									
									
									
									
								
							@@ -33,7 +33,7 @@ git checkout develop
 | 
			
		||||
## Minimum Requirements
 | 
			
		||||
 | 
			
		||||
- [Python 3.7](https://www.python.org/downloads/)
 | 
			
		||||
- [Conan 1.55](https://conan.io/downloads.html)
 | 
			
		||||
- [Conan 2.x](https://conan.io/downloads)
 | 
			
		||||
- [CMake 3.16](https://cmake.org/download/)
 | 
			
		||||
 | 
			
		||||
`rippled` is written in the C++20 dialect and includes the `<concepts>` header.
 | 
			
		||||
@@ -65,13 +65,24 @@ can't build earlier Boost versions.
 | 
			
		||||
1. (Optional) If you've never used Conan, use autodetect to set up a default profile.
 | 
			
		||||
 | 
			
		||||
   ```
 | 
			
		||||
   conan profile new default --detect
 | 
			
		||||
   conan profile detect --force
 | 
			
		||||
   ```
 | 
			
		||||
 | 
			
		||||
2. Update the compiler settings.
 | 
			
		||||
 | 
			
		||||
   For Conan 2, you can edit the profile directly at `~/.conan2/profiles/default`,
 | 
			
		||||
   or use the Conan CLI. Ensure C++20 is set:
 | 
			
		||||
 | 
			
		||||
   ```
 | 
			
		||||
   conan profile update settings.compiler.cppstd=20 default
 | 
			
		||||
   conan profile show
 | 
			
		||||
   ```
 | 
			
		||||
 | 
			
		||||
   Look for `compiler.cppstd=20` in the output. If it's not set, edit the profile:
 | 
			
		||||
 | 
			
		||||
   ```
 | 
			
		||||
   # Edit ~/.conan2/profiles/default and ensure these settings exist:
 | 
			
		||||
   [settings]
 | 
			
		||||
   compiler.cppstd=20
 | 
			
		||||
   ```
 | 
			
		||||
 | 
			
		||||
   Linux developers will commonly have a default Conan [profile][] that compiles
 | 
			
		||||
@@ -80,7 +91,9 @@ can't build earlier Boost versions.
 | 
			
		||||
   then you will need to choose the `libstdc++11` ABI.
 | 
			
		||||
 | 
			
		||||
   ```
 | 
			
		||||
   conan profile update settings.compiler.libcxx=libstdc++11 default
 | 
			
		||||
   # In ~/.conan2/profiles/default, ensure:
 | 
			
		||||
   [settings]
 | 
			
		||||
   compiler.libcxx=libstdc++11
 | 
			
		||||
   ```
 | 
			
		||||
 | 
			
		||||
   On Windows, you should use the x64 native build tools.
 | 
			
		||||
@@ -91,7 +104,9 @@ can't build earlier Boost versions.
 | 
			
		||||
   architecture.
 | 
			
		||||
 | 
			
		||||
   ```
 | 
			
		||||
   conan profile update settings.arch=x86_64 default
 | 
			
		||||
   # In ~/.conan2/profiles/default, ensure:
 | 
			
		||||
   [settings]
 | 
			
		||||
   arch=x86_64
 | 
			
		||||
   ```
 | 
			
		||||
 | 
			
		||||
3. (Optional) If you have multiple compilers installed on your platform,
 | 
			
		||||
@@ -100,16 +115,18 @@ can't build earlier Boost versions.
 | 
			
		||||
   in the generated CMake toolchain file.
 | 
			
		||||
 | 
			
		||||
   ```
 | 
			
		||||
   conan profile update 'conf.tools.build:compiler_executables={"c": "<path>", "cpp": "<path>"}' default
 | 
			
		||||
   # In ~/.conan2/profiles/default, add under [conf] section:
 | 
			
		||||
   [conf]
 | 
			
		||||
   tools.build:compiler_executables={"c": "<path>", "cpp": "<path>"}
 | 
			
		||||
   ```
 | 
			
		||||
 | 
			
		||||
   It should choose the compiler for dependencies as well,
 | 
			
		||||
   but not all of them have a Conan recipe that respects this setting (yet).
 | 
			
		||||
   For the rest, you can set these environment variables:
 | 
			
		||||
   For setting environment variables for dependencies:
 | 
			
		||||
 | 
			
		||||
   ```
 | 
			
		||||
   conan profile update env.CC=<path> default
 | 
			
		||||
   conan profile update env.CXX=<path> default
 | 
			
		||||
   # In ~/.conan2/profiles/default, add under [buildenv] section:
 | 
			
		||||
   [buildenv]
 | 
			
		||||
   CC=<path>
 | 
			
		||||
   CXX=<path>
 | 
			
		||||
   ```
 | 
			
		||||
 | 
			
		||||
4. Export our [Conan recipe for Snappy](./external/snappy).
 | 
			
		||||
@@ -117,14 +134,20 @@ 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 --version 1.1.10 --user xahaud --channel 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 --version 4.0.3 --user xahaud --channel stable
 | 
			
		||||
   ```
 | 
			
		||||
 | 
			
		||||
6. Export our [Conan recipe for WasmEdge](./external/wasmedge).
 | 
			
		||||
 | 
			
		||||
   ```
 | 
			
		||||
   conan export external/wasmedge --version 0.11.2 --user xahaud --channel stable
 | 
			
		||||
   ```
 | 
			
		||||
 | 
			
		||||
### Build and Test
 | 
			
		||||
@@ -259,23 +282,26 @@ and can be helpful for detecting `#include` omissions.
 | 
			
		||||
If you have trouble building dependencies after changing Conan settings,
 | 
			
		||||
try removing the Conan cache.
 | 
			
		||||
 | 
			
		||||
For Conan 2:
 | 
			
		||||
```
 | 
			
		||||
rm -rf ~/.conan/data
 | 
			
		||||
rm -rf ~/.conan2/p
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Or clear the entire Conan 2 cache:
 | 
			
		||||
```
 | 
			
		||||
conan cache clean "*"
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### no std::result_of
 | 
			
		||||
### macOS compilation with Apple Clang 17+
 | 
			
		||||
 | 
			
		||||
If your compiler version is recent enough to have removed `std::result_of` as
 | 
			
		||||
part of C++20, e.g. Apple Clang 15.0, then you might need to add a preprocessor
 | 
			
		||||
definition to your build.
 | 
			
		||||
If you're on macOS with Apple Clang 17 or newer, you need to add a compiler flag to work around a compilation error in gRPC dependencies.
 | 
			
		||||
 | 
			
		||||
Edit `~/.conan2/profiles/default` and add under the `[conf]` section:
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
conan profile update 'options.boost:extra_b2_flags="define=BOOST_ASIO_HAS_STD_INVOKE_RESULT"' default
 | 
			
		||||
conan profile update 'env.CFLAGS="-DBOOST_ASIO_HAS_STD_INVOKE_RESULT"' default
 | 
			
		||||
conan profile update 'env.CXXFLAGS="-DBOOST_ASIO_HAS_STD_INVOKE_RESULT"' default
 | 
			
		||||
conan profile update 'conf.tools.build:cflags+=["-DBOOST_ASIO_HAS_STD_INVOKE_RESULT"]' default
 | 
			
		||||
conan profile update 'conf.tools.build:cxxflags+=["-DBOOST_ASIO_HAS_STD_INVOKE_RESULT"]' default
 | 
			
		||||
[conf]
 | 
			
		||||
tools.build:cxxflags=["-Wno-missing-template-arg-list-after-template-kw"]
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -50,6 +50,12 @@ target_sources (xrpl_core PRIVATE
 | 
			
		||||
  src/ripple/beast/utility/src/beast_Journal.cpp
 | 
			
		||||
  src/ripple/beast/utility/src/beast_PropertyStream.cpp)
 | 
			
		||||
 | 
			
		||||
# Conditionally add enhanced logging source when BEAST_ENHANCED_LOGGING is enabled
 | 
			
		||||
if(DEFINED BEAST_ENHANCED_LOGGING AND BEAST_ENHANCED_LOGGING)
 | 
			
		||||
  target_sources(xrpl_core PRIVATE
 | 
			
		||||
    src/ripple/beast/utility/src/beast_EnhancedLogging.cpp)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
#[===============================[
 | 
			
		||||
    core sources
 | 
			
		||||
#]===============================]
 | 
			
		||||
@@ -155,6 +161,13 @@ target_link_libraries (xrpl_core
 | 
			
		||||
    ed25519::ed25519
 | 
			
		||||
    date::date
 | 
			
		||||
    Ripple::opts)
 | 
			
		||||
 | 
			
		||||
# Link date-tz library when enhanced logging is enabled
 | 
			
		||||
if(DEFINED BEAST_ENHANCED_LOGGING AND BEAST_ENHANCED_LOGGING)
 | 
			
		||||
  if(TARGET date::date-tz)
 | 
			
		||||
    target_link_libraries(xrpl_core PUBLIC date::date-tz)
 | 
			
		||||
  endif()
 | 
			
		||||
endif()
 | 
			
		||||
#[=================================[
 | 
			
		||||
   main/core headers installation
 | 
			
		||||
#]=================================]
 | 
			
		||||
@@ -444,6 +457,8 @@ target_sources (rippled PRIVATE
 | 
			
		||||
  src/ripple/app/tx/impl/CreateCheck.cpp
 | 
			
		||||
  src/ripple/app/tx/impl/CreateOffer.cpp
 | 
			
		||||
  src/ripple/app/tx/impl/CreateTicket.cpp
 | 
			
		||||
  src/ripple/app/tx/impl/Cron.cpp
 | 
			
		||||
  src/ripple/app/tx/impl/CronSet.cpp
 | 
			
		||||
  src/ripple/app/tx/impl/DeleteAccount.cpp
 | 
			
		||||
  src/ripple/app/tx/impl/DepositPreauth.cpp
 | 
			
		||||
  src/ripple/app/tx/impl/Escrow.cpp
 | 
			
		||||
@@ -548,7 +563,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
 | 
			
		||||
@@ -722,6 +736,7 @@ if (tests)
 | 
			
		||||
    src/test/app/BaseFee_test.cpp
 | 
			
		||||
    src/test/app/Check_test.cpp
 | 
			
		||||
    src/test/app/ClaimReward_test.cpp
 | 
			
		||||
    src/test/app/Cron_test.cpp
 | 
			
		||||
    src/test/app/Clawback_test.cpp
 | 
			
		||||
    src/test/app/CrossingLimits_test.cpp
 | 
			
		||||
    src/test/app/DeliverMin_test.cpp
 | 
			
		||||
@@ -886,6 +901,7 @@ if (tests)
 | 
			
		||||
    src/test/jtx/impl/amount.cpp
 | 
			
		||||
    src/test/jtx/impl/balance.cpp
 | 
			
		||||
    src/test/jtx/impl/check.cpp
 | 
			
		||||
    src/test/jtx/impl/cron.cpp
 | 
			
		||||
    src/test/jtx/impl/delivermin.cpp
 | 
			
		||||
    src/test/jtx/impl/deposit.cpp
 | 
			
		||||
    src/test/jtx/impl/envconfig.cpp
 | 
			
		||||
@@ -949,6 +965,7 @@ if (tests)
 | 
			
		||||
    src/test/nodestore/Basics_test.cpp
 | 
			
		||||
    src/test/nodestore/DatabaseShard_test.cpp
 | 
			
		||||
    src/test/nodestore/Database_test.cpp
 | 
			
		||||
    src/test/nodestore/NuDBFactory_test.cpp
 | 
			
		||||
    src/test/nodestore/Timing_test.cpp
 | 
			
		||||
    src/test/nodestore/import_test.cpp
 | 
			
		||||
    src/test/nodestore/varint_test.cpp
 | 
			
		||||
@@ -995,6 +1012,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
 | 
			
		||||
@@ -1068,6 +1090,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
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										156
									
								
								CMakeLists.txt
									
									
									
									
									
								
							
							
						
						
									
										156
									
								
								CMakeLists.txt
									
									
									
									
									
								
							@@ -33,6 +33,25 @@ if(Git_FOUND)
 | 
			
		||||
    endif()
 | 
			
		||||
endif() #git
 | 
			
		||||
 | 
			
		||||
# make SOURCE_ROOT_PATH define available for logging
 | 
			
		||||
set(SOURCE_ROOT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/src/")
 | 
			
		||||
add_definitions(-DSOURCE_ROOT_PATH="${SOURCE_ROOT_PATH}")
 | 
			
		||||
 | 
			
		||||
# BEAST_ENHANCED_LOGGING option - adds file:line numbers and formatting to logs
 | 
			
		||||
# Default to ON for Debug builds, OFF for Release
 | 
			
		||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
 | 
			
		||||
    option(BEAST_ENHANCED_LOGGING "Include file and line numbers in log messages" ON)
 | 
			
		||||
else()
 | 
			
		||||
    option(BEAST_ENHANCED_LOGGING "Include file and line numbers in log messages" OFF)
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
if(BEAST_ENHANCED_LOGGING)
 | 
			
		||||
    add_definitions(-DBEAST_ENHANCED_LOGGING=1)
 | 
			
		||||
    message(STATUS "Log line numbers enabled")
 | 
			
		||||
else()
 | 
			
		||||
    message(STATUS "Log line numbers disabled")
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
if(thread_safety_analysis)
 | 
			
		||||
  add_compile_options(-Wthread-safety -D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS -DRIPPLE_ENABLE_THREAD_SAFETY_ANNOTATIONS)
 | 
			
		||||
  add_compile_options("-stdlib=libc++")
 | 
			
		||||
@@ -50,11 +69,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)
 | 
			
		||||
@@ -67,9 +81,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)
 | 
			
		||||
@@ -81,86 +93,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
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
###
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -176,10 +176,11 @@ existing maintainer without a vote.
 | 
			
		||||
 | 
			
		||||
## Current Maintainers
 | 
			
		||||
 | 
			
		||||
* [Richard Holland](https://github.com/RichardAH) (XRPL Labs + XRP Ledger Foundation)
 | 
			
		||||
* [Denis Angell](https://github.com/dangell7) (XRPL Labs + XRP Ledger Foundation)
 | 
			
		||||
* [Wietse Wind](https://github.com/WietseWind) (XRPL Labs + XRP Ledger Foundation)
 | 
			
		||||
* [Richard Holland](https://github.com/RichardAH) (XRPL Labs + INFTF)
 | 
			
		||||
* [Denis Angell](https://github.com/dangell7) (XRPL Labs + INFTF)
 | 
			
		||||
* [Wietse Wind](https://github.com/WietseWind) (XRPL Labs + INFTF)
 | 
			
		||||
* [tequ](https://github.com/tequdev) (Independent + INFTF)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[1]: https://docs.github.com/en/get-started/quickstart/contributing-to-projects
 | 
			
		||||
[2]: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/incorporating-changes-from-a-pull-request/about-pull-request-merges#squash-and-merge-your-commits
 | 
			
		||||
[2]: https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/incorporating-changes-from-a-pull-request/about-pull-request-merges#squash-and-merge-your-commits
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
 | 
			
		||||
**Note:** Throughout this README, references to "we" or "our" pertain to the community and contributors involved in the Xahau network. It does not imply a legal entity or a specific collection of individuals.
 | 
			
		||||
 | 
			
		||||
[Xahau](https://xahau.network/) is a decentralized cryptographic ledger that builds upon the robust foundation of the XRP Ledger. It inherits the XRP Ledger's Byzantine Fault Tolerant consensus algorithm and enhances it with additional features and functionalities. Developers and users familiar with the XRP Ledger will find that most documentation and tutorials available on [xrpl.org](https://xrpl.org) are relevant and applicable to Xahau, including those related to running validators and managing validator keys. For Xahau specific documentation you can visit our [documentation](https://docs.xahau.network/)
 | 
			
		||||
[Xahau](https://xahau.network/) is a decentralized cryptographic ledger that builds upon the robust foundation of the XRP Ledger. It inherits the XRP Ledger's Byzantine Fault Tolerant consensus algorithm and enhances it with additional features and functionalities. Developers and users familiar with the XRP Ledger will find that most documentation and tutorials available on [xrpl.org](https://xrpl.org) are relevant and applicable to Xahau, including those related to running validators and managing validator keys. For Xahau specific documentation you can visit our [documentation](https://xahau.network/)
 | 
			
		||||
 | 
			
		||||
## XAH
 | 
			
		||||
XAH is the public, counterparty-free asset native to Xahau and functions primarily as network gas. Transactions submitted to the Xahau network must supply an appropriate amount of XAH, to be burnt by the network as a fee, in order to be successfully included in a validated ledger. In addition, XAH also acts as a bridge currency within the Xahau DEX. XAH is traded on the open-market and is available for anyone to access. Xahau was created in 2023 with a supply of 600 million units of XAH.
 | 
			
		||||
@@ -12,7 +12,7 @@ The server software that powers Xahau is called `xahaud` and is available in thi
 | 
			
		||||
 | 
			
		||||
### Build from Source
 | 
			
		||||
 | 
			
		||||
* [Read the build instructions in our documentation](https://docs.xahau.network/infrastructure/building-xahau)
 | 
			
		||||
* [Read the build instructions in our documentation](https://xahau.network/infrastructure/building-xahau)
 | 
			
		||||
* If you encounter any issues, please [open an issue](https://github.com/xahau/xahaud/issues)
 | 
			
		||||
 | 
			
		||||
## Highlights of Xahau
 | 
			
		||||
@@ -58,7 +58,7 @@ git-subtree. See those directories' README files for more details.
 | 
			
		||||
 | 
			
		||||
- **Documentation**: Documentation for XRPL, Xahau and Hooks.
 | 
			
		||||
  - [Xrpl Documentation](https://xrpl.org)
 | 
			
		||||
  - [Xahau Documentation](https://docs.xahau.network/)
 | 
			
		||||
  - [Xahau Documentation](https://xahau.network/)
 | 
			
		||||
  - [Hooks Technical Documentation](https://xrpl-hooks.readme.io/)
 | 
			
		||||
- **Explorers**: Explore the Xahau ledger using various explorers:
 | 
			
		||||
  - [xahauexplorer.com](https://xahauexplorer.com)
 | 
			
		||||
 
 | 
			
		||||
@@ -5,8 +5,6 @@
 | 
			
		||||
# debugging.
 | 
			
		||||
set -ex
 | 
			
		||||
 | 
			
		||||
set -e
 | 
			
		||||
 | 
			
		||||
echo "START INSIDE CONTAINER - CORE"
 | 
			
		||||
 | 
			
		||||
echo "-- BUILD CORES:       $3"
 | 
			
		||||
@@ -14,6 +12,13 @@ echo "-- GITHUB_REPOSITORY: $1"
 | 
			
		||||
echo "-- GITHUB_SHA:        $2"
 | 
			
		||||
echo "-- GITHUB_RUN_NUMBER: $4"
 | 
			
		||||
 | 
			
		||||
# Use mounted filesystem for temp files to avoid container space limits
 | 
			
		||||
export TMPDIR=/io/tmp
 | 
			
		||||
export TEMP=/io/tmp
 | 
			
		||||
export TMP=/io/tmp
 | 
			
		||||
mkdir -p /io/tmp
 | 
			
		||||
echo "=== Using temp directory: /io/tmp ==="
 | 
			
		||||
 | 
			
		||||
umask 0000;
 | 
			
		||||
 | 
			
		||||
cd /io/ &&
 | 
			
		||||
@@ -27,7 +32,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 +44,40 @@ 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 --version 1.1.10 --user xahaud --channel stable &&
 | 
			
		||||
conan export external/soci --version 4.0.3 --user xahaud --channel stable &&
 | 
			
		||||
conan export external/wasmedge --version 0.11.2 --user xahaud --channel 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 &&
 | 
			
		||||
# Install dependencies - tool_requires in conanfile.py handles glibc 2.28 compatibility
 | 
			
		||||
# for build tools (protoc, grpc plugins, b2) in HBB environment
 | 
			
		||||
# The tool_requires('b2/5.3.2') in conanfile.py should force b2 to build from source
 | 
			
		||||
# with the correct toolchain, avoiding the GLIBCXX_3.4.29 issue
 | 
			
		||||
echo "=== Installing dependencies ===" &&
 | 
			
		||||
conan install .. --output-folder . --build missing --settings build_type=$BUILD_TYPE \
 | 
			
		||||
  -o with_wasmedge=False -o tool_requires_b2=True &&
 | 
			
		||||
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 && echo "=== Re-running final link with verbose output ===" && rm -f rippled && ninja -v rippled &&
 | 
			
		||||
ccache -s &&
 | 
			
		||||
strip -s rippled &&
 | 
			
		||||
mv rippled xahaud &&
 | 
			
		||||
echo "=== Full ldd output ===" &&
 | 
			
		||||
ldd xahaud &&
 | 
			
		||||
echo "=== Running libcheck ===" &&
 | 
			
		||||
libcheck xahaud &&
 | 
			
		||||
echo "Build host: `hostname`" > release.info &&
 | 
			
		||||
echo "Build date: `date`" >> release.info &&
 | 
			
		||||
echo "Build md5: `md5sum xahaud`" >> release.info &&
 | 
			
		||||
@@ -69,8 +102,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;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
#
 | 
			
		||||
# Default validators.txt
 | 
			
		||||
#
 | 
			
		||||
# This file is located in the same folder as your rippled.cfg file
 | 
			
		||||
# This file is located in the same folder as your xahaud.cfg file
 | 
			
		||||
# and defines which validators your server trusts not to collude.
 | 
			
		||||
#
 | 
			
		||||
# This file is UTF-8 with DOS, UNIX, or Mac style line endings.
 | 
			
		||||
@@ -17,18 +17,17 @@
 | 
			
		||||
#   See validator_list_sites and validator_list_keys below.
 | 
			
		||||
#
 | 
			
		||||
#   Examples:
 | 
			
		||||
#    n9KorY8QtTdRx7TVDpwnG9NvyxsDwHUKUEeDLY3AkiGncVaSXZi5
 | 
			
		||||
#    n9MqiExBcoG19UXwoLjBJnhsxEhAZMuWwJDRdkyDz1EkEkwzQTNt
 | 
			
		||||
#    n9L3GdotB8a3AqtsvS7NXt4BUTQSAYyJUr9xtFj2qXJjfbZsawKY
 | 
			
		||||
#    n9M7G6eLwQtUjfCthWUmTN8L4oEZn1sNr46yvKrpsq58K1C6LAxz
 | 
			
		||||
#
 | 
			
		||||
# [validator_list_sites]
 | 
			
		||||
#
 | 
			
		||||
#   List of URIs serving lists of recommended validators.
 | 
			
		||||
#
 | 
			
		||||
#   Examples:
 | 
			
		||||
#    https://vl.ripple.com
 | 
			
		||||
#    https://vl.xrplf.org
 | 
			
		||||
#    https://vl.xahau.org
 | 
			
		||||
#    http://127.0.0.1:8000
 | 
			
		||||
#    file:///etc/opt/ripple/vl.txt
 | 
			
		||||
#    file:///etc/opt/xahaud/vl.txt
 | 
			
		||||
#
 | 
			
		||||
# [validator_list_keys]
 | 
			
		||||
#
 | 
			
		||||
@@ -39,50 +38,48 @@
 | 
			
		||||
#   Validator list keys should be hex-encoded.
 | 
			
		||||
#
 | 
			
		||||
#   Examples:
 | 
			
		||||
#    ED2677ABFFD1B33AC6FBC3062B71F1E8397C1505E1C42C64D11AD1B28FF73F4734
 | 
			
		||||
#    ED307A760EE34F2D0CAA103377B1969117C38B8AA0AA1E2A24DAC1F32FC97087ED
 | 
			
		||||
#    EDA46E9C39B1389894E690E58914DC1029602870370A0993E5B87C4A24EAF4A8E8
 | 
			
		||||
#
 | 
			
		||||
# [import_vl_keys]
 | 
			
		||||
#
 | 
			
		||||
#   This section is used to import the public keys of trusted validator list publishers.
 | 
			
		||||
#   The keys are used to authenticate and accept new lists of trusted validators.
 | 
			
		||||
#   In this example, the key for the publisher "vl.xrplf.org" is imported.
 | 
			
		||||
#   Each key is represented as a hexadecimal string.
 | 
			
		||||
# 
 | 
			
		||||
#   Examples:
 | 
			
		||||
#    ED2677ABFFD1B33AC6FBC3062B71F1E8397C1505E1C42C64D11AD1B28FF73F4734
 | 
			
		||||
#	 ED45D1840EE724BE327ABE9146503D5848EFD5F38B6D5FEDE71E80ACCE5E6E738B
 | 
			
		||||
#	 ED42AEC58B701EEBB77356FFFEC26F83C1F0407263530F068C7C73D392C7E06FD1
 | 
			
		||||
#	 ED2677ABFFD1B33AC6FBC3062B71F1E8397C1505E1C42C64D11AD1B28FF73F4734
 | 
			
		||||
 | 
			
		||||
# The default validator list publishers that the rippled instance
 | 
			
		||||
# The default validator list publishers that the xahaud instance
 | 
			
		||||
# trusts.
 | 
			
		||||
#
 | 
			
		||||
# WARNING: Changing these values can cause your rippled instance to see a
 | 
			
		||||
#          validated ledger that contradicts other rippled instances'
 | 
			
		||||
# WARNING: Changing these values can cause your xahaud instance to see a
 | 
			
		||||
#          validated ledger that contradicts other xahaud instances'
 | 
			
		||||
#          validated ledgers (aka a ledger fork) if your validator list(s)
 | 
			
		||||
#          do not sufficiently overlap with the list(s) used by others.
 | 
			
		||||
#          See: https://arxiv.org/pdf/1802.07242.pdf
 | 
			
		||||
 | 
			
		||||
[validator_list_sites]
 | 
			
		||||
https://vl.ripple.com
 | 
			
		||||
https://vl.xrplf.org
 | 
			
		||||
https://vl.xahau.org
 | 
			
		||||
 | 
			
		||||
[validator_list_keys]
 | 
			
		||||
#vl.ripple.com
 | 
			
		||||
ED2677ABFFD1B33AC6FBC3062B71F1E8397C1505E1C42C64D11AD1B28FF73F4734
 | 
			
		||||
# vl.xrplf.org
 | 
			
		||||
ED45D1840EE724BE327ABE9146503D5848EFD5F38B6D5FEDE71E80ACCE5E6E738B
 | 
			
		||||
# vl.xahau.org
 | 
			
		||||
EDA46E9C39B1389894E690E58914DC1029602870370A0993E5B87C4A24EAF4A8E8
 | 
			
		||||
 | 
			
		||||
[import_vl_keys]
 | 
			
		||||
# vl.xrplf.org
 | 
			
		||||
ED45D1840EE724BE327ABE9146503D5848EFD5F38B6D5FEDE71E80ACCE5E6E738B
 | 
			
		||||
ED42AEC58B701EEBB77356FFFEC26F83C1F0407263530F068C7C73D392C7E06FD1
 | 
			
		||||
ED2677ABFFD1B33AC6FBC3062B71F1E8397C1505E1C42C64D11AD1B28FF73F4734
 | 
			
		||||
 | 
			
		||||
# To use the test network (see https://xrpl.org/connect-your-rippled-to-the-xrp-test-net.html),
 | 
			
		||||
# To use the test network (see https://xahau.network/docs/infrastructure/installing-xahaud),
 | 
			
		||||
# use the following configuration instead:
 | 
			
		||||
#
 | 
			
		||||
# [validator_list_sites]
 | 
			
		||||
# https://vl.altnet.rippletest.net
 | 
			
		||||
#
 | 
			
		||||
# [validator_list_keys]
 | 
			
		||||
# ED264807102805220DA0F312E71FC2C69E1552C9C5790F6C25E3729DEB573D5860
 | 
			
		||||
# [validators]
 | 
			
		||||
# nHBoJCE3wPgkTcrNPMHyTJFQ2t77EyCAqcBRspFCpL6JhwCm94VZ
 | 
			
		||||
# nHUVv4g47bFMySAZFUKVaXUYEmfiUExSoY4FzwXULNwJRzju4XnQ
 | 
			
		||||
# nHBvr8avSFTz4TFxZvvi4rEJZZtyqE3J6KAAcVWVtifsE7edPM7q
 | 
			
		||||
# nHUH3Z8TRU57zetHbEPr1ynyrJhxQCwrJvNjr4j1SMjYADyW1WWe
 | 
			
		||||
#
 | 
			
		||||
# [import_vl_keys]
 | 
			
		||||
# ED264807102805220DA0F312E71FC2C69E1552C9C5790F6C25E3729DEB573D5860
 | 
			
		||||
 
 | 
			
		||||
@@ -9,7 +9,7 @@
 | 
			
		||||
#
 | 
			
		||||
#   2. Peer Protocol
 | 
			
		||||
#
 | 
			
		||||
#   3. Ripple Protocol
 | 
			
		||||
#   3. XRPL Protocol
 | 
			
		||||
#
 | 
			
		||||
#   4. HTTPS Client
 | 
			
		||||
#
 | 
			
		||||
@@ -29,18 +29,17 @@
 | 
			
		||||
#
 | 
			
		||||
# Purpose
 | 
			
		||||
#
 | 
			
		||||
#   This file documents and provides examples of all rippled server process
 | 
			
		||||
#   configuration options. When the rippled server instance is launched, it
 | 
			
		||||
#   This file documents and provides examples of all xahaud server process
 | 
			
		||||
#   configuration options. When the xahaud server instance is launched, it
 | 
			
		||||
#   looks for a file with the following name:
 | 
			
		||||
#
 | 
			
		||||
#     rippled.cfg
 | 
			
		||||
#     xahaud.cfg
 | 
			
		||||
#
 | 
			
		||||
#   For more information on where the rippled server instance searches for the
 | 
			
		||||
#   file, visit:
 | 
			
		||||
#   To run xahaud with a custom configuration file, use the "--conf {file}" flag.
 | 
			
		||||
#   By default, xahaud will look in the local working directory or the home directory.
 | 
			
		||||
#
 | 
			
		||||
#     https://xrpl.org/commandline-usage.html#generic-options
 | 
			
		||||
#
 | 
			
		||||
#   This file should be named rippled.cfg. This file is UTF-8 with DOS, UNIX,
 | 
			
		||||
#   This file should be named xahaud.cfg. This file is UTF-8 with DOS, UNIX,
 | 
			
		||||
#   or Mac style end of lines. Blank lines and lines beginning with '#' are
 | 
			
		||||
#   ignored. Undefined sections are reserved. No escapes are currently defined.
 | 
			
		||||
#
 | 
			
		||||
@@ -89,8 +88,8 @@
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
#   rippled offers various server protocols to clients making inbound
 | 
			
		||||
#   connections. The listening ports rippled uses are "universal" ports
 | 
			
		||||
#   xahaud offers various server protocols to clients making inbound
 | 
			
		||||
#   connections. The listening ports xahaud uses are "universal" ports
 | 
			
		||||
#   which may be configured to handshake in one or more of the available
 | 
			
		||||
#   supported protocols. These universal ports simplify administration:
 | 
			
		||||
#   A single open port can be used for multiple protocols.
 | 
			
		||||
@@ -103,7 +102,7 @@
 | 
			
		||||
#
 | 
			
		||||
#   A list of port names and key/value pairs. A port name must start with a
 | 
			
		||||
#   letter and contain only letters and numbers. The name is not case-sensitive.
 | 
			
		||||
#   For each name in this list, rippled will look for a configuration file
 | 
			
		||||
#   For each name in this list, xahaud will look for a configuration file
 | 
			
		||||
#   section with the same name and use it to create a listening port. The
 | 
			
		||||
#   name is informational only; the choice of name does not affect the function
 | 
			
		||||
#   of the listening port.
 | 
			
		||||
@@ -134,7 +133,7 @@
 | 
			
		||||
#       ip = 127.0.0.1
 | 
			
		||||
#       protocol = http
 | 
			
		||||
#
 | 
			
		||||
#   When rippled is used as a command line client (for example, issuing a
 | 
			
		||||
#   When xahaud is used as a command line client (for example, issuing a
 | 
			
		||||
#   server stop command), the first port advertising the http or https
 | 
			
		||||
#   protocol will be used to make the connection.
 | 
			
		||||
#
 | 
			
		||||
@@ -175,7 +174,7 @@
 | 
			
		||||
#       same time. It is possible have both Websockets and Secure Websockets
 | 
			
		||||
#       together in one port.
 | 
			
		||||
#
 | 
			
		||||
#       NOTE    If no ports support the peer protocol, rippled cannot
 | 
			
		||||
#       NOTE    If no ports support the peer protocol, xahaud cannot
 | 
			
		||||
#               receive incoming peer connections or become a superpeer.
 | 
			
		||||
#
 | 
			
		||||
#   limit = <number>
 | 
			
		||||
@@ -194,7 +193,7 @@
 | 
			
		||||
#       required. IP address restrictions, if any, will be checked in addition
 | 
			
		||||
#       to the credentials specified here.
 | 
			
		||||
#
 | 
			
		||||
#       When acting in the client role, rippled will supply these credentials
 | 
			
		||||
#       When acting in the client role, xahaud will supply these credentials
 | 
			
		||||
#       using HTTP's Basic Authentication headers when making outbound HTTP/S
 | 
			
		||||
#       requests.
 | 
			
		||||
#
 | 
			
		||||
@@ -237,7 +236,7 @@
 | 
			
		||||
#       WS, or WSS protocol interfaces. If administrative commands are
 | 
			
		||||
#       disabled for a port, these credentials have no effect.
 | 
			
		||||
#
 | 
			
		||||
#       When acting in the client role, rippled will supply these credentials
 | 
			
		||||
#       When acting in the client role, xahaud will supply these credentials
 | 
			
		||||
#       in the submitted JSON for any administrative command requests when
 | 
			
		||||
#       invoking JSON-RPC commands on remote servers.
 | 
			
		||||
#
 | 
			
		||||
@@ -258,7 +257,7 @@
 | 
			
		||||
#       resource controls will default to those for non-administrative users.
 | 
			
		||||
#
 | 
			
		||||
#       The secure_gateway IP addresses are intended to represent
 | 
			
		||||
#       proxies. Since rippled trusts these hosts, they must be
 | 
			
		||||
#       proxies. Since xahaud trusts these hosts, they must be
 | 
			
		||||
#       responsible for properly authenticating the remote user.
 | 
			
		||||
#
 | 
			
		||||
#       If some IP addresses are included for both "admin" and
 | 
			
		||||
@@ -272,7 +271,7 @@
 | 
			
		||||
#       Use the specified files when configuring SSL on the port.
 | 
			
		||||
#
 | 
			
		||||
#       NOTE    If no files are specified and secure protocols are selected,
 | 
			
		||||
#               rippled will generate an internal self-signed certificate.
 | 
			
		||||
#               xahaud will generate an internal self-signed certificate.
 | 
			
		||||
#
 | 
			
		||||
#       The files have these meanings:
 | 
			
		||||
#
 | 
			
		||||
@@ -295,12 +294,12 @@
 | 
			
		||||
#       Control the ciphers which the server will support over SSL on the port,
 | 
			
		||||
#       specified using the OpenSSL "cipher list format".
 | 
			
		||||
#
 | 
			
		||||
#       NOTE    If unspecified, rippled will automatically configure a modern
 | 
			
		||||
#       NOTE    If unspecified, xahaud will automatically configure a modern
 | 
			
		||||
#               cipher suite. This default suite should be widely supported.
 | 
			
		||||
#
 | 
			
		||||
#               You should not modify this string unless you have a specific
 | 
			
		||||
#               reason and cryptographic expertise. Incorrect modification may
 | 
			
		||||
#               keep rippled from connecting to other instances of rippled or
 | 
			
		||||
#               keep xahaud from connecting to other instances of xahaud or
 | 
			
		||||
#               prevent RPC and WebSocket clients from connecting.
 | 
			
		||||
#
 | 
			
		||||
#   send_queue_limit = [1..65535]
 | 
			
		||||
@@ -351,7 +350,7 @@
 | 
			
		||||
#
 | 
			
		||||
#   Examples:
 | 
			
		||||
#     { "command" : "server_info" }
 | 
			
		||||
#     { "command" : "log_level", "partition" : "ripplecalc", "severity" : "trace" }
 | 
			
		||||
#     { "command" : "log_level", "partition" : "xahaudcalc", "severity" : "trace" }
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
@@ -380,16 +379,15 @@
 | 
			
		||||
#-----------------
 | 
			
		||||
#
 | 
			
		||||
#   These settings control security and access attributes of the Peer to Peer
 | 
			
		||||
#   server section of the rippled process. Peer Protocol implements the
 | 
			
		||||
#   Ripple Payment protocol. It is over peer connections that transactions
 | 
			
		||||
#   and validations are passed from to machine to machine, to determine the
 | 
			
		||||
#   contents of validated ledgers.
 | 
			
		||||
#   server section of the xahaud process. It is over peer connections that 
 | 
			
		||||
#   transactions and validations are passed from to machine to machine, to 
 | 
			
		||||
#   determine the contents of validated ledgers.
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
# [ips]
 | 
			
		||||
#
 | 
			
		||||
#   List of hostnames or ips where the Ripple protocol is served.  A default
 | 
			
		||||
#   List of hostnames or ips where the XRPL protocol is served.  A default
 | 
			
		||||
#   starter list is included in the code and used if no other hostnames are
 | 
			
		||||
#   available.
 | 
			
		||||
#
 | 
			
		||||
@@ -398,24 +396,23 @@
 | 
			
		||||
#   does not generally matter.
 | 
			
		||||
#
 | 
			
		||||
#   The default list of entries is:
 | 
			
		||||
#     - r.ripple.com 51235
 | 
			
		||||
#     - zaphod.alloy.ee 51235
 | 
			
		||||
#     - sahyadri.isrdc.in 51235
 | 
			
		||||
#     - hubs.xahau.as16089.net 21337
 | 
			
		||||
#     - bacab.alloy.ee 21337
 | 
			
		||||
#
 | 
			
		||||
#   Examples:
 | 
			
		||||
#
 | 
			
		||||
#   [ips]
 | 
			
		||||
#   192.168.0.1
 | 
			
		||||
#   192.168.0.1 2459
 | 
			
		||||
#   r.ripple.com 51235
 | 
			
		||||
#   192.168.0.1 21337
 | 
			
		||||
#   bacab.alloy.ee 21337
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
# [ips_fixed]
 | 
			
		||||
#
 | 
			
		||||
#   List of IP addresses or hostnames to which rippled should always attempt to
 | 
			
		||||
#   List of IP addresses or hostnames to which xahaud should always attempt to
 | 
			
		||||
#   maintain peer connections with. This is useful for manually forming private
 | 
			
		||||
#   networks, for example to configure a validation server that connects to the
 | 
			
		||||
#   Ripple network through a public-facing server, or for building a set
 | 
			
		||||
#   Xahau Network through a public-facing server, or for building a set
 | 
			
		||||
#   of cluster peers.
 | 
			
		||||
#
 | 
			
		||||
#   One address or domain names per line is allowed. A port must be specified
 | 
			
		||||
@@ -465,7 +462,7 @@
 | 
			
		||||
#
 | 
			
		||||
#   IP address or domain of NTP servers to use for time synchronization.
 | 
			
		||||
#
 | 
			
		||||
#   These NTP servers are suitable for rippled servers located in the United
 | 
			
		||||
#   These NTP servers are suitable for xahaud servers located in the United
 | 
			
		||||
#   States:
 | 
			
		||||
#      time.windows.com
 | 
			
		||||
#      time.apple.com
 | 
			
		||||
@@ -566,7 +563,7 @@
 | 
			
		||||
#
 | 
			
		||||
#   minimum_txn_in_ledger_standalone = <number>
 | 
			
		||||
#
 | 
			
		||||
#       Like minimum_txn_in_ledger when rippled is running in standalone
 | 
			
		||||
#       Like minimum_txn_in_ledger when xahaud is running in standalone
 | 
			
		||||
#       mode. Default: 1000.
 | 
			
		||||
#
 | 
			
		||||
#   target_txn_in_ledger = <number>
 | 
			
		||||
@@ -703,7 +700,7 @@
 | 
			
		||||
#
 | 
			
		||||
# [validator_token]
 | 
			
		||||
#
 | 
			
		||||
#   This is an alternative to [validation_seed] that allows rippled to perform
 | 
			
		||||
#   This is an alternative to [validation_seed] that allows xahaud to perform
 | 
			
		||||
#   validation without having to store the validator keys on the network
 | 
			
		||||
#   connected server. The field should contain a single token in the form of a
 | 
			
		||||
#   base64-encoded blob.
 | 
			
		||||
@@ -738,19 +735,18 @@
 | 
			
		||||
#
 | 
			
		||||
#   Specify the file by its name or path.
 | 
			
		||||
#   Unless an absolute path is specified, it will be considered relative to
 | 
			
		||||
#   the folder in which the rippled.cfg file is located.
 | 
			
		||||
#   the folder in which the xahaud.cfg file is located.
 | 
			
		||||
#
 | 
			
		||||
#   Examples:
 | 
			
		||||
#    /home/ripple/validators.txt
 | 
			
		||||
#    C:/home/ripple/validators.txt
 | 
			
		||||
#    /home/xahaud/validators.txt
 | 
			
		||||
#    C:/home/xahaud/validators.txt
 | 
			
		||||
#
 | 
			
		||||
#   Example content:
 | 
			
		||||
#    [validators]
 | 
			
		||||
#    n949f75evCHwgyP4fPVgaHqNHxUVN15PsJEZ3B3HnXPcPjcZAoy7
 | 
			
		||||
#    n9MD5h24qrQqiyBC8aeqqCWvpiBiYQ3jxSr91uiDvmrkyHRdYLUj
 | 
			
		||||
#    n9L81uNCaPgtUJfaHh89gmdvXKAmSt5Gdsw2g1iPWaPkAHW5Nm4C
 | 
			
		||||
#    n9KiYM9CgngLvtRCQHZwgC2gjpdaZcCcbt3VboxiNFcKuwFVujzS
 | 
			
		||||
#    n9LdgEtkmGB9E2h3K4Vp7iGUaKuq23Zr32ehxiU8FWY7xoxbWTSA
 | 
			
		||||
#    n9L3GdotB8a3AqtsvS7NXt4BUTQSAYyJUr9xtFj2qXJjfbZsawKY
 | 
			
		||||
#    n9LQDHLWyFuAn5BXJuW2ow5J9uGqpmSjRYS2cFRpxf6uJbxwDzvM
 | 
			
		||||
#    n9MCWyKVUkiatXVJTKUrAESB5kBFP8R3hm43jGHtg8WBnjv3iDfb
 | 
			
		||||
#    n9KWXCLRhjpajuZtULTXsy6R5xbisA6ozGxM4zdEJFq6uHiFZDvW
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
@@ -833,7 +829,7 @@
 | 
			
		||||
#
 | 
			
		||||
#   0: Disable the ledger replay feature [default]
 | 
			
		||||
#   1: Enable the ledger replay feature. With this feature enabled, when
 | 
			
		||||
#      acquiring a ledger from the network, a rippled node only downloads
 | 
			
		||||
#      acquiring a ledger from the network, a xahaud node only downloads
 | 
			
		||||
#      the ledger header and the transactions instead of the whole ledger.
 | 
			
		||||
#      And the ledger is built by applying the transactions to the parent
 | 
			
		||||
#      ledger.
 | 
			
		||||
@@ -844,10 +840,9 @@
 | 
			
		||||
#
 | 
			
		||||
#----------------
 | 
			
		||||
#
 | 
			
		||||
#   The rippled server instance uses HTTPS GET requests in a variety of
 | 
			
		||||
#   The xahaud server instance uses HTTPS GET requests in a variety of
 | 
			
		||||
#   circumstances, including but not limited to contacting trusted domains to
 | 
			
		||||
#   fetch information such as mapping an email address to a Ripple Payment
 | 
			
		||||
#   Network address.
 | 
			
		||||
#   fetch information such as mapping an email address to a user's r address.
 | 
			
		||||
#
 | 
			
		||||
# [ssl_verify]
 | 
			
		||||
#
 | 
			
		||||
@@ -884,15 +879,15 @@
 | 
			
		||||
#
 | 
			
		||||
#------------
 | 
			
		||||
#
 | 
			
		||||
#   rippled has an optional operating mode called Reporting Mode. In Reporting
 | 
			
		||||
#   Mode, rippled does not connect to the peer to peer network. Instead, rippled
 | 
			
		||||
#   will continuously extract data from one or more rippled servers that are
 | 
			
		||||
#   xahaud has an optional operating mode called Reporting Mode. In Reporting
 | 
			
		||||
#   Mode, xahaud does not connect to the peer to peer network. Instead, xahaud 
 | 
			
		||||
#   will continuously extract data from one or more xahaud servers that are
 | 
			
		||||
#   connected to the peer to peer network (referred to as an ETL source).
 | 
			
		||||
#   Reporting mode servers will forward RPC requests that require access to the
 | 
			
		||||
#   peer to peer network (submit, fee, etc) to an ETL source.
 | 
			
		||||
#
 | 
			
		||||
#   [reporting]  Settings for Reporting Mode. If and only if this section is
 | 
			
		||||
#                present, rippled will start in reporting mode. This section
 | 
			
		||||
#                present, xahaud will start in reporting mode. This section
 | 
			
		||||
#                contains a list of ETL source names, and key-value pairs. The
 | 
			
		||||
#                ETL source names each correspond to a configuration file
 | 
			
		||||
#                section; the names must match exactly. The key-value pairs are
 | 
			
		||||
@@ -997,16 +992,16 @@
 | 
			
		||||
#
 | 
			
		||||
#------------
 | 
			
		||||
#
 | 
			
		||||
#   rippled creates 4 SQLite database to hold bookkeeping information
 | 
			
		||||
#   xahaud creates 4 SQLite database to hold bookkeeping information
 | 
			
		||||
#   about transactions, local credentials, and various other things.
 | 
			
		||||
#   It also creates the NodeDB, which holds all the objects that
 | 
			
		||||
#   make up the current and historical ledgers. In Reporting Mode, rippled
 | 
			
		||||
#   make up the current and historical ledgers. In Reporting Mode, xahauad 
 | 
			
		||||
#   uses a Postgres database instead of SQLite.
 | 
			
		||||
#
 | 
			
		||||
#   The simplest way to work with Postgres is to install it locally.
 | 
			
		||||
#   When it is running, execute the initdb.sh script in the current
 | 
			
		||||
#   directory as: sudo -u postgres ./initdb.sh
 | 
			
		||||
#   This will create the rippled user and an empty database of the same name.
 | 
			
		||||
#   This will create the xahaud user and an empty database of the same name.
 | 
			
		||||
#
 | 
			
		||||
#   The size of the NodeDB grows in proportion to the amount of new data and the
 | 
			
		||||
#   amount of historical data (a configurable setting) so the performance of the
 | 
			
		||||
@@ -1014,7 +1009,7 @@
 | 
			
		||||
#   the performance of the server.
 | 
			
		||||
#
 | 
			
		||||
#   Partial pathnames will be considered relative to the location of
 | 
			
		||||
#   the rippled.cfg file.
 | 
			
		||||
#   the xahaud.cfg file.
 | 
			
		||||
#
 | 
			
		||||
#   [node_db]               Settings for the Node Database (required)
 | 
			
		||||
#
 | 
			
		||||
@@ -1025,18 +1020,18 @@
 | 
			
		||||
#
 | 
			
		||||
#   Example:
 | 
			
		||||
#       type=nudb
 | 
			
		||||
#       path=db/nudb
 | 
			
		||||
#       path=/opt/xahaud/db/nudb
 | 
			
		||||
#
 | 
			
		||||
#   The "type" field must be present and controls the choice of backend:
 | 
			
		||||
#
 | 
			
		||||
#   type = NuDB
 | 
			
		||||
#
 | 
			
		||||
#       NuDB is a high-performance database written by Ripple Labs and optimized
 | 
			
		||||
#       for rippled and solid-state drives.
 | 
			
		||||
#       for and solid-state drives.
 | 
			
		||||
#
 | 
			
		||||
#       NuDB maintains its high speed regardless of the amount of history
 | 
			
		||||
#       stored. Online delete may be selected, but is not required. NuDB is
 | 
			
		||||
#       available on all platforms that rippled runs on.
 | 
			
		||||
#       available on all platforms that xahaud runs on.
 | 
			
		||||
#
 | 
			
		||||
#   type = RocksDB
 | 
			
		||||
#
 | 
			
		||||
@@ -1063,14 +1058,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,9 +1107,19 @@
 | 
			
		||||
#                           if sufficient IOPS capacity is available.
 | 
			
		||||
#                           Default 0.
 | 
			
		||||
#
 | 
			
		||||
#   Optional keys for NuDB or RocksDB:
 | 
			
		||||
#   online_delete for RWDB, NuDB and RocksDB:
 | 
			
		||||
#
 | 
			
		||||
#       earliest_seq        The default is 32570 to match the XRP ledger
 | 
			
		||||
#       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's
 | 
			
		||||
#                           network's earliest allowed sequence. Alternate
 | 
			
		||||
#                           networks may set this value. Minimum value of 1.
 | 
			
		||||
#                           If a [shard_db] section is defined, and this
 | 
			
		||||
@@ -1120,12 +1127,40 @@
 | 
			
		||||
#                           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.
 | 
			
		||||
#   Optional keys for NuDB only:
 | 
			
		||||
#
 | 
			
		||||
#       nudb_block_size     EXPERIMENTAL: Block size in bytes for NuDB storage.
 | 
			
		||||
#                           Must be a power of 2 between 4096 and 32768. Default is 4096.
 | 
			
		||||
#
 | 
			
		||||
#                           This parameter controls the fundamental storage unit
 | 
			
		||||
#                           size for NuDB's internal data structures. The choice
 | 
			
		||||
#                           of block size can significantly impact performance
 | 
			
		||||
#                           depending on your storage hardware and filesystem:
 | 
			
		||||
#
 | 
			
		||||
#                           - 4096 bytes: Optimal for most standard SSDs and
 | 
			
		||||
#                             traditional filesystems (ext4, NTFS, HFS+).
 | 
			
		||||
#                             Provides good balance of performance and storage
 | 
			
		||||
#                             efficiency. Recommended for most deployments.
 | 
			
		||||
#
 | 
			
		||||
#                           - 8192-16384 bytes: May improve performance on
 | 
			
		||||
#                             high-end NVMe SSDs and copy-on-write filesystems
 | 
			
		||||
#                             like ZFS or Btrfs that benefit from larger block
 | 
			
		||||
#                             alignment. Can reduce metadata overhead for large
 | 
			
		||||
#                             databases.
 | 
			
		||||
#
 | 
			
		||||
#                           - 32768 bytes (32K): Maximum supported block size
 | 
			
		||||
#                             for high-performance scenarios with very fast
 | 
			
		||||
#                             storage. May increase memory usage and reduce
 | 
			
		||||
#                             efficiency for smaller databases.
 | 
			
		||||
#
 | 
			
		||||
#                           Note: This setting cannot be changed after database
 | 
			
		||||
#                           creation without rebuilding the entire database.
 | 
			
		||||
#                           Choose carefully based on your hardware and expected
 | 
			
		||||
#                           database size.
 | 
			
		||||
#
 | 
			
		||||
#                           Example: nudb_block_size=4096
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
#       These keys modify the behavior of online_delete, and thus are only
 | 
			
		||||
#       relevant if online_delete is defined and non-zero:
 | 
			
		||||
#
 | 
			
		||||
@@ -1159,7 +1194,7 @@
 | 
			
		||||
#
 | 
			
		||||
#       recovery_wait_seconds
 | 
			
		||||
#                           The online delete process checks periodically
 | 
			
		||||
#                           that rippled is still in sync with the network,
 | 
			
		||||
#                           that xahaud is still in sync with the network,
 | 
			
		||||
#                           and that the validated ledger is less than
 | 
			
		||||
#                           'age_threshold_seconds' old. If not, then continue
 | 
			
		||||
#                           sleeping for this number of seconds and 
 | 
			
		||||
@@ -1198,8 +1233,8 @@
 | 
			
		||||
#   The server creates and maintains 4 to 5 bookkeeping SQLite databases in
 | 
			
		||||
#   the 'database_path' location. If you omit this configuration setting,
 | 
			
		||||
#   the server creates a directory called "db" located in the same place as
 | 
			
		||||
#   your rippled.cfg file.
 | 
			
		||||
#   Partial pathnames are relative to the location of the rippled executable.
 | 
			
		||||
#   your xahaud.cfg file.
 | 
			
		||||
#   Partial pathnames are relative to the location of the xahaud executable.
 | 
			
		||||
#
 | 
			
		||||
#   [shard_db]      Settings for the Shard Database (optional)
 | 
			
		||||
#
 | 
			
		||||
@@ -1275,7 +1310,7 @@
 | 
			
		||||
#                           The default is "wal", which uses a write-ahead
 | 
			
		||||
#                           log to implement database transactions.
 | 
			
		||||
#                           Alternately, "memory" saves disk I/O, but if
 | 
			
		||||
#                           rippled crashes during a transaction, the
 | 
			
		||||
#                           xahaud crashes during a transaction, the
 | 
			
		||||
#                           database is likely to be corrupted.
 | 
			
		||||
#                           See https://www.sqlite.org/pragma.html#pragma_journal_mode
 | 
			
		||||
#                           for more details about the available options.
 | 
			
		||||
@@ -1285,7 +1320,7 @@
 | 
			
		||||
#       synchronous         Valid values: off, normal, full, extra
 | 
			
		||||
#                           The default is "normal", which works well with
 | 
			
		||||
#                           the "wal" journal mode. Alternatively, "off"
 | 
			
		||||
#                           allows rippled to continue as soon as data is
 | 
			
		||||
#                           allows xahaud to continue as soon as data is
 | 
			
		||||
#                           passed to the OS, which can significantly
 | 
			
		||||
#                           increase speed, but risks data corruption if
 | 
			
		||||
#                           the host computer crashes before writing that
 | 
			
		||||
@@ -1299,7 +1334,7 @@
 | 
			
		||||
#                           The default is "file", which will use files
 | 
			
		||||
#                           for temporary database tables and indices.
 | 
			
		||||
#                           Alternatively, "memory" may save I/O, but
 | 
			
		||||
#                           rippled does not currently use many, if any,
 | 
			
		||||
#                           xahaud does not currently use many, if any,
 | 
			
		||||
#                           of these temporary objects.
 | 
			
		||||
#                           See https://www.sqlite.org/pragma.html#pragma_temp_store
 | 
			
		||||
#                           for more details about the available options.
 | 
			
		||||
@@ -1311,9 +1346,9 @@
 | 
			
		||||
#      conninfo             Info for connecting to Postgres. Format is
 | 
			
		||||
#                           postgres://[username]:[password]@[ip]/[database].
 | 
			
		||||
#                           The database and user must already exist. If this
 | 
			
		||||
#                           section is missing and rippled is running in
 | 
			
		||||
#                           Reporting Mode, rippled will connect as the
 | 
			
		||||
#                           user running rippled to a database with the
 | 
			
		||||
#                           section is missing and xahaud is running in
 | 
			
		||||
#                           Reporting Mode, xahaud will connect as the
 | 
			
		||||
#                           user running xahaud to a database with the
 | 
			
		||||
#                           same name. On Linux and Mac OS X, the connection
 | 
			
		||||
#                           will take place using the server's UNIX domain
 | 
			
		||||
#                           socket. On Windows, through the localhost IP
 | 
			
		||||
@@ -1322,7 +1357,7 @@
 | 
			
		||||
#      use_tx_tables        Valid values: 1, 0
 | 
			
		||||
#                           The default is 1 (true). Determines whether to use
 | 
			
		||||
#                           the SQLite transaction database. If set to 0,
 | 
			
		||||
#                           rippled will not write to the transaction database,
 | 
			
		||||
#                           xahaud will not write to the transaction database,
 | 
			
		||||
#                           and will reject tx, account_tx and tx_history RPCs.
 | 
			
		||||
#                           In Reporting Mode, this setting is ignored.
 | 
			
		||||
#
 | 
			
		||||
@@ -1350,7 +1385,7 @@
 | 
			
		||||
#
 | 
			
		||||
#   These settings are designed to help server administrators diagnose
 | 
			
		||||
#   problems, and obtain detailed information about the activities being
 | 
			
		||||
#   performed by the rippled process.
 | 
			
		||||
#   performed by the xahaud process.
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
@@ -1367,7 +1402,7 @@
 | 
			
		||||
#
 | 
			
		||||
#   Configuration parameters for the Beast. Insight stats collection module.
 | 
			
		||||
#
 | 
			
		||||
#   Insight is a module that collects information from the areas of rippled
 | 
			
		||||
#   Insight is a module that collects information from the areas of xahaud 
 | 
			
		||||
#   that have instrumentation. The configuration parameters control where the
 | 
			
		||||
#   collection metrics are sent. The parameters are expressed as key = value
 | 
			
		||||
#   pairs with no white space. The main parameter is the choice of server:
 | 
			
		||||
@@ -1376,7 +1411,7 @@
 | 
			
		||||
#
 | 
			
		||||
#       Choice of server to send metrics to. Currently the only choice is
 | 
			
		||||
#       "statsd" which sends UDP packets to a StatsD daemon, which must be
 | 
			
		||||
#       running while rippled is running. More information on StatsD is
 | 
			
		||||
#       running while xahaud is running. More information on StatsD is
 | 
			
		||||
#       available here:
 | 
			
		||||
#           https://github.com/b/statsd_spec
 | 
			
		||||
#
 | 
			
		||||
@@ -1386,7 +1421,7 @@
 | 
			
		||||
#                 in the format, n.n.n.n:port.
 | 
			
		||||
#
 | 
			
		||||
#       "prefix"  A string prepended to each collected metric. This is used
 | 
			
		||||
#                 to distinguish between different running instances of rippled.
 | 
			
		||||
#                 to distinguish between different running instances of xahaud.
 | 
			
		||||
#
 | 
			
		||||
#     If this section is missing, or the server type is unspecified or unknown,
 | 
			
		||||
#     statistics are not collected or reported.
 | 
			
		||||
@@ -1413,7 +1448,7 @@
 | 
			
		||||
#
 | 
			
		||||
#   Example:
 | 
			
		||||
#     [perf]
 | 
			
		||||
#     perf_log=/var/log/rippled/perf.log
 | 
			
		||||
#     perf_log=/var/log/xahaud/perf.log
 | 
			
		||||
#     log_interval=2
 | 
			
		||||
#
 | 
			
		||||
#-------------------------------------------------------------------------------
 | 
			
		||||
@@ -1422,8 +1457,8 @@
 | 
			
		||||
#
 | 
			
		||||
#----------
 | 
			
		||||
#
 | 
			
		||||
#   The vote settings configure settings for the entire Ripple network.
 | 
			
		||||
#   While a single instance of rippled cannot unilaterally enforce network-wide
 | 
			
		||||
#   The vote settings configure settings for the entire Xahau Network.
 | 
			
		||||
#   While a single instance of xahaud cannot unilaterally enforce network-wide
 | 
			
		||||
#   settings, these choices become part of the instance's vote during the
 | 
			
		||||
#   consensus process for each voting ledger.
 | 
			
		||||
#
 | 
			
		||||
@@ -1435,9 +1470,9 @@
 | 
			
		||||
#
 | 
			
		||||
#       The cost of the reference transaction fee, specified in drops.
 | 
			
		||||
#       The reference transaction is the simplest form of transaction.
 | 
			
		||||
#       It represents an XRP payment between two parties.
 | 
			
		||||
#       It represents an XAH payment between two parties.
 | 
			
		||||
#
 | 
			
		||||
#       If this parameter is unspecified, rippled will use an internal
 | 
			
		||||
#       If this parameter is unspecified, xahaud will use an internal
 | 
			
		||||
#       default. Don't change this without understanding the consequences.
 | 
			
		||||
#
 | 
			
		||||
#       Example:
 | 
			
		||||
@@ -1446,26 +1481,26 @@
 | 
			
		||||
#   account_reserve = <drops>
 | 
			
		||||
#
 | 
			
		||||
#       The account reserve requirement is specified in drops. The portion of an
 | 
			
		||||
#       account's XRP balance that is at or below the reserve may only be
 | 
			
		||||
#       account's XAH balance that is at or below the reserve may only be
 | 
			
		||||
#       spent on transaction fees, and not transferred out of the account.
 | 
			
		||||
#
 | 
			
		||||
#       If this parameter is unspecified, rippled will use an internal
 | 
			
		||||
#       If this parameter is unspecified, xahaud will use an internal
 | 
			
		||||
#       default. Don't change this without understanding the consequences.
 | 
			
		||||
#
 | 
			
		||||
#       Example:
 | 
			
		||||
#           account_reserve = 10000000   # 10 XRP
 | 
			
		||||
#           account_reserve = 10000000   # 10 XAH
 | 
			
		||||
#
 | 
			
		||||
#   owner_reserve = <drops>
 | 
			
		||||
#
 | 
			
		||||
#       The owner reserve is the amount of XRP reserved in the account for
 | 
			
		||||
#       The owner reserve is the amount of XAH reserved in the account for
 | 
			
		||||
#       each ledger item owned by the account. Ledger items an account may
 | 
			
		||||
#       own include trust lines, open orders, and tickets.
 | 
			
		||||
#
 | 
			
		||||
#       If this parameter is unspecified, rippled will use an internal
 | 
			
		||||
#       If this parameter is unspecified, xahaud will use an internal
 | 
			
		||||
#       default. Don't change this without understanding the consequences.
 | 
			
		||||
#
 | 
			
		||||
#       Example:
 | 
			
		||||
#           owner_reserve = 2000000      # 2 XRP
 | 
			
		||||
#           owner_reserve = 2000000      # 2 XAH
 | 
			
		||||
#
 | 
			
		||||
#-------------------------------------------------------------------------------
 | 
			
		||||
#
 | 
			
		||||
@@ -1503,7 +1538,7 @@
 | 
			
		||||
#   tool instead.
 | 
			
		||||
#
 | 
			
		||||
#   This flag has no effect on the "sign" and "sign_for" command line options
 | 
			
		||||
#   that rippled makes available.
 | 
			
		||||
#   that xahaud makes available.
 | 
			
		||||
#
 | 
			
		||||
#   The default value of this field is "false"
 | 
			
		||||
#
 | 
			
		||||
@@ -1582,7 +1617,7 @@
 | 
			
		||||
#--------------------
 | 
			
		||||
#
 | 
			
		||||
#   Administrators can use these values as a starting point for configuring
 | 
			
		||||
#   their instance of rippled, but each value should be checked to make sure
 | 
			
		||||
#   their instance of xahaud, but each value should be checked to make sure
 | 
			
		||||
#   it meets the business requirements for the organization.
 | 
			
		||||
#
 | 
			
		||||
# Server
 | 
			
		||||
@@ -1592,7 +1627,7 @@
 | 
			
		||||
#   "peer"
 | 
			
		||||
#
 | 
			
		||||
#       Peer protocol open to everyone. This is required to accept
 | 
			
		||||
#       incoming rippled connections. This does not affect automatic
 | 
			
		||||
#       incoming xahaud connections. This does not affect automatic
 | 
			
		||||
#       or manual outgoing Peer protocol connections.
 | 
			
		||||
#
 | 
			
		||||
#   "rpc"
 | 
			
		||||
@@ -1620,8 +1655,8 @@
 | 
			
		||||
#   NOTE
 | 
			
		||||
#
 | 
			
		||||
#       To accept connections on well known ports such as 80 (HTTP) or
 | 
			
		||||
#       443 (HTTPS), most operating systems will require rippled to
 | 
			
		||||
#       run with administrator privileges, or else rippled will not start.
 | 
			
		||||
#       443 (HTTPS), most operating systems will require xahaud to
 | 
			
		||||
#       run with administrator privileges, or else xahaud will not start.
 | 
			
		||||
 | 
			
		||||
[server]
 | 
			
		||||
port_rpc_admin_local
 | 
			
		||||
@@ -1632,20 +1667,20 @@ port_ws_admin_local
 | 
			
		||||
#ssl_cert = /etc/ssl/certs/server.crt
 | 
			
		||||
 | 
			
		||||
[port_rpc_admin_local]
 | 
			
		||||
port = 5005
 | 
			
		||||
port = 5009
 | 
			
		||||
ip = 127.0.0.1
 | 
			
		||||
admin = 127.0.0.1
 | 
			
		||||
protocol = http
 | 
			
		||||
 | 
			
		||||
[port_peer]
 | 
			
		||||
port = 51235
 | 
			
		||||
port = 21337
 | 
			
		||||
ip = 0.0.0.0
 | 
			
		||||
# alternatively, to accept connections on IPv4 + IPv6, use:
 | 
			
		||||
#ip = ::
 | 
			
		||||
protocol = peer
 | 
			
		||||
 | 
			
		||||
[port_ws_admin_local]
 | 
			
		||||
port = 6006
 | 
			
		||||
port = 6009
 | 
			
		||||
ip = 127.0.0.1
 | 
			
		||||
admin = 127.0.0.1
 | 
			
		||||
protocol = ws
 | 
			
		||||
@@ -1656,15 +1691,15 @@ ip = 127.0.0.1
 | 
			
		||||
secure_gateway = 127.0.0.1
 | 
			
		||||
 | 
			
		||||
#[port_ws_public]
 | 
			
		||||
#port = 6005
 | 
			
		||||
#port = 6008
 | 
			
		||||
#ip = 127.0.0.1
 | 
			
		||||
#protocol = wss
 | 
			
		||||
 | 
			
		||||
#-------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
# This is primary persistent datastore for rippled.  This includes transaction
 | 
			
		||||
# This is primary persistent datastore for xahaud.  This includes transaction
 | 
			
		||||
# metadata, account states, and ledger headers.  Helpful information can be
 | 
			
		||||
# found at https://xrpl.org/capacity-planning.html#node-db-type
 | 
			
		||||
# found at https://xahau.network/docs/infrastructure/system-requirements
 | 
			
		||||
# type=NuDB is recommended for non-validators with fast SSDs. Validators or
 | 
			
		||||
#    slow / spinning disks should use RocksDB. Caution: Spinning disks are
 | 
			
		||||
#    not recommended. They do not perform well enough to consistently remain
 | 
			
		||||
@@ -1677,16 +1712,16 @@ secure_gateway = 127.0.0.1
 | 
			
		||||
#    deletion.
 | 
			
		||||
[node_db]
 | 
			
		||||
type=NuDB
 | 
			
		||||
path=/var/lib/rippled/db/nudb
 | 
			
		||||
path=/opt/xahaud/db/nudb
 | 
			
		||||
online_delete=512
 | 
			
		||||
advisory_delete=0
 | 
			
		||||
 | 
			
		||||
# This is the persistent datastore for shards. It is important for the health
 | 
			
		||||
# of the ripple network that rippled operators shard as much as practical.
 | 
			
		||||
# of the Xahau Network that xahaud operators shard as much as practical.
 | 
			
		||||
# NuDB requires SSD storage. Helpful information can be found at
 | 
			
		||||
# https://xrpl.org/history-sharding.html
 | 
			
		||||
#[shard_db]
 | 
			
		||||
#path=/var/lib/rippled/db/shards/nudb
 | 
			
		||||
#path=/opt/xahaud/db/shards/nudb
 | 
			
		||||
#max_historical_shards=50
 | 
			
		||||
#
 | 
			
		||||
# This optional section can be configured with a list
 | 
			
		||||
@@ -1697,7 +1732,7 @@ advisory_delete=0
 | 
			
		||||
#/path/2
 | 
			
		||||
 | 
			
		||||
[database_path]
 | 
			
		||||
/var/lib/rippled/db
 | 
			
		||||
/opt/xahaud/db
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# To use Postgres, uncomment this section and fill in the appropriate connection
 | 
			
		||||
@@ -1712,7 +1747,7 @@ advisory_delete=0
 | 
			
		||||
# This needs to be an absolute directory reference, not a relative one.
 | 
			
		||||
# Modify this value as required.
 | 
			
		||||
[debug_logfile]
 | 
			
		||||
/var/log/rippled/debug.log
 | 
			
		||||
/var/log/xahaud/debug.log
 | 
			
		||||
 | 
			
		||||
[sntp_servers]
 | 
			
		||||
time.windows.com
 | 
			
		||||
@@ -1720,15 +1755,19 @@ time.apple.com
 | 
			
		||||
time.nist.gov
 | 
			
		||||
pool.ntp.org
 | 
			
		||||
 | 
			
		||||
# To use the XRP test network
 | 
			
		||||
# (see https://xrpl.org/connect-your-rippled-to-the-xrp-test-net.html),
 | 
			
		||||
# To use the Xahau Test Network
 | 
			
		||||
# (see https://xahau.network/docs/infrastructure/installing-xahaud),
 | 
			
		||||
# use the following [ips] section:
 | 
			
		||||
# [ips]
 | 
			
		||||
# r.altnet.rippletest.net 51235
 | 
			
		||||
# 79.110.60.121 21338
 | 
			
		||||
# 79.110.60.122 21338
 | 
			
		||||
# 79.110.60.124 21338
 | 
			
		||||
# 79.110.60.125 21338
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# File containing trusted validator keys or validator list publishers.
 | 
			
		||||
# Unless an absolute path is specified, it will be considered relative to the
 | 
			
		||||
# folder in which the rippled.cfg file is located.
 | 
			
		||||
# folder in which the xahaud.cfg file is located.
 | 
			
		||||
[validators_file]
 | 
			
		||||
validators.txt
 | 
			
		||||
 | 
			
		||||
@@ -9,7 +9,7 @@
 | 
			
		||||
#
 | 
			
		||||
#   2. Peer Protocol
 | 
			
		||||
#
 | 
			
		||||
#   3. Ripple Protocol
 | 
			
		||||
#   3. XRPL Protocol
 | 
			
		||||
#
 | 
			
		||||
#   4. HTTPS Client
 | 
			
		||||
#
 | 
			
		||||
@@ -29,18 +29,16 @@
 | 
			
		||||
#
 | 
			
		||||
# Purpose
 | 
			
		||||
#
 | 
			
		||||
#   This file documents and provides examples of all rippled server process
 | 
			
		||||
#   configuration options. When the rippled server instance is launched, it
 | 
			
		||||
#   This file documents and provides examples of all xahaud server process
 | 
			
		||||
#   configuration options. When the xahaud server instance is launched, it
 | 
			
		||||
#   looks for a file with the following name:
 | 
			
		||||
#
 | 
			
		||||
#     rippled.cfg
 | 
			
		||||
#     xahaud.cfg
 | 
			
		||||
#
 | 
			
		||||
#   For more information on where the rippled server instance searches for the
 | 
			
		||||
#   file, visit:
 | 
			
		||||
#   To run xahaud with a custom configuration file, use the "--conf {file}" flag.
 | 
			
		||||
#   By default, xahaud will look in the local working directory or the home directory
 | 
			
		||||
#
 | 
			
		||||
#     https://xrpl.org/commandline-usage.html#generic-options
 | 
			
		||||
#
 | 
			
		||||
#   This file should be named rippled.cfg. This file is UTF-8 with DOS, UNIX,
 | 
			
		||||
#   This file should be named xahaud.cfg. This file is UTF-8 with DOS, UNIX,
 | 
			
		||||
#   or Mac style end of lines. Blank lines and lines beginning with '#' are
 | 
			
		||||
#   ignored. Undefined sections are reserved. No escapes are currently defined.
 | 
			
		||||
#
 | 
			
		||||
@@ -89,8 +87,8 @@
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
#   rippled offers various server protocols to clients making inbound
 | 
			
		||||
#   connections. The listening ports rippled uses are "universal" ports
 | 
			
		||||
#   xahaud offers various server protocols to clients making inbound
 | 
			
		||||
#   connections. The listening ports xahaud uses are "universal" ports
 | 
			
		||||
#   which may be configured to handshake in one or more of the available
 | 
			
		||||
#   supported protocols. These universal ports simplify administration:
 | 
			
		||||
#   A single open port can be used for multiple protocols.
 | 
			
		||||
@@ -103,7 +101,7 @@
 | 
			
		||||
#
 | 
			
		||||
#   A list of port names and key/value pairs. A port name must start with a
 | 
			
		||||
#   letter and contain only letters and numbers. The name is not case-sensitive.
 | 
			
		||||
#   For each name in this list, rippled will look for a configuration file
 | 
			
		||||
#   For each name in this list, xahaud will look for a configuration file
 | 
			
		||||
#   section with the same name and use it to create a listening port. The
 | 
			
		||||
#   name is informational only; the choice of name does not affect the function
 | 
			
		||||
#   of the listening port.
 | 
			
		||||
@@ -134,7 +132,7 @@
 | 
			
		||||
#       ip = 127.0.0.1
 | 
			
		||||
#       protocol = http
 | 
			
		||||
#
 | 
			
		||||
#   When rippled is used as a command line client (for example, issuing a
 | 
			
		||||
#   When xahaud is used as a command line client (for example, issuing a
 | 
			
		||||
#   server stop command), the first port advertising the http or https
 | 
			
		||||
#   protocol will be used to make the connection.
 | 
			
		||||
#
 | 
			
		||||
@@ -175,7 +173,7 @@
 | 
			
		||||
#       same time. It is possible have both Websockets and Secure Websockets
 | 
			
		||||
#       together in one port.
 | 
			
		||||
#
 | 
			
		||||
#       NOTE    If no ports support the peer protocol, rippled cannot
 | 
			
		||||
#       NOTE    If no ports support the peer protocol, xahaud cannot
 | 
			
		||||
#               receive incoming peer connections or become a superpeer.
 | 
			
		||||
#
 | 
			
		||||
#   limit = <number>
 | 
			
		||||
@@ -194,7 +192,7 @@
 | 
			
		||||
#       required. IP address restrictions, if any, will be checked in addition
 | 
			
		||||
#       to the credentials specified here.
 | 
			
		||||
#
 | 
			
		||||
#       When acting in the client role, rippled will supply these credentials
 | 
			
		||||
#       When acting in the client role, xahaud will supply these credentials
 | 
			
		||||
#       using HTTP's Basic Authentication headers when making outbound HTTP/S
 | 
			
		||||
#       requests.
 | 
			
		||||
#
 | 
			
		||||
@@ -227,7 +225,7 @@
 | 
			
		||||
#       WS, or WSS protocol interfaces. If administrative commands are
 | 
			
		||||
#       disabled for a port, these credentials have no effect.
 | 
			
		||||
#
 | 
			
		||||
#       When acting in the client role, rippled will supply these credentials
 | 
			
		||||
#       When acting in the client role, xahaud will supply these credentials
 | 
			
		||||
#       in the submitted JSON for any administrative command requests when
 | 
			
		||||
#       invoking JSON-RPC commands on remote servers.
 | 
			
		||||
#
 | 
			
		||||
@@ -247,11 +245,11 @@
 | 
			
		||||
#       resource controls will default to those for non-administrative users.
 | 
			
		||||
#
 | 
			
		||||
#       The secure_gateway IP addresses are intended to represent
 | 
			
		||||
#       proxies. Since rippled trusts these hosts, they must be
 | 
			
		||||
#       proxies. Since xahaud trusts these hosts, they must be
 | 
			
		||||
#       responsible for properly authenticating the remote user.
 | 
			
		||||
#
 | 
			
		||||
#       The same IP address cannot be used in both "admin" and "secure_gateway"
 | 
			
		||||
#       lists for the same port. In this case, rippled will abort with an error
 | 
			
		||||
#       lists for the same port. In this case, xahaud will abort with an error
 | 
			
		||||
#       message to the console shortly after startup
 | 
			
		||||
#
 | 
			
		||||
#   ssl_key = <filename>
 | 
			
		||||
@@ -261,7 +259,7 @@
 | 
			
		||||
#       Use the specified files when configuring SSL on the port.
 | 
			
		||||
#
 | 
			
		||||
#       NOTE    If no files are specified and secure protocols are selected,
 | 
			
		||||
#               rippled will generate an internal self-signed certificate.
 | 
			
		||||
#               xahaud will generate an internal self-signed certificate.
 | 
			
		||||
#
 | 
			
		||||
#       The files have these meanings:
 | 
			
		||||
#
 | 
			
		||||
@@ -284,12 +282,12 @@
 | 
			
		||||
#       Control the ciphers which the server will support over SSL on the port,
 | 
			
		||||
#       specified using the OpenSSL "cipher list format".
 | 
			
		||||
#
 | 
			
		||||
#       NOTE    If unspecified, rippled will automatically configure a modern
 | 
			
		||||
#       NOTE    If unspecified, xahaud will automatically configure a modern
 | 
			
		||||
#               cipher suite. This default suite should be widely supported.
 | 
			
		||||
#
 | 
			
		||||
#               You should not modify this string unless you have a specific
 | 
			
		||||
#               reason and cryptographic expertise. Incorrect modification may
 | 
			
		||||
#               keep rippled from connecting to other instances of rippled or
 | 
			
		||||
#               keep xahaud from connecting to other instances of xahaud or
 | 
			
		||||
#               prevent RPC and WebSocket clients from connecting.
 | 
			
		||||
#
 | 
			
		||||
#   send_queue_limit = [1..65535]
 | 
			
		||||
@@ -340,7 +338,7 @@
 | 
			
		||||
#
 | 
			
		||||
#   Examples:
 | 
			
		||||
#     { "command" : "server_info" }
 | 
			
		||||
#     { "command" : "log_level", "partition" : "ripplecalc", "severity" : "trace" }
 | 
			
		||||
#     { "command" : "log_level", "partition" : "xahaucalc", "severity" : "trace" }
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
@@ -369,8 +367,8 @@
 | 
			
		||||
#-----------------
 | 
			
		||||
#
 | 
			
		||||
#   These settings control security and access attributes of the Peer to Peer
 | 
			
		||||
#   server section of the rippled process. Peer Protocol implements the
 | 
			
		||||
#   Ripple Payment protocol. It is over peer connections that transactions
 | 
			
		||||
#   server section of the xahaud process. Peer Protocol implements the
 | 
			
		||||
#   XRPL Payment protocol. It is over peer connections that transactions
 | 
			
		||||
#   and validations are passed from to machine to machine, to determine the
 | 
			
		||||
#   contents of validated ledgers.
 | 
			
		||||
#
 | 
			
		||||
@@ -378,7 +376,7 @@
 | 
			
		||||
#
 | 
			
		||||
# [ips]
 | 
			
		||||
#
 | 
			
		||||
#   List of hostnames or ips where the Ripple protocol is served.  A default
 | 
			
		||||
#   List of hostnames or ips where the XRPL protocol is served.  A default
 | 
			
		||||
#   starter list is included in the code and used if no other hostnames are
 | 
			
		||||
#   available.
 | 
			
		||||
#
 | 
			
		||||
@@ -387,24 +385,23 @@
 | 
			
		||||
#   does not generally matter.
 | 
			
		||||
#
 | 
			
		||||
#   The default list of entries is:
 | 
			
		||||
#     - r.ripple.com 51235
 | 
			
		||||
#     - zaphod.alloy.ee 51235
 | 
			
		||||
#     - sahyadri.isrdc.in 51235
 | 
			
		||||
#     - bacab.alloy.ee 21337
 | 
			
		||||
#     - hubs.xahau.as16089.net 21337
 | 
			
		||||
#
 | 
			
		||||
#   Examples:
 | 
			
		||||
#
 | 
			
		||||
#   [ips]
 | 
			
		||||
#   192.168.0.1
 | 
			
		||||
#   192.168.0.1 2459
 | 
			
		||||
#   r.ripple.com 51235
 | 
			
		||||
#   192.168.0.1 21337
 | 
			
		||||
#   bacab.alloy.ee 21337
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
# [ips_fixed]
 | 
			
		||||
#
 | 
			
		||||
#   List of IP addresses or hostnames to which rippled should always attempt to
 | 
			
		||||
#   List of IP addresses or hostnames to which xahaud should always attempt to
 | 
			
		||||
#   maintain peer connections with. This is useful for manually forming private
 | 
			
		||||
#   networks, for example to configure a validation server that connects to the
 | 
			
		||||
#   Ripple network through a public-facing server, or for building a set
 | 
			
		||||
#   Xahau Network through a public-facing server, or for building a set
 | 
			
		||||
#   of cluster peers.
 | 
			
		||||
#
 | 
			
		||||
#   One address or domain names per line is allowed. A port must be specified
 | 
			
		||||
@@ -454,7 +451,7 @@
 | 
			
		||||
#
 | 
			
		||||
#   IP address or domain of NTP servers to use for time synchronization.
 | 
			
		||||
#
 | 
			
		||||
#   These NTP servers are suitable for rippled servers located in the United
 | 
			
		||||
#   These NTP servers are suitable for xahaud servers located in the United
 | 
			
		||||
#   States:
 | 
			
		||||
#      time.windows.com
 | 
			
		||||
#      time.apple.com
 | 
			
		||||
@@ -555,7 +552,7 @@
 | 
			
		||||
#
 | 
			
		||||
#   minimum_txn_in_ledger_standalone = <number>
 | 
			
		||||
#
 | 
			
		||||
#       Like minimum_txn_in_ledger when rippled is running in standalone
 | 
			
		||||
#       Like minimum_txn_in_ledger when xahaud is running in standalone
 | 
			
		||||
#       mode. Default: 1000.
 | 
			
		||||
#
 | 
			
		||||
#   target_txn_in_ledger = <number>
 | 
			
		||||
@@ -682,7 +679,7 @@
 | 
			
		||||
#
 | 
			
		||||
# [validator_token]
 | 
			
		||||
#
 | 
			
		||||
#   This is an alternative to [validation_seed] that allows rippled to perform
 | 
			
		||||
#   This is an alternative to [validation_seed] that allows xahaud to perform
 | 
			
		||||
#   validation without having to store the validator keys on the network
 | 
			
		||||
#   connected server. The field should contain a single token in the form of a
 | 
			
		||||
#   base64-encoded blob.
 | 
			
		||||
@@ -717,22 +714,21 @@
 | 
			
		||||
#
 | 
			
		||||
#   Specify the file by its name or path.
 | 
			
		||||
#   Unless an absolute path is specified, it will be considered relative to
 | 
			
		||||
#   the folder in which the rippled.cfg file is located.
 | 
			
		||||
#   the folder in which the xahaud.cfg file is located.
 | 
			
		||||
#
 | 
			
		||||
#   Examples:
 | 
			
		||||
#    /home/ripple/validators.txt
 | 
			
		||||
#    C:/home/ripple/validators.txt
 | 
			
		||||
#    /home/xahaud/validators.txt
 | 
			
		||||
#    C:/home/xahaud/validators.txt
 | 
			
		||||
#
 | 
			
		||||
#   Example content:
 | 
			
		||||
#    [validators]
 | 
			
		||||
#    n949f75evCHwgyP4fPVgaHqNHxUVN15PsJEZ3B3HnXPcPjcZAoy7
 | 
			
		||||
#    n9MD5h24qrQqiyBC8aeqqCWvpiBiYQ3jxSr91uiDvmrkyHRdYLUj
 | 
			
		||||
#    n9L81uNCaPgtUJfaHh89gmdvXKAmSt5Gdsw2g1iPWaPkAHW5Nm4C
 | 
			
		||||
#    n9KiYM9CgngLvtRCQHZwgC2gjpdaZcCcbt3VboxiNFcKuwFVujzS
 | 
			
		||||
#    n9LdgEtkmGB9E2h3K4Vp7iGUaKuq23Zr32ehxiU8FWY7xoxbWTSA
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
#    n9L3GdotB8a3AqtsvS7NXt4BUTQSAYyJUr9xtFj2qXJjfbZsawKY
 | 
			
		||||
#    n9LQDHLWyFuAn5BXJuW2ow5J9uGqpmSjRYS2cFRpxf6uJbxwDzvM
 | 
			
		||||
#    n9MCWyKVUkiatXVJTKUrAESB5kBFP8R3hm43jGHtg8WBnjv3iDfb
 | 
			
		||||
#    n9KWXCLRhjpajuZtULTXsy6R5xbisA6ozGxM4zdEJFq6uHiFZDvW
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# [path_search]
 | 
			
		||||
#   When searching for paths, the default search aggressiveness. This can take
 | 
			
		||||
#   exponentially more resources as the size is increased.
 | 
			
		||||
@@ -795,7 +791,7 @@
 | 
			
		||||
#
 | 
			
		||||
#   0: Disable the ledger replay feature [default]
 | 
			
		||||
#   1: Enable the ledger replay feature. With this feature enabled, when
 | 
			
		||||
#      acquiring a ledger from the network, a rippled node only downloads
 | 
			
		||||
#      acquiring a ledger from the network, a xahaud node only downloads
 | 
			
		||||
#      the ledger header and the transactions instead of the whole ledger.
 | 
			
		||||
#      And the ledger is built by applying the transactions to the parent
 | 
			
		||||
#      ledger.
 | 
			
		||||
@@ -806,9 +802,9 @@
 | 
			
		||||
#
 | 
			
		||||
#----------------
 | 
			
		||||
#
 | 
			
		||||
#   The rippled server instance uses HTTPS GET requests in a variety of
 | 
			
		||||
#   The xahaud server instance uses HTTPS GET requests in a variety of
 | 
			
		||||
#   circumstances, including but not limited to contacting trusted domains to
 | 
			
		||||
#   fetch information such as mapping an email address to a Ripple Payment
 | 
			
		||||
#   fetch information such as mapping an email address to a XRPL Payment
 | 
			
		||||
#   Network address.
 | 
			
		||||
#
 | 
			
		||||
# [ssl_verify]
 | 
			
		||||
@@ -846,15 +842,15 @@
 | 
			
		||||
#
 | 
			
		||||
#------------
 | 
			
		||||
#
 | 
			
		||||
#   rippled has an optional operating mode called Reporting Mode. In Reporting
 | 
			
		||||
#   Mode, rippled does not connect to the peer to peer network. Instead, rippled
 | 
			
		||||
#   will continuously extract data from one or more rippled servers that are
 | 
			
		||||
#   xahaud has an optional operating mode called Reporting Mode. In Reporting
 | 
			
		||||
#   Mode, xahaud does not connect to the peer to peer network. Instead, xahaud
 | 
			
		||||
#   will continuously extract data from one or more xahaud servers that are
 | 
			
		||||
#   connected to the peer to peer network (referred to as an ETL source).
 | 
			
		||||
#   Reporting mode servers will forward RPC requests that require access to the
 | 
			
		||||
#   peer to peer network (submit, fee, etc) to an ETL source.
 | 
			
		||||
#
 | 
			
		||||
#   [reporting]  Settings for Reporting Mode. If and only if this section is
 | 
			
		||||
#                present, rippled will start in reporting mode. This section
 | 
			
		||||
#                present, xahaud will start in reporting mode. This section
 | 
			
		||||
#                contains a list of ETL source names, and key-value pairs. The
 | 
			
		||||
#                ETL source names each correspond to a configuration file
 | 
			
		||||
#                section; the names must match exactly. The key-value pairs are
 | 
			
		||||
@@ -959,16 +955,16 @@
 | 
			
		||||
#
 | 
			
		||||
#------------
 | 
			
		||||
#
 | 
			
		||||
#   rippled creates 4 SQLite database to hold bookkeeping information
 | 
			
		||||
#   xahaud creates 4 SQLite database to hold bookkeeping information
 | 
			
		||||
#   about transactions, local credentials, and various other things.
 | 
			
		||||
#   It also creates the NodeDB, which holds all the objects that
 | 
			
		||||
#   make up the current and historical ledgers. In Reporting Mode, rippled
 | 
			
		||||
#   make up the current and historical ledgers. In Reporting Mode, xahaud
 | 
			
		||||
#   uses a Postgres database instead of SQLite.
 | 
			
		||||
#
 | 
			
		||||
#   The simplest way to work with Postgres is to install it locally.
 | 
			
		||||
#   When it is running, execute the initdb.sh script in the current
 | 
			
		||||
#   directory as: sudo -u postgres ./initdb.sh
 | 
			
		||||
#   This will create the rippled user and an empty database of the same name.
 | 
			
		||||
#   This will create the xahaud user and an empty database of the same name.
 | 
			
		||||
#
 | 
			
		||||
#   The size of the NodeDB grows in proportion to the amount of new data and the
 | 
			
		||||
#   amount of historical data (a configurable setting) so the performance of the
 | 
			
		||||
@@ -976,7 +972,7 @@
 | 
			
		||||
#   the performance of the server.
 | 
			
		||||
#
 | 
			
		||||
#   Partial pathnames will be considered relative to the location of
 | 
			
		||||
#   the rippled.cfg file.
 | 
			
		||||
#   the xahaud.cfg file.
 | 
			
		||||
#
 | 
			
		||||
#   [node_db]               Settings for the Node Database (required)
 | 
			
		||||
#
 | 
			
		||||
@@ -994,11 +990,11 @@
 | 
			
		||||
#   type = NuDB
 | 
			
		||||
#
 | 
			
		||||
#       NuDB is a high-performance database written by Ripple Labs and optimized
 | 
			
		||||
#       for rippled and solid-state drives.
 | 
			
		||||
#       for solid-state drives.
 | 
			
		||||
#
 | 
			
		||||
#       NuDB maintains its high speed regardless of the amount of history
 | 
			
		||||
#       stored. Online delete may be selected, but is not required. NuDB is
 | 
			
		||||
#       available on all platforms that rippled runs on.
 | 
			
		||||
#       available on all platforms that xahaud runs on.
 | 
			
		||||
#
 | 
			
		||||
#   type = RocksDB
 | 
			
		||||
#
 | 
			
		||||
@@ -1103,14 +1099,14 @@
 | 
			
		||||
#
 | 
			
		||||
#       recovery_wait_seconds
 | 
			
		||||
#                           The online delete process checks periodically
 | 
			
		||||
#                           that rippled is still in sync with the network,
 | 
			
		||||
#                           that xahaud is still in sync with the network,
 | 
			
		||||
#                           and that the validated ledger is less than
 | 
			
		||||
#                           'age_threshold_seconds' old. By default, if it
 | 
			
		||||
#                           is not the online delete process aborts and
 | 
			
		||||
#                           tries again later. If 'recovery_wait_seconds'
 | 
			
		||||
#                           is set and rippled is out of sync, but likely to
 | 
			
		||||
#                           is set and xahaud is out of sync, but likely to
 | 
			
		||||
#                           recover quickly, then online delete will wait
 | 
			
		||||
#                           this number of seconds for rippled to get back
 | 
			
		||||
#                           this number of seconds for xahaud to get back
 | 
			
		||||
#                           into sync before it aborts.
 | 
			
		||||
#                           Set this value if the node is otherwise staying
 | 
			
		||||
#                           in sync, or recovering quickly, but the online
 | 
			
		||||
@@ -1146,8 +1142,8 @@
 | 
			
		||||
#   The server creates and maintains 4 to 5 bookkeeping SQLite databases in
 | 
			
		||||
#   the 'database_path' location. If you omit this configuration setting,
 | 
			
		||||
#   the server creates a directory called "db" located in the same place as
 | 
			
		||||
#   your rippled.cfg file.
 | 
			
		||||
#   Partial pathnames are relative to the location of the rippled executable.
 | 
			
		||||
#   your xahaud.cfg file.
 | 
			
		||||
#   Partial pathnames are relative to the location of the xahaud executable.
 | 
			
		||||
#
 | 
			
		||||
#   [shard_db]      Settings for the Shard Database (optional)
 | 
			
		||||
#
 | 
			
		||||
@@ -1223,7 +1219,7 @@
 | 
			
		||||
#                           The default is "wal", which uses a write-ahead
 | 
			
		||||
#                           log to implement database transactions.
 | 
			
		||||
#                           Alternately, "memory" saves disk I/O, but if
 | 
			
		||||
#                           rippled crashes during a transaction, the
 | 
			
		||||
#                           xahaud crashes during a transaction, the
 | 
			
		||||
#                           database is likely to be corrupted.
 | 
			
		||||
#                           See https://www.sqlite.org/pragma.html#pragma_journal_mode
 | 
			
		||||
#                           for more details about the available options.
 | 
			
		||||
@@ -1233,7 +1229,7 @@
 | 
			
		||||
#       synchronous         Valid values: off, normal, full, extra
 | 
			
		||||
#                           The default is "normal", which works well with
 | 
			
		||||
#                           the "wal" journal mode. Alternatively, "off"
 | 
			
		||||
#                           allows rippled to continue as soon as data is
 | 
			
		||||
#                           allows xahaud to continue as soon as data is
 | 
			
		||||
#                           passed to the OS, which can significantly
 | 
			
		||||
#                           increase speed, but risks data corruption if
 | 
			
		||||
#                           the host computer crashes before writing that
 | 
			
		||||
@@ -1247,7 +1243,7 @@
 | 
			
		||||
#                           The default is "file", which will use files
 | 
			
		||||
#                           for temporary database tables and indices.
 | 
			
		||||
#                           Alternatively, "memory" may save I/O, but
 | 
			
		||||
#                           rippled does not currently use many, if any,
 | 
			
		||||
#                           xahaud does not currently use many, if any,
 | 
			
		||||
#                           of these temporary objects.
 | 
			
		||||
#                           See https://www.sqlite.org/pragma.html#pragma_temp_store
 | 
			
		||||
#                           for more details about the available options.
 | 
			
		||||
@@ -1259,9 +1255,9 @@
 | 
			
		||||
#      conninfo             Info for connecting to Postgres. Format is
 | 
			
		||||
#                           postgres://[username]:[password]@[ip]/[database].
 | 
			
		||||
#                           The database and user must already exist. If this
 | 
			
		||||
#                           section is missing and rippled is running in
 | 
			
		||||
#                           Reporting Mode, rippled will connect as the
 | 
			
		||||
#                           user running rippled to a database with the
 | 
			
		||||
#                           section is missing and xahaud is running in
 | 
			
		||||
#                           Reporting Mode, xahaud will connect as the
 | 
			
		||||
#                           user running xahaud to a database with the
 | 
			
		||||
#                           same name. On Linux and Mac OS X, the connection
 | 
			
		||||
#                           will take place using the server's UNIX domain
 | 
			
		||||
#                           socket. On Windows, through the localhost IP
 | 
			
		||||
@@ -1270,7 +1266,7 @@
 | 
			
		||||
#      use_tx_tables        Valid values: 1, 0
 | 
			
		||||
#                           The default is 1 (true). Determines whether to use
 | 
			
		||||
#                           the SQLite transaction database. If set to 0,
 | 
			
		||||
#                           rippled will not write to the transaction database,
 | 
			
		||||
#                           xahaud will not write to the transaction database,
 | 
			
		||||
#                           and will reject tx, account_tx and tx_history RPCs.
 | 
			
		||||
#                           In Reporting Mode, this setting is ignored.
 | 
			
		||||
#
 | 
			
		||||
@@ -1298,7 +1294,7 @@
 | 
			
		||||
#
 | 
			
		||||
#   These settings are designed to help server administrators diagnose
 | 
			
		||||
#   problems, and obtain detailed information about the activities being
 | 
			
		||||
#   performed by the rippled process.
 | 
			
		||||
#   performed by the xahaud process.
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
#
 | 
			
		||||
@@ -1315,7 +1311,7 @@
 | 
			
		||||
#
 | 
			
		||||
#   Configuration parameters for the Beast. Insight stats collection module.
 | 
			
		||||
#
 | 
			
		||||
#   Insight is a module that collects information from the areas of rippled
 | 
			
		||||
#   Insight is a module that collects information from the areas of xahaud
 | 
			
		||||
#   that have instrumentation. The configuration parameters control where the
 | 
			
		||||
#   collection metrics are sent. The parameters are expressed as key = value
 | 
			
		||||
#   pairs with no white space. The main parameter is the choice of server:
 | 
			
		||||
@@ -1324,7 +1320,7 @@
 | 
			
		||||
#
 | 
			
		||||
#       Choice of server to send metrics to. Currently the only choice is
 | 
			
		||||
#       "statsd" which sends UDP packets to a StatsD daemon, which must be
 | 
			
		||||
#       running while rippled is running. More information on StatsD is
 | 
			
		||||
#       running while xahaud is running. More information on StatsD is
 | 
			
		||||
#       available here:
 | 
			
		||||
#           https://github.com/b/statsd_spec
 | 
			
		||||
#
 | 
			
		||||
@@ -1334,7 +1330,7 @@
 | 
			
		||||
#                 in the format, n.n.n.n:port.
 | 
			
		||||
#
 | 
			
		||||
#       "prefix"  A string prepended to each collected metric. This is used
 | 
			
		||||
#                 to distinguish between different running instances of rippled.
 | 
			
		||||
#                 to distinguish between different running instances of xahaud.
 | 
			
		||||
#
 | 
			
		||||
#     If this section is missing, or the server type is unspecified or unknown,
 | 
			
		||||
#     statistics are not collected or reported.
 | 
			
		||||
@@ -1361,7 +1357,7 @@
 | 
			
		||||
#
 | 
			
		||||
#   Example:
 | 
			
		||||
#     [perf]
 | 
			
		||||
#     perf_log=/var/log/rippled/perf.log
 | 
			
		||||
#     perf_log=/var/log/xahaud/perf.log
 | 
			
		||||
#     log_interval=2
 | 
			
		||||
#
 | 
			
		||||
#-------------------------------------------------------------------------------
 | 
			
		||||
@@ -1370,8 +1366,8 @@
 | 
			
		||||
#
 | 
			
		||||
#----------
 | 
			
		||||
#
 | 
			
		||||
#   The vote settings configure settings for the entire Ripple network.
 | 
			
		||||
#   While a single instance of rippled cannot unilaterally enforce network-wide
 | 
			
		||||
#   The vote settings configure settings for the entire Xahau Network.
 | 
			
		||||
#   While a single instance of xahaud cannot unilaterally enforce network-wide
 | 
			
		||||
#   settings, these choices become part of the instance's vote during the
 | 
			
		||||
#   consensus process for each voting ledger.
 | 
			
		||||
#
 | 
			
		||||
@@ -1383,9 +1379,9 @@
 | 
			
		||||
#
 | 
			
		||||
#       The cost of the reference transaction fee, specified in drops.
 | 
			
		||||
#       The reference transaction is the simplest form of transaction.
 | 
			
		||||
#       It represents an XRP payment between two parties.
 | 
			
		||||
#       It represents an XAH payment between two parties.
 | 
			
		||||
#
 | 
			
		||||
#       If this parameter is unspecified, rippled will use an internal
 | 
			
		||||
#       If this parameter is unspecified, xahaud will use an internal
 | 
			
		||||
#       default. Don't change this without understanding the consequences.
 | 
			
		||||
#
 | 
			
		||||
#       Example:
 | 
			
		||||
@@ -1394,26 +1390,26 @@
 | 
			
		||||
#   account_reserve = <drops>
 | 
			
		||||
#
 | 
			
		||||
#       The account reserve requirement is specified in drops. The portion of an
 | 
			
		||||
#       account's XRP balance that is at or below the reserve may only be
 | 
			
		||||
#       account's XAH balance that is at or below the reserve may only be
 | 
			
		||||
#       spent on transaction fees, and not transferred out of the account.
 | 
			
		||||
#
 | 
			
		||||
#       If this parameter is unspecified, rippled will use an internal
 | 
			
		||||
#       If this parameter is unspecified, xahaud will use an internal
 | 
			
		||||
#       default. Don't change this without understanding the consequences.
 | 
			
		||||
#
 | 
			
		||||
#       Example:
 | 
			
		||||
#           account_reserve = 10000000   # 10 XRP
 | 
			
		||||
#           account_reserve = 10000000   # 10 XAH
 | 
			
		||||
#
 | 
			
		||||
#   owner_reserve = <drops>
 | 
			
		||||
#
 | 
			
		||||
#       The owner reserve is the amount of XRP reserved in the account for
 | 
			
		||||
#       The owner reserve is the amount of XAH reserved in the account for
 | 
			
		||||
#       each ledger item owned by the account. Ledger items an account may
 | 
			
		||||
#       own include trust lines, open orders, and tickets.
 | 
			
		||||
#
 | 
			
		||||
#       If this parameter is unspecified, rippled will use an internal
 | 
			
		||||
#       If this parameter is unspecified, xahaud will use an internal
 | 
			
		||||
#       default. Don't change this without understanding the consequences.
 | 
			
		||||
#
 | 
			
		||||
#       Example:
 | 
			
		||||
#           owner_reserve = 2000000      # 2 XRP
 | 
			
		||||
#           owner_reserve = 2000000      # 2 XAH
 | 
			
		||||
#
 | 
			
		||||
#-------------------------------------------------------------------------------
 | 
			
		||||
#
 | 
			
		||||
@@ -1451,7 +1447,7 @@
 | 
			
		||||
#   tool instead.
 | 
			
		||||
#
 | 
			
		||||
#   This flag has no effect on the "sign" and "sign_for" command line options
 | 
			
		||||
#   that rippled makes available.
 | 
			
		||||
#   that xahaud makes available.
 | 
			
		||||
#
 | 
			
		||||
#   The default value of this field is "false"
 | 
			
		||||
#
 | 
			
		||||
@@ -1530,7 +1526,7 @@
 | 
			
		||||
#--------------------
 | 
			
		||||
#
 | 
			
		||||
#   Administrators can use these values as a starting point for configuring
 | 
			
		||||
#   their instance of rippled, but each value should be checked to make sure
 | 
			
		||||
#   their instance of xahaud, but each value should be checked to make sure
 | 
			
		||||
#   it meets the business requirements for the organization.
 | 
			
		||||
#
 | 
			
		||||
# Server
 | 
			
		||||
@@ -1540,7 +1536,7 @@
 | 
			
		||||
#   "peer"
 | 
			
		||||
#
 | 
			
		||||
#       Peer protocol open to everyone. This is required to accept
 | 
			
		||||
#       incoming rippled connections. This does not affect automatic
 | 
			
		||||
#       incoming xahaud connections. This does not affect automatic
 | 
			
		||||
#       or manual outgoing Peer protocol connections.
 | 
			
		||||
#
 | 
			
		||||
#   "rpc"
 | 
			
		||||
@@ -1568,8 +1564,8 @@
 | 
			
		||||
#   NOTE
 | 
			
		||||
#
 | 
			
		||||
#       To accept connections on well known ports such as 80 (HTTP) or
 | 
			
		||||
#       443 (HTTPS), most operating systems will require rippled to
 | 
			
		||||
#       run with administrator privileges, or else rippled will not start.
 | 
			
		||||
#       443 (HTTPS), most operating systems will require xahaud to
 | 
			
		||||
#       run with administrator privileges, or else xahaud will not start.
 | 
			
		||||
 | 
			
		||||
[server]
 | 
			
		||||
port_rpc_admin_local
 | 
			
		||||
@@ -1587,7 +1583,7 @@ admin = 127.0.0.1
 | 
			
		||||
protocol = http
 | 
			
		||||
 | 
			
		||||
[port_peer]
 | 
			
		||||
port = 51235
 | 
			
		||||
port = 21337
 | 
			
		||||
ip = 0.0.0.0
 | 
			
		||||
# alternatively, to accept connections on IPv4 + IPv6, use:
 | 
			
		||||
#ip = ::
 | 
			
		||||
@@ -1611,9 +1607,9 @@ protocol = ws
 | 
			
		||||
 | 
			
		||||
#-------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
# This is primary persistent datastore for rippled.  This includes transaction
 | 
			
		||||
# This is primary persistent datastore for xahaud.  This includes transaction
 | 
			
		||||
# metadata, account states, and ledger headers.  Helpful information can be
 | 
			
		||||
# found at https://xrpl.org/capacity-planning.html#node-db-type
 | 
			
		||||
# found at https://xahau.network/docs/infrastructure/system-requirements
 | 
			
		||||
# type=NuDB is recommended for non-validators with fast SSDs. Validators or
 | 
			
		||||
#    slow / spinning disks should use RocksDB. Caution: Spinning disks are
 | 
			
		||||
#    not recommended. They do not perform well enough to consistently remain
 | 
			
		||||
@@ -1626,16 +1622,16 @@ protocol = ws
 | 
			
		||||
#    deletion.
 | 
			
		||||
[node_db]
 | 
			
		||||
type=NuDB
 | 
			
		||||
path=/var/lib/rippled-reporting/db/nudb
 | 
			
		||||
path=/opt/xahaud-reporting/db/nudb
 | 
			
		||||
# online_delete=512 #
 | 
			
		||||
advisory_delete=0
 | 
			
		||||
 | 
			
		||||
# This is the persistent datastore for shards. It is important for the health
 | 
			
		||||
# of the ripple network that rippled operators shard as much as practical.
 | 
			
		||||
# of the Xahau Network that xahaud operators shard as much as practical.
 | 
			
		||||
# NuDB requires SSD storage. Helpful information can be found at
 | 
			
		||||
# https://xrpl.org/history-sharding.html
 | 
			
		||||
#[shard_db]
 | 
			
		||||
#path=/var/lib/rippled/db/shards/nudb
 | 
			
		||||
#path=/opt/xahaud-reporting/db/shards/nudb
 | 
			
		||||
#max_historical_shards=50
 | 
			
		||||
#
 | 
			
		||||
# This optional section can be configured with a list
 | 
			
		||||
@@ -1646,7 +1642,7 @@ advisory_delete=0
 | 
			
		||||
#/path/2
 | 
			
		||||
 | 
			
		||||
[database_path]
 | 
			
		||||
/var/lib/rippled-reporting/db
 | 
			
		||||
/opt/xahaud-reporting/db
 | 
			
		||||
 | 
			
		||||
# To use Postgres, uncomment this section and fill in the appropriate connection
 | 
			
		||||
# info. Postgres can only be used in Reporting Mode.
 | 
			
		||||
@@ -1660,7 +1656,7 @@ advisory_delete=0
 | 
			
		||||
# This needs to be an absolute directory reference, not a relative one.
 | 
			
		||||
# Modify this value as required.
 | 
			
		||||
[debug_logfile]
 | 
			
		||||
/var/log/rippled-reporting/debug.log
 | 
			
		||||
/var/log/xahaud-reporting/debug.log
 | 
			
		||||
 | 
			
		||||
[sntp_servers]
 | 
			
		||||
time.windows.com
 | 
			
		||||
@@ -1668,17 +1664,20 @@ time.apple.com
 | 
			
		||||
time.nist.gov
 | 
			
		||||
pool.ntp.org
 | 
			
		||||
 | 
			
		||||
# To use the XRP test network
 | 
			
		||||
# (see https://xrpl.org/connect-your-rippled-to-the-xrp-test-net.html),
 | 
			
		||||
# To use the Xahau Test Network
 | 
			
		||||
# (see https://xahau.network/docs/infrastructure/installing-xahaud),
 | 
			
		||||
# use the following [ips] section:
 | 
			
		||||
# [ips]
 | 
			
		||||
# r.altnet.rippletest.net 51235
 | 
			
		||||
# 79.110.60.121 21338
 | 
			
		||||
# 79.110.60.122 21338
 | 
			
		||||
# 79.110.60.124 21338
 | 
			
		||||
# 79.110.60.125 21338
 | 
			
		||||
 | 
			
		||||
# File containing trusted validator keys or validator list publishers.
 | 
			
		||||
# Unless an absolute path is specified, it will be considered relative to the
 | 
			
		||||
# folder in which the rippled.cfg file is located.
 | 
			
		||||
# folder in which the xahaud.cfg file is located.
 | 
			
		||||
[validators_file]
 | 
			
		||||
/opt/rippled-reporting/etc/validators.txt
 | 
			
		||||
/opt/xahaud-reporting/etc/validators.txt
 | 
			
		||||
 | 
			
		||||
# Turn down default logging to save disk space in the long run.
 | 
			
		||||
# Valid values here are trace, debug, info, warning, error, and fatal
 | 
			
		||||
@@ -1699,5 +1698,5 @@ etl_source
 | 
			
		||||
 | 
			
		||||
[etl_source]
 | 
			
		||||
source_grpc_port=50051
 | 
			
		||||
source_ws_port=6005
 | 
			
		||||
source_ws_port=6008
 | 
			
		||||
source_ip=127.0.0.1
 | 
			
		||||
							
								
								
									
										9
									
								
								cfg/rippled-standalone.cfg → cfg/xahaud-standalone.cfg
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										9
									
								
								cfg/rippled-standalone.cfg → cfg/xahaud-standalone.cfg
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
# standalone: ./rippled -a --ledgerfile config/genesis.json --conf config/rippled-standalone.cfg
 | 
			
		||||
# standalone: ./xahaud -a --ledgerfile config/genesis.json --conf config/xahaud-standalone.cfg
 | 
			
		||||
[server]
 | 
			
		||||
port_rpc_admin_local
 | 
			
		||||
port_ws_public
 | 
			
		||||
@@ -21,7 +21,7 @@ ip = 0.0.0.0
 | 
			
		||||
protocol = ws
 | 
			
		||||
 | 
			
		||||
# [port_peer]
 | 
			
		||||
# port = 51235
 | 
			
		||||
# port = 21337
 | 
			
		||||
# ip = 0.0.0.0
 | 
			
		||||
# protocol = peer
 | 
			
		||||
 | 
			
		||||
@@ -69,7 +69,8 @@ time.nist.gov
 | 
			
		||||
pool.ntp.org
 | 
			
		||||
 | 
			
		||||
[ips]
 | 
			
		||||
r.ripple.com 51235
 | 
			
		||||
bacab.alloy.ee 21337
 | 
			
		||||
hubs.xahau.as16089.net 21337
 | 
			
		||||
 | 
			
		||||
[validators_file]
 | 
			
		||||
validators-example.txt
 | 
			
		||||
@@ -94,7 +95,7 @@ validators-example.txt
 | 
			
		||||
1000000
 | 
			
		||||
 | 
			
		||||
[network_id]
 | 
			
		||||
21338
 | 
			
		||||
21337
 | 
			
		||||
 | 
			
		||||
[amendments]
 | 
			
		||||
740352F2412A9909880C23A559FCECEDA3BE2126FED62FC7660D628A06927F11 Flow
 | 
			
		||||
							
								
								
									
										109
									
								
								conanfile.py
									
									
									
									
									
								
							
							
						
						
									
										109
									
								
								conanfile.py
									
									
									
									
									
								
							@@ -21,22 +21,20 @@ class Xrpl(ConanFile):
 | 
			
		||||
        'static': [True, False],
 | 
			
		||||
        'tests': [True, False],
 | 
			
		||||
        'unity': [True, False],
 | 
			
		||||
        'with_wasmedge': [True, False],
 | 
			
		||||
        'tool_requires_b2': [True, False],
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    requires = [
 | 
			
		||||
        'boost/1.86.0',
 | 
			
		||||
        'date/3.0.1',
 | 
			
		||||
        'date/3.0.3',
 | 
			
		||||
        'libarchive/3.6.0',
 | 
			
		||||
        'lz4/1.9.3',
 | 
			
		||||
        'lz4/1.9.4',
 | 
			
		||||
        'grpc/1.50.1',
 | 
			
		||||
        'nudb/2.0.8',
 | 
			
		||||
        'openssl/1.1.1u',
 | 
			
		||||
        'protobuf/3.21.9',
 | 
			
		||||
        'snappy/1.1.10',
 | 
			
		||||
        'soci/4.0.3',
 | 
			
		||||
        'sqlite3/3.42.0',
 | 
			
		||||
        'zlib/1.2.13',
 | 
			
		||||
        'wasmedge/0.11.2',
 | 
			
		||||
        'openssl/3.6.0',
 | 
			
		||||
        'protobuf/3.21.12',
 | 
			
		||||
        'soci/4.0.3@xahaud/stable',
 | 
			
		||||
        'zlib/1.3.1',
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    default_options = {
 | 
			
		||||
@@ -50,42 +48,44 @@ class Xrpl(ConanFile):
 | 
			
		||||
        'static': True,
 | 
			
		||||
        'tests': True,
 | 
			
		||||
        'unity': False,
 | 
			
		||||
        'with_wasmedge': True,
 | 
			
		||||
        'tool_requires_b2': False,
 | 
			
		||||
 | 
			
		||||
        'cassandra-cpp-driver:shared': False,
 | 
			
		||||
        'date:header_only': True,
 | 
			
		||||
        'grpc:shared': False,
 | 
			
		||||
        'grpc:secure': True,
 | 
			
		||||
        'libarchive:shared': False,
 | 
			
		||||
        'libarchive:with_acl': False,
 | 
			
		||||
        'libarchive:with_bzip2': False,
 | 
			
		||||
        'libarchive:with_cng': False,
 | 
			
		||||
        'libarchive:with_expat': False,
 | 
			
		||||
        'libarchive:with_iconv': False,
 | 
			
		||||
        'libarchive:with_libxml2': False,
 | 
			
		||||
        'libarchive:with_lz4': True,
 | 
			
		||||
        'libarchive:with_lzma': False,
 | 
			
		||||
        'libarchive:with_lzo': False,
 | 
			
		||||
        'libarchive:with_nettle': False,
 | 
			
		||||
        'libarchive:with_openssl': False,
 | 
			
		||||
        'libarchive:with_pcreposix': False,
 | 
			
		||||
        'libarchive:with_xattr': False,
 | 
			
		||||
        'libarchive:with_zlib': False,
 | 
			
		||||
        'libpq:shared': False,
 | 
			
		||||
        'lz4:shared': False,
 | 
			
		||||
        'openssl:shared': False,
 | 
			
		||||
        'protobuf:shared': False,
 | 
			
		||||
        'protobuf:with_zlib': True,
 | 
			
		||||
        'rocksdb:enable_sse': False,
 | 
			
		||||
        'rocksdb:lite': False,
 | 
			
		||||
        'rocksdb:shared': False,
 | 
			
		||||
        'rocksdb:use_rtti': True,
 | 
			
		||||
        'rocksdb:with_jemalloc': False,
 | 
			
		||||
        'rocksdb:with_lz4': True,
 | 
			
		||||
        'rocksdb:with_snappy': True,
 | 
			
		||||
        'snappy:shared': False,
 | 
			
		||||
        'soci:shared': False,
 | 
			
		||||
        'soci:with_sqlite3': True,
 | 
			
		||||
        'soci:with_boost': True,
 | 
			
		||||
        'cassandra-cpp-driver/*:shared': False,
 | 
			
		||||
        'date/*:header_only': False,
 | 
			
		||||
        'grpc/*:shared': False,
 | 
			
		||||
        'grpc/*:secure': True,
 | 
			
		||||
        'libarchive/*:shared': False,
 | 
			
		||||
        'libarchive/*:with_acl': False,
 | 
			
		||||
        'libarchive/*:with_bzip2': False,
 | 
			
		||||
        'libarchive/*:with_cng': False,
 | 
			
		||||
        'libarchive/*:with_expat': False,
 | 
			
		||||
        'libarchive/*:with_iconv': False,
 | 
			
		||||
        'libarchive/*:with_libxml2': False,
 | 
			
		||||
        'libarchive/*:with_lz4': True,
 | 
			
		||||
        'libarchive/*:with_lzma': False,
 | 
			
		||||
        'libarchive/*:with_lzo': False,
 | 
			
		||||
        'libarchive/*:with_nettle': False,
 | 
			
		||||
        'libarchive/*:with_openssl': False,
 | 
			
		||||
        'libarchive/*:with_pcreposix': False,
 | 
			
		||||
        'libarchive/*:with_xattr': False,
 | 
			
		||||
        'libarchive/*:with_zlib': False,
 | 
			
		||||
        'libpq/*:shared': False,
 | 
			
		||||
        'lz4/*:shared': False,
 | 
			
		||||
        'openssl/*:shared': False,
 | 
			
		||||
        'protobuf/*:shared': False,
 | 
			
		||||
        'protobuf/*:with_zlib': True,
 | 
			
		||||
        'rocksdb/*:enable_sse': False,
 | 
			
		||||
        'rocksdb/*:lite': False,
 | 
			
		||||
        'rocksdb/*:shared': False,
 | 
			
		||||
        'rocksdb/*:use_rtti': True,
 | 
			
		||||
        'rocksdb/*:with_jemalloc': False,
 | 
			
		||||
        'rocksdb/*:with_lz4': True,
 | 
			
		||||
        'rocksdb/*:with_snappy': True,
 | 
			
		||||
        'snappy/*:shared': False,
 | 
			
		||||
        'soci/*:shared': False,
 | 
			
		||||
        'soci/*:with_sqlite3': True,
 | 
			
		||||
        'soci/*:with_boost': True,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    def set_version(self):
 | 
			
		||||
@@ -96,11 +96,28 @@ class Xrpl(ConanFile):
 | 
			
		||||
            match = next(m for m in matches if m)
 | 
			
		||||
            self.version = match.group(1)
 | 
			
		||||
 | 
			
		||||
    def build_requirements(self):
 | 
			
		||||
        # These provide build tools (protoc, grpc plugins) that run during build
 | 
			
		||||
        self.tool_requires('protobuf/3.21.12')
 | 
			
		||||
        self.tool_requires('grpc/1.50.1')
 | 
			
		||||
        # Explicitly require b2 (e.g. for building from source for glibc compatibility)
 | 
			
		||||
        if self.options.tool_requires_b2:
 | 
			
		||||
            self.tool_requires('b2/5.3.2')
 | 
			
		||||
 | 
			
		||||
    def configure(self):
 | 
			
		||||
        if self.settings.compiler == 'apple-clang':
 | 
			
		||||
            self.options['boost'].visibility = 'global'
 | 
			
		||||
            self.options['boost/*'].visibility = 'global'
 | 
			
		||||
 | 
			
		||||
    def requirements(self):
 | 
			
		||||
        # Force sqlite3 version to avoid conflicts with soci
 | 
			
		||||
        self.requires('sqlite3/3.42.0', override=True)
 | 
			
		||||
        # Force our custom snappy build for all dependencies
 | 
			
		||||
        self.requires('snappy/1.1.10@xahaud/stable', override=True)
 | 
			
		||||
        # Force boost version for all dependencies to avoid conflicts
 | 
			
		||||
        self.requires('boost/1.86.0', override=True)
 | 
			
		||||
 | 
			
		||||
        if self.options.with_wasmedge:
 | 
			
		||||
            self.requires('wasmedge/0.11.2@xahaud/stable')
 | 
			
		||||
        if self.options.jemalloc:
 | 
			
		||||
            self.requires('jemalloc/5.2.1')
 | 
			
		||||
        if self.options.reporting:
 | 
			
		||||
 
 | 
			
		||||
@@ -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:
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										11
									
								
								external/wasmedge/conanfile.py
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										11
									
								
								external/wasmedge/conanfile.py
									
									
									
									
										vendored
									
									
								
							@@ -38,8 +38,15 @@ class WasmedgeConan(ConanFile):
 | 
			
		||||
            raise ConanInvalidConfiguration("Binaries for this combination of version/os/arch/compiler are not available")
 | 
			
		||||
 | 
			
		||||
    def package_id(self):
 | 
			
		||||
        del self.info.settings.compiler.version
 | 
			
		||||
        self.info.settings.compiler = self._compiler_alias
 | 
			
		||||
        # Make binary compatible across compiler versions (since we're downloading prebuilt)
 | 
			
		||||
        self.info.settings.rm_safe("compiler.version")
 | 
			
		||||
        # Group compilers by their binary compatibility
 | 
			
		||||
        # Note: We must use self.info.settings here, not self.settings (forbidden in Conan 2)
 | 
			
		||||
        compiler_name = str(self.info.settings.compiler)
 | 
			
		||||
        if compiler_name in ["Visual Studio", "msvc"]:
 | 
			
		||||
            self.info.settings.compiler = "Visual Studio"
 | 
			
		||||
        else:
 | 
			
		||||
            self.info.settings.compiler = "gcc"
 | 
			
		||||
 | 
			
		||||
    def build(self):
 | 
			
		||||
        # This is packaging binaries so the download needs to be in build
 | 
			
		||||
 
 | 
			
		||||
@@ -48,4 +48,4 @@
 | 
			
		||||
#define TOO_MANY_STATE_MODIFICATIONS -44
 | 
			
		||||
#define TOO_MANY_NAMESPACES -45
 | 
			
		||||
#define HOOK_ERROR_CODES
 | 
			
		||||
#endif //HOOK_ERROR_CODES
 | 
			
		||||
#endif //HOOK_ERROR_CODES
 | 
			
		||||
 
 | 
			
		||||
@@ -12,8 +12,6 @@ accept(uint32_t read_ptr, uint32_t read_len, int64_t error_code);
 | 
			
		||||
extern int64_t
 | 
			
		||||
rollback(uint32_t read_ptr, uint32_t read_len, int64_t error_code);
 | 
			
		||||
 | 
			
		||||
// UTIL
 | 
			
		||||
 | 
			
		||||
extern int64_t
 | 
			
		||||
util_raddr(
 | 
			
		||||
    uint32_t write_ptr,
 | 
			
		||||
@@ -56,8 +54,6 @@ util_keylet(
 | 
			
		||||
    uint32_t e,
 | 
			
		||||
    uint32_t f);
 | 
			
		||||
 | 
			
		||||
// STO
 | 
			
		||||
 | 
			
		||||
extern int64_t
 | 
			
		||||
sto_validate(uint32_t tread_ptr, uint32_t tread_len);
 | 
			
		||||
 | 
			
		||||
@@ -85,8 +81,6 @@ sto_erase(
 | 
			
		||||
    uint32_t read_len,
 | 
			
		||||
    uint32_t field_id);
 | 
			
		||||
 | 
			
		||||
// EMITTED TXN
 | 
			
		||||
 | 
			
		||||
extern int64_t
 | 
			
		||||
etxn_burden(void);
 | 
			
		||||
 | 
			
		||||
@@ -112,8 +106,6 @@ emit(
 | 
			
		||||
    uint32_t read_ptr,
 | 
			
		||||
    uint32_t read_len);
 | 
			
		||||
 | 
			
		||||
// FLOAT
 | 
			
		||||
 | 
			
		||||
extern int64_t
 | 
			
		||||
float_set(int32_t exponent, int64_t mantissa);
 | 
			
		||||
 | 
			
		||||
@@ -174,8 +166,6 @@ float_log(int64_t float1);
 | 
			
		||||
extern int64_t
 | 
			
		||||
float_root(int64_t float1, uint32_t n);
 | 
			
		||||
 | 
			
		||||
// LEDGER
 | 
			
		||||
 | 
			
		||||
extern int64_t
 | 
			
		||||
fee_base(void);
 | 
			
		||||
 | 
			
		||||
@@ -200,8 +190,6 @@ ledger_keylet(
 | 
			
		||||
    uint32_t hread_ptr,
 | 
			
		||||
    uint32_t hread_len);
 | 
			
		||||
 | 
			
		||||
// HOOK
 | 
			
		||||
 | 
			
		||||
extern int64_t
 | 
			
		||||
hook_account(uint32_t write_ptr, uint32_t write_len);
 | 
			
		||||
 | 
			
		||||
@@ -233,8 +221,6 @@ hook_skip(uint32_t read_ptr, uint32_t read_len, uint32_t flags);
 | 
			
		||||
extern int64_t
 | 
			
		||||
hook_pos(void);
 | 
			
		||||
 | 
			
		||||
// SLOT
 | 
			
		||||
 | 
			
		||||
extern int64_t
 | 
			
		||||
slot(uint32_t write_ptr, uint32_t write_len, uint32_t slot);
 | 
			
		||||
 | 
			
		||||
@@ -262,8 +248,6 @@ slot_type(uint32_t slot_no, uint32_t flags);
 | 
			
		||||
extern int64_t
 | 
			
		||||
slot_float(uint32_t slot_no);
 | 
			
		||||
 | 
			
		||||
// STATE
 | 
			
		||||
 | 
			
		||||
extern int64_t
 | 
			
		||||
state_set(
 | 
			
		||||
    uint32_t read_ptr,
 | 
			
		||||
@@ -300,8 +284,6 @@ state_foreign(
 | 
			
		||||
    uint32_t aread_ptr,
 | 
			
		||||
    uint32_t aread_len);
 | 
			
		||||
 | 
			
		||||
// TRACE
 | 
			
		||||
 | 
			
		||||
extern int64_t
 | 
			
		||||
trace(
 | 
			
		||||
    uint32_t mread_ptr,
 | 
			
		||||
@@ -316,8 +298,6 @@ trace_num(uint32_t read_ptr, uint32_t read_len, int64_t number);
 | 
			
		||||
extern int64_t
 | 
			
		||||
trace_float(uint32_t read_ptr, uint32_t read_len, int64_t float1);
 | 
			
		||||
 | 
			
		||||
// OTXN
 | 
			
		||||
 | 
			
		||||
extern int64_t
 | 
			
		||||
otxn_burden(void);
 | 
			
		||||
 | 
			
		||||
@@ -346,9 +326,8 @@ otxn_param(
 | 
			
		||||
extern int64_t
 | 
			
		||||
meta_slot(uint32_t slot_no);
 | 
			
		||||
 | 
			
		||||
// featureHooks1
 | 
			
		||||
 | 
			
		||||
extern int64_t xpop_slot(uint32_t, uint32_t);
 | 
			
		||||
extern int64_t
 | 
			
		||||
xpop_slot(uint32_t slot_no_tx, uint32_t slot_no_meta);
 | 
			
		||||
 | 
			
		||||
#define HOOK_EXTERN
 | 
			
		||||
#endif  // HOOK_EXTERN
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										58
									
								
								hook/generate_error.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										58
									
								
								hook/generate_error.sh
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,58 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
set -eu
 | 
			
		||||
 | 
			
		||||
SCRIPT_DIR=$(dirname "$0")
 | 
			
		||||
SCRIPT_DIR=$(cd "$SCRIPT_DIR" && pwd)
 | 
			
		||||
 | 
			
		||||
ENUM_FILE="$SCRIPT_DIR/../src/ripple/app/hook/Enum.h"
 | 
			
		||||
 | 
			
		||||
echo '// For documentation please see: https://xrpl-hooks.readme.io/reference/'
 | 
			
		||||
echo '// Generated using generate_error.sh'
 | 
			
		||||
echo '#ifndef HOOK_ERROR_CODES'
 | 
			
		||||
sed -n '/enum hook_return_code/,/};/p' "$ENUM_FILE" |
 | 
			
		||||
    awk '
 | 
			
		||||
        function ltrim(s) { sub(/^[[:space:]]+/, "", s); return s }
 | 
			
		||||
        function rtrim(s) { sub(/[[:space:]]+$/, "", s); return s }
 | 
			
		||||
        function trim(s) { return rtrim(ltrim(s)) }
 | 
			
		||||
        function emit(entry) {
 | 
			
		||||
            entry = trim(entry)
 | 
			
		||||
            if (entry == "")
 | 
			
		||||
                return
 | 
			
		||||
            gsub(/,[[:space:]]*$/, "", entry)
 | 
			
		||||
            split(entry, parts, "=")
 | 
			
		||||
            if (length(parts) < 2)
 | 
			
		||||
                return
 | 
			
		||||
            name = trim(parts[1])
 | 
			
		||||
            value = trim(parts[2])
 | 
			
		||||
            if (name == "" || value == "")
 | 
			
		||||
                return
 | 
			
		||||
            printf "#define %s %s\n", name, value
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        {
 | 
			
		||||
            line = $0
 | 
			
		||||
            if (line ~ /enum[[:space:]]+hook_return_code/)
 | 
			
		||||
                next
 | 
			
		||||
            if (line ~ /^[[:space:]]*\{/)
 | 
			
		||||
                next
 | 
			
		||||
 | 
			
		||||
            sub(/\/\/.*$/, "", line)
 | 
			
		||||
 | 
			
		||||
            if (line ~ /^[[:space:]]*\};/) {
 | 
			
		||||
                emit(buffer)
 | 
			
		||||
                exit
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (line ~ /^[[:space:]]*$/)
 | 
			
		||||
                next
 | 
			
		||||
 | 
			
		||||
            buffer = buffer line " "
 | 
			
		||||
 | 
			
		||||
            if (line ~ /,[[:space:]]*$/) {
 | 
			
		||||
                emit(buffer)
 | 
			
		||||
                buffer = ""
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    '
 | 
			
		||||
echo '#define HOOK_ERROR_CODES'
 | 
			
		||||
echo '#endif //HOOK_ERROR_CODES'
 | 
			
		||||
							
								
								
									
										145
									
								
								hook/generate_extern.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										145
									
								
								hook/generate_extern.sh
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,145 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
set -eu
 | 
			
		||||
 | 
			
		||||
SCRIPT_DIR=$(dirname "$0")
 | 
			
		||||
SCRIPT_DIR=$(cd "$SCRIPT_DIR" && pwd)
 | 
			
		||||
 | 
			
		||||
APPLY_HOOK="$SCRIPT_DIR/../src/ripple/app/hook/applyHook.h"
 | 
			
		||||
 | 
			
		||||
{
 | 
			
		||||
    echo '// For documentation please see: https://xrpl-hooks.readme.io/reference/'
 | 
			
		||||
    echo '// Generated using generate_extern.sh'
 | 
			
		||||
    echo '#include <stdint.h>'
 | 
			
		||||
    echo '#ifndef HOOK_EXTERN'
 | 
			
		||||
    echo
 | 
			
		||||
    awk '
 | 
			
		||||
        function trim(s) {
 | 
			
		||||
            sub(/^[[:space:]]+/, "", s);
 | 
			
		||||
            sub(/[[:space:]]+$/, "", s);
 | 
			
		||||
            return s;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        function emit(ret, name, argc, argt, argn) {
 | 
			
		||||
            attr = (name == "_g") ? " __attribute__((noduplicate))" : "";
 | 
			
		||||
            if (!first)
 | 
			
		||||
                printf("\n");
 | 
			
		||||
            first = 0;
 | 
			
		||||
            printf("extern %s%s\n", ret, attr);
 | 
			
		||||
            if (argc == 0) {
 | 
			
		||||
                printf("%s(void);\n", name);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            if (argc <= 3) {
 | 
			
		||||
                line = argt[1] " " argn[1];
 | 
			
		||||
                for (i = 2; i <= argc; ++i)
 | 
			
		||||
                    line = line ", " argt[i] " " argn[i];
 | 
			
		||||
                printf("%s(%s);\n", name, line);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            printf("%s(\n", name);
 | 
			
		||||
            for (i = 1; i <= argc; ++i) {
 | 
			
		||||
                sep = (i < argc) ? "," : ");";
 | 
			
		||||
                printf("    %s %s%s\n", argt[i], argn[i], sep);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        function process(buffer, kind,    payload, parts, n, i, arg, tokens, argc, argt, argn) {
 | 
			
		||||
            if (kind == "func")
 | 
			
		||||
                sub(/^DECLARE_HOOK_FUNCTION[[:space:]]*\(/, "", buffer);
 | 
			
		||||
            else
 | 
			
		||||
                sub(/^DECLARE_HOOK_FUNCNARG[[:space:]]*\(/, "", buffer);
 | 
			
		||||
            buffer = trim(buffer);
 | 
			
		||||
            sub(/\)[[:space:]]*$/, "", buffer);
 | 
			
		||||
            n = split(buffer, parts, ",");
 | 
			
		||||
            for (i = 1; i <= n; ++i)
 | 
			
		||||
                parts[i] = trim(parts[i]);
 | 
			
		||||
            ret = parts[1];
 | 
			
		||||
            name = parts[2];
 | 
			
		||||
            argc = 0;
 | 
			
		||||
            delete argt;
 | 
			
		||||
            delete argn;
 | 
			
		||||
            for (i = 3; i <= n; ++i) {
 | 
			
		||||
                arg = parts[i];
 | 
			
		||||
                if (arg == "")
 | 
			
		||||
                    continue;
 | 
			
		||||
                split(arg, tokens, /[[:space:]]+/);
 | 
			
		||||
                if (length(tokens) < 2)
 | 
			
		||||
                    continue;
 | 
			
		||||
                ++argc;
 | 
			
		||||
                argt[argc] = tokens[1];
 | 
			
		||||
                argn[argc] = tokens[2];
 | 
			
		||||
            }
 | 
			
		||||
            emit(ret, name, argc, argt, argn);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        BEGIN {
 | 
			
		||||
            first = 1;
 | 
			
		||||
            in_block = 0;
 | 
			
		||||
            in_macro = 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        {
 | 
			
		||||
            line = $0;
 | 
			
		||||
            if (in_block) {
 | 
			
		||||
                if (line ~ /\*\//) {
 | 
			
		||||
                    sub(/.*\*\//, "", line);
 | 
			
		||||
                    in_block = 0;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                    next;
 | 
			
		||||
            }
 | 
			
		||||
            while (line ~ /\/\*/) {
 | 
			
		||||
                if (line ~ /\/\*.*\*\//) {
 | 
			
		||||
                    gsub(/\/\*.*\*\//, "", line);
 | 
			
		||||
                }
 | 
			
		||||
                else {
 | 
			
		||||
                    sub(/\/\*.*/, "", line);
 | 
			
		||||
                    in_block = 1;
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            sub(/\/\/.*$/, "", line);
 | 
			
		||||
            line = trim(line);
 | 
			
		||||
            if (line == "")
 | 
			
		||||
                next;
 | 
			
		||||
 | 
			
		||||
            if (!in_macro && line ~ /^DECLARE_HOOK_FUNCTION\(/) {
 | 
			
		||||
                buffer = line;
 | 
			
		||||
                kind = "func";
 | 
			
		||||
                if (line ~ /\);[[:space:]]*$/) {
 | 
			
		||||
                    sub(/\);[[:space:]]*$/, "", buffer);
 | 
			
		||||
                    process(buffer, kind);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                    in_macro = 1;
 | 
			
		||||
                next;
 | 
			
		||||
            }
 | 
			
		||||
            if (!in_macro && line ~ /^DECLARE_HOOK_FUNCNARG\(/) {
 | 
			
		||||
                buffer = line;
 | 
			
		||||
                kind = "narg";
 | 
			
		||||
                if (line ~ /\);[[:space:]]*$/) {
 | 
			
		||||
                    sub(/\);[[:space:]]*$/, "", buffer);
 | 
			
		||||
                    process(buffer, kind);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                    in_macro = 1;
 | 
			
		||||
                next;
 | 
			
		||||
            }
 | 
			
		||||
            if (in_macro) {
 | 
			
		||||
                buffer = buffer " " line;
 | 
			
		||||
                if (line ~ /\);[[:space:]]*$/) {
 | 
			
		||||
                    sub(/\);[[:space:]]*$/, "", buffer);
 | 
			
		||||
                    process(buffer, kind);
 | 
			
		||||
                    in_macro = 0;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        END {
 | 
			
		||||
            printf("\n");
 | 
			
		||||
        }
 | 
			
		||||
    ' "$APPLY_HOOK"
 | 
			
		||||
 | 
			
		||||
    echo '#define HOOK_EXTERN'
 | 
			
		||||
    echo '#endif  // HOOK_EXTERN'
 | 
			
		||||
}
 | 
			
		||||
@@ -1,8 +1,13 @@
 | 
			
		||||
#/bin/bash
 | 
			
		||||
RIPPLED_ROOT="../src/ripple"
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
set -eu
 | 
			
		||||
 | 
			
		||||
SCRIPT_DIR=$(dirname "$0")
 | 
			
		||||
SCRIPT_DIR=$(cd "$SCRIPT_DIR" && pwd)
 | 
			
		||||
 | 
			
		||||
RIPPLED_ROOT="$SCRIPT_DIR/../src/ripple"
 | 
			
		||||
echo '// For documentation please see: https://xrpl-hooks.readme.io/reference/'
 | 
			
		||||
echo '// Generated using generate_sfcodes.sh'
 | 
			
		||||
cat $RIPPLED_ROOT/protocol/impl/SField.cpp | grep -E '^CONSTRUCT_' |
 | 
			
		||||
cat "$RIPPLED_ROOT/protocol/impl/SField.cpp" | grep -E '^CONSTRUCT_' |
 | 
			
		||||
    sed 's/UINT16,/1,/g' |
 | 
			
		||||
    sed 's/UINT32,/2,/g' |
 | 
			
		||||
    sed 's/UINT64,/3,/g' |
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										38
									
								
								hook/generate_tts.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										38
									
								
								hook/generate_tts.sh
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,38 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
set -eu
 | 
			
		||||
 | 
			
		||||
SCRIPT_DIR=$(dirname "$0")
 | 
			
		||||
SCRIPT_DIR=$(cd "$SCRIPT_DIR" && pwd)
 | 
			
		||||
 | 
			
		||||
RIPPLED_ROOT="$SCRIPT_DIR/../src/ripple"
 | 
			
		||||
TX_FORMATS="$RIPPLED_ROOT/protocol/TxFormats.h"
 | 
			
		||||
 | 
			
		||||
echo '// For documentation please see: https://xrpl-hooks.readme.io/reference/'
 | 
			
		||||
echo '// Generated using generate_tts.sh'
 | 
			
		||||
sed -n '/enum TxType/,/};/p' "$TX_FORMATS" |
 | 
			
		||||
    awk '
 | 
			
		||||
        function ltrim(s) { sub(/^[[:space:]]+/, "", s); return s }
 | 
			
		||||
        function rtrim(s) { sub(/[[:space:]]+$/, "", s); return s }
 | 
			
		||||
        function trim(s) { return rtrim(ltrim(s)) }
 | 
			
		||||
 | 
			
		||||
        /^[ \t]*tt[A-Z0-9_]+/ {
 | 
			
		||||
            line = $0
 | 
			
		||||
            deprecated = (line ~ /\[\[deprecated/)
 | 
			
		||||
            gsub(/\[\[deprecated[^]]*\]\]/, "", line)
 | 
			
		||||
            sub(/\/\/.*$/, "", line)
 | 
			
		||||
            gsub(/,[[:space:]]*$/, "", line)
 | 
			
		||||
 | 
			
		||||
            split(line, parts, "=")
 | 
			
		||||
            if (length(parts) < 2)
 | 
			
		||||
                next
 | 
			
		||||
 | 
			
		||||
            name = trim(parts[1])
 | 
			
		||||
            value = trim(parts[2])
 | 
			
		||||
            if (name == "" || value == "")
 | 
			
		||||
                next
 | 
			
		||||
 | 
			
		||||
            prefix = deprecated ? "// " : ""
 | 
			
		||||
            postfix = deprecated ? " // deprecated" : ""
 | 
			
		||||
            printf "%s#define %s %s%s\n", prefix, name, value, postfix
 | 
			
		||||
        }
 | 
			
		||||
    '
 | 
			
		||||
@@ -37,6 +37,7 @@
 | 
			
		||||
#define KEYLET_NFT_OFFER 23
 | 
			
		||||
#define KEYLET_HOOK_DEFINITION 24
 | 
			
		||||
#define KEYLET_HOOK_STATE_DIR 25
 | 
			
		||||
#define KEYLET_CRON 26
 | 
			
		||||
 | 
			
		||||
#define COMPARE_EQUAL 1U
 | 
			
		||||
#define COMPARE_LESS 2U
 | 
			
		||||
 
 | 
			
		||||
@@ -15,6 +15,7 @@
 | 
			
		||||
#define sfHookEmitCount ((1U << 16U) + 18U)
 | 
			
		||||
#define sfHookExecutionIndex ((1U << 16U) + 19U)
 | 
			
		||||
#define sfHookApiVersion ((1U << 16U) + 20U)
 | 
			
		||||
#define sfHookStateScale ((1U << 16U) + 21U)
 | 
			
		||||
#define sfNetworkID ((2U << 16U) + 1U)
 | 
			
		||||
#define sfFlags ((2U << 16U) + 2U)
 | 
			
		||||
#define sfSourceTag ((2U << 16U) + 3U)
 | 
			
		||||
@@ -62,6 +63,9 @@
 | 
			
		||||
#define sfEmitGeneration ((2U << 16U) + 46U)
 | 
			
		||||
#define sfLockCount ((2U << 16U) + 49U)
 | 
			
		||||
#define sfFirstNFTokenSequence ((2U << 16U) + 50U)
 | 
			
		||||
#define sfStartTime ((2U << 16U) + 93U)
 | 
			
		||||
#define sfRepeatCount ((2U << 16U) + 94U)
 | 
			
		||||
#define sfDelaySeconds ((2U << 16U) + 95U)
 | 
			
		||||
#define sfXahauActivationLgrSeq ((2U << 16U) + 96U)
 | 
			
		||||
#define sfImportSequence ((2U << 16U) + 97U)
 | 
			
		||||
#define sfRewardTime ((2U << 16U) + 98U)
 | 
			
		||||
@@ -105,6 +109,7 @@
 | 
			
		||||
#define sfEmitParentTxnID ((5U << 16U) + 11U)
 | 
			
		||||
#define sfEmitNonce ((5U << 16U) + 12U)
 | 
			
		||||
#define sfEmitHookHash ((5U << 16U) + 13U)
 | 
			
		||||
#define sfObjectID ((5U << 16U) + 14U)
 | 
			
		||||
#define sfBookDirectory ((5U << 16U) + 16U)
 | 
			
		||||
#define sfInvoiceID ((5U << 16U) + 17U)
 | 
			
		||||
#define sfNickname ((5U << 16U) + 18U)
 | 
			
		||||
@@ -129,6 +134,8 @@
 | 
			
		||||
#define sfGovernanceFlags ((5U << 16U) + 99U)
 | 
			
		||||
#define sfGovernanceMarks ((5U << 16U) + 98U)
 | 
			
		||||
#define sfEmittedTxnID ((5U << 16U) + 97U)
 | 
			
		||||
#define sfHookCanEmit ((5U << 16U) + 96U)
 | 
			
		||||
#define sfCron ((5U << 16U) + 95U)
 | 
			
		||||
#define sfAmount ((6U << 16U) + 1U)
 | 
			
		||||
#define sfBalance ((6U << 16U) + 2U)
 | 
			
		||||
#define sfLimitAmount ((6U << 16U) + 3U)
 | 
			
		||||
@@ -173,6 +180,8 @@
 | 
			
		||||
#define sfHookParameterName ((7U << 16U) + 24U)
 | 
			
		||||
#define sfHookParameterValue ((7U << 16U) + 25U)
 | 
			
		||||
#define sfBlob ((7U << 16U) + 26U)
 | 
			
		||||
#define sfRemarkValue ((7U << 16U) + 98U)
 | 
			
		||||
#define sfRemarkName ((7U << 16U) + 99U)
 | 
			
		||||
#define sfAccount ((8U << 16U) + 1U)
 | 
			
		||||
#define sfOwner ((8U << 16U) + 2U)
 | 
			
		||||
#define sfDestination ((8U << 16U) + 3U)
 | 
			
		||||
@@ -212,6 +221,7 @@
 | 
			
		||||
#define sfHookDefinition ((14U << 16U) + 22U)
 | 
			
		||||
#define sfHookParameter ((14U << 16U) + 23U)
 | 
			
		||||
#define sfHookGrant ((14U << 16U) + 24U)
 | 
			
		||||
#define sfRemark ((14U << 16U) + 97U)
 | 
			
		||||
#define sfGenesisMint ((14U << 16U) + 96U)
 | 
			
		||||
#define sfActiveValidator ((14U << 16U) + 95U)
 | 
			
		||||
#define sfImportVLKey ((14U << 16U) + 94U)
 | 
			
		||||
@@ -232,8 +242,9 @@
 | 
			
		||||
#define sfHookExecutions ((15U << 16U) + 18U)
 | 
			
		||||
#define sfHookParameters ((15U << 16U) + 19U)
 | 
			
		||||
#define sfHookGrants ((15U << 16U) + 20U)
 | 
			
		||||
#define sfRemarks ((15U << 16U) + 97U)
 | 
			
		||||
#define sfGenesisMints ((15U << 16U) + 96U)
 | 
			
		||||
#define sfActiveValidators ((15U << 16U) + 95U)
 | 
			
		||||
#define sfImportVLKeys ((15U << 16U) + 94U)
 | 
			
		||||
#define sfHookEmissions ((15U << 16U) + 93U)
 | 
			
		||||
#define sfAmounts ((15U << 16U) + 92U)
 | 
			
		||||
#define sfAmounts ((15U << 16U) + 92U)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
// For documentation please see: https://xrpl-hooks.readme.io/reference/
 | 
			
		||||
// Generated using generate_tts.sh
 | 
			
		||||
#define ttPAYMENT 0
 | 
			
		||||
#define ttESCROW_CREATE 1
 | 
			
		||||
#define ttESCROW_FINISH 2
 | 
			
		||||
@@ -8,6 +9,7 @@
 | 
			
		||||
// #define ttNICKNAME_SET 6 // deprecated
 | 
			
		||||
#define ttOFFER_CREATE 7
 | 
			
		||||
#define ttOFFER_CANCEL 8
 | 
			
		||||
// #define ttCONTRACT 9 // deprecated
 | 
			
		||||
#define ttTICKET_CREATE 10
 | 
			
		||||
// #define ttSPINAL_TAP 11 // deprecated
 | 
			
		||||
#define ttSIGNER_LIST_SET 12
 | 
			
		||||
@@ -26,11 +28,15 @@
 | 
			
		||||
#define ttNFTOKEN_CREATE_OFFER 27
 | 
			
		||||
#define ttNFTOKEN_CANCEL_OFFER 28
 | 
			
		||||
#define ttNFTOKEN_ACCEPT_OFFER 29
 | 
			
		||||
#define ttCLAWBACK 30
 | 
			
		||||
#define ttURITOKEN_MINT 45
 | 
			
		||||
#define ttURITOKEN_BURN 46
 | 
			
		||||
#define ttURITOKEN_BUY 47
 | 
			
		||||
#define ttURITOKEN_CREATE_SELL_OFFER 48
 | 
			
		||||
#define ttURITOKEN_CANCEL_SELL_OFFER 49
 | 
			
		||||
#define ttCRON 92
 | 
			
		||||
#define ttCRON_SET 93
 | 
			
		||||
#define ttREMARKS_SET 94
 | 
			
		||||
#define ttREMIT 95
 | 
			
		||||
#define ttGENESIS_MINT 96
 | 
			
		||||
#define ttIMPORT 97
 | 
			
		||||
@@ -40,4 +46,4 @@
 | 
			
		||||
#define ttFEE 101
 | 
			
		||||
#define ttUNL_MODIFY 102
 | 
			
		||||
#define ttEMIT_FAILURE 103
 | 
			
		||||
#define ttUNL_REPORT 104
 | 
			
		||||
#define ttUNL_REPORT 104
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,9 @@
 | 
			
		||||
#!/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 +15,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 +47,192 @@ 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 2 and CMake
 | 
			
		||||
RUN /hbb_exe/activate-exec pip3 install "conan>=2.0,<3.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
 | 
			
		||||
 | 
			
		||||
# Dual Boost configuration in HBB environment:
 | 
			
		||||
# - Manual Boost in /usr/local (minimal: for WasmEdge which is pre-built in Docker)
 | 
			
		||||
# - Conan Boost (full: for the application and all dependencies via toolchain)
 | 
			
		||||
#
 | 
			
		||||
# Install minimal Boost 1.86.0 for WasmEdge only (filesystem and its dependencies)
 | 
			
		||||
# The main application will use Conan-provided Boost for all other components
 | 
			
		||||
# IMPORTANT: Understanding Boost linking options:
 | 
			
		||||
#   - link=static: Creates static Boost libraries (.a files) instead of shared (.so files)
 | 
			
		||||
#   - runtime-link=shared: Links Boost libraries against shared libc (glibc)
 | 
			
		||||
# WasmEdge only needs boost::filesystem and boost::system
 | 
			
		||||
RUN /hbb_exe/activate-exec bash -c "echo 'Boost cache bust: v5-minimal' && \
 | 
			
		||||
    rm -rf /usr/local/lib/libboost* /usr/local/include/boost && \
 | 
			
		||||
    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 install \
 | 
			
		||||
        link=static runtime-link=shared -j${BUILD_CORES} \
 | 
			
		||||
        --with-filesystem --with-system && \
 | 
			
		||||
    cd /tmp && \
 | 
			
		||||
    rm -rf boost boost.tar.gz"
 | 
			
		||||
 | 
			
		||||
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 && \
 | 
			
		||||
    ln -sf /opt/rh/gcc-toolset-11/root/usr/bin/ranlib /usr/bin/ranlib && \
 | 
			
		||||
    echo '=== Binutils version check ===' && \
 | 
			
		||||
    ar --version | head -1 && \
 | 
			
		||||
    ranlib --version | head -1 && \
 | 
			
		||||
    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 2
 | 
			
		||||
# NOTE: Using echo commands instead of heredocs because heredocs in Docker RUN commands are finnicky
 | 
			
		||||
RUN /hbb_exe/activate-exec bash -c "ccache -M 10G && \
 | 
			
		||||
    ccache -o cache_dir=/cache/ccache && \
 | 
			
		||||
    ccache -o compiler_check=content && \
 | 
			
		||||
    mkdir -p ~/.conan2 /cache/conan2 /cache/conan2_download /cache/conan2_sources && \
 | 
			
		||||
    echo 'core.cache:storage_path=/cache/conan2' > ~/.conan2/global.conf && \
 | 
			
		||||
    echo 'core.download:download_cache=/cache/conan2_download' >> ~/.conan2/global.conf && \
 | 
			
		||||
    echo 'core.sources:download_cache=/cache/conan2_sources' >> ~/.conan2/global.conf && \
 | 
			
		||||
    conan profile detect --force && \
 | 
			
		||||
    echo '[settings]' > ~/.conan2/profiles/default && \
 | 
			
		||||
    echo 'arch=x86_64' >> ~/.conan2/profiles/default && \
 | 
			
		||||
    echo 'build_type=Release' >> ~/.conan2/profiles/default && \
 | 
			
		||||
    echo 'compiler=gcc' >> ~/.conan2/profiles/default && \
 | 
			
		||||
    echo 'compiler.cppstd=20' >> ~/.conan2/profiles/default && \
 | 
			
		||||
    echo 'compiler.libcxx=libstdc++11' >> ~/.conan2/profiles/default && \
 | 
			
		||||
    echo 'compiler.version=11' >> ~/.conan2/profiles/default && \
 | 
			
		||||
    echo 'os=Linux' >> ~/.conan2/profiles/default && \
 | 
			
		||||
    echo '' >> ~/.conan2/profiles/default && \
 | 
			
		||||
    echo '[conf]' >> ~/.conan2/profiles/default && \
 | 
			
		||||
    echo '# Force building from source for packages with binary compatibility issues' >> ~/.conan2/profiles/default && \
 | 
			
		||||
    echo '*:tools.system.package_manager:mode=build' >> ~/.conan2/profiles/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>
 | 
			
		||||
@@ -28,6 +29,8 @@ enum HookEmissionFlags : uint16_t {
 | 
			
		||||
};
 | 
			
		||||
}  // namespace ripple
 | 
			
		||||
 | 
			
		||||
using namespace ripple;
 | 
			
		||||
 | 
			
		||||
namespace hook {
 | 
			
		||||
// RH TODO: put these somewhere better, and allow rules to be fed in
 | 
			
		||||
inline uint32_t
 | 
			
		||||
@@ -42,10 +45,26 @@ maxHookParameterValueSize(void)
 | 
			
		||||
    return 256;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline uint32_t
 | 
			
		||||
maxHookStateDataSize(void)
 | 
			
		||||
inline uint16_t
 | 
			
		||||
maxHookStateScale(void)
 | 
			
		||||
{
 | 
			
		||||
    return 256U;
 | 
			
		||||
    return 16;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline uint32_t
 | 
			
		||||
maxHookStateDataSize(uint16_t hookStateScale)
 | 
			
		||||
{
 | 
			
		||||
    if (hookStateScale == 0)
 | 
			
		||||
    {
 | 
			
		||||
        // should not happen, but just in case
 | 
			
		||||
        return 256U;
 | 
			
		||||
    }
 | 
			
		||||
    if (hookStateScale > maxHookStateScale())
 | 
			
		||||
    {
 | 
			
		||||
        // should not happen, but just in case
 | 
			
		||||
        return 256 * maxHookStateScale();
 | 
			
		||||
    }
 | 
			
		||||
    return 256U * hookStateScale;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline uint32_t
 | 
			
		||||
@@ -259,8 +278,7 @@ enum keylet_code : uint32_t {
 | 
			
		||||
    NFT_OFFER = 23,
 | 
			
		||||
    HOOK_DEFINITION = 24,
 | 
			
		||||
    HOOK_STATE_DIR = 25,
 | 
			
		||||
    LAST_KLTYPE_V0 = HOOK_DEFINITION,
 | 
			
		||||
    LAST_KLTYPE_V1 = HOOK_STATE_DIR,
 | 
			
		||||
    CRON = 26
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -30,8 +30,9 @@ isEmittedTxn(ripple::STTx const& tx);
 | 
			
		||||
class HookStateMap : public std::map<
 | 
			
		||||
                         ripple::AccountID,  // account that owns the state
 | 
			
		||||
                         std::tuple<
 | 
			
		||||
                             int64_t,  // remaining available ownercount
 | 
			
		||||
                             int64_t,  // total namespace count
 | 
			
		||||
                             int64_t,   // remaining available ownercount
 | 
			
		||||
                             int64_t,   // total namespace count
 | 
			
		||||
                             uint16_t,  // hook state scale
 | 
			
		||||
                             std::map<
 | 
			
		||||
                                 ripple::uint256,  // namespace
 | 
			
		||||
                                 std::map<
 | 
			
		||||
@@ -74,6 +75,7 @@ DECLARE_HOOK_FUNCTION(
 | 
			
		||||
    uint32_t read_ptr,
 | 
			
		||||
    uint32_t read_len,
 | 
			
		||||
    int64_t error_code);
 | 
			
		||||
 | 
			
		||||
DECLARE_HOOK_FUNCTION(
 | 
			
		||||
    int64_t,
 | 
			
		||||
    util_raddr,
 | 
			
		||||
@@ -97,6 +99,26 @@ DECLARE_HOOK_FUNCTION(
 | 
			
		||||
    uint32_t sread_len,
 | 
			
		||||
    uint32_t kread_ptr,
 | 
			
		||||
    uint32_t kread_len);
 | 
			
		||||
DECLARE_HOOK_FUNCTION(
 | 
			
		||||
    int64_t,
 | 
			
		||||
    util_sha512h,
 | 
			
		||||
    uint32_t write_ptr,
 | 
			
		||||
    uint32_t write_len,
 | 
			
		||||
    uint32_t read_ptr,
 | 
			
		||||
    uint32_t read_len);
 | 
			
		||||
DECLARE_HOOK_FUNCTION(
 | 
			
		||||
    int64_t,
 | 
			
		||||
    util_keylet,
 | 
			
		||||
    uint32_t write_ptr,
 | 
			
		||||
    uint32_t write_len,
 | 
			
		||||
    uint32_t keylet_type,
 | 
			
		||||
    uint32_t a,
 | 
			
		||||
    uint32_t b,
 | 
			
		||||
    uint32_t c,
 | 
			
		||||
    uint32_t d,
 | 
			
		||||
    uint32_t e,
 | 
			
		||||
    uint32_t f);
 | 
			
		||||
 | 
			
		||||
DECLARE_HOOK_FUNCTION(
 | 
			
		||||
    int64_t,
 | 
			
		||||
    sto_validate,
 | 
			
		||||
@@ -133,25 +155,6 @@ DECLARE_HOOK_FUNCTION(
 | 
			
		||||
    uint32_t read_len,
 | 
			
		||||
    uint32_t field_id);
 | 
			
		||||
 | 
			
		||||
DECLARE_HOOK_FUNCTION(
 | 
			
		||||
    int64_t,
 | 
			
		||||
    util_sha512h,
 | 
			
		||||
    uint32_t write_ptr,
 | 
			
		||||
    uint32_t write_len,
 | 
			
		||||
    uint32_t read_ptr,
 | 
			
		||||
    uint32_t read_len);
 | 
			
		||||
DECLARE_HOOK_FUNCTION(
 | 
			
		||||
    int64_t,
 | 
			
		||||
    util_keylet,
 | 
			
		||||
    uint32_t write_ptr,
 | 
			
		||||
    uint32_t write_len,
 | 
			
		||||
    uint32_t keylet_type,
 | 
			
		||||
    uint32_t a,
 | 
			
		||||
    uint32_t b,
 | 
			
		||||
    uint32_t c,
 | 
			
		||||
    uint32_t d,
 | 
			
		||||
    uint32_t e,
 | 
			
		||||
    uint32_t f);
 | 
			
		||||
DECLARE_HOOK_FUNCNARG(int64_t, etxn_burden);
 | 
			
		||||
DECLARE_HOOK_FUNCTION(
 | 
			
		||||
    int64_t,
 | 
			
		||||
@@ -214,7 +217,6 @@ DECLARE_HOOK_FUNCTION(
 | 
			
		||||
DECLARE_HOOK_FUNCTION(int64_t, float_invert, int64_t float1);
 | 
			
		||||
DECLARE_HOOK_FUNCTION(int64_t, float_divide, int64_t float1, int64_t float2);
 | 
			
		||||
DECLARE_HOOK_FUNCNARG(int64_t, float_one);
 | 
			
		||||
 | 
			
		||||
DECLARE_HOOK_FUNCTION(int64_t, float_mantissa, int64_t float1);
 | 
			
		||||
DECLARE_HOOK_FUNCTION(int64_t, float_sign, int64_t float1);
 | 
			
		||||
DECLARE_HOOK_FUNCTION(
 | 
			
		||||
@@ -226,17 +228,6 @@ DECLARE_HOOK_FUNCTION(
 | 
			
		||||
DECLARE_HOOK_FUNCTION(int64_t, float_log, int64_t float1);
 | 
			
		||||
DECLARE_HOOK_FUNCTION(int64_t, float_root, int64_t float1, uint32_t n);
 | 
			
		||||
 | 
			
		||||
DECLARE_HOOK_FUNCTION(
 | 
			
		||||
    int64_t,
 | 
			
		||||
    hook_account,
 | 
			
		||||
    uint32_t write_ptr,
 | 
			
		||||
    uint32_t write_len);
 | 
			
		||||
DECLARE_HOOK_FUNCTION(
 | 
			
		||||
    int64_t,
 | 
			
		||||
    hook_hash,
 | 
			
		||||
    uint32_t write_ptr,
 | 
			
		||||
    uint32_t write_len,
 | 
			
		||||
    int32_t hook_no);
 | 
			
		||||
DECLARE_HOOK_FUNCNARG(int64_t, fee_base);
 | 
			
		||||
DECLARE_HOOK_FUNCNARG(int64_t, ledger_seq);
 | 
			
		||||
DECLARE_HOOK_FUNCNARG(int64_t, ledger_last_time);
 | 
			
		||||
@@ -250,7 +241,6 @@ DECLARE_HOOK_FUNCTION(
 | 
			
		||||
    ledger_nonce,
 | 
			
		||||
    uint32_t write_ptr,
 | 
			
		||||
    uint32_t write_len);
 | 
			
		||||
 | 
			
		||||
DECLARE_HOOK_FUNCTION(
 | 
			
		||||
    int64_t,
 | 
			
		||||
    ledger_keylet,
 | 
			
		||||
@@ -261,6 +251,17 @@ DECLARE_HOOK_FUNCTION(
 | 
			
		||||
    uint32_t hread_ptr,
 | 
			
		||||
    uint32_t hread_len);
 | 
			
		||||
 | 
			
		||||
DECLARE_HOOK_FUNCTION(
 | 
			
		||||
    int64_t,
 | 
			
		||||
    hook_account,
 | 
			
		||||
    uint32_t write_ptr,
 | 
			
		||||
    uint32_t write_len);
 | 
			
		||||
DECLARE_HOOK_FUNCTION(
 | 
			
		||||
    int64_t,
 | 
			
		||||
    hook_hash,
 | 
			
		||||
    uint32_t write_ptr,
 | 
			
		||||
    uint32_t write_len,
 | 
			
		||||
    int32_t hook_no);
 | 
			
		||||
DECLARE_HOOK_FUNCTION(
 | 
			
		||||
    int64_t,
 | 
			
		||||
    hook_param_set,
 | 
			
		||||
@@ -270,7 +271,6 @@ DECLARE_HOOK_FUNCTION(
 | 
			
		||||
    uint32_t kread_len,
 | 
			
		||||
    uint32_t hread_ptr,
 | 
			
		||||
    uint32_t hread_len);
 | 
			
		||||
 | 
			
		||||
DECLARE_HOOK_FUNCTION(
 | 
			
		||||
    int64_t,
 | 
			
		||||
    hook_param,
 | 
			
		||||
@@ -278,9 +278,7 @@ DECLARE_HOOK_FUNCTION(
 | 
			
		||||
    uint32_t write_len,
 | 
			
		||||
    uint32_t read_ptr,
 | 
			
		||||
    uint32_t read_len);
 | 
			
		||||
 | 
			
		||||
DECLARE_HOOK_FUNCNARG(int64_t, hook_again);
 | 
			
		||||
 | 
			
		||||
DECLARE_HOOK_FUNCTION(
 | 
			
		||||
    int64_t,
 | 
			
		||||
    hook_skip,
 | 
			
		||||
@@ -355,6 +353,7 @@ DECLARE_HOOK_FUNCTION(
 | 
			
		||||
    uint32_t nread_len,
 | 
			
		||||
    uint32_t aread_ptr,
 | 
			
		||||
    uint32_t aread_len);
 | 
			
		||||
 | 
			
		||||
DECLARE_HOOK_FUNCTION(
 | 
			
		||||
    int64_t,
 | 
			
		||||
    trace,
 | 
			
		||||
@@ -467,9 +466,6 @@ apply(
 | 
			
		||||
 | 
			
		||||
struct HookContext;
 | 
			
		||||
 | 
			
		||||
uint32_t
 | 
			
		||||
computeHookStateOwnerCount(uint32_t hookStateCount);
 | 
			
		||||
 | 
			
		||||
int64_t
 | 
			
		||||
computeExecutionFee(uint64_t instructionCount);
 | 
			
		||||
int64_t
 | 
			
		||||
 
 | 
			
		||||
@@ -75,6 +75,11 @@ getTransactionalStakeHolders(STTx const& tx, ReadView const& rv)
 | 
			
		||||
 | 
			
		||||
    switch (tt)
 | 
			
		||||
    {
 | 
			
		||||
        case ttCRON: {
 | 
			
		||||
            ADD_TSH(tx.getAccountID(sfOwner), tshWEAK);
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        case ttREMIT: {
 | 
			
		||||
            if (destAcc)
 | 
			
		||||
                ADD_TSH(*destAcc, tshSTRONG);
 | 
			
		||||
@@ -857,12 +862,6 @@ parseCurrency(uint8_t* cu_ptr, uint32_t cu_len)
 | 
			
		||||
        return {};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t
 | 
			
		||||
hook::computeHookStateOwnerCount(uint32_t hookStateCount)
 | 
			
		||||
{
 | 
			
		||||
    return hookStateCount;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline int64_t
 | 
			
		||||
serialize_keylet(
 | 
			
		||||
    ripple::Keylet& kl,
 | 
			
		||||
@@ -1075,14 +1074,18 @@ hook::setHookState(
 | 
			
		||||
        return tefINTERNAL;
 | 
			
		||||
 | 
			
		||||
    // if the blob is too large don't set it
 | 
			
		||||
    if (data.size() > hook::maxHookStateDataSize())
 | 
			
		||||
    uint16_t const hookStateScale = sleAccount->isFieldPresent(sfHookStateScale)
 | 
			
		||||
        ? sleAccount->getFieldU16(sfHookStateScale)
 | 
			
		||||
        : 1;
 | 
			
		||||
 | 
			
		||||
    if (data.size() > hook::maxHookStateDataSize(hookStateScale))
 | 
			
		||||
        return temHOOK_DATA_TOO_LARGE;
 | 
			
		||||
 | 
			
		||||
    auto hookStateKeylet = ripple::keylet::hookState(acc, key, ns);
 | 
			
		||||
    auto hookStateDirKeylet = ripple::keylet::hookStateDir(acc, ns);
 | 
			
		||||
 | 
			
		||||
    uint32_t stateCount = sleAccount->getFieldU32(sfHookStateCount);
 | 
			
		||||
    uint32_t oldStateReserve = computeHookStateOwnerCount(stateCount);
 | 
			
		||||
    uint32_t oldStateCount = stateCount;
 | 
			
		||||
 | 
			
		||||
    auto hookState = view.peek(hookStateKeylet);
 | 
			
		||||
 | 
			
		||||
@@ -1113,13 +1116,15 @@ hook::setHookState(
 | 
			
		||||
        if (stateCount > 0)
 | 
			
		||||
            --stateCount;  // guard this because in the "impossible" event it is
 | 
			
		||||
                           // already 0 we'll wrap back to int_max
 | 
			
		||||
 | 
			
		||||
        // if removing this state entry would destroy the allotment then reduce
 | 
			
		||||
        // the owner count
 | 
			
		||||
        if (computeHookStateOwnerCount(stateCount) < oldStateReserve)
 | 
			
		||||
            adjustOwnerCount(view, sleAccount, -1, j);
 | 
			
		||||
        if (stateCount < oldStateCount)
 | 
			
		||||
            adjustOwnerCount(view, sleAccount, -hookStateScale, j);
 | 
			
		||||
 | 
			
		||||
        sleAccount->setFieldU32(sfHookStateCount, stateCount);
 | 
			
		||||
        if (view.rules().enabled(featureExtendedHookState) && stateCount == 0)
 | 
			
		||||
            sleAccount->makeFieldAbsent(sfHookStateCount);
 | 
			
		||||
        else
 | 
			
		||||
            sleAccount->setFieldU32(sfHookStateCount, stateCount);
 | 
			
		||||
 | 
			
		||||
        if (nsDestroyed)
 | 
			
		||||
            hook::removeHookNamespaceEntry(*sleAccount, ns);
 | 
			
		||||
@@ -1146,19 +1151,19 @@ hook::setHookState(
 | 
			
		||||
    {
 | 
			
		||||
        ++stateCount;
 | 
			
		||||
 | 
			
		||||
        if (computeHookStateOwnerCount(stateCount) > oldStateReserve)
 | 
			
		||||
        if (stateCount > oldStateCount)
 | 
			
		||||
        {
 | 
			
		||||
            // the hook used its allocated allotment of state entries for its
 | 
			
		||||
            // previous ownercount increment ownercount and give it another
 | 
			
		||||
            // allotment
 | 
			
		||||
 | 
			
		||||
            ++ownerCount;
 | 
			
		||||
            ownerCount += hookStateScale;
 | 
			
		||||
            XRPAmount const newReserve{view.fees().accountReserve(ownerCount)};
 | 
			
		||||
 | 
			
		||||
            if (STAmount((*sleAccount)[sfBalance]).xrp() < newReserve)
 | 
			
		||||
                return tecINSUFFICIENT_RESERVE;
 | 
			
		||||
 | 
			
		||||
            adjustOwnerCount(view, sleAccount, 1, j);
 | 
			
		||||
            adjustOwnerCount(view, sleAccount, hookStateScale, j);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // update state count
 | 
			
		||||
@@ -1446,7 +1451,7 @@ lookup_state_cache(
 | 
			
		||||
    if (stateMap.find(acc) == stateMap.end())
 | 
			
		||||
        return std::nullopt;
 | 
			
		||||
 | 
			
		||||
    auto& stateMapAcc = std::get<2>(stateMap[acc]);
 | 
			
		||||
    auto& stateMapAcc = std::get<3>(stateMap[acc]);
 | 
			
		||||
    if (stateMapAcc.find(ns) == stateMapAcc.end())
 | 
			
		||||
        return std::nullopt;
 | 
			
		||||
 | 
			
		||||
@@ -1481,6 +1486,7 @@ set_state_cache(
 | 
			
		||||
 | 
			
		||||
    if (stateMap.find(acc) == stateMap.end())
 | 
			
		||||
    {
 | 
			
		||||
        // new Account Key
 | 
			
		||||
        // if this is the first time this account has been interacted with
 | 
			
		||||
        // we will compute how many available reserve positions there are
 | 
			
		||||
        auto const& fees = hookCtx.applyCtx.view().fees();
 | 
			
		||||
@@ -1492,6 +1498,10 @@ set_state_cache(
 | 
			
		||||
 | 
			
		||||
        STAmount bal = accSLE->getFieldAmount(sfBalance);
 | 
			
		||||
 | 
			
		||||
        uint16_t const hookStateScale = accSLE->isFieldPresent(sfHookStateScale)
 | 
			
		||||
            ? accSLE->getFieldU16(sfHookStateScale)
 | 
			
		||||
            : 1;
 | 
			
		||||
 | 
			
		||||
        int64_t availableForReserves = bal.xrp().drops() -
 | 
			
		||||
            fees.accountReserve(accSLE->getFieldU32(sfOwnerCount)).drops();
 | 
			
		||||
 | 
			
		||||
@@ -1502,7 +1512,7 @@ set_state_cache(
 | 
			
		||||
 | 
			
		||||
        availableForReserves /= increment;
 | 
			
		||||
 | 
			
		||||
        if (availableForReserves < 1 && modified)
 | 
			
		||||
        if (availableForReserves < hookStateScale && modified)
 | 
			
		||||
            return RESERVE_INSUFFICIENT;
 | 
			
		||||
 | 
			
		||||
        int64_t namespaceCount = accSLE->isFieldPresent(sfHookNamespaces)
 | 
			
		||||
@@ -1521,20 +1531,28 @@ set_state_cache(
 | 
			
		||||
 | 
			
		||||
        stateMap.modified_entry_count++;
 | 
			
		||||
 | 
			
		||||
        // sanity check
 | 
			
		||||
        if (view.rules().enabled(featureExtendedHookState) &&
 | 
			
		||||
            availableForReserves < hookStateScale)
 | 
			
		||||
            return INTERNAL_ERROR;
 | 
			
		||||
 | 
			
		||||
        stateMap[acc] = {
 | 
			
		||||
            availableForReserves - 1,
 | 
			
		||||
            availableForReserves - hookStateScale,
 | 
			
		||||
            namespaceCount,
 | 
			
		||||
            hookStateScale,
 | 
			
		||||
            {{ns, {{key, {modified, data}}}}}};
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    auto& availableForReserves = std::get<0>(stateMap[acc]);
 | 
			
		||||
    auto& namespaceCount = std::get<1>(stateMap[acc]);
 | 
			
		||||
    auto& stateMapAcc = std::get<2>(stateMap[acc]);
 | 
			
		||||
    bool const canReserveNew = availableForReserves > 0;
 | 
			
		||||
    auto& hookStateScale = std::get<2>(stateMap[acc]);
 | 
			
		||||
    auto& stateMapAcc = std::get<3>(stateMap[acc]);
 | 
			
		||||
    bool const canReserveNew = availableForReserves >= hookStateScale;
 | 
			
		||||
 | 
			
		||||
    if (stateMapAcc.find(ns) == stateMapAcc.end())
 | 
			
		||||
    {
 | 
			
		||||
        // new Namespace Key
 | 
			
		||||
        if (modified)
 | 
			
		||||
        {
 | 
			
		||||
            if (!canReserveNew)
 | 
			
		||||
@@ -1552,7 +1570,11 @@ set_state_cache(
 | 
			
		||||
                namespaceCount++;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            availableForReserves--;
 | 
			
		||||
            if (view.rules().enabled(featureExtendedHookState) &&
 | 
			
		||||
                availableForReserves < hookStateScale)
 | 
			
		||||
                return INTERNAL_ERROR;
 | 
			
		||||
 | 
			
		||||
            availableForReserves -= hookStateScale;
 | 
			
		||||
            stateMap.modified_entry_count++;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -1564,11 +1586,17 @@ set_state_cache(
 | 
			
		||||
    auto& stateMapNs = stateMapAcc[ns];
 | 
			
		||||
    if (stateMapNs.find(key) == stateMapNs.end())
 | 
			
		||||
    {
 | 
			
		||||
        // new State Key
 | 
			
		||||
        if (modified)
 | 
			
		||||
        {
 | 
			
		||||
            if (!canReserveNew)
 | 
			
		||||
                return RESERVE_INSUFFICIENT;
 | 
			
		||||
            availableForReserves--;
 | 
			
		||||
 | 
			
		||||
            if (view.rules().enabled(featureExtendedHookState) &&
 | 
			
		||||
                availableForReserves < hookStateScale)
 | 
			
		||||
                return INTERNAL_ERROR;
 | 
			
		||||
 | 
			
		||||
            availableForReserves -= hookStateScale;
 | 
			
		||||
            stateMap.modified_entry_count++;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -1577,6 +1605,7 @@ set_state_cache(
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // existing State Key
 | 
			
		||||
    if (modified)
 | 
			
		||||
    {
 | 
			
		||||
        if (!stateMapNs[key].first)
 | 
			
		||||
@@ -1665,7 +1694,15 @@ DEFINE_HOOK_FUNCTION(
 | 
			
		||||
        (aread_len && NOT_IN_BOUNDS(aread_ptr, aread_len, memory_length)))
 | 
			
		||||
        return OUT_OF_BOUNDS;
 | 
			
		||||
 | 
			
		||||
    uint32_t maxSize = hook::maxHookStateDataSize();
 | 
			
		||||
    auto const sleAccount = view.peek(hookCtx.result.accountKeylet);
 | 
			
		||||
    if (!sleAccount && view.rules().enabled(featureExtendedHookState))
 | 
			
		||||
        return tefINTERNAL;
 | 
			
		||||
 | 
			
		||||
    uint16_t const hookStateScale = sleAccount->isFieldPresent(sfHookStateScale)
 | 
			
		||||
        ? sleAccount->getFieldU16(sfHookStateScale)
 | 
			
		||||
        : 1;
 | 
			
		||||
 | 
			
		||||
    uint32_t maxSize = hook::maxHookStateDataSize(hookStateScale);
 | 
			
		||||
    if (read_len > maxSize)
 | 
			
		||||
        return TOO_BIG;
 | 
			
		||||
 | 
			
		||||
@@ -1809,7 +1846,7 @@ hook::finalizeHookState(
 | 
			
		||||
    for (const auto& accEntry : stateMap)
 | 
			
		||||
    {
 | 
			
		||||
        const auto& acc = accEntry.first;
 | 
			
		||||
        for (const auto& nsEntry : std::get<2>(accEntry.second))
 | 
			
		||||
        for (const auto& nsEntry : std::get<3>(accEntry.second))
 | 
			
		||||
        {
 | 
			
		||||
            const auto& ns = nsEntry.first;
 | 
			
		||||
            for (const auto& cacheEntry : nsEntry.second)
 | 
			
		||||
@@ -2866,17 +2903,6 @@ DEFINE_HOOK_FUNCTION(
 | 
			
		||||
    if (write_len < 34)
 | 
			
		||||
        return TOO_SMALL;
 | 
			
		||||
 | 
			
		||||
    bool const v1 = applyCtx.view().rules().enabled(featureHooksUpdate1);
 | 
			
		||||
 | 
			
		||||
    if (keylet_type == 0)
 | 
			
		||||
        return INVALID_ARGUMENT;
 | 
			
		||||
 | 
			
		||||
    auto const last =
 | 
			
		||||
        v1 ? keylet_code::LAST_KLTYPE_V1 : keylet_code::LAST_KLTYPE_V0;
 | 
			
		||||
 | 
			
		||||
    if (keylet_type > last)
 | 
			
		||||
        return INVALID_ARGUMENT;
 | 
			
		||||
 | 
			
		||||
    try
 | 
			
		||||
    {
 | 
			
		||||
        switch (keylet_type)
 | 
			
		||||
@@ -2978,7 +3004,8 @@ DEFINE_HOOK_FUNCTION(
 | 
			
		||||
                return serialize_keylet(kl, memory, write_ptr, write_len);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // keylets that take 20 byte account id, and 4 byte uint
 | 
			
		||||
            // keylets that take 20 byte account id, and (4 byte uint for 32
 | 
			
		||||
            // byte hash)
 | 
			
		||||
            case keylet_code::OFFER:
 | 
			
		||||
            case keylet_code::CHECK:
 | 
			
		||||
            case keylet_code::ESCROW:
 | 
			
		||||
@@ -3021,6 +3048,33 @@ DEFINE_HOOK_FUNCTION(
 | 
			
		||||
                return serialize_keylet(kl, memory, write_ptr, write_len);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
                // keylets that take 20 byte account id, and 4 byte uint
 | 
			
		||||
            case keylet_code::CRON: {
 | 
			
		||||
                if (!applyCtx.view().rules().enabled(featureCron))
 | 
			
		||||
                    return INVALID_ARGUMENT;
 | 
			
		||||
 | 
			
		||||
                if (a == 0 || b == 0)
 | 
			
		||||
                    return INVALID_ARGUMENT;
 | 
			
		||||
                if (e != 0 || f != 0 || d != 0)
 | 
			
		||||
                    return INVALID_ARGUMENT;
 | 
			
		||||
 | 
			
		||||
                uint32_t read_ptr = a, read_len = b;
 | 
			
		||||
 | 
			
		||||
                if (NOT_IN_BOUNDS(read_ptr, read_len, memory_length))
 | 
			
		||||
                    return OUT_OF_BOUNDS;
 | 
			
		||||
 | 
			
		||||
                if (read_len != 20)
 | 
			
		||||
                    return INVALID_ARGUMENT;
 | 
			
		||||
 | 
			
		||||
                ripple::AccountID id = AccountID::fromVoid(memory + read_ptr);
 | 
			
		||||
 | 
			
		||||
                uint32_t seq = c;
 | 
			
		||||
 | 
			
		||||
                ripple::Keylet kl = ripple::keylet::cron(seq, id);
 | 
			
		||||
 | 
			
		||||
                return serialize_keylet(kl, memory, write_ptr, write_len);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // keylets that take a 32 byte uint and an 8byte uint64
 | 
			
		||||
            case keylet_code::PAGE: {
 | 
			
		||||
                if (a == 0 || b == 0)
 | 
			
		||||
@@ -3068,6 +3122,9 @@ DEFINE_HOOK_FUNCTION(
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            case keylet_code::HOOK_STATE_DIR: {
 | 
			
		||||
                if (!applyCtx.view().rules().enabled(featureHooksUpdate1))
 | 
			
		||||
                    return INVALID_ARGUMENT;
 | 
			
		||||
 | 
			
		||||
                if (a == 0 || b == 0 || c == 0 || d == 0)
 | 
			
		||||
                    return INVALID_ARGUMENT;
 | 
			
		||||
 | 
			
		||||
@@ -3150,15 +3207,15 @@ DEFINE_HOOK_FUNCTION(
 | 
			
		||||
                if (a == 0 || b == 0 || c == 0 || d == 0 || e == 0 || f == 0)
 | 
			
		||||
                    return INVALID_ARGUMENT;
 | 
			
		||||
 | 
			
		||||
                uint32_t hi_ptr = a, hi_len = b, lo_ptr = c, lo_len = d,
 | 
			
		||||
                uint32_t acc1_ptr = a, acc1_len = b, acc2_ptr = c, acc2_len = d,
 | 
			
		||||
                         cu_ptr = e, cu_len = f;
 | 
			
		||||
 | 
			
		||||
                if (NOT_IN_BOUNDS(hi_ptr, hi_len, memory_length) ||
 | 
			
		||||
                    NOT_IN_BOUNDS(lo_ptr, lo_len, memory_length) ||
 | 
			
		||||
                if (NOT_IN_BOUNDS(acc1_ptr, acc1_len, memory_length) ||
 | 
			
		||||
                    NOT_IN_BOUNDS(acc2_ptr, acc2_len, memory_length) ||
 | 
			
		||||
                    NOT_IN_BOUNDS(cu_ptr, cu_len, memory_length))
 | 
			
		||||
                    return OUT_OF_BOUNDS;
 | 
			
		||||
 | 
			
		||||
                if (hi_len != 20 || lo_len != 20)
 | 
			
		||||
                if (acc1_len != 20 || acc2_len != 20)
 | 
			
		||||
                    return INVALID_ARGUMENT;
 | 
			
		||||
 | 
			
		||||
                std::optional<Currency> cur =
 | 
			
		||||
@@ -3167,8 +3224,8 @@ DEFINE_HOOK_FUNCTION(
 | 
			
		||||
                    return INVALID_ARGUMENT;
 | 
			
		||||
 | 
			
		||||
                auto kl = ripple::keylet::line(
 | 
			
		||||
                    AccountID::fromVoid(memory + hi_ptr),
 | 
			
		||||
                    AccountID::fromVoid(memory + lo_ptr),
 | 
			
		||||
                    AccountID::fromVoid(memory + acc1_ptr),
 | 
			
		||||
                    AccountID::fromVoid(memory + acc2_ptr),
 | 
			
		||||
                    *cur);
 | 
			
		||||
                return serialize_keylet(kl, memory, write_ptr, write_len);
 | 
			
		||||
            }
 | 
			
		||||
@@ -3242,7 +3299,7 @@ DEFINE_HOOK_FUNCTION(
 | 
			
		||||
        return INTERNAL_ERROR;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return NO_SUCH_KEYLET;
 | 
			
		||||
    return INVALID_ARGUMENT;
 | 
			
		||||
 | 
			
		||||
    HOOK_TEARDOWN();
 | 
			
		||||
}
 | 
			
		||||
@@ -3577,7 +3634,7 @@ DEFINE_HOOK_FUNCTION(
 | 
			
		||||
    {
 | 
			
		||||
        JLOG(j.trace()) << "HookEmit[" << HC_ACC()
 | 
			
		||||
                        << "]: Transaction preflight failure: "
 | 
			
		||||
                        << preflightResult.ter;
 | 
			
		||||
                        << transHuman(preflightResult.ter);
 | 
			
		||||
        return EMISSION_FAILURE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -156,34 +156,22 @@ deserializeManifest(Slice s, beast::Journal journal)
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <class Stream>
 | 
			
		||||
Stream&
 | 
			
		||||
logMftAct(
 | 
			
		||||
    Stream& s,
 | 
			
		||||
    std::string const& action,
 | 
			
		||||
    PublicKey const& pk,
 | 
			
		||||
    std::uint32_t seq)
 | 
			
		||||
{
 | 
			
		||||
    s << "Manifest: " << action
 | 
			
		||||
      << ";Pk: " << toBase58(TokenType::NodePublic, pk) << ";Seq: " << seq
 | 
			
		||||
      << ";";
 | 
			
		||||
    return s;
 | 
			
		||||
}
 | 
			
		||||
// Helper macros to format manifest log messages while preserving line numbers
 | 
			
		||||
#define LOG_MANIFEST_ACTION(stream, action, pk, seq)                   \
 | 
			
		||||
    do                                                                 \
 | 
			
		||||
    {                                                                  \
 | 
			
		||||
        JLOG(stream) << "Manifest: " << action                         \
 | 
			
		||||
                     << ";Pk: " << toBase58(TokenType::NodePublic, pk) \
 | 
			
		||||
                     << ";Seq: " << seq << ";";                        \
 | 
			
		||||
    } while (0)
 | 
			
		||||
 | 
			
		||||
template <class Stream>
 | 
			
		||||
Stream&
 | 
			
		||||
logMftAct(
 | 
			
		||||
    Stream& s,
 | 
			
		||||
    std::string const& action,
 | 
			
		||||
    PublicKey const& pk,
 | 
			
		||||
    std::uint32_t seq,
 | 
			
		||||
    std::uint32_t oldSeq)
 | 
			
		||||
{
 | 
			
		||||
    s << "Manifest: " << action
 | 
			
		||||
      << ";Pk: " << toBase58(TokenType::NodePublic, pk) << ";Seq: " << seq
 | 
			
		||||
      << ";OldSeq: " << oldSeq << ";";
 | 
			
		||||
    return s;
 | 
			
		||||
}
 | 
			
		||||
#define LOG_MANIFEST_ACTION_WITH_OLD(stream, action, pk, seq, oldSeq)    \
 | 
			
		||||
    do                                                                   \
 | 
			
		||||
    {                                                                    \
 | 
			
		||||
        JLOG(stream) << "Manifest: " << action                           \
 | 
			
		||||
                     << ";Pk: " << toBase58(TokenType::NodePublic, pk)   \
 | 
			
		||||
                     << ";Seq: " << seq << ";OldSeq: " << oldSeq << ";"; \
 | 
			
		||||
    } while (0)
 | 
			
		||||
 | 
			
		||||
bool
 | 
			
		||||
Manifest::verify() const
 | 
			
		||||
@@ -381,7 +369,7 @@ ManifestCache::applyManifest(Manifest m)
 | 
			
		||||
            // several cases including when we receive manifests from a peer who
 | 
			
		||||
            // doesn't have the latest data.
 | 
			
		||||
            if (auto stream = j_.debug())
 | 
			
		||||
                logMftAct(
 | 
			
		||||
                LOG_MANIFEST_ACTION_WITH_OLD(
 | 
			
		||||
                    stream,
 | 
			
		||||
                    "Stale",
 | 
			
		||||
                    m.masterKey,
 | 
			
		||||
@@ -393,7 +381,7 @@ ManifestCache::applyManifest(Manifest m)
 | 
			
		||||
        if (checkSignature && !m.verify())
 | 
			
		||||
        {
 | 
			
		||||
            if (auto stream = j_.warn())
 | 
			
		||||
                logMftAct(stream, "Invalid", m.masterKey, m.sequence);
 | 
			
		||||
                LOG_MANIFEST_ACTION(stream, "Invalid", m.masterKey, m.sequence);
 | 
			
		||||
            return ManifestDisposition::invalid;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -407,7 +395,7 @@ ManifestCache::applyManifest(Manifest m)
 | 
			
		||||
        bool const revoked = m.revoked();
 | 
			
		||||
 | 
			
		||||
        if (auto stream = j_.warn(); stream && revoked)
 | 
			
		||||
            logMftAct(stream, "Revoked", m.masterKey, m.sequence);
 | 
			
		||||
            LOG_MANIFEST_ACTION(stream, "Revoked", m.masterKey, m.sequence);
 | 
			
		||||
 | 
			
		||||
        // Sanity check: the master key of this manifest should not be used as
 | 
			
		||||
        // the ephemeral key of another manifest:
 | 
			
		||||
@@ -476,7 +464,7 @@ ManifestCache::applyManifest(Manifest m)
 | 
			
		||||
    if (iter == map_.end())
 | 
			
		||||
    {
 | 
			
		||||
        if (auto stream = j_.info())
 | 
			
		||||
            logMftAct(stream, "AcceptedNew", m.masterKey, m.sequence);
 | 
			
		||||
            LOG_MANIFEST_ACTION(stream, "AcceptedNew", m.masterKey, m.sequence);
 | 
			
		||||
 | 
			
		||||
        if (!revoked)
 | 
			
		||||
            signingToMasterKeys_[m.signingKey] = m.masterKey;
 | 
			
		||||
@@ -489,7 +477,7 @@ ManifestCache::applyManifest(Manifest m)
 | 
			
		||||
    // An ephemeral key was revoked and superseded by a new key. This is
 | 
			
		||||
    // expected, but should happen infrequently.
 | 
			
		||||
    if (auto stream = j_.info())
 | 
			
		||||
        logMftAct(
 | 
			
		||||
        LOG_MANIFEST_ACTION_WITH_OLD(
 | 
			
		||||
            stream,
 | 
			
		||||
            "AcceptedUpdate",
 | 
			
		||||
            m.masterKey,
 | 
			
		||||
@@ -584,4 +572,9 @@ ManifestCache::save(
 | 
			
		||||
 | 
			
		||||
    saveManifests(*db, dbTable, isTrusted, map_, j_);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Clean up macros to avoid namespace pollution
 | 
			
		||||
#undef LOG_MANIFEST_ACTION
 | 
			
		||||
#undef LOG_MANIFEST_ACTION_WITH_OLD
 | 
			
		||||
 | 
			
		||||
}  // namespace ripple
 | 
			
		||||
 
 | 
			
		||||
@@ -1477,6 +1477,64 @@ TxQ::accept(Application& app, OpenView& view)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Inject cron transactions, if any
 | 
			
		||||
    if (view.rules().enabled(featureCron))
 | 
			
		||||
    {
 | 
			
		||||
        uint32_t currentTime =
 | 
			
		||||
            view.parentCloseTime().time_since_epoch().count();
 | 
			
		||||
        uint256 klStart = keylet::cron(0, AccountID(beast::zero)).key;
 | 
			
		||||
        uint256 const klEnd =
 | 
			
		||||
            keylet::cron(currentTime + 1, AccountID(beast::zero)).key;
 | 
			
		||||
 | 
			
		||||
        std::set<AccountID> cronAccs;
 | 
			
		||||
 | 
			
		||||
        auto counter = 0;
 | 
			
		||||
        // include max 128 cron txns in the ledger
 | 
			
		||||
        while (++counter < 129 && klStart < klEnd)
 | 
			
		||||
        {
 | 
			
		||||
            std::optional<uint256 const> next = view.succ(klStart, klEnd);
 | 
			
		||||
            if (!next.has_value())
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            Keylet kl{ltANY, *next};
 | 
			
		||||
 | 
			
		||||
            if (view.exists(kl))
 | 
			
		||||
            {
 | 
			
		||||
                auto sle = view.read(kl);
 | 
			
		||||
                if (safe_cast<LedgerEntryType>(
 | 
			
		||||
                        sle->getFieldU16(sfLedgerEntryType)) == ltCRON)
 | 
			
		||||
                {
 | 
			
		||||
                    // valid cron object, add it to the list
 | 
			
		||||
                    cronAccs.emplace(sle->getAccountID(sfOwner));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            klStart = *next;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        auto const seq = view.info().seq;
 | 
			
		||||
 | 
			
		||||
        // insert Cron pseudos for each of the accs we need to ping
 | 
			
		||||
        for (AccountID const& id : cronAccs)
 | 
			
		||||
        {
 | 
			
		||||
            STTx cronTx(ttCRON, [=](auto& obj) {
 | 
			
		||||
                obj[sfAccount] = AccountID();
 | 
			
		||||
                obj[sfLedgerSequence] = seq;
 | 
			
		||||
                obj[sfOwner] = id;
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            uint256 txID = cronTx.getTransactionID();
 | 
			
		||||
 | 
			
		||||
            auto s = std::make_shared<ripple::Serializer>();
 | 
			
		||||
            cronTx.add(*s);
 | 
			
		||||
 | 
			
		||||
            app.getHashRouter().setFlags(txID, SF_PRIVATE2);
 | 
			
		||||
            app.getHashRouter().setFlags(txID, SF_EMITTED);
 | 
			
		||||
            view.rawTxInsert(txID, std::move(s), nullptr);
 | 
			
		||||
            ledgerChanged = true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Inject emitted transactions if any
 | 
			
		||||
    if (view.rules().enabled(featureHooks))
 | 
			
		||||
        do
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
    }
 | 
			
		||||
@@ -224,7 +221,8 @@ public:
 | 
			
		||||
 | 
			
		||||
        if (!ledger->info().accountHash.isNonZero())
 | 
			
		||||
        {
 | 
			
		||||
            JLOG(j.fatal()) << "AH is zero: " << getJson({*ledger, {}});
 | 
			
		||||
            JLOG(j.fatal())
 | 
			
		||||
                << "AH is zero: " << getJson({*ledger, {}}).asString();
 | 
			
		||||
            assert(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -293,10 +291,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 +446,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 +649,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 +700,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 +734,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 +785,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 +857,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 +867,10 @@ public:
 | 
			
		||||
                            lookingForMarker = false;
 | 
			
		||||
                        }
 | 
			
		||||
                        else
 | 
			
		||||
                        {
 | 
			
		||||
                            ++txnSeq;
 | 
			
		||||
                            continue;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    else if (numberOfResults == 0)
 | 
			
		||||
                    {
 | 
			
		||||
@@ -837,12 +879,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 +896,7 @@ public:
 | 
			
		||||
                        std::move(rawMeta));
 | 
			
		||||
                    --numberOfResults;
 | 
			
		||||
                    ++total;
 | 
			
		||||
                    ++txnSeq;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -871,11 +912,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 +924,10 @@ public:
 | 
			
		||||
                            lookingForMarker = false;
 | 
			
		||||
                        }
 | 
			
		||||
                        else
 | 
			
		||||
                        {
 | 
			
		||||
                            --txnSeq;
 | 
			
		||||
                            continue;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    else if (numberOfResults == 0)
 | 
			
		||||
                    {
 | 
			
		||||
@@ -892,12 +936,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 +954,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>();
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -94,21 +94,6 @@ Change::preflight(PreflightContext const& ctx)
 | 
			
		||||
                                  "of sfImportVLKey, sfActiveValidator";
 | 
			
		||||
            return temMALFORMED;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // if we do specify import_vl_keys in config then we won't approve keys
 | 
			
		||||
        // that aren't on our list
 | 
			
		||||
        if (ctx.tx.isFieldPresent(sfImportVLKey) &&
 | 
			
		||||
            !ctx.app.config().IMPORT_VL_KEYS.empty())
 | 
			
		||||
        {
 | 
			
		||||
            auto const& inner = const_cast<ripple::STTx&>(ctx.tx)
 | 
			
		||||
                                    .getField(sfImportVLKey)
 | 
			
		||||
                                    .downcast<STObject>();
 | 
			
		||||
            auto const pk = inner.getFieldVL(sfPublicKey);
 | 
			
		||||
            std::string const strPk = strHex(makeSlice(pk));
 | 
			
		||||
            if (ctx.app.config().IMPORT_VL_KEYS.find(strPk) ==
 | 
			
		||||
                ctx.app.config().IMPORT_VL_KEYS.end())
 | 
			
		||||
                return telIMPORT_VL_KEY_NOT_RECOGNISED;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return tesSUCCESS;
 | 
			
		||||
@@ -168,9 +153,42 @@ Change::preclaim(PreclaimContext const& ctx)
 | 
			
		||||
            return tesSUCCESS;
 | 
			
		||||
        case ttAMENDMENT:
 | 
			
		||||
        case ttUNL_MODIFY:
 | 
			
		||||
        case ttUNL_REPORT:
 | 
			
		||||
        case ttEMIT_FAILURE:
 | 
			
		||||
            return tesSUCCESS;
 | 
			
		||||
        case ttUNL_REPORT: {
 | 
			
		||||
            if (!ctx.tx.isFieldPresent(sfImportVLKey) ||
 | 
			
		||||
                ctx.app.config().IMPORT_VL_KEYS.empty())
 | 
			
		||||
                return tesSUCCESS;
 | 
			
		||||
 | 
			
		||||
            // if we do specify import_vl_keys in config then we won't approve
 | 
			
		||||
            // keys that aren't on our list and/or aren't in the ledger object
 | 
			
		||||
            auto const& inner = const_cast<ripple::STTx&>(ctx.tx)
 | 
			
		||||
                                    .getField(sfImportVLKey)
 | 
			
		||||
                                    .downcast<STObject>();
 | 
			
		||||
            auto const pkBlob = inner.getFieldVL(sfPublicKey);
 | 
			
		||||
            std::string const strPk = strHex(makeSlice(pkBlob));
 | 
			
		||||
            if (ctx.app.config().IMPORT_VL_KEYS.find(strPk) !=
 | 
			
		||||
                ctx.app.config().IMPORT_VL_KEYS.end())
 | 
			
		||||
                return tesSUCCESS;
 | 
			
		||||
 | 
			
		||||
            auto const pkType = publicKeyType(makeSlice(pkBlob));
 | 
			
		||||
            if (!pkType)
 | 
			
		||||
                return tefINTERNAL;
 | 
			
		||||
 | 
			
		||||
            PublicKey const pk(makeSlice(pkBlob));
 | 
			
		||||
 | 
			
		||||
            // check on ledger
 | 
			
		||||
            if (auto const unlRep = ctx.view.read(keylet::UNLReport());
 | 
			
		||||
                unlRep && unlRep->isFieldPresent(sfImportVLKeys))
 | 
			
		||||
            {
 | 
			
		||||
                auto const& vlKeys = unlRep->getFieldArray(sfImportVLKeys);
 | 
			
		||||
                for (auto const& k : vlKeys)
 | 
			
		||||
                    if (PublicKey(k[sfPublicKey]) == pk)
 | 
			
		||||
                        return tesSUCCESS;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return telIMPORT_VL_KEY_NOT_RECOGNISED;
 | 
			
		||||
        }
 | 
			
		||||
        default:
 | 
			
		||||
            return temUNKNOWN;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										189
									
								
								src/ripple/app/tx/impl/Cron.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										189
									
								
								src/ripple/app/tx/impl/Cron.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,189 @@
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
/*
 | 
			
		||||
    This file is part of rippled: https://github.com/ripple/rippled
 | 
			
		||||
    Copyright (c) 2024 XRPL-Labs
 | 
			
		||||
 | 
			
		||||
    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/tx/impl/Cron.h>
 | 
			
		||||
#include <ripple/basics/Log.h>
 | 
			
		||||
#include <ripple/core/Config.h>
 | 
			
		||||
#include <ripple/ledger/View.h>
 | 
			
		||||
#include <ripple/protocol/Feature.h>
 | 
			
		||||
#include <ripple/protocol/Indexes.h>
 | 
			
		||||
#include <ripple/protocol/PublicKey.h>
 | 
			
		||||
#include <ripple/protocol/Quality.h>
 | 
			
		||||
#include <ripple/protocol/TxFlags.h>
 | 
			
		||||
#include <ripple/protocol/st.h>
 | 
			
		||||
 | 
			
		||||
namespace ripple {
 | 
			
		||||
 | 
			
		||||
TxConsequences
 | 
			
		||||
Cron::makeTxConsequences(PreflightContext const& ctx)
 | 
			
		||||
{
 | 
			
		||||
    return TxConsequences{ctx.tx, TxConsequences::normal};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
NotTEC
 | 
			
		||||
Cron::preflight(PreflightContext const& ctx)
 | 
			
		||||
{
 | 
			
		||||
    if (!ctx.rules.enabled(featureCron))
 | 
			
		||||
        return temDISABLED;
 | 
			
		||||
 | 
			
		||||
    auto const ret = preflight0(ctx);
 | 
			
		||||
    if (!isTesSuccess(ret))
 | 
			
		||||
        return ret;
 | 
			
		||||
 | 
			
		||||
    auto account = ctx.tx.getAccountID(sfAccount);
 | 
			
		||||
    if (account != beast::zero)
 | 
			
		||||
    {
 | 
			
		||||
        JLOG(ctx.j.warn()) << "Cron: Bad source id";
 | 
			
		||||
        return temBAD_SRC_ACCOUNT;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // No point in going any further if the transaction fee is malformed.
 | 
			
		||||
    auto const fee = ctx.tx.getFieldAmount(sfFee);
 | 
			
		||||
    if (!fee.native() || fee != beast::zero)
 | 
			
		||||
    {
 | 
			
		||||
        JLOG(ctx.j.warn()) << "Cron: invalid fee";
 | 
			
		||||
        return temBAD_FEE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!ctx.tx.getSigningPubKey().empty() || !ctx.tx.getSignature().empty() ||
 | 
			
		||||
        ctx.tx.isFieldPresent(sfSigners))
 | 
			
		||||
    {
 | 
			
		||||
        JLOG(ctx.j.warn()) << "Cron: Bad signature";
 | 
			
		||||
        return temBAD_SIGNATURE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (ctx.tx.getFieldU32(sfSequence) != 0 ||
 | 
			
		||||
        ctx.tx.isFieldPresent(sfPreviousTxnID))
 | 
			
		||||
    {
 | 
			
		||||
        JLOG(ctx.j.warn()) << "Cron: Bad sequence";
 | 
			
		||||
        return temBAD_SEQUENCE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return tesSUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TER
 | 
			
		||||
Cron::preclaim(PreclaimContext const& ctx)
 | 
			
		||||
{
 | 
			
		||||
    if (!ctx.view.rules().enabled(featureCron))
 | 
			
		||||
        return temDISABLED;
 | 
			
		||||
 | 
			
		||||
    return tesSUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TER
 | 
			
		||||
Cron::doApply()
 | 
			
		||||
{
 | 
			
		||||
    auto& view = ctx_.view();
 | 
			
		||||
    auto const& tx = ctx_.tx;
 | 
			
		||||
 | 
			
		||||
    AccountID const& id = tx.getAccountID(sfOwner);
 | 
			
		||||
 | 
			
		||||
    auto sle = view.peek(keylet::account(id));
 | 
			
		||||
    if (!sle)
 | 
			
		||||
    {
 | 
			
		||||
        // should never happen... but might in a race condition with acc delete
 | 
			
		||||
        JLOG(j_.warn()) << "Cron: sfOwner account missing. " << id;
 | 
			
		||||
        return tesSUCCESS;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!sle->isFieldPresent(sfCron))
 | 
			
		||||
    {
 | 
			
		||||
        JLOG(j_.warn()) << "Cron: sfCron missing from account " << id;
 | 
			
		||||
        return tefINTERNAL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    uint256 ptr = sle->getFieldH256(sfCron);
 | 
			
		||||
    Keylet klOld{ltCRON, ptr};
 | 
			
		||||
    auto sleCron = view.peek(klOld);
 | 
			
		||||
    if (!sleCron)
 | 
			
		||||
    {
 | 
			
		||||
        JLOG(j_.warn()) << "Cron: Cron object missing for account " << id;
 | 
			
		||||
        return tesSUCCESS;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    uint32_t delay = sleCron->getFieldU32(sfDelaySeconds);
 | 
			
		||||
    uint32_t recur = sleCron->getFieldU32(sfRepeatCount);
 | 
			
		||||
 | 
			
		||||
    uint32_t lastStartTime = sleCron->getFieldU32(sfStartTime);
 | 
			
		||||
 | 
			
		||||
    // do all this sanity checking before we modify the ledger...
 | 
			
		||||
    uint32_t afterTime = lastStartTime + delay;
 | 
			
		||||
    if (afterTime < lastStartTime)
 | 
			
		||||
        return tefINTERNAL;
 | 
			
		||||
 | 
			
		||||
    // in all circumstances the Cron object is deleted...
 | 
			
		||||
    // if there are further crons to do then a new one is created at the next
 | 
			
		||||
    // time point
 | 
			
		||||
 | 
			
		||||
    if (!view.dirRemove(
 | 
			
		||||
            keylet::ownerDir(id), (*sleCron)[sfOwnerNode], klOld, false))
 | 
			
		||||
        return tefBAD_LEDGER;
 | 
			
		||||
 | 
			
		||||
    view.erase(sleCron);
 | 
			
		||||
 | 
			
		||||
    if (recur == 0)
 | 
			
		||||
    {
 | 
			
		||||
        // already at last execution, stop here
 | 
			
		||||
        adjustOwnerCount(view, sle, -1, j_);
 | 
			
		||||
        sle->makeFieldAbsent(sfCron);
 | 
			
		||||
        view.update(sle);
 | 
			
		||||
        return tesSUCCESS;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // more executions remain, so create a new object
 | 
			
		||||
 | 
			
		||||
    Keylet klCron = keylet::cron(afterTime, id);
 | 
			
		||||
 | 
			
		||||
    // insert into owner dir, we don't need to check reserve because we've just
 | 
			
		||||
    // deleted an object
 | 
			
		||||
    auto const page =
 | 
			
		||||
        view.dirInsert(keylet::ownerDir(id), klCron, describeOwnerDir(id));
 | 
			
		||||
    if (!page)
 | 
			
		||||
        return tecDIR_FULL;
 | 
			
		||||
 | 
			
		||||
    sleCron = std::make_shared<SLE>(klCron);
 | 
			
		||||
 | 
			
		||||
    sleCron->setFieldU64(sfOwnerNode, *page);
 | 
			
		||||
    sleCron->setFieldU32(sfDelaySeconds, delay);
 | 
			
		||||
    sleCron->setFieldU32(sfRepeatCount, recur - 1);
 | 
			
		||||
    sleCron->setFieldU32(sfStartTime, afterTime);
 | 
			
		||||
    sleCron->setAccountID(sfOwner, id);
 | 
			
		||||
 | 
			
		||||
    sle->setFieldH256(sfCron, klCron.key);
 | 
			
		||||
 | 
			
		||||
    view.insert(sleCron);
 | 
			
		||||
    view.update(sle);
 | 
			
		||||
 | 
			
		||||
    return tesSUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
Cron::preCompute()
 | 
			
		||||
{
 | 
			
		||||
    assert(account_ == beast::zero);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
XRPAmount
 | 
			
		||||
Cron::calculateBaseFee(ReadView const& view, STTx const& tx)
 | 
			
		||||
{
 | 
			
		||||
    return XRPAmount{0};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}  // namespace ripple
 | 
			
		||||
							
								
								
									
										60
									
								
								src/ripple/app/tx/impl/Cron.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								src/ripple/app/tx/impl/Cron.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,60 @@
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
/*
 | 
			
		||||
    This file is part of rippled: https://github.com/ripple/rippled
 | 
			
		||||
    Copyright (c) 2024 XRPL-Labs
 | 
			
		||||
 | 
			
		||||
    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.
 | 
			
		||||
*/
 | 
			
		||||
//==============================================================================
 | 
			
		||||
 | 
			
		||||
#ifndef RIPPLE_TX_CRON_H_INCLUDED
 | 
			
		||||
#define RIPPLE_TX_CRON_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#include <ripple/app/tx/impl/Transactor.h>
 | 
			
		||||
#include <ripple/basics/Log.h>
 | 
			
		||||
#include <ripple/core/Config.h>
 | 
			
		||||
#include <ripple/protocol/Indexes.h>
 | 
			
		||||
 | 
			
		||||
namespace ripple {
 | 
			
		||||
 | 
			
		||||
class Cron : public Transactor
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    static constexpr ConsequencesFactoryType ConsequencesFactory{Custom};
 | 
			
		||||
 | 
			
		||||
    explicit Cron(ApplyContext& ctx) : Transactor(ctx)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static XRPAmount
 | 
			
		||||
    calculateBaseFee(ReadView const& view, STTx const& tx);
 | 
			
		||||
 | 
			
		||||
    static TxConsequences
 | 
			
		||||
    makeTxConsequences(PreflightContext const& ctx);
 | 
			
		||||
 | 
			
		||||
    static NotTEC
 | 
			
		||||
    preflight(PreflightContext const& ctx);
 | 
			
		||||
 | 
			
		||||
    static TER
 | 
			
		||||
    preclaim(PreclaimContext const&);
 | 
			
		||||
 | 
			
		||||
    TER
 | 
			
		||||
    doApply() override;
 | 
			
		||||
 | 
			
		||||
    void
 | 
			
		||||
    preCompute() override;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}  // namespace ripple
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
							
								
								
									
										305
									
								
								src/ripple/app/tx/impl/CronSet.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										305
									
								
								src/ripple/app/tx/impl/CronSet.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,305 @@
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
/*
 | 
			
		||||
    This file is part of rippled: https://github.com/ripple/rippled
 | 
			
		||||
    Copyright (c) 2024 XRPL-Labs
 | 
			
		||||
 | 
			
		||||
    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/tx/impl/CronSet.h>
 | 
			
		||||
#include <ripple/basics/Log.h>
 | 
			
		||||
#include <ripple/ledger/View.h>
 | 
			
		||||
#include <ripple/protocol/Feature.h>
 | 
			
		||||
#include <ripple/protocol/Indexes.h>
 | 
			
		||||
#include <ripple/protocol/TxFlags.h>
 | 
			
		||||
#include <ripple/protocol/st.h>
 | 
			
		||||
 | 
			
		||||
namespace ripple {
 | 
			
		||||
 | 
			
		||||
TxConsequences
 | 
			
		||||
CronSet::makeTxConsequences(PreflightContext const& ctx)
 | 
			
		||||
{
 | 
			
		||||
    return TxConsequences{ctx.tx, TxConsequences::normal};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
NotTEC
 | 
			
		||||
CronSet::preflight(PreflightContext const& ctx)
 | 
			
		||||
{
 | 
			
		||||
    if (!ctx.rules.enabled(featureCron))
 | 
			
		||||
        return temDISABLED;
 | 
			
		||||
 | 
			
		||||
    if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
 | 
			
		||||
        return ret;
 | 
			
		||||
 | 
			
		||||
    auto& tx = ctx.tx;
 | 
			
		||||
    auto& j = ctx.j;
 | 
			
		||||
 | 
			
		||||
    if (tx.getFlags() & tfCronSetMask)
 | 
			
		||||
    {
 | 
			
		||||
        JLOG(j.warn()) << "CronSet: Invalid flags set.";
 | 
			
		||||
        return temINVALID_FLAG;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // DelaySeconds (D), RepeatCount (R), StartTime (S)
 | 
			
		||||
    // DRS - Set Cron with Delay and Repeat and StartTime
 | 
			
		||||
    // DR- - Invalid(StartTime is required)
 | 
			
		||||
    // D-S - Invalid (both DelaySeconds and RepeatCount are required)
 | 
			
		||||
    // -RS - Invalid (both DelaySeconds and RepeatCount are required)
 | 
			
		||||
    // --S - Onetime cron with StartTime only
 | 
			
		||||
    // -- - Clear any existing cron (succeeds even if there isn't one) / with
 | 
			
		||||
    // tfCronUnset flag set
 | 
			
		||||
 | 
			
		||||
    bool const hasDelay = tx.isFieldPresent(sfDelaySeconds);
 | 
			
		||||
    bool const hasRepeat = tx.isFieldPresent(sfRepeatCount);
 | 
			
		||||
    bool const hasStartTime = tx.isFieldPresent(sfStartTime);
 | 
			
		||||
 | 
			
		||||
    if (tx.isFlag(tfCronUnset))
 | 
			
		||||
    {
 | 
			
		||||
        // delete operation
 | 
			
		||||
        if (hasDelay || hasRepeat || hasStartTime)
 | 
			
		||||
        {
 | 
			
		||||
            JLOG(j.debug()) << "CronSet: tfCronUnset flag cannot be used with "
 | 
			
		||||
                               "DelaySeconds, RepeatCount or StartTime.";
 | 
			
		||||
            return temMALFORMED;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        // create operation
 | 
			
		||||
 | 
			
		||||
        if (!hasStartTime)
 | 
			
		||||
        {
 | 
			
		||||
            JLOG(j.debug())
 | 
			
		||||
                << "CronSet: StartTime is required. Use StartTime=0 for "
 | 
			
		||||
                   "immediate execution, or specify a future timestamp.";
 | 
			
		||||
            return temMALFORMED;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if ((!hasDelay && hasRepeat) || (hasDelay && !hasRepeat))
 | 
			
		||||
        {
 | 
			
		||||
            JLOG(j.debug())
 | 
			
		||||
                << "CronSet: DelaySeconds and RepeatCount must both be present "
 | 
			
		||||
                   "for recurring crons, or both absent for one-off crons.";
 | 
			
		||||
            return temMALFORMED;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // check delay is not too high
 | 
			
		||||
        if (hasDelay)
 | 
			
		||||
        {
 | 
			
		||||
            auto delay = tx.getFieldU32(sfDelaySeconds);
 | 
			
		||||
            if (delay > 31536000UL /* 365 days in seconds */)
 | 
			
		||||
            {
 | 
			
		||||
                JLOG(j.debug())
 | 
			
		||||
                    << "CronSet: DelaySeconds was too high. (max 365 "
 | 
			
		||||
                       "days in seconds).";
 | 
			
		||||
                return temMALFORMED;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // check repeat is not too high
 | 
			
		||||
        if (hasRepeat)
 | 
			
		||||
        {
 | 
			
		||||
            auto recur = tx.getFieldU32(sfRepeatCount);
 | 
			
		||||
            if (recur == 0)
 | 
			
		||||
            {
 | 
			
		||||
                JLOG(j.debug())
 | 
			
		||||
                    << "CronSet: RepeatCount must be greater than 0."
 | 
			
		||||
                       "For one-time execution, omit DelaySeconds and "
 | 
			
		||||
                       "RepeatCount.";
 | 
			
		||||
                return temMALFORMED;
 | 
			
		||||
            }
 | 
			
		||||
            if (recur > 256)
 | 
			
		||||
            {
 | 
			
		||||
                JLOG(j.debug())
 | 
			
		||||
                    << "CronSet: RepeatCount too high. Limit is 256. Issue "
 | 
			
		||||
                       "new CronSet to increase.";
 | 
			
		||||
                return temMALFORMED;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return preflight2(ctx);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TER
 | 
			
		||||
CronSet::preclaim(PreclaimContext const& ctx)
 | 
			
		||||
{
 | 
			
		||||
    if (ctx.tx.isFieldPresent(sfStartTime) &&
 | 
			
		||||
        ctx.tx.getFieldU32(sfStartTime) != 0)
 | 
			
		||||
    {
 | 
			
		||||
        // StartTime 0 means the cron will execute immediately
 | 
			
		||||
 | 
			
		||||
        auto const startTime = ctx.tx.getFieldU32(sfStartTime);
 | 
			
		||||
        auto const parentCloseTime =
 | 
			
		||||
            ctx.view.parentCloseTime().time_since_epoch().count();
 | 
			
		||||
 | 
			
		||||
        if (startTime < parentCloseTime)
 | 
			
		||||
        {
 | 
			
		||||
            JLOG(ctx.j.debug()) << "CronSet: StartTime must be in the future "
 | 
			
		||||
                                   "(or 0 for immediate execution)";
 | 
			
		||||
            return tecEXPIRED;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (startTime > ctx.view.parentCloseTime().time_since_epoch().count() +
 | 
			
		||||
                365 * 24 * 60 * 60)
 | 
			
		||||
        {
 | 
			
		||||
            JLOG(ctx.j.debug()) << "CronSet: StartTime is too far in the "
 | 
			
		||||
                                   "future (max 365 days).";
 | 
			
		||||
            return tecEXPIRED;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return tesSUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TER
 | 
			
		||||
CronSet::doApply()
 | 
			
		||||
{
 | 
			
		||||
    auto& view = ctx_.view();
 | 
			
		||||
    auto const& tx = ctx_.tx;
 | 
			
		||||
 | 
			
		||||
    bool const isDelete = tx.isFlag(tfCronUnset);
 | 
			
		||||
 | 
			
		||||
    // delay can be zero, in which case the cron will usually execute next
 | 
			
		||||
    // ledger.
 | 
			
		||||
    uint32_t delay{0};
 | 
			
		||||
    uint32_t recur{0};
 | 
			
		||||
    uint32_t startTime{0};
 | 
			
		||||
 | 
			
		||||
    if (!isDelete)
 | 
			
		||||
    {
 | 
			
		||||
        if (tx.isFieldPresent(sfDelaySeconds))
 | 
			
		||||
            delay = tx.getFieldU32(sfDelaySeconds);
 | 
			
		||||
        if (tx.isFieldPresent(sfRepeatCount))
 | 
			
		||||
            recur = tx.getFieldU32(sfRepeatCount);
 | 
			
		||||
        if (tx.isFieldPresent(sfStartTime))
 | 
			
		||||
        {
 | 
			
		||||
            startTime = tx.getFieldU32(sfStartTime);
 | 
			
		||||
            if (startTime == 0)
 | 
			
		||||
                startTime = view.parentCloseTime().time_since_epoch().count();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    AccountID const& id = tx.getAccountID(sfAccount);
 | 
			
		||||
    auto sle = view.peek(keylet::account(id));
 | 
			
		||||
    if (!sle)
 | 
			
		||||
        return tefINTERNAL;
 | 
			
		||||
 | 
			
		||||
    // in all cases whatsoever, this transaction will delete an existing
 | 
			
		||||
    // old cron object and return the owner reserve to the owner.
 | 
			
		||||
 | 
			
		||||
    if (sle->isFieldPresent(sfCron))
 | 
			
		||||
    {
 | 
			
		||||
        Keylet klOld{ltCRON, sle->getFieldH256(sfCron)};
 | 
			
		||||
 | 
			
		||||
        auto sleCron = view.peek(klOld);
 | 
			
		||||
        if (!sleCron)
 | 
			
		||||
        {
 | 
			
		||||
            JLOG(j_.warn()) << "CronSet: Cron object didn't exist.";
 | 
			
		||||
            return tefBAD_LEDGER;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (safe_cast<LedgerEntryType>(
 | 
			
		||||
                sleCron->getFieldU16(sfLedgerEntryType)) != ltCRON)
 | 
			
		||||
        {
 | 
			
		||||
            JLOG(j_.warn()) << "CronSet: sfCron pointed to non-cron object!!";
 | 
			
		||||
            return tefBAD_LEDGER;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!view.dirRemove(
 | 
			
		||||
                keylet::ownerDir(id), (*sleCron)[sfOwnerNode], klOld, false))
 | 
			
		||||
        {
 | 
			
		||||
            JLOG(j_.warn()) << "CronSet: Ownerdir bad. " << id;
 | 
			
		||||
            return tefBAD_LEDGER;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        view.erase(sleCron);
 | 
			
		||||
        adjustOwnerCount(view, sle, -1, j_);
 | 
			
		||||
        sle->makeFieldAbsent(sfCron);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // if the operation is a delete (no delay or recur specified then stop
 | 
			
		||||
    // here.)
 | 
			
		||||
    if (isDelete)
 | 
			
		||||
    {
 | 
			
		||||
        view.update(sle);
 | 
			
		||||
        return tesSUCCESS;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // execution to here means we're creating a new Cron object and adding it to
 | 
			
		||||
    // the user's owner dir
 | 
			
		||||
 | 
			
		||||
    Keylet klCron = keylet::cron(startTime, id);
 | 
			
		||||
 | 
			
		||||
    std::shared_ptr<SLE> sleCron = std::make_shared<SLE>(klCron);
 | 
			
		||||
 | 
			
		||||
    STAmount const reserve{
 | 
			
		||||
        view.fees().accountReserve(sle->getFieldU32(sfOwnerCount) + 1)};
 | 
			
		||||
 | 
			
		||||
    STAmount const afterFee =
 | 
			
		||||
        mPriorBalance - ctx_.tx.getFieldAmount(sfFee).xrp();
 | 
			
		||||
 | 
			
		||||
    if (afterFee > mPriorBalance || afterFee < reserve)
 | 
			
		||||
        return tecINSUFFICIENT_RESERVE;
 | 
			
		||||
 | 
			
		||||
    // add to owner dir
 | 
			
		||||
    auto const page =
 | 
			
		||||
        view.dirInsert(keylet::ownerDir(id), klCron, describeOwnerDir(id));
 | 
			
		||||
    if (!page)
 | 
			
		||||
        return tecDIR_FULL;
 | 
			
		||||
 | 
			
		||||
    sleCron->setFieldU64(sfOwnerNode, *page);
 | 
			
		||||
 | 
			
		||||
    adjustOwnerCount(view, sle, 1, j_);
 | 
			
		||||
 | 
			
		||||
    // set the fields
 | 
			
		||||
    sleCron->setFieldU32(sfStartTime, startTime);
 | 
			
		||||
    sleCron->setFieldU32(sfDelaySeconds, delay);
 | 
			
		||||
    sleCron->setFieldU32(sfRepeatCount, recur);
 | 
			
		||||
    sleCron->setAccountID(sfOwner, id);
 | 
			
		||||
 | 
			
		||||
    sle->setFieldH256(sfCron, klCron.key);
 | 
			
		||||
 | 
			
		||||
    view.update(sle);
 | 
			
		||||
 | 
			
		||||
    view.insert(sleCron);
 | 
			
		||||
 | 
			
		||||
    return tesSUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
XRPAmount
 | 
			
		||||
CronSet::calculateBaseFee(ReadView const& view, STTx const& tx)
 | 
			
		||||
{
 | 
			
		||||
    auto const baseFee = Transactor::calculateBaseFee(view, tx);
 | 
			
		||||
 | 
			
		||||
    if (tx.isFlag(tfCronUnset))
 | 
			
		||||
        // delete cron
 | 
			
		||||
        return baseFee;
 | 
			
		||||
 | 
			
		||||
    auto const repeatCount =
 | 
			
		||||
        tx.isFieldPresent(sfRepeatCount) ? tx.getFieldU32(sfRepeatCount) : 0;
 | 
			
		||||
 | 
			
		||||
    // factor a cost based on the total number of txns expected
 | 
			
		||||
    // for RepeatCount of 0 we have this txn (CronSet) and the
 | 
			
		||||
    // single Cron txn (2). For a RepeatCount of 1 we have this txn,
 | 
			
		||||
    // the first time the cron executes, and the second time (3).
 | 
			
		||||
    uint32_t const additionalExpectedExecutions = 1 + repeatCount;
 | 
			
		||||
    auto const additionalFee = baseFee * additionalExpectedExecutions;
 | 
			
		||||
 | 
			
		||||
    if (baseFee + additionalFee < baseFee)
 | 
			
		||||
        return baseFee;
 | 
			
		||||
 | 
			
		||||
    return baseFee + additionalFee;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}  // namespace ripple
 | 
			
		||||
							
								
								
									
										56
									
								
								src/ripple/app/tx/impl/CronSet.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								src/ripple/app/tx/impl/CronSet.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,56 @@
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
/*
 | 
			
		||||
    This file is part of rippled: https://github.com/ripple/rippled
 | 
			
		||||
    Copyright (c) 2024 XRPL-Labs
 | 
			
		||||
 | 
			
		||||
    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.
 | 
			
		||||
*/
 | 
			
		||||
//==============================================================================
 | 
			
		||||
 | 
			
		||||
#ifndef RIPPLE_TX_CRONSET_H_INCLUDED
 | 
			
		||||
#define RIPPLE_TX_CRONSET_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#include <ripple/app/tx/impl/Transactor.h>
 | 
			
		||||
#include <ripple/basics/Log.h>
 | 
			
		||||
#include <ripple/protocol/Indexes.h>
 | 
			
		||||
 | 
			
		||||
namespace ripple {
 | 
			
		||||
 | 
			
		||||
class CronSet : public Transactor
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    static constexpr ConsequencesFactoryType ConsequencesFactory{Custom};
 | 
			
		||||
 | 
			
		||||
    explicit CronSet(ApplyContext& ctx) : Transactor(ctx)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static XRPAmount
 | 
			
		||||
    calculateBaseFee(ReadView const& view, STTx const& tx);
 | 
			
		||||
 | 
			
		||||
    static TxConsequences
 | 
			
		||||
    makeTxConsequences(PreflightContext const& ctx);
 | 
			
		||||
 | 
			
		||||
    static NotTEC
 | 
			
		||||
    preflight(PreflightContext const& ctx);
 | 
			
		||||
 | 
			
		||||
    static TER
 | 
			
		||||
    preclaim(PreclaimContext const&);
 | 
			
		||||
 | 
			
		||||
    TER
 | 
			
		||||
    doApply() override;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}  // namespace ripple
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -491,6 +491,7 @@ LedgerEntryTypesMatch::visitEntry(
 | 
			
		||||
            case ltNFTOKEN_PAGE:
 | 
			
		||||
            case ltNFTOKEN_OFFER:
 | 
			
		||||
            case ltURI_TOKEN:
 | 
			
		||||
            case ltCRON:
 | 
			
		||||
            case ltIMPORT_VLSEQ:
 | 
			
		||||
            case ltUNL_REPORT:
 | 
			
		||||
                break;
 | 
			
		||||
 
 | 
			
		||||
@@ -184,6 +184,19 @@ SetAccount::preflight(PreflightContext const& ctx)
 | 
			
		||||
            return temMALFORMED;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // HookStateScale
 | 
			
		||||
    if (tx.isFieldPresent(sfHookStateScale))
 | 
			
		||||
    {
 | 
			
		||||
        if (!ctx.rules.enabled(featureExtendedHookState))
 | 
			
		||||
            return temMALFORMED;
 | 
			
		||||
 | 
			
		||||
        uint16_t scale = tx.getFieldU16(sfHookStateScale);
 | 
			
		||||
        if (scale == 0 ||
 | 
			
		||||
            scale > hook::maxHookStateScale())  // Min: 1, Max: 16 (256
 | 
			
		||||
                                                // * 16 = 4096 bytes)
 | 
			
		||||
            return temMALFORMED;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return preflight2(ctx);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -249,6 +262,20 @@ SetAccount::preclaim(PreclaimContext const& ctx)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // HookStateScale
 | 
			
		||||
    if (ctx.tx.isFieldPresent(sfHookStateScale))
 | 
			
		||||
    {
 | 
			
		||||
        uint16_t const newScale = ctx.tx.getFieldU16(sfHookStateScale);
 | 
			
		||||
        uint16_t const currentScale = sle->getFieldU16(sfHookStateScale);
 | 
			
		||||
        uint32_t const stateCount = sle->getFieldU32(sfHookStateCount);
 | 
			
		||||
        if (stateCount > 0 && newScale < currentScale)
 | 
			
		||||
        {
 | 
			
		||||
            JLOG(ctx.j.trace())
 | 
			
		||||
                << "Cannot decrease HookStateScale if state count is not zero.";
 | 
			
		||||
            return tecHAS_HOOK_STATE;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return tesSUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -629,6 +656,50 @@ SetAccount::doApply()
 | 
			
		||||
    if (uFlagsIn != uFlagsOut)
 | 
			
		||||
        sle->setFieldU32(sfFlags, uFlagsOut);
 | 
			
		||||
 | 
			
		||||
    // HookStateScale
 | 
			
		||||
    if (tx.isFieldPresent(sfHookStateScale))
 | 
			
		||||
    {
 | 
			
		||||
        uint16_t const newScale = tx.getFieldU16(sfHookStateScale);
 | 
			
		||||
        uint16_t const oldScale = sle->isFieldPresent(sfHookStateScale)
 | 
			
		||||
            ? sle->getFieldU16(sfHookStateScale)
 | 
			
		||||
            : 1;
 | 
			
		||||
        if (newScale == oldScale)
 | 
			
		||||
        {
 | 
			
		||||
            // do nothing
 | 
			
		||||
        }
 | 
			
		||||
        else if (newScale == 1)
 | 
			
		||||
        {
 | 
			
		||||
            sle->makeFieldAbsent(sfHookStateScale);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            // increase OwnerCount
 | 
			
		||||
            uint32_t const stateCount = sle->getFieldU32(sfHookStateCount);
 | 
			
		||||
            uint32_t const oldOwnerCount = sle->getFieldU32(sfOwnerCount);
 | 
			
		||||
 | 
			
		||||
            uint32_t const newOwnerCount = oldOwnerCount -
 | 
			
		||||
                (oldScale * stateCount) + (newScale * stateCount);
 | 
			
		||||
 | 
			
		||||
            // sanity check
 | 
			
		||||
            if (newOwnerCount < oldOwnerCount)
 | 
			
		||||
                return tecINTERNAL;
 | 
			
		||||
 | 
			
		||||
            if (newOwnerCount != oldOwnerCount)
 | 
			
		||||
            {
 | 
			
		||||
                STAmount const balance = STAmount((*sle)[sfBalance]).xrp();
 | 
			
		||||
                XRPAmount const reserve =
 | 
			
		||||
                    view().fees().accountReserve(newOwnerCount);
 | 
			
		||||
                if (balance < reserve)
 | 
			
		||||
                    return tecINSUFFICIENT_RESERVE;
 | 
			
		||||
 | 
			
		||||
                adjustOwnerCount(
 | 
			
		||||
                    view(), sle, newOwnerCount - oldOwnerCount, j_);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            sle->setFieldU16(sfHookStateScale, newScale);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return tesSUCCESS;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -33,6 +33,7 @@
 | 
			
		||||
#include <ripple/protocol/STArray.h>
 | 
			
		||||
#include <ripple/protocol/STObject.h>
 | 
			
		||||
#include <ripple/protocol/STTx.h>
 | 
			
		||||
#include <ripple/protocol/TxFlags.h>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <exception>
 | 
			
		||||
@@ -665,6 +666,13 @@ SetHook::preflight(PreflightContext const& ctx)
 | 
			
		||||
    if (!isTesSuccess(ret))
 | 
			
		||||
        return ret;
 | 
			
		||||
 | 
			
		||||
    if (ctx.rules.enabled(fixInvalidTxFlags) &&
 | 
			
		||||
        ctx.tx.getFlags() & tfUniversalMask)
 | 
			
		||||
    {
 | 
			
		||||
        JLOG(ctx.j.trace()) << "SetHook: Invalid flags set.";
 | 
			
		||||
        return temINVALID_FLAG;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!ctx.tx.isFieldPresent(sfHooks))
 | 
			
		||||
    {
 | 
			
		||||
        JLOG(ctx.j.trace())
 | 
			
		||||
@@ -850,6 +858,9 @@ SetHook::destroyNamespace(
 | 
			
		||||
    bool const fixEnabled = ctx.rules.enabled(fixNSDelete);
 | 
			
		||||
    bool partialDelete = false;
 | 
			
		||||
    uint32_t oldStateCount = sleAccount->getFieldU32(sfHookStateCount);
 | 
			
		||||
    uint16_t scale = sleAccount->isFieldPresent(sfHookStateScale)
 | 
			
		||||
        ? sleAccount->getFieldU16(sfHookStateScale)
 | 
			
		||||
        : 1;
 | 
			
		||||
 | 
			
		||||
    std::vector<uint256> toDelete;
 | 
			
		||||
    toDelete.reserve(sleDir->getFieldV256(sfIndexes).size());
 | 
			
		||||
@@ -921,6 +932,15 @@ SetHook::destroyNamespace(
 | 
			
		||||
        view.erase(sleItem);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (view.rules().enabled(featureExtendedHookState) &&
 | 
			
		||||
        oldStateCount < toDelete.size())
 | 
			
		||||
    {
 | 
			
		||||
        JLOG(ctx.j.fatal()) << "HookSet(" << hook::log::NSDELETE_COUNT << ")["
 | 
			
		||||
                            << HS_ACC() << "]: DeleteState "
 | 
			
		||||
                            << "stateCount less than zero (overflow)";
 | 
			
		||||
        return tefBAD_LEDGER;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    uint32_t stateCount = oldStateCount - toDelete.size();
 | 
			
		||||
    if (stateCount > oldStateCount)
 | 
			
		||||
    {
 | 
			
		||||
@@ -937,7 +957,18 @@ SetHook::destroyNamespace(
 | 
			
		||||
        sleAccount->setFieldU32(sfHookStateCount, stateCount);
 | 
			
		||||
 | 
			
		||||
    if (ctx.rules.enabled(fixNSDelete))
 | 
			
		||||
        adjustOwnerCount(view, sleAccount, -toDelete.size(), ctx.j);
 | 
			
		||||
    {
 | 
			
		||||
        auto const ownerCount = sleAccount->getFieldU32(sfOwnerCount);
 | 
			
		||||
        if (view.rules().enabled(featureExtendedHookState) &&
 | 
			
		||||
            ownerCount < toDelete.size() * scale)
 | 
			
		||||
        {
 | 
			
		||||
            JLOG(ctx.j.fatal()) << "HookSet(" << hook::log::NSDELETE_COUNT
 | 
			
		||||
                                << ")[" << HS_ACC() << "]: DeleteState "
 | 
			
		||||
                                << "OwnerCount less than zero (overflow)";
 | 
			
		||||
            return tefBAD_LEDGER;
 | 
			
		||||
        }
 | 
			
		||||
        adjustOwnerCount(view, sleAccount, -toDelete.size() * scale, ctx.j);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!partialDelete && sleAccount->isFieldPresent(sfHookNamespaces))
 | 
			
		||||
        hook::removeHookNamespaceEntry(*sleAccount, ns);
 | 
			
		||||
 
 | 
			
		||||
@@ -27,6 +27,7 @@
 | 
			
		||||
#include <ripple/protocol/STArray.h>
 | 
			
		||||
#include <ripple/protocol/STObject.h>
 | 
			
		||||
#include <ripple/protocol/STTx.h>
 | 
			
		||||
#include <ripple/protocol/TxFlags.h>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
 | 
			
		||||
@@ -81,6 +82,13 @@ SetSignerList::preflight(PreflightContext const& ctx)
 | 
			
		||||
    if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
 | 
			
		||||
        return ret;
 | 
			
		||||
 | 
			
		||||
    if (ctx.rules.enabled(fixInvalidTxFlags) &&
 | 
			
		||||
        (ctx.tx.getFlags() & tfUniversalMask))
 | 
			
		||||
    {
 | 
			
		||||
        JLOG(ctx.j.trace()) << "SetSignerList: invalid flags.";
 | 
			
		||||
        return temINVALID_FLAG;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    auto const result = determineOperation(ctx.tx, ctx.flags, ctx.j);
 | 
			
		||||
 | 
			
		||||
    if (!isTesSuccess(std::get<0>(result)))
 | 
			
		||||
 
 | 
			
		||||
@@ -28,6 +28,8 @@
 | 
			
		||||
#include <ripple/app/tx/impl/CreateCheck.h>
 | 
			
		||||
#include <ripple/app/tx/impl/CreateOffer.h>
 | 
			
		||||
#include <ripple/app/tx/impl/CreateTicket.h>
 | 
			
		||||
#include <ripple/app/tx/impl/Cron.h>
 | 
			
		||||
#include <ripple/app/tx/impl/CronSet.h>
 | 
			
		||||
#include <ripple/app/tx/impl/DeleteAccount.h>
 | 
			
		||||
#include <ripple/app/tx/impl/DepositPreauth.h>
 | 
			
		||||
#include <ripple/app/tx/impl/Escrow.h>
 | 
			
		||||
@@ -181,6 +183,10 @@ invoke_preflight(PreflightContext const& ctx)
 | 
			
		||||
        case ttURITOKEN_CREATE_SELL_OFFER:
 | 
			
		||||
        case ttURITOKEN_CANCEL_SELL_OFFER:
 | 
			
		||||
            return invoke_preflight_helper<URIToken>(ctx);
 | 
			
		||||
        case ttCRON_SET:
 | 
			
		||||
            return invoke_preflight_helper<CronSet>(ctx);
 | 
			
		||||
        case ttCRON:
 | 
			
		||||
            return invoke_preflight_helper<Cron>(ctx);
 | 
			
		||||
        default:
 | 
			
		||||
            assert(false);
 | 
			
		||||
            return {temUNKNOWN, TxConsequences{temUNKNOWN}};
 | 
			
		||||
@@ -306,6 +312,10 @@ invoke_preclaim(PreclaimContext const& ctx)
 | 
			
		||||
        case ttURITOKEN_CREATE_SELL_OFFER:
 | 
			
		||||
        case ttURITOKEN_CANCEL_SELL_OFFER:
 | 
			
		||||
            return invoke_preclaim<URIToken>(ctx);
 | 
			
		||||
        case ttCRON_SET:
 | 
			
		||||
            return invoke_preclaim<CronSet>(ctx);
 | 
			
		||||
        case ttCRON:
 | 
			
		||||
            return invoke_preclaim<Cron>(ctx);
 | 
			
		||||
        default:
 | 
			
		||||
            assert(false);
 | 
			
		||||
            return temUNKNOWN;
 | 
			
		||||
@@ -393,6 +403,10 @@ invoke_calculateBaseFee(ReadView const& view, STTx const& tx)
 | 
			
		||||
        case ttURITOKEN_CREATE_SELL_OFFER:
 | 
			
		||||
        case ttURITOKEN_CANCEL_SELL_OFFER:
 | 
			
		||||
            return URIToken::calculateBaseFee(view, tx);
 | 
			
		||||
        case ttCRON_SET:
 | 
			
		||||
            return CronSet::calculateBaseFee(view, tx);
 | 
			
		||||
        case ttCRON:
 | 
			
		||||
            return Cron::calculateBaseFee(view, tx);
 | 
			
		||||
        default:
 | 
			
		||||
            return XRPAmount{0};
 | 
			
		||||
    }
 | 
			
		||||
@@ -586,6 +600,14 @@ invoke_apply(ApplyContext& ctx)
 | 
			
		||||
            URIToken p(ctx);
 | 
			
		||||
            return p();
 | 
			
		||||
        }
 | 
			
		||||
        case ttCRON_SET: {
 | 
			
		||||
            CronSet p(ctx);
 | 
			
		||||
            return p();
 | 
			
		||||
        }
 | 
			
		||||
        case ttCRON: {
 | 
			
		||||
            Cron p(ctx);
 | 
			
		||||
            return p();
 | 
			
		||||
        }
 | 
			
		||||
        default:
 | 
			
		||||
            assert(false);
 | 
			
		||||
            return {temUNKNOWN, false};
 | 
			
		||||
 
 | 
			
		||||
@@ -249,13 +249,22 @@ private:
 | 
			
		||||
// Wraps a Journal::Stream to skip evaluation of
 | 
			
		||||
// expensive argument lists if the stream is not active.
 | 
			
		||||
#ifndef JLOG
 | 
			
		||||
#ifdef BEAST_ENHANCED_LOGGING
 | 
			
		||||
#define JLOG(x) \
 | 
			
		||||
    if (!x)     \
 | 
			
		||||
    if (!(x))   \
 | 
			
		||||
    {           \
 | 
			
		||||
    }           \
 | 
			
		||||
    else        \
 | 
			
		||||
        (x).withLocation(__FILE__, __LINE__)
 | 
			
		||||
#else
 | 
			
		||||
#define JLOG(x) \
 | 
			
		||||
    if (!(x))   \
 | 
			
		||||
    {           \
 | 
			
		||||
    }           \
 | 
			
		||||
    else        \
 | 
			
		||||
        x
 | 
			
		||||
#endif
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Debug logging:
 | 
			
		||||
 
 | 
			
		||||
@@ -17,11 +17,19 @@
 | 
			
		||||
*/
 | 
			
		||||
//==============================================================================
 | 
			
		||||
 | 
			
		||||
#include <date/date.h>
 | 
			
		||||
 | 
			
		||||
#include <ripple/basics/Log.h>
 | 
			
		||||
#include <ripple/basics/chrono.h>
 | 
			
		||||
#include <ripple/basics/contract.h>
 | 
			
		||||
#ifdef BEAST_ENHANCED_LOGGING
 | 
			
		||||
#include <ripple/beast/utility/EnhancedLogging.h>
 | 
			
		||||
#include <date/tz.h>
 | 
			
		||||
#endif
 | 
			
		||||
#include <boost/algorithm/string.hpp>
 | 
			
		||||
#include <cassert>
 | 
			
		||||
#include <cstring>
 | 
			
		||||
#include <ctime>
 | 
			
		||||
#include <fstream>
 | 
			
		||||
#include <functional>
 | 
			
		||||
#include <iostream>
 | 
			
		||||
@@ -316,11 +324,46 @@ Logs::format(
 | 
			
		||||
{
 | 
			
		||||
    output.reserve(message.size() + partition.size() + 100);
 | 
			
		||||
 | 
			
		||||
    output = to_string(std::chrono::system_clock::now());
 | 
			
		||||
#ifdef BEAST_ENHANCED_LOGGING
 | 
			
		||||
    // Environment variables are used instead of config file because:
 | 
			
		||||
    // 1. Logging starts before config parsing (needed to debug config issues)
 | 
			
		||||
    // 2. This is a developer feature - devs can easily set env vars
 | 
			
		||||
    // 3. Allows per-run overrides without editing config files
 | 
			
		||||
    static const char* fmt = []() {
 | 
			
		||||
        const char* env = std::getenv("LOG_DATE_FORMAT");
 | 
			
		||||
        return env ? env : "%Y-%b-%d %T %Z";  // Default format
 | 
			
		||||
    }();
 | 
			
		||||
 | 
			
		||||
    // Check if we should use local time
 | 
			
		||||
    static const bool useLocalTime = []() {
 | 
			
		||||
        const char* env = std::getenv("LOG_DATE_LOCAL");
 | 
			
		||||
        return env && std::strcmp(env, "1") == 0;
 | 
			
		||||
    }();
 | 
			
		||||
 | 
			
		||||
    if (useLocalTime)
 | 
			
		||||
    {
 | 
			
		||||
        auto now = std::chrono::system_clock::now();
 | 
			
		||||
        auto local = date::make_zoned(date::current_zone(), now);
 | 
			
		||||
        output = date::format(fmt, local);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        output = date::format(fmt, std::chrono::system_clock::now());
 | 
			
		||||
    }
 | 
			
		||||
#else
 | 
			
		||||
    output = to_string(std::chrono::system_clock::now());
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    if (!output.empty())  // Allow setting date format to an empty string
 | 
			
		||||
        output += " ";
 | 
			
		||||
 | 
			
		||||
    output += " ";
 | 
			
		||||
    if (!partition.empty())
 | 
			
		||||
    {
 | 
			
		||||
#ifdef BEAST_ENHANCED_LOGGING
 | 
			
		||||
        output += beast::detail::get_log_highlight_color();
 | 
			
		||||
#endif
 | 
			
		||||
        output += partition + ":";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    using namespace beast::severities;
 | 
			
		||||
    switch (severity)
 | 
			
		||||
@@ -348,6 +391,10 @@ Logs::format(
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifdef BEAST_ENHANCED_LOGGING
 | 
			
		||||
    output += "\033[0m";
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    output += message;
 | 
			
		||||
 | 
			
		||||
    // Limit the maximum length of the output
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										85
									
								
								src/ripple/beast/utility/EnhancedLogging.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								src/ripple/beast/utility/EnhancedLogging.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,85 @@
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
/*
 | 
			
		||||
    This file is part of Beast: https://github.com/vinniefalco/Beast
 | 
			
		||||
    Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
 | 
			
		||||
 | 
			
		||||
    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.
 | 
			
		||||
*/
 | 
			
		||||
//==============================================================================
 | 
			
		||||
 | 
			
		||||
#ifndef BEAST_UTILITY_ENHANCEDLOGGING_H_INCLUDED
 | 
			
		||||
#define BEAST_UTILITY_ENHANCEDLOGGING_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#include <cstddef>  // for size_t
 | 
			
		||||
#include <iosfwd>   // for std::ostream
 | 
			
		||||
 | 
			
		||||
namespace beast {
 | 
			
		||||
namespace detail {
 | 
			
		||||
 | 
			
		||||
// Check if we should use colors - cached at startup
 | 
			
		||||
bool
 | 
			
		||||
should_log_use_colors();
 | 
			
		||||
 | 
			
		||||
// Get the log highlight color - can be overridden via
 | 
			
		||||
// LOG_HIGHLIGHT_COLOR
 | 
			
		||||
const char*
 | 
			
		||||
get_log_highlight_color();
 | 
			
		||||
 | 
			
		||||
// Strip source root path from __FILE__ at compile time
 | 
			
		||||
// IMPORTANT: This MUST stay in the header as constexpr for compile-time
 | 
			
		||||
// evaluation!
 | 
			
		||||
constexpr const char*
 | 
			
		||||
strip_source_root(const char* file)
 | 
			
		||||
{
 | 
			
		||||
#ifdef SOURCE_ROOT_PATH
 | 
			
		||||
    constexpr const char* sourceRoot = SOURCE_ROOT_PATH;
 | 
			
		||||
    constexpr auto strlen_constexpr = [](const char* s) constexpr
 | 
			
		||||
    {
 | 
			
		||||
        const char* p = s;
 | 
			
		||||
        while (*p)
 | 
			
		||||
            ++p;
 | 
			
		||||
        return p - s;
 | 
			
		||||
    };
 | 
			
		||||
    constexpr auto strncmp_constexpr =
 | 
			
		||||
        [](const char* a, const char* b, size_t n) constexpr
 | 
			
		||||
    {
 | 
			
		||||
        for (size_t i = 0; i < n; ++i)
 | 
			
		||||
        {
 | 
			
		||||
            if (a[i] != b[i])
 | 
			
		||||
                return a[i] - b[i];
 | 
			
		||||
            if (a[i] == '\0')
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
        return 0;
 | 
			
		||||
    };
 | 
			
		||||
    constexpr size_t sourceRootLen = strlen_constexpr(sourceRoot);
 | 
			
		||||
    return (strncmp_constexpr(file, sourceRoot, sourceRootLen) == 0)
 | 
			
		||||
        ? file + sourceRootLen
 | 
			
		||||
        : file;
 | 
			
		||||
#else
 | 
			
		||||
    return file;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Check if location info should be shown - cached at startup
 | 
			
		||||
bool
 | 
			
		||||
should_show_location();
 | 
			
		||||
 | 
			
		||||
// Helper to write location string (no leading/trailing space)
 | 
			
		||||
void
 | 
			
		||||
log_write_location_string(std::ostream& os, const char* file, int line);
 | 
			
		||||
 | 
			
		||||
}  // namespace detail
 | 
			
		||||
}  // namespace beast
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -146,6 +146,10 @@ private:
 | 
			
		||||
 | 
			
		||||
        ScopedStream(Sink& sink, Severity level);
 | 
			
		||||
 | 
			
		||||
#ifdef BEAST_ENHANCED_LOGGING
 | 
			
		||||
        ScopedStream(Sink& sink, Severity level, const char* file, int line);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        template <typename T>
 | 
			
		||||
        ScopedStream(Stream const& stream, T const& t);
 | 
			
		||||
 | 
			
		||||
@@ -173,6 +177,10 @@ private:
 | 
			
		||||
        Sink& m_sink;
 | 
			
		||||
        Severity const m_level;
 | 
			
		||||
        std::ostringstream mutable m_ostream;
 | 
			
		||||
#ifdef BEAST_ENHANCED_LOGGING
 | 
			
		||||
        const char* file_ = nullptr;
 | 
			
		||||
        int line_ = 0;
 | 
			
		||||
#endif
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
#ifndef __INTELLISENSE__
 | 
			
		||||
@@ -191,6 +199,33 @@ private:
 | 
			
		||||
    //--------------------------------------------------------------------------
 | 
			
		||||
public:
 | 
			
		||||
    /** Provide a light-weight way to check active() before string formatting */
 | 
			
		||||
 | 
			
		||||
#ifdef BEAST_ENHANCED_LOGGING
 | 
			
		||||
    /** Stream with location information that prepends file:line to the first
 | 
			
		||||
     * message */
 | 
			
		||||
    class StreamWithLocation
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        StreamWithLocation(Stream const& stream, const char* file, int line)
 | 
			
		||||
            : file_(file), line_(line), stream_(stream)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /** Override to inject file:line before the first output */
 | 
			
		||||
        template <typename T>
 | 
			
		||||
        ScopedStream
 | 
			
		||||
        operator<<(T const& t) const;
 | 
			
		||||
 | 
			
		||||
        ScopedStream
 | 
			
		||||
        operator<<(std::ostream& manip(std::ostream&)) const;
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
        const char* file_;
 | 
			
		||||
        int line_;
 | 
			
		||||
        const Stream& stream_;
 | 
			
		||||
    };
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    class Stream
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
@@ -255,6 +290,15 @@ public:
 | 
			
		||||
        operator<<(T const& t) const;
 | 
			
		||||
        /** @} */
 | 
			
		||||
 | 
			
		||||
#ifdef BEAST_ENHANCED_LOGGING
 | 
			
		||||
        /** Create a StreamWithLocation that prepends file:line info */
 | 
			
		||||
        StreamWithLocation
 | 
			
		||||
        withLocation(const char* file, int line) const
 | 
			
		||||
        {
 | 
			
		||||
            return StreamWithLocation(*this, file, line);
 | 
			
		||||
        }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
        Sink& m_sink;
 | 
			
		||||
        Severity m_level;
 | 
			
		||||
@@ -354,6 +398,8 @@ static_assert(std::is_nothrow_destructible<Journal>::value == true, "");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
Journal::ScopedStream::ScopedStream(Journal::Stream const& stream, T const& t)
 | 
			
		||||
    : ScopedStream(stream.sink(), stream.level())
 | 
			
		||||
@@ -378,6 +424,21 @@ Journal::Stream::operator<<(T const& t) const
 | 
			
		||||
    return ScopedStream(*this, t);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef BEAST_ENHANCED_LOGGING
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
template <typename T>
 | 
			
		||||
Journal::ScopedStream
 | 
			
		||||
Journal::StreamWithLocation::operator<<(T const& t) const
 | 
			
		||||
{
 | 
			
		||||
    // Create a ScopedStream with location info
 | 
			
		||||
    ScopedStream scoped(stream_.sink(), stream_.level(), file_, line_);
 | 
			
		||||
    scoped.ostream() << t;
 | 
			
		||||
    return scoped;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace detail {
 | 
			
		||||
 | 
			
		||||
template <class CharT, class Traits = std::char_traits<CharT>>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										114
									
								
								src/ripple/beast/utility/src/beast_EnhancedLogging.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								src/ripple/beast/utility/src/beast_EnhancedLogging.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,114 @@
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
/*
 | 
			
		||||
    This file is part of Beast: https://github.com/vinniefalco/Beast
 | 
			
		||||
    Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
 | 
			
		||||
 | 
			
		||||
    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/beast/utility/EnhancedLogging.h>
 | 
			
		||||
#include <cstdlib>
 | 
			
		||||
#include <cstring>
 | 
			
		||||
#include <ostream>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
namespace beast {
 | 
			
		||||
namespace detail {
 | 
			
		||||
 | 
			
		||||
// Check if we should use colors - cached at startup
 | 
			
		||||
bool
 | 
			
		||||
should_log_use_colors()
 | 
			
		||||
{
 | 
			
		||||
    static const bool use_colors = []() {
 | 
			
		||||
        // Honor NO_COLOR environment variable (standard)
 | 
			
		||||
        if (std::getenv("NO_COLOR"))
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
        // Honor FORCE_COLOR to override terminal detection
 | 
			
		||||
        if (std::getenv("FORCE_COLOR"))
 | 
			
		||||
            return true;
 | 
			
		||||
 | 
			
		||||
        // Check if stderr is a terminal
 | 
			
		||||
        return isatty(STDERR_FILENO) != 0;
 | 
			
		||||
    }();
 | 
			
		||||
    return use_colors;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Get the log highlight color - can be overridden via
 | 
			
		||||
// LOG_HIGHLIGHT_COLOR
 | 
			
		||||
const char*
 | 
			
		||||
get_log_highlight_color()
 | 
			
		||||
{
 | 
			
		||||
    static const char* escape = []() {
 | 
			
		||||
        const char* env = std::getenv("LOG_HIGHLIGHT_COLOR");
 | 
			
		||||
        if (!env)
 | 
			
		||||
            return "\033[36m";  // Default: cyan
 | 
			
		||||
 | 
			
		||||
        // Simple map of color names to escape sequences
 | 
			
		||||
        if (std::strcmp(env, "red") == 0)
 | 
			
		||||
            return "\033[31m";
 | 
			
		||||
        if (std::strcmp(env, "green") == 0)
 | 
			
		||||
            return "\033[32m";
 | 
			
		||||
        if (std::strcmp(env, "yellow") == 0)
 | 
			
		||||
            return "\033[33m";
 | 
			
		||||
        if (std::strcmp(env, "blue") == 0)
 | 
			
		||||
            return "\033[34m";
 | 
			
		||||
        if (std::strcmp(env, "magenta") == 0)
 | 
			
		||||
            return "\033[35m";
 | 
			
		||||
        if (std::strcmp(env, "cyan") == 0)
 | 
			
		||||
            return "\033[36m";
 | 
			
		||||
        if (std::strcmp(env, "white") == 0)
 | 
			
		||||
            return "\033[37m";
 | 
			
		||||
        if (std::strcmp(env, "gray") == 0 || std::strcmp(env, "grey") == 0)
 | 
			
		||||
            return "\033[90m";  // Bright black (gray)
 | 
			
		||||
        if (std::strcmp(env, "orange") == 0)
 | 
			
		||||
            return "\033[93m";  // Bright yellow (appears orange-ish)
 | 
			
		||||
        if (std::strcmp(env, "none") == 0)
 | 
			
		||||
            return "";
 | 
			
		||||
 | 
			
		||||
        // Default to cyan if unknown color name
 | 
			
		||||
        return "\033[36m";
 | 
			
		||||
    }();
 | 
			
		||||
    return escape;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Check if location info should be shown - cached at startup
 | 
			
		||||
bool
 | 
			
		||||
should_show_location()
 | 
			
		||||
{
 | 
			
		||||
    static const bool show = []() {
 | 
			
		||||
        const char* env = std::getenv("LOG_DISABLE");
 | 
			
		||||
        // Show location by default, hide if LOG_DISABLE=1
 | 
			
		||||
        return !env || std::strcmp(env, "1") != 0;
 | 
			
		||||
    }();
 | 
			
		||||
    return show;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Helper to write location string (no leading/trailing space)
 | 
			
		||||
void
 | 
			
		||||
log_write_location_string(std::ostream& os, const char* file, int line)
 | 
			
		||||
{
 | 
			
		||||
    if (detail::should_log_use_colors())
 | 
			
		||||
    {
 | 
			
		||||
        os << detail::get_log_highlight_color() << "["
 | 
			
		||||
           << detail::strip_source_root(file) << ":" << line << "]\033[0m";
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        os << "[" << detail::strip_source_root(file) << ":" << line << "]";
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}  // namespace detail
 | 
			
		||||
}  // namespace beast
 | 
			
		||||
@@ -19,6 +19,11 @@
 | 
			
		||||
 | 
			
		||||
#include <ripple/beast/utility/Journal.h>
 | 
			
		||||
#include <cassert>
 | 
			
		||||
#ifdef BEAST_ENHANCED_LOGGING
 | 
			
		||||
#include <ripple/beast/utility/EnhancedLogging.h>
 | 
			
		||||
#include <cstdlib>
 | 
			
		||||
#include <cstring>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace beast {
 | 
			
		||||
 | 
			
		||||
@@ -131,9 +136,36 @@ Journal::ScopedStream::ScopedStream(
 | 
			
		||||
    m_ostream << manip;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef BEAST_ENHANCED_LOGGING
 | 
			
		||||
Journal::ScopedStream::ScopedStream(
 | 
			
		||||
    Sink& sink,
 | 
			
		||||
    Severity level,
 | 
			
		||||
    const char* file,
 | 
			
		||||
    int line)
 | 
			
		||||
    : m_sink(sink), m_level(level), file_(file), line_(line)
 | 
			
		||||
{
 | 
			
		||||
    // Modifiers applied from all ctors
 | 
			
		||||
    m_ostream << std::boolalpha << std::showbase;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
Journal::ScopedStream::~ScopedStream()
 | 
			
		||||
{
 | 
			
		||||
    std::string const& s(m_ostream.str());
 | 
			
		||||
    std::string s(m_ostream.str());
 | 
			
		||||
 | 
			
		||||
#ifdef BEAST_ENHANCED_LOGGING
 | 
			
		||||
    // Add suffix if location is enabled
 | 
			
		||||
    if (file_ && detail::should_show_location() && !s.empty() && s != "\n")
 | 
			
		||||
    {
 | 
			
		||||
        std::ostringstream combined;
 | 
			
		||||
        combined << s;
 | 
			
		||||
        if (!s.empty() && s.back() != ' ')
 | 
			
		||||
            combined << " ";
 | 
			
		||||
        detail::log_write_location_string(combined, file_, line_);
 | 
			
		||||
        s = combined.str();
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    if (!s.empty())
 | 
			
		||||
    {
 | 
			
		||||
        if (s == "\n")
 | 
			
		||||
@@ -157,4 +189,18 @@ Journal::Stream::operator<<(std::ostream& manip(std::ostream&)) const
 | 
			
		||||
    return ScopedStream(*this, manip);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef BEAST_ENHANCED_LOGGING
 | 
			
		||||
 | 
			
		||||
// Implementation moved to use new constructor
 | 
			
		||||
Journal::ScopedStream
 | 
			
		||||
Journal::StreamWithLocation::operator<<(
 | 
			
		||||
    std::ostream& manip(std::ostream&)) const
 | 
			
		||||
{
 | 
			
		||||
    // Create a ScopedStream with location info
 | 
			
		||||
    ScopedStream scoped(stream_.sink(), stream_.level(), file_, line_);
 | 
			
		||||
    scoped.ostream() << manip;
 | 
			
		||||
    return scoped;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
}  // namespace beast
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -23,6 +23,7 @@
 | 
			
		||||
#include <ripple/nodestore/Types.h>
 | 
			
		||||
#include <atomic>
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <optional>
 | 
			
		||||
 | 
			
		||||
namespace ripple {
 | 
			
		||||
namespace NodeStore {
 | 
			
		||||
@@ -175,6 +176,14 @@ public:
 | 
			
		||||
    virtual int
 | 
			
		||||
    fdRequired() const = 0;
 | 
			
		||||
 | 
			
		||||
    /** Get the block size for backends that support it
 | 
			
		||||
     */
 | 
			
		||||
    virtual std::optional<std::size_t>
 | 
			
		||||
    getBlockSize() const
 | 
			
		||||
    {
 | 
			
		||||
        return std::nullopt;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** Returns read and write stats.
 | 
			
		||||
 | 
			
		||||
        @note The Counters struct is specific to and only used
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
@@ -18,6 +18,7 @@
 | 
			
		||||
//==============================================================================
 | 
			
		||||
 | 
			
		||||
#include <ripple/basics/contract.h>
 | 
			
		||||
#include <ripple/beast/core/LexicalCast.h>
 | 
			
		||||
#include <ripple/nodestore/Factory.h>
 | 
			
		||||
#include <ripple/nodestore/Manager.h>
 | 
			
		||||
#include <ripple/nodestore/impl/DecodedBlob.h>
 | 
			
		||||
@@ -31,6 +32,7 @@
 | 
			
		||||
#include <exception>
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <nudb/nudb.hpp>
 | 
			
		||||
#include <sstream>
 | 
			
		||||
 | 
			
		||||
namespace ripple {
 | 
			
		||||
namespace NodeStore {
 | 
			
		||||
@@ -48,6 +50,7 @@ public:
 | 
			
		||||
    size_t const keyBytes_;
 | 
			
		||||
    std::size_t const burstSize_;
 | 
			
		||||
    std::string const name_;
 | 
			
		||||
    std::size_t const blockSize_;
 | 
			
		||||
    nudb::store db_;
 | 
			
		||||
    std::atomic<bool> deletePath_;
 | 
			
		||||
    Scheduler& scheduler_;
 | 
			
		||||
@@ -62,6 +65,7 @@ public:
 | 
			
		||||
        , keyBytes_(keyBytes)
 | 
			
		||||
        , burstSize_(burstSize)
 | 
			
		||||
        , name_(get(keyValues, "path"))
 | 
			
		||||
        , blockSize_(parseBlockSize(name_, keyValues, journal))
 | 
			
		||||
        , deletePath_(false)
 | 
			
		||||
        , scheduler_(scheduler)
 | 
			
		||||
    {
 | 
			
		||||
@@ -81,6 +85,7 @@ public:
 | 
			
		||||
        , keyBytes_(keyBytes)
 | 
			
		||||
        , burstSize_(burstSize)
 | 
			
		||||
        , name_(get(keyValues, "path"))
 | 
			
		||||
        , blockSize_(parseBlockSize(name_, keyValues, journal))
 | 
			
		||||
        , db_(context)
 | 
			
		||||
        , deletePath_(false)
 | 
			
		||||
        , scheduler_(scheduler)
 | 
			
		||||
@@ -110,6 +115,12 @@ public:
 | 
			
		||||
        return name_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::optional<std::size_t>
 | 
			
		||||
    getBlockSize() const override
 | 
			
		||||
    {
 | 
			
		||||
        return blockSize_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void
 | 
			
		||||
    open(bool createIfMissing, uint64_t appType, uint64_t uid, uint64_t salt)
 | 
			
		||||
        override
 | 
			
		||||
@@ -137,7 +148,7 @@ public:
 | 
			
		||||
                uid,
 | 
			
		||||
                salt,
 | 
			
		||||
                keyBytes_,
 | 
			
		||||
                nudb::block_size(kp),
 | 
			
		||||
                blockSize_,
 | 
			
		||||
                0.50,
 | 
			
		||||
                ec);
 | 
			
		||||
            if (ec == nudb::errc::file_exists)
 | 
			
		||||
@@ -362,6 +373,56 @@ public:
 | 
			
		||||
    {
 | 
			
		||||
        return 3;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    static std::size_t
 | 
			
		||||
    parseBlockSize(
 | 
			
		||||
        std::string const& name,
 | 
			
		||||
        Section const& keyValues,
 | 
			
		||||
        beast::Journal journal)
 | 
			
		||||
    {
 | 
			
		||||
        using namespace boost::filesystem;
 | 
			
		||||
        auto const folder = path(name);
 | 
			
		||||
        auto const kp = (folder / "nudb.key").string();
 | 
			
		||||
 | 
			
		||||
        std::size_t const defaultSize =
 | 
			
		||||
            nudb::block_size(kp);  // Default 4K from NuDB
 | 
			
		||||
        std::size_t blockSize = defaultSize;
 | 
			
		||||
        std::string blockSizeStr;
 | 
			
		||||
 | 
			
		||||
        if (!get_if_exists(keyValues, "nudb_block_size", blockSizeStr))
 | 
			
		||||
        {
 | 
			
		||||
            return blockSize;  // Early return with default
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            std::size_t const parsedBlockSize =
 | 
			
		||||
                beast::lexicalCastThrow<std::size_t>(blockSizeStr);
 | 
			
		||||
 | 
			
		||||
            // Validate: must be power of 2 between 4K and 32K
 | 
			
		||||
            if (parsedBlockSize < 4096 || parsedBlockSize > 32768 ||
 | 
			
		||||
                (parsedBlockSize & (parsedBlockSize - 1)) != 0)
 | 
			
		||||
            {
 | 
			
		||||
                std::stringstream s;
 | 
			
		||||
                s << "Invalid nudb_block_size: " << parsedBlockSize
 | 
			
		||||
                  << ". Must be power of 2 between 4096 and 32768.";
 | 
			
		||||
                Throw<std::runtime_error>(s.str());
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            JLOG(journal.info())
 | 
			
		||||
                << "Using custom NuDB block size: " << parsedBlockSize
 | 
			
		||||
                << " bytes";
 | 
			
		||||
            return parsedBlockSize;
 | 
			
		||||
        }
 | 
			
		||||
        catch (std::exception const& e)
 | 
			
		||||
        {
 | 
			
		||||
            std::stringstream s;
 | 
			
		||||
            s << "Invalid nudb_block_size value: " << blockSizeStr
 | 
			
		||||
              << ". Error: " << e.what();
 | 
			
		||||
            Throw<std::runtime_error>(s.str());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 
 | 
			
		||||
@@ -239,19 +239,17 @@ verifyHandshake(
 | 
			
		||||
            throw std::runtime_error("Invalid server domain");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Check the network. Omitting Network-ID (on either side ours, or theirs)
 | 
			
		||||
    // means NID=0
 | 
			
		||||
    // Check network ID, treating absent/empty as default network 0
 | 
			
		||||
    {
 | 
			
		||||
        uint32_t peer_nid = 0;
 | 
			
		||||
        std::uint32_t nid{0};
 | 
			
		||||
 | 
			
		||||
        if (auto const iter = headers.find("Network-ID"); iter != headers.end())
 | 
			
		||||
        {
 | 
			
		||||
            if (!beast::lexicalCastChecked(
 | 
			
		||||
                    peer_nid, std::string(iter->value())))
 | 
			
		||||
            if (!beast::lexicalCastChecked(nid, std::string(iter->value())))
 | 
			
		||||
                throw std::runtime_error("Invalid peer network identifier");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        uint32_t our_nid = networkID ? *networkID : 0;
 | 
			
		||||
        if (peer_nid != our_nid)
 | 
			
		||||
        if (networkID.value_or(0) != nid)
 | 
			
		||||
            throw std::runtime_error("Peer is on a different network");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -74,7 +74,7 @@ namespace detail {
 | 
			
		||||
// Feature.cpp. Because it's only used to reserve storage, and determine how
 | 
			
		||||
// large to make the FeatureBitset, it MAY be larger. It MUST NOT be less than
 | 
			
		||||
// the actual number of amendments. A LogicError on startup will verify this.
 | 
			
		||||
static constexpr std::size_t numFeatures = 85;
 | 
			
		||||
static constexpr std::size_t numFeatures = 88;
 | 
			
		||||
 | 
			
		||||
/** Amendments that this server supports and the default voting behavior.
 | 
			
		||||
   Whether they are enabled depends on the Rules defined in the validated
 | 
			
		||||
@@ -373,6 +373,9 @@ extern uint256 const fixProvisionalDoubleThreading;
 | 
			
		||||
extern uint256 const featureClawback;
 | 
			
		||||
extern uint256 const featureDeepFreeze;
 | 
			
		||||
extern uint256 const featureIOUIssuerWeakTSH;
 | 
			
		||||
extern uint256 const featureCron;
 | 
			
		||||
extern uint256 const fixInvalidTxFlags;
 | 
			
		||||
extern uint256 const featureExtendedHookState;
 | 
			
		||||
 | 
			
		||||
}  // namespace ripple
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -297,6 +297,9 @@ import_vlseq(PublicKey const& key) noexcept;
 | 
			
		||||
Keylet
 | 
			
		||||
uritoken(AccountID const& issuer, Blob const& uri);
 | 
			
		||||
 | 
			
		||||
Keylet
 | 
			
		||||
cron(uint32_t timestamp, AccountID const& id);
 | 
			
		||||
 | 
			
		||||
}  // namespace keylet
 | 
			
		||||
 | 
			
		||||
// Everything below is deprecated and should be removed in favor of keylets:
 | 
			
		||||
 
 | 
			
		||||
@@ -58,6 +58,12 @@ enum LedgerEntryType : std::uint16_t
 | 
			
		||||
     */
 | 
			
		||||
    ltACCOUNT_ROOT = 0x0061,
 | 
			
		||||
 | 
			
		||||
    /** A ledger object representing a scheduled cron execution on an account.
 | 
			
		||||
     
 | 
			
		||||
        \sa keylet::cron
 | 
			
		||||
    */
 | 
			
		||||
    ltCRON = 0x0041,
 | 
			
		||||
 | 
			
		||||
    /** A ledger object which contains a list of object identifiers.
 | 
			
		||||
 | 
			
		||||
        \sa keylet::page, keylet::quality, keylet::book, keylet::next and
 | 
			
		||||
 
 | 
			
		||||
@@ -354,6 +354,7 @@ extern SF_UINT16 const sfHookStateChangeCount;
 | 
			
		||||
extern SF_UINT16 const sfHookEmitCount;
 | 
			
		||||
extern SF_UINT16 const sfHookExecutionIndex;
 | 
			
		||||
extern SF_UINT16 const sfHookApiVersion;
 | 
			
		||||
extern SF_UINT16 const sfHookStateScale;
 | 
			
		||||
 | 
			
		||||
// 32-bit integers (common)
 | 
			
		||||
extern SF_UINT32 const sfNetworkID;
 | 
			
		||||
@@ -410,6 +411,9 @@ extern SF_UINT32 const sfRewardLgrLast;
 | 
			
		||||
extern SF_UINT32 const sfFirstNFTokenSequence;
 | 
			
		||||
extern SF_UINT32 const sfImportSequence;
 | 
			
		||||
extern SF_UINT32 const sfXahauActivationLgrSeq;
 | 
			
		||||
extern SF_UINT32 const sfDelaySeconds;
 | 
			
		||||
extern SF_UINT32 const sfRepeatCount;
 | 
			
		||||
extern SF_UINT32 const sfStartTime;
 | 
			
		||||
 | 
			
		||||
// 64-bit integers (common)
 | 
			
		||||
extern SF_UINT64 const sfIndexNext;
 | 
			
		||||
@@ -486,6 +490,7 @@ extern SF_UINT256 const sfURITokenID;
 | 
			
		||||
extern SF_UINT256 const sfGovernanceFlags;
 | 
			
		||||
extern SF_UINT256 const sfGovernanceMarks;
 | 
			
		||||
extern SF_UINT256 const sfEmittedTxnID;
 | 
			
		||||
extern SF_UINT256 const sfCron;
 | 
			
		||||
 | 
			
		||||
// currency amount (common)
 | 
			
		||||
extern SF_AMOUNT const sfAmount;
 | 
			
		||||
 
 | 
			
		||||
@@ -343,6 +343,7 @@ enum TECcodes : TERUnderlyingType {
 | 
			
		||||
    tecINSUF_RESERVE_SELLER = 187,
 | 
			
		||||
    tecIMMUTABLE = 188,
 | 
			
		||||
    tecTOO_MANY_REMARKS = 189,
 | 
			
		||||
    tecHAS_HOOK_STATE = 190,
 | 
			
		||||
    tecLAST_POSSIBLE_ENTRY = 255,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user