mirror of
				https://github.com/XRPLF/rippled.git
				synced 2025-11-04 11:15:56 +00:00 
			
		
		
		
	Compare commits
	
		
			55 Commits
		
	
	
		
			415a412d42
			...
			ab9644267d
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					ab9644267d | ||
| 
						 | 
					25c5e3b17f | ||
| 
						 | 
					8eb233c2ea | ||
| 
						 | 
					50fc93f742 | ||
| 
						 | 
					ab45a8a737 | ||
| 
						 | 
					dfafb141cc | ||
| 
						 | 
					4e32d2ed98 | ||
| 
						 | 
					fa69918124 | ||
| 
						 | 
					cbbb2b1be0 | ||
| 
						 | 
					cf2d763fa1 | ||
| 
						 | 
					2dd1d682ac | ||
| 
						 | 
					4cb1084c02 | ||
| 
						 | 
					8d1b3b3994 | ||
| 
						 | 
					b39d7a6519 | ||
| 
						 | 
					b0910e359e | ||
| 
						 | 
					44e027e516 | ||
| 
						 | 
					a10f42a3aa | ||
| 
						 | 
					efd4c1b95d | ||
| 
						 | 
					f8b4f692f1 | ||
| 
						 | 
					80a3ae6386 | ||
| 
						 | 
					48d38c1e2c | ||
| 
						 | 
					553fb5be3b | ||
| 
						 | 
					efa917d9f3 | ||
| 
						 | 
					bd3bc917f8 | ||
| 
						 | 
					ed5d6f3e22 | ||
| 
						 | 
					a8e4da0b11 | ||
| 
						 | 
					1dd60242de | ||
| 
						 | 
					76611c3f46 | ||
| 
						 | 
					5efaf0c328 | ||
| 
						 | 
					0aa23933ea | ||
| 
						 | 
					21f3c12d85 | ||
| 
						 | 
					7d5ed0cd8d | ||
| 
						 | 
					d9960d5ba0 | ||
| 
						 | 
					91fa6b2295 | ||
| 
						 | 
					76f774e22d | ||
| 
						 | 
					f4f7618173 | ||
| 
						 | 
					66f16469f9 | ||
| 
						 | 
					1845b1c656 | ||
| 
						 | 
					e192ffe964 | ||
| 
						 | 
					2bf77cc8f6 | ||
| 
						 | 
					5e33ca56fd | ||
| 
						 | 
					7c39c810eb | ||
| 
						 | 
					a7792ebcae | ||
| 
						 | 
					83ee3788e1 | ||
| 
						 | 
					ae719b86d3 | ||
| 
						 | 
					dd722f8b3f | ||
| 
						 | 
					30190a5feb | ||
| 
						 | 
					afb6e0e41b | ||
| 
						 | 
					5523557226 | ||
| 
						 | 
					b64707f53b | ||
| 
						 | 
					0b113f371f | ||
| 
						 | 
					b4c894c1ba | ||
| 
						 | 
					92281a4ede | ||
| 
						 | 
					e80642fc12 | ||
| 
						 | 
					640ce4988f | 
							
								
								
									
										27
									
								
								.github/actions/build-deps/action.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										27
									
								
								.github/actions/build-deps/action.yml
									
									
									
									
										vendored
									
									
								
							@@ -4,20 +4,23 @@ description: "Install Conan dependencies, optionally forcing a rebuild of all de
 | 
			
		||||
# Note that actions do not support 'type' and all inputs are strings, see
 | 
			
		||||
# https://docs.github.com/en/actions/reference/workflows-and-actions/metadata-syntax#inputs.
 | 
			
		||||
inputs:
 | 
			
		||||
  verbosity:
 | 
			
		||||
    description: "The build verbosity."
 | 
			
		||||
    required: false
 | 
			
		||||
    default: "verbose"
 | 
			
		||||
  build_dir:
 | 
			
		||||
    description: "The directory where to build."
 | 
			
		||||
    required: true
 | 
			
		||||
  build_type:
 | 
			
		||||
    description: 'The build type to use ("Debug", "Release").'
 | 
			
		||||
    required: true
 | 
			
		||||
  build_nproc:
 | 
			
		||||
    description: "The number of processors to use for building."
 | 
			
		||||
    required: true
 | 
			
		||||
  force_build:
 | 
			
		||||
    description: 'Force building of all dependencies ("true", "false").'
 | 
			
		||||
    required: false
 | 
			
		||||
    default: "false"
 | 
			
		||||
  log_verbosity:
 | 
			
		||||
    description: "The logging verbosity."
 | 
			
		||||
    required: false
 | 
			
		||||
    default: "verbose"
 | 
			
		||||
 | 
			
		||||
runs:
 | 
			
		||||
  using: composite
 | 
			
		||||
@@ -26,19 +29,21 @@ runs:
 | 
			
		||||
      shell: bash
 | 
			
		||||
      env:
 | 
			
		||||
        BUILD_DIR: ${{ inputs.build_dir }}
 | 
			
		||||
        BUILD_NPROC: ${{ inputs.build_nproc }}
 | 
			
		||||
        BUILD_OPTION: ${{ inputs.force_build == 'true' && '*' || 'missing' }}
 | 
			
		||||
        BUILD_TYPE: ${{ inputs.build_type }}
 | 
			
		||||
        LOG_VERBOSITY: ${{ inputs.log_verbosity }}
 | 
			
		||||
      run: |
 | 
			
		||||
        echo 'Installing dependencies.'
 | 
			
		||||
        mkdir -p '${{ env.BUILD_DIR }}'
 | 
			
		||||
        cd '${{ env.BUILD_DIR }}'
 | 
			
		||||
        mkdir -p "${BUILD_DIR}"
 | 
			
		||||
        cd "${BUILD_DIR}"
 | 
			
		||||
        conan install \
 | 
			
		||||
          --output-folder . \
 | 
			
		||||
          --build=${{ env.BUILD_OPTION }} \
 | 
			
		||||
          --build="${BUILD_OPTION}" \
 | 
			
		||||
          --options:host='&:tests=True' \
 | 
			
		||||
          --options:host='&:xrpld=True' \
 | 
			
		||||
          --settings:all build_type='${{ env.BUILD_TYPE }}' \
 | 
			
		||||
          --conf:all tools.build:verbosity='${{ inputs.verbosity }}' \
 | 
			
		||||
          --conf:all tools.compilation:verbosity='${{ inputs.verbosity }}' \
 | 
			
		||||
          --conf:all tools.build:jobs=$(nproc) \
 | 
			
		||||
          --settings:all build_type="${BUILD_TYPE}" \
 | 
			
		||||
          --conf:all tools.build:jobs=${BUILD_NPROC} \
 | 
			
		||||
          --conf:all tools.build:verbosity="${LOG_VERBOSITY}" \
 | 
			
		||||
          --conf:all tools.compilation:verbosity="${LOG_VERBOSITY}" \
 | 
			
		||||
          ..
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								.github/actions/setup-conan/action.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.github/actions/setup-conan/action.yml
									
									
									
									
										vendored
									
									
								
							@@ -39,8 +39,8 @@ runs:
 | 
			
		||||
        CONAN_REMOTE_NAME: ${{ inputs.conan_remote_name }}
 | 
			
		||||
        CONAN_REMOTE_URL: ${{ inputs.conan_remote_url }}
 | 
			
		||||
      run: |
 | 
			
		||||
        echo "Adding Conan remote '${{ env.CONAN_REMOTE_NAME }}' at '${{ env.CONAN_REMOTE_URL }}'."
 | 
			
		||||
        conan remote add --index 0 --force '${{ env.CONAN_REMOTE_NAME }}' '${{ env.CONAN_REMOTE_URL }}'
 | 
			
		||||
        echo "Adding Conan remote '${CONAN_REMOTE_NAME}' at '${CONAN_REMOTE_URL}'."
 | 
			
		||||
        conan remote add --index 0 --force "${CONAN_REMOTE_NAME}" "${CONAN_REMOTE_URL}"
 | 
			
		||||
 | 
			
		||||
        echo 'Listing Conan remotes.'
 | 
			
		||||
        conan remote list
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,7 @@ Loop: xrpld.app xrpld.rpc
 | 
			
		||||
  xrpld.rpc > xrpld.app
 | 
			
		||||
 | 
			
		||||
Loop: xrpld.app xrpld.shamap
 | 
			
		||||
  xrpld.app > xrpld.shamap
 | 
			
		||||
  xrpld.shamap ~= xrpld.app
 | 
			
		||||
 | 
			
		||||
Loop: xrpld.core xrpld.perflog
 | 
			
		||||
  xrpld.perflog == xrpld.core
 | 
			
		||||
 
 | 
			
		||||
@@ -8,6 +8,10 @@ libxrpl.ledger > xrpl.ledger
 | 
			
		||||
libxrpl.ledger > xrpl.protocol
 | 
			
		||||
libxrpl.net > xrpl.basics
 | 
			
		||||
libxrpl.net > xrpl.net
 | 
			
		||||
libxrpl.nodestore > xrpl.basics
 | 
			
		||||
libxrpl.nodestore > xrpl.json
 | 
			
		||||
libxrpl.nodestore > xrpl.nodestore
 | 
			
		||||
libxrpl.nodestore > xrpl.protocol
 | 
			
		||||
libxrpl.protocol > xrpl.basics
 | 
			
		||||
libxrpl.protocol > xrpl.json
 | 
			
		||||
libxrpl.protocol > xrpl.protocol
 | 
			
		||||
@@ -18,6 +22,9 @@ libxrpl.server > xrpl.basics
 | 
			
		||||
libxrpl.server > xrpl.json
 | 
			
		||||
libxrpl.server > xrpl.protocol
 | 
			
		||||
libxrpl.server > xrpl.server
 | 
			
		||||
libxrpl.shamap > xrpl.basics
 | 
			
		||||
libxrpl.shamap > xrpl.protocol
 | 
			
		||||
libxrpl.shamap > xrpl.shamap
 | 
			
		||||
test.app > test.jtx
 | 
			
		||||
test.app > test.rpc
 | 
			
		||||
test.app > test.toplevel
 | 
			
		||||
@@ -25,11 +32,11 @@ test.app > test.unit_test
 | 
			
		||||
test.app > xrpl.basics
 | 
			
		||||
test.app > xrpld.app
 | 
			
		||||
test.app > xrpld.core
 | 
			
		||||
test.app > xrpld.nodestore
 | 
			
		||||
test.app > xrpld.overlay
 | 
			
		||||
test.app > xrpld.rpc
 | 
			
		||||
test.app > xrpl.json
 | 
			
		||||
test.app > xrpl.ledger
 | 
			
		||||
test.app > xrpl.nodestore
 | 
			
		||||
test.app > xrpl.protocol
 | 
			
		||||
test.app > xrpl.resource
 | 
			
		||||
test.basics > test.jtx
 | 
			
		||||
@@ -86,8 +93,7 @@ test.nodestore > test.toplevel
 | 
			
		||||
test.nodestore > test.unit_test
 | 
			
		||||
test.nodestore > xrpl.basics
 | 
			
		||||
test.nodestore > xrpld.core
 | 
			
		||||
test.nodestore > xrpld.nodestore
 | 
			
		||||
test.nodestore > xrpld.unity
 | 
			
		||||
test.nodestore > xrpl.nodestore
 | 
			
		||||
test.overlay > test.jtx
 | 
			
		||||
test.overlay > test.toplevel
 | 
			
		||||
test.overlay > test.unit_test
 | 
			
		||||
@@ -95,8 +101,8 @@ test.overlay > xrpl.basics
 | 
			
		||||
test.overlay > xrpld.app
 | 
			
		||||
test.overlay > xrpld.overlay
 | 
			
		||||
test.overlay > xrpld.peerfinder
 | 
			
		||||
test.overlay > xrpld.shamap
 | 
			
		||||
test.overlay > xrpl.protocol
 | 
			
		||||
test.overlay > xrpl.shamap
 | 
			
		||||
test.peerfinder > test.beast
 | 
			
		||||
test.peerfinder > test.unit_test
 | 
			
		||||
test.peerfinder > xrpl.basics
 | 
			
		||||
@@ -131,19 +137,22 @@ test.server > xrpl.json
 | 
			
		||||
test.server > xrpl.server
 | 
			
		||||
test.shamap > test.unit_test
 | 
			
		||||
test.shamap > xrpl.basics
 | 
			
		||||
test.shamap > xrpld.nodestore
 | 
			
		||||
test.shamap > xrpld.shamap
 | 
			
		||||
test.shamap > xrpl.nodestore
 | 
			
		||||
test.shamap > xrpl.protocol
 | 
			
		||||
test.shamap > xrpl.shamap
 | 
			
		||||
test.toplevel > test.csf
 | 
			
		||||
test.toplevel > xrpl.json
 | 
			
		||||
test.unit_test > xrpl.basics
 | 
			
		||||
tests.libxrpl > xrpl.basics
 | 
			
		||||
tests.libxrpl > xrpl.ledger
 | 
			
		||||
tests.libxrpl > xrpl.json
 | 
			
		||||
tests.libxrpl > xrpl.net
 | 
			
		||||
xrpl.json > xrpl.basics
 | 
			
		||||
xrpl.ledger > xrpl.basics
 | 
			
		||||
xrpl.ledger > xrpl.protocol
 | 
			
		||||
xrpl.net > xrpl.basics
 | 
			
		||||
xrpl.nodestore > xrpl.basics
 | 
			
		||||
xrpl.nodestore > xrpl.protocol
 | 
			
		||||
xrpl.protocol > xrpl.basics
 | 
			
		||||
xrpl.protocol > xrpl.json
 | 
			
		||||
xrpl.resource > xrpl.basics
 | 
			
		||||
@@ -152,17 +161,21 @@ xrpl.resource > xrpl.protocol
 | 
			
		||||
xrpl.server > xrpl.basics
 | 
			
		||||
xrpl.server > xrpl.json
 | 
			
		||||
xrpl.server > xrpl.protocol
 | 
			
		||||
xrpl.shamap > xrpl.basics
 | 
			
		||||
xrpl.shamap > xrpl.nodestore
 | 
			
		||||
xrpl.shamap > xrpl.protocol
 | 
			
		||||
xrpld.app > test.unit_test
 | 
			
		||||
xrpld.app > xrpl.basics
 | 
			
		||||
xrpld.app > xrpld.conditions
 | 
			
		||||
xrpld.app > xrpld.consensus
 | 
			
		||||
xrpld.app > xrpld.nodestore
 | 
			
		||||
xrpld.app > xrpld.perflog
 | 
			
		||||
xrpld.app > xrpl.json
 | 
			
		||||
xrpld.app > xrpl.ledger
 | 
			
		||||
xrpld.app > xrpl.net
 | 
			
		||||
xrpld.app > xrpl.nodestore
 | 
			
		||||
xrpld.app > xrpl.protocol
 | 
			
		||||
xrpld.app > xrpl.resource
 | 
			
		||||
xrpld.app > xrpl.shamap
 | 
			
		||||
xrpld.conditions > xrpl.basics
 | 
			
		||||
xrpld.conditions > xrpl.protocol
 | 
			
		||||
xrpld.consensus > xrpl.basics
 | 
			
		||||
@@ -172,11 +185,6 @@ xrpld.core > xrpl.basics
 | 
			
		||||
xrpld.core > xrpl.json
 | 
			
		||||
xrpld.core > xrpl.net
 | 
			
		||||
xrpld.core > xrpl.protocol
 | 
			
		||||
xrpld.nodestore > xrpl.basics
 | 
			
		||||
xrpld.nodestore > xrpld.core
 | 
			
		||||
xrpld.nodestore > xrpld.unity
 | 
			
		||||
xrpld.nodestore > xrpl.json
 | 
			
		||||
xrpld.nodestore > xrpl.protocol
 | 
			
		||||
xrpld.overlay > xrpl.basics
 | 
			
		||||
xrpld.overlay > xrpld.core
 | 
			
		||||
xrpld.overlay > xrpld.peerfinder
 | 
			
		||||
@@ -192,13 +200,11 @@ xrpld.perflog > xrpl.basics
 | 
			
		||||
xrpld.perflog > xrpl.json
 | 
			
		||||
xrpld.rpc > xrpl.basics
 | 
			
		||||
xrpld.rpc > xrpld.core
 | 
			
		||||
xrpld.rpc > xrpld.nodestore
 | 
			
		||||
xrpld.rpc > xrpl.json
 | 
			
		||||
xrpld.rpc > xrpl.ledger
 | 
			
		||||
xrpld.rpc > xrpl.net
 | 
			
		||||
xrpld.rpc > xrpl.nodestore
 | 
			
		||||
xrpld.rpc > xrpl.protocol
 | 
			
		||||
xrpld.rpc > xrpl.resource
 | 
			
		||||
xrpld.rpc > xrpl.server
 | 
			
		||||
xrpld.shamap > xrpl.basics
 | 
			
		||||
xrpld.shamap > xrpld.nodestore
 | 
			
		||||
xrpld.shamap > xrpl.protocol
 | 
			
		||||
xrpld.shamap > xrpl.shamap
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										26
									
								
								.github/scripts/strategy-matrix/linux.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										26
									
								
								.github/scripts/strategy-matrix/linux.json
									
									
									
									
										vendored
									
									
								
							@@ -73,47 +73,61 @@
 | 
			
		||||
      "compiler_version": "20",
 | 
			
		||||
      "image_sha": "6948666"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "distro_name": "rhel",
 | 
			
		||||
      "distro_version": "8",
 | 
			
		||||
      "compiler_name": "gcc",
 | 
			
		||||
      "compiler_version": "14",
 | 
			
		||||
      "image_sha": "10e69b4"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "distro_name": "rhel",
 | 
			
		||||
      "distro_version": "8",
 | 
			
		||||
      "compiler_name": "clang",
 | 
			
		||||
      "compiler_version": "any",
 | 
			
		||||
      "image_sha": "10e69b4"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "distro_name": "rhel",
 | 
			
		||||
      "distro_version": "9",
 | 
			
		||||
      "compiler_name": "gcc",
 | 
			
		||||
      "compiler_version": "12",
 | 
			
		||||
      "image_sha": "6948666"
 | 
			
		||||
      "image_sha": "10e69b4"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "distro_name": "rhel",
 | 
			
		||||
      "distro_version": "9",
 | 
			
		||||
      "compiler_name": "gcc",
 | 
			
		||||
      "compiler_version": "13",
 | 
			
		||||
      "image_sha": "6948666"
 | 
			
		||||
      "image_sha": "10e69b4"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "distro_name": "rhel",
 | 
			
		||||
      "distro_version": "9",
 | 
			
		||||
      "compiler_name": "gcc",
 | 
			
		||||
      "compiler_version": "14",
 | 
			
		||||
      "image_sha": "6948666"
 | 
			
		||||
      "image_sha": "10e69b4"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "distro_name": "rhel",
 | 
			
		||||
      "distro_version": "9",
 | 
			
		||||
      "compiler_name": "clang",
 | 
			
		||||
      "compiler_version": "any",
 | 
			
		||||
      "image_sha": "6948666"
 | 
			
		||||
      "image_sha": "10e69b4"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "distro_name": "rhel",
 | 
			
		||||
      "distro_version": "10",
 | 
			
		||||
      "compiler_name": "gcc",
 | 
			
		||||
      "compiler_version": "14",
 | 
			
		||||
      "image_sha": "6948666"
 | 
			
		||||
      "image_sha": "10e69b4"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "distro_name": "rhel",
 | 
			
		||||
      "distro_version": "10",
 | 
			
		||||
      "compiler_name": "clang",
 | 
			
		||||
      "compiler_version": "any",
 | 
			
		||||
      "image_sha": "6948666"
 | 
			
		||||
      "image_sha": "10e69b4"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "distro_name": "ubuntu",
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								.github/workflows/on-pr.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.github/workflows/on-pr.yml
									
									
									
									
										vendored
									
									
								
							@@ -103,6 +103,7 @@ jobs:
 | 
			
		||||
    if: ${{ needs.should-run.outputs.go == 'true' }}
 | 
			
		||||
    uses: ./.github/workflows/reusable-build-test.yml
 | 
			
		||||
    strategy:
 | 
			
		||||
      fail-fast: false
 | 
			
		||||
      matrix:
 | 
			
		||||
        os: [linux, macos, windows]
 | 
			
		||||
    with:
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										8
									
								
								.github/workflows/on-trigger.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								.github/workflows/on-trigger.yml
									
									
									
									
										vendored
									
									
								
							@@ -50,7 +50,12 @@ on:
 | 
			
		||||
  workflow_dispatch:
 | 
			
		||||
 | 
			
		||||
concurrency:
 | 
			
		||||
  group: ${{ github.workflow }}-${{ github.ref }}
 | 
			
		||||
  # When a PR is merged into the develop branch it will be assigned a unique
 | 
			
		||||
  # group identifier, so execution will continue even if another PR is merged
 | 
			
		||||
  # while it is still running. In all other cases the group identifier is shared
 | 
			
		||||
  # per branch, so that any in-progress runs are cancelled when a new commit is
 | 
			
		||||
  # pushed.
 | 
			
		||||
  group: ${{ github.workflow }}-${{ github.event_name == 'push' && github.ref == 'refs/heads/develop' && github.sha || github.ref }}
 | 
			
		||||
  cancel-in-progress: true
 | 
			
		||||
 | 
			
		||||
defaults:
 | 
			
		||||
@@ -65,6 +70,7 @@ jobs:
 | 
			
		||||
  build-test:
 | 
			
		||||
    uses: ./.github/workflows/reusable-build-test.yml
 | 
			
		||||
    strategy:
 | 
			
		||||
      fail-fast: ${{ github.event_name == 'merge_group' }}
 | 
			
		||||
      matrix:
 | 
			
		||||
        os: [linux, macos, windows]
 | 
			
		||||
    with:
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								.github/workflows/pre-commit.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/pre-commit.yml
									
									
									
									
										vendored
									
									
								
							@@ -9,7 +9,7 @@ on:
 | 
			
		||||
jobs:
 | 
			
		||||
  # Call the workflow in the XRPLF/actions repo that runs the pre-commit hooks.
 | 
			
		||||
  run-hooks:
 | 
			
		||||
    uses: XRPLF/actions/.github/workflows/pre-commit.yml@af1b0f0d764cda2e5435f5ac97b240d4bd4d95d3
 | 
			
		||||
    uses: XRPLF/actions/.github/workflows/pre-commit.yml@34790936fae4c6c751f62ec8c06696f9c1a5753a
 | 
			
		||||
    with:
 | 
			
		||||
      runs_on: ubuntu-latest
 | 
			
		||||
      container: '{ "image": "ghcr.io/xrplf/ci/tools-rippled-pre-commit:sha-a8c7be1" }'
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										18
									
								
								.github/workflows/publish-docs.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										18
									
								
								.github/workflows/publish-docs.yml
									
									
									
									
										vendored
									
									
								
							@@ -23,6 +23,7 @@ defaults:
 | 
			
		||||
 | 
			
		||||
env:
 | 
			
		||||
  BUILD_DIR: .build
 | 
			
		||||
  NPROC_SUBTRACT: 2
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  publish:
 | 
			
		||||
@@ -33,6 +34,13 @@ jobs:
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: Checkout repository
 | 
			
		||||
        uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
 | 
			
		||||
 | 
			
		||||
      - name: Get number of processors
 | 
			
		||||
        uses: XRPLF/actions/.github/actions/get-nproc@046b1620f6bfd6cd0985dc82c3df02786801fe0a
 | 
			
		||||
        id: nproc
 | 
			
		||||
        with:
 | 
			
		||||
          subtract: ${{ env.NPROC_SUBTRACT }}
 | 
			
		||||
 | 
			
		||||
      - name: Check configuration
 | 
			
		||||
        run: |
 | 
			
		||||
          echo 'Checking path.'
 | 
			
		||||
@@ -46,12 +54,16 @@ jobs:
 | 
			
		||||
 | 
			
		||||
          echo 'Checking Doxygen version.'
 | 
			
		||||
          doxygen --version
 | 
			
		||||
 | 
			
		||||
      - name: Build documentation
 | 
			
		||||
        env:
 | 
			
		||||
          BUILD_NPROC: ${{ steps.nproc.outputs.nproc }}
 | 
			
		||||
        run: |
 | 
			
		||||
          mkdir -p ${{ env.BUILD_DIR }}
 | 
			
		||||
          cd ${{ env.BUILD_DIR }}
 | 
			
		||||
          mkdir -p "${BUILD_DIR}"
 | 
			
		||||
          cd "${BUILD_DIR}"
 | 
			
		||||
          cmake -Donly_docs=ON ..
 | 
			
		||||
          cmake --build . --target docs --parallel $(nproc)
 | 
			
		||||
          cmake --build . --target docs --parallel ${BUILD_NPROC}
 | 
			
		||||
 | 
			
		||||
      - name: Publish documentation
 | 
			
		||||
        if: ${{ github.ref_type == 'branch' && github.ref_name == github.event.repository.default_branch }}
 | 
			
		||||
        uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0
 | 
			
		||||
 
 | 
			
		||||
@@ -39,6 +39,12 @@ on:
 | 
			
		||||
        required: true
 | 
			
		||||
        type: string
 | 
			
		||||
 | 
			
		||||
      nproc_subtract:
 | 
			
		||||
        description: "The number of processors to subtract when calculating parallelism."
 | 
			
		||||
        required: false
 | 
			
		||||
        type: number
 | 
			
		||||
        default: 2
 | 
			
		||||
 | 
			
		||||
    secrets:
 | 
			
		||||
      CODECOV_TOKEN:
 | 
			
		||||
        description: "The Codecov token to use for uploading coverage reports."
 | 
			
		||||
@@ -55,6 +61,7 @@ jobs:
 | 
			
		||||
      runs_on: ${{ inputs.runs_on }}
 | 
			
		||||
      image: ${{ inputs.image }}
 | 
			
		||||
      config_name: ${{ inputs.config_name }}
 | 
			
		||||
      nproc_subtract: ${{ inputs.nproc_subtract }}
 | 
			
		||||
    secrets:
 | 
			
		||||
      CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
 | 
			
		||||
 | 
			
		||||
@@ -67,3 +74,4 @@ jobs:
 | 
			
		||||
      runs_on: ${{ inputs.runs_on }}
 | 
			
		||||
      image: ${{ inputs.image }}
 | 
			
		||||
      config_name: ${{ inputs.config_name }}
 | 
			
		||||
      nproc_subtract: ${{ inputs.nproc_subtract }}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								.github/workflows/reusable-build-test.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/reusable-build-test.yml
									
									
									
									
										vendored
									
									
								
							@@ -42,7 +42,7 @@ jobs:
 | 
			
		||||
      - generate-matrix
 | 
			
		||||
    uses: ./.github/workflows/reusable-build-test-config.yml
 | 
			
		||||
    strategy:
 | 
			
		||||
      fail-fast: false
 | 
			
		||||
      fail-fast: ${{ github.event_name == 'merge_group' }}
 | 
			
		||||
      matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix) }}
 | 
			
		||||
      max-parallel: 10
 | 
			
		||||
    with:
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										49
									
								
								.github/workflows/reusable-build.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										49
									
								
								.github/workflows/reusable-build.yml
									
									
									
									
										vendored
									
									
								
							@@ -34,6 +34,11 @@ on:
 | 
			
		||||
        required: true
 | 
			
		||||
        type: string
 | 
			
		||||
 | 
			
		||||
      nproc_subtract:
 | 
			
		||||
        description: "The number of processors to subtract when calculating parallelism."
 | 
			
		||||
        required: true
 | 
			
		||||
        type: number
 | 
			
		||||
 | 
			
		||||
    secrets:
 | 
			
		||||
      CODECOV_TOKEN:
 | 
			
		||||
        description: "The Codecov token to use for uploading coverage reports."
 | 
			
		||||
@@ -48,6 +53,7 @@ jobs:
 | 
			
		||||
    name: Build ${{ inputs.config_name }}
 | 
			
		||||
    runs-on: ${{ fromJSON(inputs.runs_on) }}
 | 
			
		||||
    container: ${{ inputs.image != '' && inputs.image || null }}
 | 
			
		||||
    timeout-minutes: 60
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: Cleanup workspace
 | 
			
		||||
        if: ${{ runner.os == 'macOS' }}
 | 
			
		||||
@@ -57,13 +63,19 @@ jobs:
 | 
			
		||||
        uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
 | 
			
		||||
 | 
			
		||||
      - name: Prepare runner
 | 
			
		||||
        uses: XRPLF/actions/.github/actions/prepare-runner@638e0dc11ea230f91bd26622fb542116bb5254d5
 | 
			
		||||
        uses: XRPLF/actions/.github/actions/prepare-runner@99685816bb60a95a66852f212f382580e180df3a
 | 
			
		||||
        with:
 | 
			
		||||
          disable_ccache: false
 | 
			
		||||
 | 
			
		||||
      - name: Print build environment
 | 
			
		||||
        uses: ./.github/actions/print-env
 | 
			
		||||
 | 
			
		||||
      - name: Get number of processors
 | 
			
		||||
        uses: XRPLF/actions/.github/actions/get-nproc@046b1620f6bfd6cd0985dc82c3df02786801fe0a
 | 
			
		||||
        id: nproc
 | 
			
		||||
        with:
 | 
			
		||||
          subtract: ${{ inputs.nproc_subtract }}
 | 
			
		||||
 | 
			
		||||
      - name: Setup Conan
 | 
			
		||||
        uses: ./.github/actions/setup-conan
 | 
			
		||||
 | 
			
		||||
@@ -71,7 +83,11 @@ jobs:
 | 
			
		||||
        uses: ./.github/actions/build-deps
 | 
			
		||||
        with:
 | 
			
		||||
          build_dir: ${{ inputs.build_dir }}
 | 
			
		||||
          build_nproc: ${{ steps.nproc.outputs.nproc }}
 | 
			
		||||
          build_type: ${{ inputs.build_type }}
 | 
			
		||||
          # Set the verbosity to "quiet" for Windows to avoid an excessive
 | 
			
		||||
          # amount of logs. For other OSes, the "verbose" logs are more useful.
 | 
			
		||||
          log_verbosity: ${{ runner.os == 'Windows' && 'quiet' || 'verbose' }}
 | 
			
		||||
 | 
			
		||||
      - name: Configure CMake
 | 
			
		||||
        shell: bash
 | 
			
		||||
@@ -83,33 +99,50 @@ jobs:
 | 
			
		||||
          cmake \
 | 
			
		||||
            -G '${{ runner.os == 'Windows' && 'Visual Studio 17 2022' || 'Ninja' }}' \
 | 
			
		||||
            -DCMAKE_TOOLCHAIN_FILE:FILEPATH=build/generators/conan_toolchain.cmake \
 | 
			
		||||
            -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \
 | 
			
		||||
            ${{ env.CMAKE_ARGS }} \
 | 
			
		||||
            -DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \
 | 
			
		||||
            ${CMAKE_ARGS} \
 | 
			
		||||
            ..
 | 
			
		||||
 | 
			
		||||
      - name: Build the binary
 | 
			
		||||
        shell: bash
 | 
			
		||||
        working-directory: ${{ inputs.build_dir }}
 | 
			
		||||
        env:
 | 
			
		||||
          BUILD_NPROC: ${{ steps.nproc.outputs.nproc }}
 | 
			
		||||
          BUILD_TYPE: ${{ inputs.build_type }}
 | 
			
		||||
          CMAKE_TARGET: ${{ inputs.cmake_target }}
 | 
			
		||||
        run: |
 | 
			
		||||
          cmake \
 | 
			
		||||
            --build . \
 | 
			
		||||
            --config ${{ env.BUILD_TYPE }} \
 | 
			
		||||
            --parallel $(nproc) \
 | 
			
		||||
            --target ${{ env.CMAKE_TARGET }}
 | 
			
		||||
            --config "${BUILD_TYPE}" \
 | 
			
		||||
            --parallel ${BUILD_NPROC} \
 | 
			
		||||
            --target "${CMAKE_TARGET}"
 | 
			
		||||
 | 
			
		||||
      - name: Put built binaries in one location
 | 
			
		||||
        shell: bash
 | 
			
		||||
        working-directory: ${{ inputs.build_dir }}
 | 
			
		||||
        env:
 | 
			
		||||
          BUILD_TYPE_DIR: ${{ runner.os == 'Windows' && inputs.build_type || '' }}
 | 
			
		||||
          CMAKE_TARGET: ${{ inputs.cmake_target }}
 | 
			
		||||
        run: |
 | 
			
		||||
          mkdir -p ./binaries/doctest/
 | 
			
		||||
 | 
			
		||||
          cp ./${BUILD_TYPE_DIR}/rippled* ./binaries/
 | 
			
		||||
          if [ "${CMAKE_TARGET}" != 'coverage' ]; then
 | 
			
		||||
            cp ./src/tests/libxrpl/${BUILD_TYPE_DIR}/xrpl.test.* ./binaries/doctest/
 | 
			
		||||
          fi
 | 
			
		||||
 | 
			
		||||
      - name: Upload rippled artifact
 | 
			
		||||
        uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
 | 
			
		||||
        env:
 | 
			
		||||
          BUILD_DIR: ${{ inputs.build_dir }}
 | 
			
		||||
        with:
 | 
			
		||||
          name: rippled-${{ inputs.config_name }}
 | 
			
		||||
          path: ${{ inputs.build_dir }}/${{ runner.os == 'Windows' && inputs.build_type || '' }}/rippled${{ runner.os == 'Windows' && '.exe' || '' }}
 | 
			
		||||
          path: ${{ env.BUILD_DIR }}/binaries/
 | 
			
		||||
          retention-days: 3
 | 
			
		||||
          if-no-files-found: error
 | 
			
		||||
 | 
			
		||||
      - name: Upload coverage report
 | 
			
		||||
        if: ${{ inputs.cmake_target == 'coverage' }}
 | 
			
		||||
        if: ${{ github.repository_owner == 'XRPLF' && inputs.cmake_target == 'coverage' }}
 | 
			
		||||
        uses: codecov/codecov-action@18283e04ce6e62d37312384ff67231eb8fd56d24 # v5.4.3
 | 
			
		||||
        with:
 | 
			
		||||
          disable_search: true
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								.github/workflows/reusable-notify-clio.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								.github/workflows/reusable-notify-clio.yml
									
									
									
									
										vendored
									
									
								
							@@ -51,7 +51,7 @@ jobs:
 | 
			
		||||
        run: |
 | 
			
		||||
          echo 'Generating user and channel.'
 | 
			
		||||
          echo "user=clio" >> "${GITHUB_OUTPUT}"
 | 
			
		||||
          echo "channel=pr_${{ env.PR_NUMBER }}" >> "${GITHUB_OUTPUT}"
 | 
			
		||||
          echo "channel=pr_${PR_NUMBER}" >> "${GITHUB_OUTPUT}"
 | 
			
		||||
          echo 'Extracting version.'
 | 
			
		||||
          echo "version=$(cat src/libxrpl/protocol/BuildInfo.cpp | grep "versionString =" | awk -F '"' '{print $2}')" >> "${GITHUB_OUTPUT}"
 | 
			
		||||
      - name: Calculate conan reference
 | 
			
		||||
@@ -64,13 +64,15 @@ jobs:
 | 
			
		||||
          conan_remote_name: ${{ inputs.conan_remote_name }}
 | 
			
		||||
          conan_remote_url: ${{ inputs.conan_remote_url }}
 | 
			
		||||
      - name: Log into Conan remote
 | 
			
		||||
        run: conan remote login ${{ inputs.conan_remote_name }} "${{ secrets.conan_remote_username }}" --password "${{ secrets.conan_remote_password }}"
 | 
			
		||||
        env:
 | 
			
		||||
          CONAN_REMOTE_NAME: ${{ inputs.conan_remote_name }}
 | 
			
		||||
        run: conan remote login "${CONAN_REMOTE_NAME}" "${{ secrets.conan_remote_username }}" --password "${{ secrets.conan_remote_password }}"
 | 
			
		||||
      - name: Upload package
 | 
			
		||||
        env:
 | 
			
		||||
          CONAN_REMOTE_NAME: ${{ inputs.conan_remote_name }}
 | 
			
		||||
        run: |
 | 
			
		||||
          conan export --user=${{ steps.generate.outputs.user }} --channel=${{ steps.generate.outputs.channel }} .
 | 
			
		||||
          conan upload --confirm --check --remote=${{ env.CONAN_REMOTE_NAME }} xrpl/${{ steps.conan_ref.outputs.conan_ref }}
 | 
			
		||||
          conan upload --confirm --check --remote="${CONAN_REMOTE_NAME}" xrpl/${{ steps.conan_ref.outputs.conan_ref }}
 | 
			
		||||
    outputs:
 | 
			
		||||
      conan_ref: ${{ steps.conan_ref.outputs.conan_ref }}
 | 
			
		||||
 | 
			
		||||
@@ -86,4 +88,4 @@ jobs:
 | 
			
		||||
          gh api --method POST -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" \
 | 
			
		||||
          /repos/xrplf/clio/dispatches -f "event_type=check_libxrpl" \
 | 
			
		||||
          -F "client_payload[conan_ref]=${{ needs.upload.outputs.conan_ref }}" \
 | 
			
		||||
          -F "client_payload[pr_url]=${{ env.PR_URL }}"
 | 
			
		||||
          -F "client_payload[pr_url]=${PR_URL}"
 | 
			
		||||
 
 | 
			
		||||
@@ -38,4 +38,4 @@ jobs:
 | 
			
		||||
        env:
 | 
			
		||||
          GENERATE_CONFIG: ${{ inputs.os != '' && format('--config={0}.json', inputs.os) || '' }}
 | 
			
		||||
          GENERATE_OPTION: ${{ inputs.strategy_matrix == 'all' && '--all' || '' }}
 | 
			
		||||
        run: ./generate.py ${{ env.GENERATE_OPTION }} ${{ env.GENERATE_CONFIG }} >> "${GITHUB_OUTPUT}"
 | 
			
		||||
        run: ./generate.py ${GENERATE_OPTION} ${GENERATE_CONFIG} >> "${GITHUB_OUTPUT}"
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										48
									
								
								.github/workflows/reusable-test.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										48
									
								
								.github/workflows/reusable-test.yml
									
									
									
									
										vendored
									
									
								
							@@ -26,12 +26,28 @@ on:
 | 
			
		||||
        required: true
 | 
			
		||||
        type: string
 | 
			
		||||
 | 
			
		||||
      nproc_subtract:
 | 
			
		||||
        description: "The number of processors to subtract when calculating parallelism."
 | 
			
		||||
        required: true
 | 
			
		||||
        type: number
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  test:
 | 
			
		||||
    name: Test ${{ inputs.config_name }}
 | 
			
		||||
    runs-on: ${{ fromJSON(inputs.runs_on) }}
 | 
			
		||||
    container: ${{ inputs.image != '' && inputs.image || null }}
 | 
			
		||||
    timeout-minutes: 30
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: Cleanup workspace
 | 
			
		||||
        if: ${{ runner.os == 'macOS' }}
 | 
			
		||||
        uses: XRPLF/actions/.github/actions/cleanup-workspace@3f044c7478548e3c32ff68980eeb36ece02b364e
 | 
			
		||||
 | 
			
		||||
      - name: Get number of processors
 | 
			
		||||
        uses: XRPLF/actions/.github/actions/get-nproc@046b1620f6bfd6cd0985dc82c3df02786801fe0a
 | 
			
		||||
        id: nproc
 | 
			
		||||
        with:
 | 
			
		||||
          subtract: ${{ inputs.nproc_subtract }}
 | 
			
		||||
 | 
			
		||||
      - name: Download rippled artifact
 | 
			
		||||
        uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
 | 
			
		||||
        with:
 | 
			
		||||
@@ -61,9 +77,35 @@ jobs:
 | 
			
		||||
        run: |
 | 
			
		||||
          ./rippled --version | grep libvoidstar
 | 
			
		||||
 | 
			
		||||
      - name: Test the binary
 | 
			
		||||
      - name: Run the embedded tests
 | 
			
		||||
        if: ${{ inputs.run_tests }}
 | 
			
		||||
        shell: bash
 | 
			
		||||
        env:
 | 
			
		||||
          BUILD_NPROC: ${{ steps.nproc.outputs.nproc }}
 | 
			
		||||
        run: |
 | 
			
		||||
          ./rippled --unittest --unittest-jobs $(nproc)
 | 
			
		||||
          ctest -j $(nproc) --output-on-failure
 | 
			
		||||
          ./rippled --unittest --unittest-jobs ${BUILD_NPROC}
 | 
			
		||||
 | 
			
		||||
      - name: Run the separate tests
 | 
			
		||||
        if: ${{ inputs.run_tests }}
 | 
			
		||||
        env:
 | 
			
		||||
          EXT: ${{ runner.os == 'Windows' && '.exe' || '' }}
 | 
			
		||||
        shell: bash
 | 
			
		||||
        run: |
 | 
			
		||||
          for test_file in ./doctest/*${EXT}; do
 | 
			
		||||
            echo "Executing $test_file"
 | 
			
		||||
            chmod +x "$test_file"
 | 
			
		||||
            if [[ "${{ runner.os }}" == "Windows" && "$test_file" == "./doctest/xrpl.test.net.exe" ]]; then
 | 
			
		||||
              echo "Skipping $test_file on Windows"
 | 
			
		||||
            else
 | 
			
		||||
              "$test_file"
 | 
			
		||||
            fi
 | 
			
		||||
          done
 | 
			
		||||
 | 
			
		||||
      - name: Debug failure (Linux)
 | 
			
		||||
        if: ${{ failure() && runner.os == 'Linux' && inputs.run_tests }}
 | 
			
		||||
        shell: bash
 | 
			
		||||
        run: |
 | 
			
		||||
          echo "IPv4 local port range:"
 | 
			
		||||
          cat /proc/sys/net/ipv4/ip_local_port_range
 | 
			
		||||
          echo "Netstat:"
 | 
			
		||||
          netstat -an
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										31
									
								
								.github/workflows/upload-conan-deps.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										31
									
								
								.github/workflows/upload-conan-deps.yml
									
									
									
									
										vendored
									
									
								
							@@ -34,6 +34,7 @@ on:
 | 
			
		||||
env:
 | 
			
		||||
  CONAN_REMOTE_NAME: xrplf
 | 
			
		||||
  CONAN_REMOTE_URL: https://conan.ripplex.io
 | 
			
		||||
  NPROC_SUBTRACT: 2
 | 
			
		||||
 | 
			
		||||
concurrency:
 | 
			
		||||
  group: ${{ github.workflow }}-${{ github.ref }}
 | 
			
		||||
@@ -61,12 +62,23 @@ jobs:
 | 
			
		||||
        if: ${{ runner.os == 'macOS' }}
 | 
			
		||||
        uses: XRPLF/actions/.github/actions/cleanup-workspace@3f044c7478548e3c32ff68980eeb36ece02b364e
 | 
			
		||||
 | 
			
		||||
      - uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
 | 
			
		||||
      - name: Checkout repository
 | 
			
		||||
        uses: actions/checkout@08eba0b27e820071cde6df949e0beb9ba4906955 # v4.3.0
 | 
			
		||||
 | 
			
		||||
      - name: Prepare runner
 | 
			
		||||
        uses: XRPLF/actions/.github/actions/prepare-runner@638e0dc11ea230f91bd26622fb542116bb5254d5
 | 
			
		||||
        uses: XRPLF/actions/.github/actions/prepare-runner@99685816bb60a95a66852f212f382580e180df3a
 | 
			
		||||
        with:
 | 
			
		||||
          disable_ccache: false
 | 
			
		||||
 | 
			
		||||
      - name: Print build environment
 | 
			
		||||
        uses: ./.github/actions/print-env
 | 
			
		||||
 | 
			
		||||
      - name: Get number of processors
 | 
			
		||||
        uses: XRPLF/actions/.github/actions/get-nproc@046b1620f6bfd6cd0985dc82c3df02786801fe0a
 | 
			
		||||
        id: nproc
 | 
			
		||||
        with:
 | 
			
		||||
          subtract: ${{ env.NPROC_SUBTRACT }}
 | 
			
		||||
 | 
			
		||||
      - name: Setup Conan
 | 
			
		||||
        uses: ./.github/actions/setup-conan
 | 
			
		||||
        with:
 | 
			
		||||
@@ -77,18 +89,19 @@ jobs:
 | 
			
		||||
        uses: ./.github/actions/build-deps
 | 
			
		||||
        with:
 | 
			
		||||
          build_dir: .build
 | 
			
		||||
          build_nproc: ${{ steps.nproc.outputs.nproc }}
 | 
			
		||||
          build_type: ${{ matrix.build_type }}
 | 
			
		||||
          force_build: ${{ github.event_name == 'schedule' || github.event.inputs.force_source_build == 'true' }}
 | 
			
		||||
          # The verbosity is set to "quiet" for Windows to avoid an excessive amount of logs, while it
 | 
			
		||||
          # is set to "verbose" otherwise to provide more information during the build process.
 | 
			
		||||
          verbosity: ${{ runner.os == 'Windows' && 'quiet' || 'verbose' }}
 | 
			
		||||
          # Set the verbosity to "quiet" for Windows to avoid an excessive
 | 
			
		||||
          # amount of logs. For other OSes, the "verbose" logs are more useful.
 | 
			
		||||
          log_verbosity: ${{ runner.os == 'Windows' && 'quiet' || 'verbose' }}
 | 
			
		||||
 | 
			
		||||
      - name: Log into Conan remote
 | 
			
		||||
        if: ${{ github.repository_owner == 'XRPLF' && github.event_name != 'pull_request' }}
 | 
			
		||||
        run: conan remote login ${{ env.CONAN_REMOTE_NAME }} "${{ secrets.CONAN_REMOTE_USERNAME }}" --password "${{ secrets.CONAN_REMOTE_PASSWORD }}"
 | 
			
		||||
        if: ${{ github.repository_owner == 'XRPLF' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') }}
 | 
			
		||||
        run: conan remote login "${CONAN_REMOTE_NAME}" "${{ secrets.CONAN_REMOTE_USERNAME }}" --password "${{ secrets.CONAN_REMOTE_PASSWORD }}"
 | 
			
		||||
 | 
			
		||||
      - name: Upload Conan packages
 | 
			
		||||
        if: ${{ github.repository_owner == 'XRPLF' && github.event_name != 'pull_request' && github.event_name != 'schedule' }}
 | 
			
		||||
        if: ${{ github.repository_owner == 'XRPLF' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') }}
 | 
			
		||||
        env:
 | 
			
		||||
          FORCE_OPTION: ${{ github.event.inputs.force_upload == 'true' && '--force' || '' }}
 | 
			
		||||
        run: conan upload "*" --remote='${{ env.CONAN_REMOTE_NAME }}' --confirm ${{ env.FORCE_OPTION }}
 | 
			
		||||
        run: conan upload "*" --remote="${CONAN_REMOTE_NAME}" --confirm ${FORCE_OPTION}
 | 
			
		||||
 
 | 
			
		||||
@@ -975,6 +975,47 @@
 | 
			
		||||
#                           number of ledger records online. Must be greater
 | 
			
		||||
#                           than or equal to ledger_history.
 | 
			
		||||
#
 | 
			
		||||
#   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.
 | 
			
		||||
#                             Minimizes memory footprint and provides consistent
 | 
			
		||||
#                             low-latency access patterns across diverse hardware.
 | 
			
		||||
#
 | 
			
		||||
#                           - 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. Offers better sequential throughput and
 | 
			
		||||
#                             reduced I/O operations at the cost of higher memory
 | 
			
		||||
#                             usage per operation.
 | 
			
		||||
#
 | 
			
		||||
#                           - 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. Best suited for
 | 
			
		||||
#                             enterprise environments with abundant RAM.
 | 
			
		||||
#
 | 
			
		||||
#                           Performance testing is recommended before deploying
 | 
			
		||||
#                           any non-default block size in production environments.
 | 
			
		||||
#
 | 
			
		||||
#                           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:
 | 
			
		||||
#
 | 
			
		||||
@@ -1471,6 +1512,7 @@ secure_gateway = 127.0.0.1
 | 
			
		||||
[node_db]
 | 
			
		||||
type=NuDB
 | 
			
		||||
path=/var/lib/rippled/db/nudb
 | 
			
		||||
nudb_block_size=4096
 | 
			
		||||
online_delete=512
 | 
			
		||||
advisory_delete=0
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -45,7 +45,7 @@ if (static OR APPLE OR MSVC)
 | 
			
		||||
  set (OPENSSL_USE_STATIC_LIBS ON)
 | 
			
		||||
endif ()
 | 
			
		||||
set (OPENSSL_MSVC_STATIC_RT ON)
 | 
			
		||||
find_dependency (OpenSSL 1.1.1 REQUIRED)
 | 
			
		||||
find_dependency (OpenSSL REQUIRED)
 | 
			
		||||
find_dependency (ZLIB)
 | 
			
		||||
find_dependency (date)
 | 
			
		||||
if (TARGET ZLIB::ZLIB)
 | 
			
		||||
 
 | 
			
		||||
@@ -53,14 +53,15 @@ add_library(xrpl.imports.main INTERFACE)
 | 
			
		||||
 | 
			
		||||
target_link_libraries(xrpl.imports.main
 | 
			
		||||
  INTERFACE
 | 
			
		||||
    LibArchive::LibArchive
 | 
			
		||||
    OpenSSL::Crypto
 | 
			
		||||
    Ripple::boost
 | 
			
		||||
    Ripple::opts
 | 
			
		||||
    Ripple::syslibs
 | 
			
		||||
    absl::random_random
 | 
			
		||||
    date::date
 | 
			
		||||
    ed25519::ed25519
 | 
			
		||||
    LibArchive::LibArchive
 | 
			
		||||
    OpenSSL::Crypto
 | 
			
		||||
    Ripple::boost
 | 
			
		||||
    Ripple::libs
 | 
			
		||||
    Ripple::opts
 | 
			
		||||
    Ripple::syslibs
 | 
			
		||||
    secp256k1::secp256k1
 | 
			
		||||
    xrpl.libpb
 | 
			
		||||
    xxHash::xxhash
 | 
			
		||||
@@ -111,6 +112,21 @@ target_link_libraries(xrpl.libxrpl.net PUBLIC
 | 
			
		||||
add_module(xrpl server)
 | 
			
		||||
target_link_libraries(xrpl.libxrpl.server PUBLIC xrpl.libxrpl.protocol)
 | 
			
		||||
 | 
			
		||||
add_module(xrpl nodestore)
 | 
			
		||||
target_link_libraries(xrpl.libxrpl.nodestore PUBLIC
 | 
			
		||||
        xrpl.libxrpl.basics
 | 
			
		||||
        xrpl.libxrpl.json
 | 
			
		||||
        xrpl.libxrpl.protocol
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
add_module(xrpl shamap)
 | 
			
		||||
target_link_libraries(xrpl.libxrpl.shamap PUBLIC
 | 
			
		||||
        xrpl.libxrpl.basics
 | 
			
		||||
        xrpl.libxrpl.crypto
 | 
			
		||||
        xrpl.libxrpl.protocol
 | 
			
		||||
        xrpl.libxrpl.nodestore
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
add_module(xrpl ledger)
 | 
			
		||||
target_link_libraries(xrpl.libxrpl.ledger PUBLIC
 | 
			
		||||
  xrpl.libxrpl.basics
 | 
			
		||||
@@ -136,6 +152,8 @@ target_link_modules(xrpl PUBLIC
 | 
			
		||||
  protocol
 | 
			
		||||
  resource
 | 
			
		||||
  server
 | 
			
		||||
  nodestore
 | 
			
		||||
  shamap
 | 
			
		||||
  net
 | 
			
		||||
  ledger
 | 
			
		||||
)
 | 
			
		||||
 
 | 
			
		||||
@@ -8,20 +8,23 @@ install (
 | 
			
		||||
  TARGETS
 | 
			
		||||
    common
 | 
			
		||||
    opts
 | 
			
		||||
    ripple_syslibs
 | 
			
		||||
    ripple_boost
 | 
			
		||||
    ripple_libs
 | 
			
		||||
    ripple_syslibs
 | 
			
		||||
    xrpl.imports.main
 | 
			
		||||
    xrpl.libpb
 | 
			
		||||
    xrpl.libxrpl
 | 
			
		||||
    xrpl.libxrpl.basics
 | 
			
		||||
    xrpl.libxrpl.beast
 | 
			
		||||
    xrpl.libxrpl.crypto
 | 
			
		||||
    xrpl.libxrpl.json
 | 
			
		||||
    xrpl.libxrpl.ledger
 | 
			
		||||
    xrpl.libxrpl.net
 | 
			
		||||
    xrpl.libxrpl.nodestore
 | 
			
		||||
    xrpl.libxrpl.protocol
 | 
			
		||||
    xrpl.libxrpl.resource
 | 
			
		||||
    xrpl.libxrpl.ledger
 | 
			
		||||
    xrpl.libxrpl.server
 | 
			
		||||
    xrpl.libxrpl.net
 | 
			
		||||
    xrpl.libxrpl
 | 
			
		||||
    xrpl.libxrpl.shamap
 | 
			
		||||
    antithesis-sdk-cpp
 | 
			
		||||
  EXPORT RippleExports
 | 
			
		||||
  LIBRARY DESTINATION lib
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@ function(xrpl_add_test name)
 | 
			
		||||
  "${CMAKE_CURRENT_SOURCE_DIR}/${name}/*.cpp"
 | 
			
		||||
  "${CMAKE_CURRENT_SOURCE_DIR}/${name}.cpp"
 | 
			
		||||
  )
 | 
			
		||||
  add_executable(${target} EXCLUDE_FROM_ALL ${ARGN} ${sources})
 | 
			
		||||
  add_executable(${target} ${ARGN} ${sources})
 | 
			
		||||
 | 
			
		||||
  isolate_headers(
 | 
			
		||||
    ${target}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,5 @@
 | 
			
		||||
# Global configuration for Conan. This is used to set the number of parallel
 | 
			
		||||
# downloads, uploads, and build jobs.
 | 
			
		||||
# downloads and uploads.
 | 
			
		||||
core:non_interactive=True
 | 
			
		||||
core.download:parallel={{ os.cpu_count() }}
 | 
			
		||||
core.upload:parallel={{ os.cpu_count() }}
 | 
			
		||||
tools.build:jobs={{ (os.cpu_count() * 4/5) | int }}
 | 
			
		||||
 
 | 
			
		||||
@@ -21,11 +21,11 @@ compiler.libcxx={{detect_api.detect_libcxx(compiler, version, compiler_exe)}}
 | 
			
		||||
 | 
			
		||||
[conf]
 | 
			
		||||
{% if compiler == "clang" and compiler_version >= 19 %}
 | 
			
		||||
tools.build:cxxflags=['-Wno-missing-template-arg-list-after-template-kw']
 | 
			
		||||
grpc/1.50.1:tools.build:cxxflags+=['-Wno-missing-template-arg-list-after-template-kw']
 | 
			
		||||
{% endif %}
 | 
			
		||||
{% if compiler == "apple-clang" and compiler_version >= 17 %}
 | 
			
		||||
tools.build:cxxflags=['-Wno-missing-template-arg-list-after-template-kw']
 | 
			
		||||
grpc/1.50.1:tools.build:cxxflags+=['-Wno-missing-template-arg-list-after-template-kw']
 | 
			
		||||
{% endif %}
 | 
			
		||||
{% if compiler == "gcc" and compiler_version < 13 %}
 | 
			
		||||
tools.build:cxxflags=['-Wno-restrict']
 | 
			
		||||
tools.build:cxxflags+=['-Wno-restrict']
 | 
			
		||||
{% endif %}
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,7 @@
 | 
			
		||||
#ifndef RIPPLE_NODESTORE_BACKEND_H_INCLUDED
 | 
			
		||||
#define RIPPLE_NODESTORE_BACKEND_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#include <xrpld/nodestore/Types.h>
 | 
			
		||||
#include <xrpl/nodestore/Types.h>
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
 | 
			
		||||
@@ -53,6 +53,14 @@ public:
 | 
			
		||||
    virtual std::string
 | 
			
		||||
    getName() = 0;
 | 
			
		||||
 | 
			
		||||
    /** Get the block size for backends that support it
 | 
			
		||||
     */
 | 
			
		||||
    virtual std::optional<std::size_t>
 | 
			
		||||
    getBlockSize() const
 | 
			
		||||
    {
 | 
			
		||||
        return std::nullopt;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /** Open the backend.
 | 
			
		||||
        @param createIfMissing Create the database files if necessary.
 | 
			
		||||
        This allows the caller to catch exceptions.
 | 
			
		||||
@@ -20,13 +20,12 @@
 | 
			
		||||
#ifndef RIPPLE_NODESTORE_DATABASE_H_INCLUDED
 | 
			
		||||
#define RIPPLE_NODESTORE_DATABASE_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#include <xrpld/nodestore/Backend.h>
 | 
			
		||||
#include <xrpld/nodestore/NodeObject.h>
 | 
			
		||||
#include <xrpld/nodestore/Scheduler.h>
 | 
			
		||||
 | 
			
		||||
#include <xrpl/basics/BasicConfig.h>
 | 
			
		||||
#include <xrpl/basics/Log.h>
 | 
			
		||||
#include <xrpl/basics/TaggedCache.ipp>
 | 
			
		||||
#include <xrpl/nodestore/Backend.h>
 | 
			
		||||
#include <xrpl/nodestore/NodeObject.h>
 | 
			
		||||
#include <xrpl/nodestore/Scheduler.h>
 | 
			
		||||
#include <xrpl/protocol/SystemParameters.h>
 | 
			
		||||
 | 
			
		||||
#include <condition_variable>
 | 
			
		||||
@@ -20,7 +20,7 @@
 | 
			
		||||
#ifndef RIPPLE_NODESTORE_DATABASEROTATING_H_INCLUDED
 | 
			
		||||
#define RIPPLE_NODESTORE_DATABASEROTATING_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#include <xrpld/nodestore/Database.h>
 | 
			
		||||
#include <xrpl/nodestore/Database.h>
 | 
			
		||||
 | 
			
		||||
namespace ripple {
 | 
			
		||||
namespace NodeStore {
 | 
			
		||||
@@ -20,7 +20,7 @@
 | 
			
		||||
#ifndef RIPPLE_NODESTORE_DUMMYSCHEDULER_H_INCLUDED
 | 
			
		||||
#define RIPPLE_NODESTORE_DUMMYSCHEDULER_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#include <xrpld/nodestore/Scheduler.h>
 | 
			
		||||
#include <xrpl/nodestore/Scheduler.h>
 | 
			
		||||
 | 
			
		||||
namespace ripple {
 | 
			
		||||
namespace NodeStore {
 | 
			
		||||
@@ -20,11 +20,10 @@
 | 
			
		||||
#ifndef RIPPLE_NODESTORE_FACTORY_H_INCLUDED
 | 
			
		||||
#define RIPPLE_NODESTORE_FACTORY_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#include <xrpld/nodestore/Backend.h>
 | 
			
		||||
#include <xrpld/nodestore/Scheduler.h>
 | 
			
		||||
 | 
			
		||||
#include <xrpl/basics/BasicConfig.h>
 | 
			
		||||
#include <xrpl/beast/utility/Journal.h>
 | 
			
		||||
#include <xrpl/nodestore/Backend.h>
 | 
			
		||||
#include <xrpl/nodestore/Scheduler.h>
 | 
			
		||||
 | 
			
		||||
#include <nudb/store.hpp>
 | 
			
		||||
 | 
			
		||||
@@ -20,8 +20,8 @@
 | 
			
		||||
#ifndef RIPPLE_NODESTORE_MANAGER_H_INCLUDED
 | 
			
		||||
#define RIPPLE_NODESTORE_MANAGER_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#include <xrpld/nodestore/DatabaseRotating.h>
 | 
			
		||||
#include <xrpld/nodestore/Factory.h>
 | 
			
		||||
#include <xrpl/nodestore/DatabaseRotating.h>
 | 
			
		||||
#include <xrpl/nodestore/Factory.h>
 | 
			
		||||
 | 
			
		||||
namespace ripple {
 | 
			
		||||
 | 
			
		||||
@@ -20,7 +20,7 @@
 | 
			
		||||
#ifndef RIPPLE_NODESTORE_SCHEDULER_H_INCLUDED
 | 
			
		||||
#define RIPPLE_NODESTORE_SCHEDULER_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#include <xrpld/nodestore/Task.h>
 | 
			
		||||
#include <xrpl/nodestore/Task.h>
 | 
			
		||||
 | 
			
		||||
#include <chrono>
 | 
			
		||||
 | 
			
		||||
@@ -20,7 +20,7 @@
 | 
			
		||||
#ifndef RIPPLE_NODESTORE_TYPES_H_INCLUDED
 | 
			
		||||
#define RIPPLE_NODESTORE_TYPES_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#include <xrpld/nodestore/NodeObject.h>
 | 
			
		||||
#include <xrpl/nodestore/NodeObject.h>
 | 
			
		||||
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
@@ -20,9 +20,9 @@
 | 
			
		||||
#ifndef RIPPLE_NODESTORE_BATCHWRITER_H_INCLUDED
 | 
			
		||||
#define RIPPLE_NODESTORE_BATCHWRITER_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#include <xrpld/nodestore/Scheduler.h>
 | 
			
		||||
#include <xrpld/nodestore/Task.h>
 | 
			
		||||
#include <xrpld/nodestore/Types.h>
 | 
			
		||||
#include <xrpl/nodestore/Scheduler.h>
 | 
			
		||||
#include <xrpl/nodestore/Task.h>
 | 
			
		||||
#include <xrpl/nodestore/Types.h>
 | 
			
		||||
 | 
			
		||||
#include <condition_variable>
 | 
			
		||||
#include <mutex>
 | 
			
		||||
@@ -20,10 +20,9 @@
 | 
			
		||||
#ifndef RIPPLE_NODESTORE_DATABASENODEIMP_H_INCLUDED
 | 
			
		||||
#define RIPPLE_NODESTORE_DATABASENODEIMP_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#include <xrpld/nodestore/Database.h>
 | 
			
		||||
 | 
			
		||||
#include <xrpl/basics/TaggedCache.h>
 | 
			
		||||
#include <xrpl/basics/chrono.h>
 | 
			
		||||
#include <xrpl/nodestore/Database.h>
 | 
			
		||||
 | 
			
		||||
namespace ripple {
 | 
			
		||||
namespace NodeStore {
 | 
			
		||||
@@ -20,7 +20,7 @@
 | 
			
		||||
#ifndef RIPPLE_NODESTORE_DATABASEROTATINGIMP_H_INCLUDED
 | 
			
		||||
#define RIPPLE_NODESTORE_DATABASEROTATINGIMP_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#include <xrpld/nodestore/DatabaseRotating.h>
 | 
			
		||||
#include <xrpl/nodestore/DatabaseRotating.h>
 | 
			
		||||
 | 
			
		||||
#include <mutex>
 | 
			
		||||
 | 
			
		||||
@@ -20,7 +20,7 @@
 | 
			
		||||
#ifndef RIPPLE_NODESTORE_DECODEDBLOB_H_INCLUDED
 | 
			
		||||
#define RIPPLE_NODESTORE_DECODEDBLOB_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#include <xrpld/nodestore/NodeObject.h>
 | 
			
		||||
#include <xrpl/nodestore/NodeObject.h>
 | 
			
		||||
 | 
			
		||||
namespace ripple {
 | 
			
		||||
namespace NodeStore {
 | 
			
		||||
@@ -20,9 +20,8 @@
 | 
			
		||||
#ifndef RIPPLE_NODESTORE_ENCODEDBLOB_H_INCLUDED
 | 
			
		||||
#define RIPPLE_NODESTORE_ENCODEDBLOB_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#include <xrpld/nodestore/NodeObject.h>
 | 
			
		||||
 | 
			
		||||
#include <xrpl/beast/utility/instrumentation.h>
 | 
			
		||||
#include <xrpl/nodestore/NodeObject.h>
 | 
			
		||||
 | 
			
		||||
#include <boost/align/align_up.hpp>
 | 
			
		||||
 | 
			
		||||
@@ -20,7 +20,7 @@
 | 
			
		||||
#ifndef RIPPLE_NODESTORE_MANAGERIMP_H_INCLUDED
 | 
			
		||||
#define RIPPLE_NODESTORE_MANAGERIMP_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#include <xrpld/nodestore/Manager.h>
 | 
			
		||||
#include <xrpl/nodestore/Manager.h>
 | 
			
		||||
 | 
			
		||||
namespace ripple {
 | 
			
		||||
 | 
			
		||||
@@ -39,7 +39,7 @@ public:
 | 
			
		||||
    static void
 | 
			
		||||
    missing_backend();
 | 
			
		||||
 | 
			
		||||
    ManagerImp() = default;
 | 
			
		||||
    ManagerImp();
 | 
			
		||||
 | 
			
		||||
    ~ManagerImp() = default;
 | 
			
		||||
 | 
			
		||||
@@ -23,11 +23,10 @@
 | 
			
		||||
// Disable lz4 deprecation warning due to incompatibility with clang attributes
 | 
			
		||||
#define LZ4_DISABLE_DEPRECATE_WARNINGS
 | 
			
		||||
 | 
			
		||||
#include <xrpld/nodestore/NodeObject.h>
 | 
			
		||||
#include <xrpld/nodestore/detail/varint.h>
 | 
			
		||||
 | 
			
		||||
#include <xrpl/basics/contract.h>
 | 
			
		||||
#include <xrpl/basics/safe_cast.h>
 | 
			
		||||
#include <xrpl/nodestore/NodeObject.h>
 | 
			
		||||
#include <xrpl/nodestore/detail/varint.h>
 | 
			
		||||
#include <xrpl/protocol/HashPrefix.h>
 | 
			
		||||
 | 
			
		||||
#include <nudb/detail/field.hpp>
 | 
			
		||||
@@ -55,7 +55,10 @@ std::size_t constexpr oversizeMetaDataCap = 5200;
 | 
			
		||||
/** The maximum number of entries per directory page */
 | 
			
		||||
std::size_t constexpr dirNodeMaxEntries = 32;
 | 
			
		||||
 | 
			
		||||
/** The maximum number of pages allowed in a directory */
 | 
			
		||||
/** The maximum number of pages allowed in a directory
 | 
			
		||||
 | 
			
		||||
    Made obsolete by fixDirectoryLimit amendment.
 | 
			
		||||
*/
 | 
			
		||||
std::uint64_t constexpr dirNodeMaxPages = 262144;
 | 
			
		||||
 | 
			
		||||
/** The maximum number of items in an NFT page */
 | 
			
		||||
 
 | 
			
		||||
@@ -21,6 +21,7 @@
 | 
			
		||||
#define RIPPLE_PROTOCOL_PUBLICKEY_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#include <xrpl/basics/Slice.h>
 | 
			
		||||
#include <xrpl/beast/net/IPEndpoint.h>
 | 
			
		||||
#include <xrpl/protocol/KeyType.h>
 | 
			
		||||
#include <xrpl/protocol/STExchange.h>
 | 
			
		||||
#include <xrpl/protocol/UintTypes.h>
 | 
			
		||||
@@ -264,6 +265,24 @@ calcNodeID(PublicKey const&);
 | 
			
		||||
AccountID
 | 
			
		||||
calcAccountID(PublicKey const& pk);
 | 
			
		||||
 | 
			
		||||
inline std::string
 | 
			
		||||
getFingerprint(
 | 
			
		||||
    beast::IP::Endpoint const& address,
 | 
			
		||||
    std::optional<PublicKey> const& publicKey = std::nullopt,
 | 
			
		||||
    std::optional<std::string> const& id = std::nullopt)
 | 
			
		||||
{
 | 
			
		||||
    std::stringstream ss;
 | 
			
		||||
    ss << "IP Address: " << address;
 | 
			
		||||
    if (publicKey.has_value())
 | 
			
		||||
    {
 | 
			
		||||
        ss << ", Public Key: " << toBase58(TokenType::NodePublic, *publicKey);
 | 
			
		||||
    }
 | 
			
		||||
    if (id.has_value())
 | 
			
		||||
    {
 | 
			
		||||
        ss << ", Id: " << id.value();
 | 
			
		||||
    }
 | 
			
		||||
    return ss.str();
 | 
			
		||||
}
 | 
			
		||||
}  // namespace ripple
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 
 | 
			
		||||
@@ -709,37 +709,6 @@ canAdd(STAmount const& amt1, STAmount const& amt2);
 | 
			
		||||
bool
 | 
			
		||||
canSubtract(STAmount const& amt1, STAmount const& amt2);
 | 
			
		||||
 | 
			
		||||
// Since `canonicalize` does not have access to a ledger, this is needed to put
 | 
			
		||||
// the low-level routine stAmountCanonicalize on an amendment switch. Only
 | 
			
		||||
// transactions need to use this switchover. Outside of a transaction it's safe
 | 
			
		||||
// to unconditionally use the new behavior.
 | 
			
		||||
 | 
			
		||||
bool
 | 
			
		||||
getSTAmountCanonicalizeSwitchover();
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
setSTAmountCanonicalizeSwitchover(bool v);
 | 
			
		||||
 | 
			
		||||
/** RAII class to set and restore the STAmount canonicalize switchover.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
class STAmountSO
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    explicit STAmountSO(bool v) : saved_(getSTAmountCanonicalizeSwitchover())
 | 
			
		||||
    {
 | 
			
		||||
        setSTAmountCanonicalizeSwitchover(v);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~STAmountSO()
 | 
			
		||||
    {
 | 
			
		||||
        setSTAmountCanonicalizeSwitchover(saved_);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    bool saved_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}  // namespace ripple
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 
 | 
			
		||||
@@ -244,6 +244,9 @@ public:
 | 
			
		||||
    getFieldPathSet(SField const& field) const;
 | 
			
		||||
    STVector256 const&
 | 
			
		||||
    getFieldV256(SField const& field) const;
 | 
			
		||||
    // If not found, returns an object constructed with the given field
 | 
			
		||||
    STObject
 | 
			
		||||
    getFieldObject(SField const& field) const;
 | 
			
		||||
    STArray const&
 | 
			
		||||
    getFieldArray(SField const& field) const;
 | 
			
		||||
    STCurrency const&
 | 
			
		||||
@@ -390,6 +393,8 @@ public:
 | 
			
		||||
    setFieldV256(SField const& field, STVector256 const& v);
 | 
			
		||||
    void
 | 
			
		||||
    setFieldArray(SField const& field, STArray const& v);
 | 
			
		||||
    void
 | 
			
		||||
    setFieldObject(SField const& field, STObject const& v);
 | 
			
		||||
 | 
			
		||||
    template <class Tag>
 | 
			
		||||
    void
 | 
			
		||||
 
 | 
			
		||||
@@ -87,8 +87,14 @@ public:
 | 
			
		||||
    getFullText() const override;
 | 
			
		||||
 | 
			
		||||
    // Outer transaction functions / signature functions.
 | 
			
		||||
    static Blob
 | 
			
		||||
    getSignature(STObject const& sigObject);
 | 
			
		||||
 | 
			
		||||
    Blob
 | 
			
		||||
    getSignature() const;
 | 
			
		||||
    getSignature() const
 | 
			
		||||
    {
 | 
			
		||||
        return getSignature(*this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    uint256
 | 
			
		||||
    getSigningHash() const;
 | 
			
		||||
@@ -119,13 +125,20 @@ public:
 | 
			
		||||
    getJson(JsonOptions options, bool binary) const;
 | 
			
		||||
 | 
			
		||||
    void
 | 
			
		||||
    sign(PublicKey const& publicKey, SecretKey const& secretKey);
 | 
			
		||||
    sign(
 | 
			
		||||
        PublicKey const& publicKey,
 | 
			
		||||
        SecretKey const& secretKey,
 | 
			
		||||
        std::optional<std::reference_wrapper<SField const>> signatureTarget =
 | 
			
		||||
            {});
 | 
			
		||||
 | 
			
		||||
    /** Check the signature.
 | 
			
		||||
        @return `true` if valid signature. If invalid, the error message string.
 | 
			
		||||
    */
 | 
			
		||||
    enum class RequireFullyCanonicalSig : bool { no, yes };
 | 
			
		||||
 | 
			
		||||
    /** Check the signature.
 | 
			
		||||
        @param requireCanonicalSig If `true`, check that the signature is fully
 | 
			
		||||
            canonical. If `false`, only check that the signature is valid.
 | 
			
		||||
        @param rules The current ledger rules.
 | 
			
		||||
        @return `true` if valid signature. If invalid, the error message string.
 | 
			
		||||
    */
 | 
			
		||||
    Expected<void, std::string>
 | 
			
		||||
    checkSign(RequireFullyCanonicalSig requireCanonicalSig, Rules const& rules)
 | 
			
		||||
        const;
 | 
			
		||||
@@ -150,17 +163,34 @@ public:
 | 
			
		||||
        char status,
 | 
			
		||||
        std::string const& escapedMetaData) const;
 | 
			
		||||
 | 
			
		||||
    std::vector<uint256>
 | 
			
		||||
    std::vector<uint256> const&
 | 
			
		||||
    getBatchTransactionIDs() const;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    /** Check the signature.
 | 
			
		||||
        @param requireCanonicalSig If `true`, check that the signature is fully
 | 
			
		||||
            canonical. If `false`, only check that the signature is valid.
 | 
			
		||||
        @param rules The current ledger rules.
 | 
			
		||||
        @param sigObject Reference to object that contains the signature fields.
 | 
			
		||||
            Will be *this more often than not.
 | 
			
		||||
        @return `true` if valid signature. If invalid, the error message string.
 | 
			
		||||
    */
 | 
			
		||||
    Expected<void, std::string>
 | 
			
		||||
    checkSingleSign(RequireFullyCanonicalSig requireCanonicalSig) const;
 | 
			
		||||
    checkSign(
 | 
			
		||||
        RequireFullyCanonicalSig requireCanonicalSig,
 | 
			
		||||
        Rules const& rules,
 | 
			
		||||
        STObject const& sigObject) const;
 | 
			
		||||
 | 
			
		||||
    Expected<void, std::string>
 | 
			
		||||
    checkSingleSign(
 | 
			
		||||
        RequireFullyCanonicalSig requireCanonicalSig,
 | 
			
		||||
        STObject const& sigObject) const;
 | 
			
		||||
 | 
			
		||||
    Expected<void, std::string>
 | 
			
		||||
    checkMultiSign(
 | 
			
		||||
        RequireFullyCanonicalSig requireCanonicalSig,
 | 
			
		||||
        Rules const& rules) const;
 | 
			
		||||
        Rules const& rules,
 | 
			
		||||
        STObject const& sigObject) const;
 | 
			
		||||
 | 
			
		||||
    Expected<void, std::string>
 | 
			
		||||
    checkBatchSingleSign(
 | 
			
		||||
@@ -179,7 +209,7 @@ private:
 | 
			
		||||
    move(std::size_t n, void* buf) override;
 | 
			
		||||
 | 
			
		||||
    friend class detail::STVar;
 | 
			
		||||
    mutable std::vector<uint256> batch_txn_ids_;
 | 
			
		||||
    mutable std::vector<uint256> batchTxnIds_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
bool
 | 
			
		||||
 
 | 
			
		||||
@@ -73,14 +73,8 @@ static constexpr std::uint32_t XRP_LEDGER_EARLIEST_SEQ{32570u};
 | 
			
		||||
 * used in asserts and tests. */
 | 
			
		||||
static constexpr std::uint32_t XRP_LEDGER_EARLIEST_FEES{562177u};
 | 
			
		||||
 | 
			
		||||
/** The minimum amount of support an amendment should have.
 | 
			
		||||
 | 
			
		||||
    @note This value is used by legacy code and will become obsolete
 | 
			
		||||
          once the fixAmendmentMajorityCalc amendment activates.
 | 
			
		||||
*/
 | 
			
		||||
constexpr std::ratio<204, 256> preFixAmendmentMajorityCalcThreshold;
 | 
			
		||||
 | 
			
		||||
constexpr std::ratio<80, 100> postFixAmendmentMajorityCalcThreshold;
 | 
			
		||||
/** The minimum amount of support an amendment should have. */
 | 
			
		||||
constexpr std::ratio<80, 100> amendmentMajorityCalcThreshold;
 | 
			
		||||
 | 
			
		||||
/** The minimum amount of time an amendment must hold a majority */
 | 
			
		||||
constexpr std::chrono::seconds const defaultAmendmentMajorityTime = weeks{2};
 | 
			
		||||
 
 | 
			
		||||
@@ -225,8 +225,9 @@ enum TERcodes : TERUnderlyingType {
 | 
			
		||||
    terQUEUED,       // Transaction is being held in TxQ until fee drops
 | 
			
		||||
    terPRE_TICKET,   // Ticket is not yet in ledger but might be on its way
 | 
			
		||||
    terNO_AMM,       // AMM doesn't exist for the asset pair
 | 
			
		||||
    terADDRESS_COLLISION,  // Failed to allocate AccountID when trying to
 | 
			
		||||
                           // create a pseudo-account
 | 
			
		||||
    terADDRESS_COLLISION,       // Failed to allocate AccountID when trying to
 | 
			
		||||
                                // create a pseudo-account
 | 
			
		||||
    terNO_DELEGATE_PERMISSION,  // Delegate does not have permission
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
@@ -361,6 +362,9 @@ enum TECcodes : TERUnderlyingType {
 | 
			
		||||
    tecLIMIT_EXCEEDED = 195,
 | 
			
		||||
    tecPSEUDO_ACCOUNT = 196,
 | 
			
		||||
    tecPRECISION_LOSS = 197,
 | 
			
		||||
    // DEPRECATED: This error code tecNO_DELEGATE_PERMISSION is reserved for
 | 
			
		||||
    // backward compatibility with historical data on non-prod networks, can be
 | 
			
		||||
    // reclaimed after those networks reset.
 | 
			
		||||
    tecNO_DELEGATE_PERMISSION = 198,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -33,51 +33,35 @@ namespace ripple {
 | 
			
		||||
 | 
			
		||||
class TxMeta
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
    struct CtorHelper
 | 
			
		||||
    {
 | 
			
		||||
        explicit CtorHelper() = default;
 | 
			
		||||
    };
 | 
			
		||||
    template <class T>
 | 
			
		||||
    TxMeta(
 | 
			
		||||
        uint256 const& txID,
 | 
			
		||||
        std::uint32_t ledger,
 | 
			
		||||
        T const& data,
 | 
			
		||||
        CtorHelper);
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    TxMeta(
 | 
			
		||||
        uint256 const& transactionID,
 | 
			
		||||
        std::uint32_t ledger,
 | 
			
		||||
        std::optional<uint256> parentBatchId = std::nullopt);
 | 
			
		||||
    TxMeta(uint256 const& transactionID, std::uint32_t ledger);
 | 
			
		||||
    TxMeta(uint256 const& txID, std::uint32_t ledger, Blob const&);
 | 
			
		||||
    TxMeta(uint256 const& txID, std::uint32_t ledger, std::string const&);
 | 
			
		||||
    TxMeta(uint256 const& txID, std::uint32_t ledger, STObject const&);
 | 
			
		||||
 | 
			
		||||
    uint256 const&
 | 
			
		||||
    getTxID() const
 | 
			
		||||
    {
 | 
			
		||||
        return mTransactionID;
 | 
			
		||||
        return transactionID_;
 | 
			
		||||
    }
 | 
			
		||||
    std::uint32_t
 | 
			
		||||
    getLgrSeq() const
 | 
			
		||||
    {
 | 
			
		||||
        return mLedger;
 | 
			
		||||
        return ledgerSeq_;
 | 
			
		||||
    }
 | 
			
		||||
    int
 | 
			
		||||
    getResult() const
 | 
			
		||||
    {
 | 
			
		||||
        return mResult;
 | 
			
		||||
        return result_;
 | 
			
		||||
    }
 | 
			
		||||
    TER
 | 
			
		||||
    getResultTER() const
 | 
			
		||||
    {
 | 
			
		||||
        return TER::fromInt(mResult);
 | 
			
		||||
        return TER::fromInt(result_);
 | 
			
		||||
    }
 | 
			
		||||
    std::uint32_t
 | 
			
		||||
    getIndex() const
 | 
			
		||||
    {
 | 
			
		||||
        return mIndex;
 | 
			
		||||
        return index_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void
 | 
			
		||||
@@ -104,66 +88,52 @@ public:
 | 
			
		||||
    STArray&
 | 
			
		||||
    getNodes()
 | 
			
		||||
    {
 | 
			
		||||
        return (mNodes);
 | 
			
		||||
        return nodes_;
 | 
			
		||||
    }
 | 
			
		||||
    STArray const&
 | 
			
		||||
    getNodes() const
 | 
			
		||||
    {
 | 
			
		||||
        return (mNodes);
 | 
			
		||||
        return nodes_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void
 | 
			
		||||
    setDeliveredAmount(STAmount const& delivered)
 | 
			
		||||
    setAdditionalFields(STObject const& obj)
 | 
			
		||||
    {
 | 
			
		||||
        mDelivered = delivered;
 | 
			
		||||
        if (obj.isFieldPresent(sfDeliveredAmount))
 | 
			
		||||
            deliveredAmount_ = obj.getFieldAmount(sfDeliveredAmount);
 | 
			
		||||
 | 
			
		||||
        if (obj.isFieldPresent(sfParentBatchID))
 | 
			
		||||
            parentBatchID_ = obj.getFieldH256(sfParentBatchID);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    STAmount
 | 
			
		||||
    std::optional<STAmount> const&
 | 
			
		||||
    getDeliveredAmount() const
 | 
			
		||||
    {
 | 
			
		||||
        XRPL_ASSERT(
 | 
			
		||||
            hasDeliveredAmount(),
 | 
			
		||||
            "ripple::TxMeta::getDeliveredAmount : non-null delivered amount");
 | 
			
		||||
        return *mDelivered;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool
 | 
			
		||||
    hasDeliveredAmount() const
 | 
			
		||||
    {
 | 
			
		||||
        return static_cast<bool>(mDelivered);
 | 
			
		||||
        return deliveredAmount_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void
 | 
			
		||||
    setParentBatchId(uint256 const& parentBatchId)
 | 
			
		||||
    setDeliveredAmount(std::optional<STAmount> const& amount)
 | 
			
		||||
    {
 | 
			
		||||
        mParentBatchId = parentBatchId;
 | 
			
		||||
        deliveredAmount_ = amount;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    uint256
 | 
			
		||||
    getParentBatchId() const
 | 
			
		||||
    void
 | 
			
		||||
    setParentBatchID(std::optional<uint256> const& id)
 | 
			
		||||
    {
 | 
			
		||||
        XRPL_ASSERT(
 | 
			
		||||
            hasParentBatchId(),
 | 
			
		||||
            "ripple::TxMeta::getParentBatchId : non-null batch id");
 | 
			
		||||
        return *mParentBatchId;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool
 | 
			
		||||
    hasParentBatchId() const
 | 
			
		||||
    {
 | 
			
		||||
        return static_cast<bool>(mParentBatchId);
 | 
			
		||||
        parentBatchID_ = id;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    uint256 mTransactionID;
 | 
			
		||||
    std::uint32_t mLedger;
 | 
			
		||||
    std::uint32_t mIndex;
 | 
			
		||||
    int mResult;
 | 
			
		||||
    uint256 transactionID_;
 | 
			
		||||
    std::uint32_t ledgerSeq_;
 | 
			
		||||
    std::uint32_t index_;
 | 
			
		||||
    int result_;
 | 
			
		||||
 | 
			
		||||
    std::optional<STAmount> mDelivered;
 | 
			
		||||
    std::optional<uint256> mParentBatchId;
 | 
			
		||||
    std::optional<STAmount> deliveredAmount_;
 | 
			
		||||
    std::optional<uint256> parentBatchID_;
 | 
			
		||||
 | 
			
		||||
    STArray mNodes;
 | 
			
		||||
    STArray nodes_;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}  // namespace ripple
 | 
			
		||||
 
 | 
			
		||||
@@ -29,15 +29,14 @@
 | 
			
		||||
 | 
			
		||||
// Add new amendments to the top of this list.
 | 
			
		||||
// Keep it sorted in reverse chronological order.
 | 
			
		||||
// If you add an amendment here, then do not forget to increment `numFeatures`
 | 
			
		||||
// in include/xrpl/protocol/Feature.h.
 | 
			
		||||
 | 
			
		||||
XRPL_FEATURE(PermissionDelegationV1_1,   Supported::no,  VoteBehavior::DefaultNo)
 | 
			
		||||
XRPL_FIX    (DirectoryLimit,             Supported::yes, VoteBehavior::DefaultNo)
 | 
			
		||||
XRPL_FIX    (IncludeKeyletFields,        Supported::yes, VoteBehavior::DefaultNo)
 | 
			
		||||
XRPL_FEATURE(DynamicMPT,                 Supported::no,  VoteBehavior::DefaultNo)
 | 
			
		||||
XRPL_FIX    (TokenEscrowV1,              Supported::yes, VoteBehavior::DefaultNo)
 | 
			
		||||
XRPL_FIX    (DelegateV1_1,               Supported::no,  VoteBehavior::DefaultNo)
 | 
			
		||||
XRPL_FIX    (PriceOracleOrder,           Supported::yes, VoteBehavior::DefaultNo)
 | 
			
		||||
XRPL_FIX    (MPTDeliveredAmount,         Supported::no,  VoteBehavior::DefaultNo)
 | 
			
		||||
XRPL_FIX    (MPTDeliveredAmount,         Supported::yes, VoteBehavior::DefaultNo)
 | 
			
		||||
XRPL_FIX    (AMMClawbackRounding,        Supported::yes, VoteBehavior::DefaultNo)
 | 
			
		||||
XRPL_FEATURE(TokenEscrow,                Supported::yes, VoteBehavior::DefaultNo)
 | 
			
		||||
XRPL_FIX    (EnforceNFTokenTrustlineV2,  Supported::yes, VoteBehavior::DefaultNo)
 | 
			
		||||
@@ -45,7 +44,6 @@ XRPL_FIX    (AMMv1_3,                    Supported::yes, VoteBehavior::DefaultNo
 | 
			
		||||
XRPL_FEATURE(PermissionedDEX,            Supported::yes, VoteBehavior::DefaultNo)
 | 
			
		||||
XRPL_FEATURE(Batch,                      Supported::yes, VoteBehavior::DefaultNo)
 | 
			
		||||
XRPL_FEATURE(SingleAssetVault,           Supported::no,  VoteBehavior::DefaultNo)
 | 
			
		||||
XRPL_FEATURE(PermissionDelegation,       Supported::no,  VoteBehavior::DefaultNo)
 | 
			
		||||
XRPL_FIX    (PayChanCancelAfter,         Supported::yes, VoteBehavior::DefaultNo)
 | 
			
		||||
// Check flags in Credential transactions
 | 
			
		||||
XRPL_FIX    (InvalidTxFlags,             Supported::yes, VoteBehavior::DefaultNo)
 | 
			
		||||
@@ -79,7 +77,6 @@ XRPL_FIX    (DisallowIncomingV1,         Supported::yes, VoteBehavior::DefaultNo
 | 
			
		||||
XRPL_FEATURE(XChainBridge,               Supported::yes, VoteBehavior::DefaultNo)
 | 
			
		||||
XRPL_FEATURE(AMM,                        Supported::yes, VoteBehavior::DefaultNo)
 | 
			
		||||
XRPL_FEATURE(Clawback,                   Supported::yes, VoteBehavior::DefaultNo)
 | 
			
		||||
XRPL_FIX    (ReducedOffersV1,            Supported::yes, VoteBehavior::DefaultNo)
 | 
			
		||||
XRPL_FIX    (NFTokenRemint,              Supported::yes, VoteBehavior::DefaultNo)
 | 
			
		||||
XRPL_FIX    (NonFungibleTokensV1_2,      Supported::yes, VoteBehavior::DefaultNo)
 | 
			
		||||
XRPL_FIX    (UniversalNumber,            Supported::yes, VoteBehavior::DefaultNo)
 | 
			
		||||
@@ -91,33 +88,17 @@ XRPL_FIX    (TrustLinesToSelf,           Supported::yes, VoteBehavior::DefaultNo
 | 
			
		||||
XRPL_FEATURE(NonFungibleTokensV1_1,      Supported::yes, VoteBehavior::DefaultNo)
 | 
			
		||||
XRPL_FEATURE(ExpandedSignerList,         Supported::yes, VoteBehavior::DefaultNo)
 | 
			
		||||
XRPL_FEATURE(CheckCashMakesTrustLine,    Supported::yes, VoteBehavior::DefaultNo)
 | 
			
		||||
XRPL_FIX    (RmSmallIncreasedQOffers,    Supported::yes, VoteBehavior::DefaultYes)
 | 
			
		||||
XRPL_FIX    (STAmountCanonicalize,       Supported::yes, VoteBehavior::DefaultYes)
 | 
			
		||||
XRPL_FEATURE(FlowSortStrands,            Supported::yes, VoteBehavior::DefaultYes)
 | 
			
		||||
XRPL_FEATURE(TicketBatch,                Supported::yes, VoteBehavior::DefaultYes)
 | 
			
		||||
XRPL_FEATURE(NegativeUNL,                Supported::yes, VoteBehavior::DefaultYes)
 | 
			
		||||
XRPL_FIX    (AmendmentMajorityCalc,      Supported::yes, VoteBehavior::DefaultYes)
 | 
			
		||||
XRPL_FEATURE(HardenedValidations,        Supported::yes, VoteBehavior::DefaultYes)
 | 
			
		||||
// fix1781: XRPEndpointSteps should be included in the circular payment check
 | 
			
		||||
XRPL_FIX    (1781,                       Supported::yes, VoteBehavior::DefaultYes)
 | 
			
		||||
XRPL_FEATURE(RequireFullyCanonicalSig,   Supported::yes, VoteBehavior::DefaultYes)
 | 
			
		||||
XRPL_FIX    (QualityUpperBound,          Supported::yes, VoteBehavior::DefaultYes)
 | 
			
		||||
XRPL_FEATURE(DeletableAccounts,          Supported::yes, VoteBehavior::DefaultYes)
 | 
			
		||||
XRPL_FIX    (PayChanRecipientOwnerDir,   Supported::yes, VoteBehavior::DefaultYes)
 | 
			
		||||
XRPL_FIX    (CheckThreading,             Supported::yes, VoteBehavior::DefaultYes)
 | 
			
		||||
XRPL_FIX    (MasterKeyAsRegularKey,      Supported::yes, VoteBehavior::DefaultYes)
 | 
			
		||||
XRPL_FIX    (TakerDryOfferRemoval,       Supported::yes, VoteBehavior::DefaultYes)
 | 
			
		||||
XRPL_FEATURE(MultiSignReserve,           Supported::yes, VoteBehavior::DefaultYes)
 | 
			
		||||
XRPL_FIX    (1578,                       Supported::yes, VoteBehavior::DefaultYes)
 | 
			
		||||
// fix1515: Use liquidity from strands that consume max offers, but mark as dry
 | 
			
		||||
XRPL_FIX    (1515,                       Supported::yes, VoteBehavior::DefaultYes)
 | 
			
		||||
XRPL_FEATURE(DepositPreauth,             Supported::yes, VoteBehavior::DefaultYes)
 | 
			
		||||
XRPL_FIX    (1623,                       Supported::yes, VoteBehavior::DefaultYes)
 | 
			
		||||
XRPL_FIX    (1543,                       Supported::yes, VoteBehavior::DefaultYes)
 | 
			
		||||
XRPL_FIX    (1571,                       Supported::yes, VoteBehavior::DefaultYes)
 | 
			
		||||
XRPL_FEATURE(Checks,                     Supported::yes, VoteBehavior::DefaultYes)
 | 
			
		||||
XRPL_FEATURE(DepositAuth,                Supported::yes, VoteBehavior::DefaultYes)
 | 
			
		||||
XRPL_FIX    (1513,                       Supported::yes, VoteBehavior::DefaultYes)
 | 
			
		||||
XRPL_FEATURE(Flow,                       Supported::yes, VoteBehavior::DefaultYes)
 | 
			
		||||
 | 
			
		||||
// The following amendments are obsolete, but must remain supported
 | 
			
		||||
@@ -138,21 +119,38 @@ XRPL_FEATURE(CryptoConditionsSuite, Supported::yes, VoteBehavior::Obsolete)
 | 
			
		||||
 | 
			
		||||
// The following amendments have been active for at least two years. Their
 | 
			
		||||
// pre-amendment code has been removed and the identifiers are deprecated.
 | 
			
		||||
// All known amendments and amendments that may appear in a validated
 | 
			
		||||
// ledger must be registered either here or above with the "active" amendments
 | 
			
		||||
XRPL_RETIRE(MultiSign)
 | 
			
		||||
XRPL_RETIRE(TrustSetAuth)
 | 
			
		||||
XRPL_RETIRE(FeeEscalation)
 | 
			
		||||
XRPL_RETIRE(PayChan)
 | 
			
		||||
XRPL_RETIRE(CryptoConditions)
 | 
			
		||||
XRPL_RETIRE(TickSize)
 | 
			
		||||
XRPL_RETIRE(fix1368)
 | 
			
		||||
XRPL_RETIRE(Escrow)
 | 
			
		||||
XRPL_RETIRE(fix1373)
 | 
			
		||||
XRPL_RETIRE(EnforceInvariants)
 | 
			
		||||
XRPL_RETIRE(SortedDirectories)
 | 
			
		||||
// All known amendments and amendments that may appear in a validated ledger
 | 
			
		||||
// must be registered either here or above with the "active" amendments
 | 
			
		||||
//
 | 
			
		||||
// Please keep this list sorted alphabetically for convenience.
 | 
			
		||||
XRPL_RETIRE(fix1201)
 | 
			
		||||
XRPL_RETIRE(fix1368)
 | 
			
		||||
XRPL_RETIRE(fix1373)
 | 
			
		||||
XRPL_RETIRE(fix1512)
 | 
			
		||||
XRPL_RETIRE(fix1513)
 | 
			
		||||
XRPL_RETIRE(fix1515)
 | 
			
		||||
XRPL_RETIRE(fix1523)
 | 
			
		||||
XRPL_RETIRE(fix1528)
 | 
			
		||||
XRPL_RETIRE(fix1543)
 | 
			
		||||
XRPL_RETIRE(fix1571)
 | 
			
		||||
XRPL_RETIRE(fix1578)
 | 
			
		||||
XRPL_RETIRE(fix1623)
 | 
			
		||||
XRPL_RETIRE(fix1781)
 | 
			
		||||
XRPL_RETIRE(fixAmendmentMajorityCalc)
 | 
			
		||||
XRPL_RETIRE(fixCheckThreading)
 | 
			
		||||
XRPL_RETIRE(fixMasterKeyAsRegularKey)
 | 
			
		||||
XRPL_RETIRE(fixQualityUpperBound)
 | 
			
		||||
XRPL_RETIRE(fixReducedOffersV1)
 | 
			
		||||
XRPL_RETIRE(fixRmSmallIncreasedQOffers)
 | 
			
		||||
XRPL_RETIRE(fixSTAmountCanonicalize)
 | 
			
		||||
XRPL_RETIRE(fixTakerDryOfferRemoval)
 | 
			
		||||
XRPL_RETIRE(CryptoConditions)
 | 
			
		||||
XRPL_RETIRE(Escrow)
 | 
			
		||||
XRPL_RETIRE(EnforceInvariants)
 | 
			
		||||
XRPL_RETIRE(FeeEscalation)
 | 
			
		||||
XRPL_RETIRE(FlowCross)
 | 
			
		||||
XRPL_RETIRE(MultiSign)
 | 
			
		||||
XRPL_RETIRE(PayChan)
 | 
			
		||||
XRPL_RETIRE(SortedDirectories)
 | 
			
		||||
XRPL_RETIRE(TickSize)
 | 
			
		||||
XRPL_RETIRE(TrustSetAuth)
 | 
			
		||||
 
 | 
			
		||||
@@ -457,7 +457,7 @@ LEDGER_ENTRY(ltCREDENTIAL, 0x0081, Credential, credential, ({
 | 
			
		||||
    {sfExpiration,           soeOPTIONAL},
 | 
			
		||||
    {sfURI,                  soeOPTIONAL},
 | 
			
		||||
    {sfIssuerNode,           soeREQUIRED},
 | 
			
		||||
    {sfSubjectNode,          soeREQUIRED},
 | 
			
		||||
    {sfSubjectNode,          soeOPTIONAL},
 | 
			
		||||
    {sfPreviousTxnID,        soeREQUIRED},
 | 
			
		||||
    {sfPreviousTxnLgrSeq,    soeREQUIRED},
 | 
			
		||||
}))
 | 
			
		||||
 
 | 
			
		||||
@@ -316,7 +316,7 @@ TRANSACTION(ttTRUST_SET, 20, TrustSet,
 | 
			
		||||
#endif
 | 
			
		||||
TRANSACTION(ttACCOUNT_DELETE, 21, AccountDelete,
 | 
			
		||||
    Delegation::notDelegatable,
 | 
			
		||||
    uint256{},
 | 
			
		||||
    featureDeletableAccounts,
 | 
			
		||||
    mustDeleteAcct,
 | 
			
		||||
    ({
 | 
			
		||||
    {sfDestination, soeREQUIRED},
 | 
			
		||||
@@ -837,7 +837,7 @@ TRANSACTION(ttPERMISSIONED_DOMAIN_DELETE, 63, PermissionedDomainDelete,
 | 
			
		||||
#endif
 | 
			
		||||
TRANSACTION(ttDELEGATE_SET, 64, DelegateSet,
 | 
			
		||||
    Delegation::notDelegatable,
 | 
			
		||||
    featurePermissionDelegation,
 | 
			
		||||
    featurePermissionDelegationV1_1,
 | 
			
		||||
    noPriv,
 | 
			
		||||
    ({
 | 
			
		||||
    {sfAuthorize, soeREQUIRED},
 | 
			
		||||
@@ -909,7 +909,7 @@ TRANSACTION(ttVAULT_DEPOSIT, 68, VaultDeposit,
 | 
			
		||||
TRANSACTION(ttVAULT_WITHDRAW, 69, VaultWithdraw,
 | 
			
		||||
    Delegation::delegatable,
 | 
			
		||||
    featureSingleAssetVault,
 | 
			
		||||
    mayDeleteMPT | mustModifyVault,
 | 
			
		||||
    mayDeleteMPT | mayAuthorizeMPT | mustModifyVault,
 | 
			
		||||
    ({
 | 
			
		||||
    {sfVaultID, soeREQUIRED},
 | 
			
		||||
    {sfAmount, soeREQUIRED, soeMPTSupported},
 | 
			
		||||
 
 | 
			
		||||
@@ -569,6 +569,7 @@ JSS(settle_delay);            // out: AccountChannels
 | 
			
		||||
JSS(severity);                // in: LogLevel
 | 
			
		||||
JSS(shares);                  // out: VaultInfo
 | 
			
		||||
JSS(signature);               // out: NetworkOPs, ChannelAuthorize
 | 
			
		||||
JSS(signature_target);        // in: TransactionSign
 | 
			
		||||
JSS(signature_verified);      // out: ChannelVerify
 | 
			
		||||
JSS(signing_key);             // out: NetworkOPs
 | 
			
		||||
JSS(signing_keys);            // out: ValidatorList
 | 
			
		||||
 
 | 
			
		||||
@@ -21,6 +21,7 @@
 | 
			
		||||
#define RIPPLE_RESOURCE_CONSUMER_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#include <xrpl/basics/Log.h>
 | 
			
		||||
#include <xrpl/protocol/PublicKey.h>
 | 
			
		||||
#include <xrpl/resource/Charge.h>
 | 
			
		||||
#include <xrpl/resource/Disposition.h>
 | 
			
		||||
 | 
			
		||||
@@ -87,6 +88,9 @@ public:
 | 
			
		||||
    Entry&
 | 
			
		||||
    entry();
 | 
			
		||||
 | 
			
		||||
    void
 | 
			
		||||
    setPublicKey(PublicKey const& publicKey);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    Logic* m_logic;
 | 
			
		||||
    Entry* m_entry;
 | 
			
		||||
 
 | 
			
		||||
@@ -53,7 +53,7 @@ struct Entry : public beast::List<Entry>::Node
 | 
			
		||||
    std::string
 | 
			
		||||
    to_string() const
 | 
			
		||||
    {
 | 
			
		||||
        return key->address.to_string();
 | 
			
		||||
        return getFingerprint(key->address, publicKey);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -82,6 +82,9 @@ struct Entry : public beast::List<Entry>::Node
 | 
			
		||||
        return local_balance.add(charge, now) + remote_balance;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // The public key of the peer
 | 
			
		||||
    std::optional<PublicKey> publicKey;
 | 
			
		||||
 | 
			
		||||
    // Back pointer to the map key (bit of a hack here)
 | 
			
		||||
    Key const* key;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -20,11 +20,10 @@
 | 
			
		||||
#ifndef RIPPLE_SHAMAP_FAMILY_H_INCLUDED
 | 
			
		||||
#define RIPPLE_SHAMAP_FAMILY_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#include <xrpld/nodestore/Database.h>
 | 
			
		||||
#include <xrpld/shamap/FullBelowCache.h>
 | 
			
		||||
#include <xrpld/shamap/TreeNodeCache.h>
 | 
			
		||||
 | 
			
		||||
#include <xrpl/beast/utility/Journal.h>
 | 
			
		||||
#include <xrpl/nodestore/Database.h>
 | 
			
		||||
#include <xrpl/shamap/FullBelowCache.h>
 | 
			
		||||
#include <xrpl/shamap/TreeNodeCache.h>
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
 | 
			
		||||
@@ -20,21 +20,19 @@
 | 
			
		||||
#ifndef RIPPLE_SHAMAP_SHAMAP_H_INCLUDED
 | 
			
		||||
#define RIPPLE_SHAMAP_SHAMAP_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#include <xrpld/nodestore/Database.h>
 | 
			
		||||
#include <xrpld/nodestore/NodeObject.h>
 | 
			
		||||
#include <xrpld/shamap/Family.h>
 | 
			
		||||
#include <xrpld/shamap/SHAMapAddNode.h>
 | 
			
		||||
#include <xrpld/shamap/SHAMapInnerNode.h>
 | 
			
		||||
#include <xrpld/shamap/SHAMapItem.h>
 | 
			
		||||
#include <xrpld/shamap/SHAMapLeafNode.h>
 | 
			
		||||
#include <xrpld/shamap/SHAMapMissingNode.h>
 | 
			
		||||
#include <xrpld/shamap/SHAMapTreeNode.h>
 | 
			
		||||
#include <xrpld/shamap/TreeNodeCache.h>
 | 
			
		||||
 | 
			
		||||
#include <xrpl/basics/IntrusivePointer.h>
 | 
			
		||||
#include <xrpl/basics/UnorderedContainers.h>
 | 
			
		||||
#include <xrpl/beast/utility/Journal.h>
 | 
			
		||||
#include <xrpl/beast/utility/instrumentation.h>
 | 
			
		||||
#include <xrpl/nodestore/Database.h>
 | 
			
		||||
#include <xrpl/nodestore/NodeObject.h>
 | 
			
		||||
#include <xrpl/shamap/Family.h>
 | 
			
		||||
#include <xrpl/shamap/SHAMapAddNode.h>
 | 
			
		||||
#include <xrpl/shamap/SHAMapInnerNode.h>
 | 
			
		||||
#include <xrpl/shamap/SHAMapItem.h>
 | 
			
		||||
#include <xrpl/shamap/SHAMapLeafNode.h>
 | 
			
		||||
#include <xrpl/shamap/SHAMapMissingNode.h>
 | 
			
		||||
#include <xrpl/shamap/SHAMapTreeNode.h>
 | 
			
		||||
 | 
			
		||||
#include <set>
 | 
			
		||||
#include <stack>
 | 
			
		||||
@@ -20,12 +20,11 @@
 | 
			
		||||
#ifndef RIPPLE_SHAMAP_SHAMAPACCOUNTSTATELEAFNODE_H_INCLUDED
 | 
			
		||||
#define RIPPLE_SHAMAP_SHAMAPACCOUNTSTATELEAFNODE_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#include <xrpld/shamap/SHAMapItem.h>
 | 
			
		||||
#include <xrpld/shamap/SHAMapLeafNode.h>
 | 
			
		||||
 | 
			
		||||
#include <xrpl/basics/CountedObject.h>
 | 
			
		||||
#include <xrpl/protocol/HashPrefix.h>
 | 
			
		||||
#include <xrpl/protocol/digest.h>
 | 
			
		||||
#include <xrpl/shamap/SHAMapItem.h>
 | 
			
		||||
#include <xrpl/shamap/SHAMapLeafNode.h>
 | 
			
		||||
 | 
			
		||||
namespace ripple {
 | 
			
		||||
 | 
			
		||||
@@ -20,10 +20,9 @@
 | 
			
		||||
#ifndef RIPPLE_SHAMAP_SHAMAPINNERNODE_H_INCLUDED
 | 
			
		||||
#define RIPPLE_SHAMAP_SHAMAPINNERNODE_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#include <xrpld/shamap/SHAMapNodeID.h>
 | 
			
		||||
#include <xrpld/shamap/detail/TaggedPointer.h>
 | 
			
		||||
 | 
			
		||||
#include <xrpl/basics/IntrusivePointer.h>
 | 
			
		||||
#include <xrpl/shamap/SHAMapNodeID.h>
 | 
			
		||||
#include <xrpl/shamap/detail/TaggedPointer.h>
 | 
			
		||||
 | 
			
		||||
#include <atomic>
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
@@ -20,8 +20,8 @@
 | 
			
		||||
#ifndef RIPPLE_SHAMAP_SHAMAPLEAFNODE_H_INCLUDED
 | 
			
		||||
#define RIPPLE_SHAMAP_SHAMAPLEAFNODE_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#include <xrpld/shamap/SHAMapItem.h>
 | 
			
		||||
#include <xrpld/shamap/SHAMapTreeNode.h>
 | 
			
		||||
#include <xrpl/shamap/SHAMapItem.h>
 | 
			
		||||
#include <xrpl/shamap/SHAMapTreeNode.h>
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
 | 
			
		||||
@@ -20,9 +20,8 @@
 | 
			
		||||
#ifndef RIPPLE_SHAMAP_SHAMAPMISSINGNODE_H_INCLUDED
 | 
			
		||||
#define RIPPLE_SHAMAP_SHAMAPMISSINGNODE_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#include <xrpld/shamap/SHAMapTreeNode.h>
 | 
			
		||||
 | 
			
		||||
#include <xrpl/basics/base_uint.h>
 | 
			
		||||
#include <xrpl/shamap/SHAMapTreeNode.h>
 | 
			
		||||
 | 
			
		||||
#include <iosfwd>
 | 
			
		||||
#include <stdexcept>
 | 
			
		||||
@@ -20,7 +20,7 @@
 | 
			
		||||
#ifndef RIPPLE_SHAMAP_SHAMAPSYNCFILTER_H_INCLUDED
 | 
			
		||||
#define RIPPLE_SHAMAP_SHAMAPSYNCFILTER_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#include <xrpld/shamap/SHAMapTreeNode.h>
 | 
			
		||||
#include <xrpl/shamap/SHAMapTreeNode.h>
 | 
			
		||||
 | 
			
		||||
#include <optional>
 | 
			
		||||
 | 
			
		||||
@@ -20,13 +20,12 @@
 | 
			
		||||
#ifndef RIPPLE_SHAMAP_SHAMAPTREENODE_H_INCLUDED
 | 
			
		||||
#define RIPPLE_SHAMAP_SHAMAPTREENODE_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#include <xrpld/shamap/SHAMapItem.h>
 | 
			
		||||
#include <xrpld/shamap/SHAMapNodeID.h>
 | 
			
		||||
 | 
			
		||||
#include <xrpl/basics/IntrusivePointer.h>
 | 
			
		||||
#include <xrpl/basics/IntrusiveRefCounts.h>
 | 
			
		||||
#include <xrpl/basics/SHAMapHash.h>
 | 
			
		||||
#include <xrpl/protocol/Serializer.h>
 | 
			
		||||
#include <xrpl/shamap/SHAMapItem.h>
 | 
			
		||||
#include <xrpl/shamap/SHAMapNodeID.h>
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <string>
 | 
			
		||||
@@ -20,12 +20,11 @@
 | 
			
		||||
#ifndef RIPPLE_SHAMAP_SHAMAPTXLEAFNODE_H_INCLUDED
 | 
			
		||||
#define RIPPLE_SHAMAP_SHAMAPTXLEAFNODE_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#include <xrpld/shamap/SHAMapItem.h>
 | 
			
		||||
#include <xrpld/shamap/SHAMapLeafNode.h>
 | 
			
		||||
 | 
			
		||||
#include <xrpl/basics/CountedObject.h>
 | 
			
		||||
#include <xrpl/protocol/HashPrefix.h>
 | 
			
		||||
#include <xrpl/protocol/digest.h>
 | 
			
		||||
#include <xrpl/shamap/SHAMapItem.h>
 | 
			
		||||
#include <xrpl/shamap/SHAMapLeafNode.h>
 | 
			
		||||
 | 
			
		||||
namespace ripple {
 | 
			
		||||
 | 
			
		||||
@@ -20,12 +20,11 @@
 | 
			
		||||
#ifndef RIPPLE_SHAMAP_SHAMAPLEAFTXPLUSMETANODE_H_INCLUDED
 | 
			
		||||
#define RIPPLE_SHAMAP_SHAMAPLEAFTXPLUSMETANODE_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#include <xrpld/shamap/SHAMapItem.h>
 | 
			
		||||
#include <xrpld/shamap/SHAMapLeafNode.h>
 | 
			
		||||
 | 
			
		||||
#include <xrpl/basics/CountedObject.h>
 | 
			
		||||
#include <xrpl/protocol/HashPrefix.h>
 | 
			
		||||
#include <xrpl/protocol/digest.h>
 | 
			
		||||
#include <xrpl/shamap/SHAMapItem.h>
 | 
			
		||||
#include <xrpl/shamap/SHAMapLeafNode.h>
 | 
			
		||||
 | 
			
		||||
namespace ripple {
 | 
			
		||||
 | 
			
		||||
@@ -20,10 +20,9 @@
 | 
			
		||||
#ifndef RIPPLE_SHAMAP_TREENODECACHE_H_INCLUDED
 | 
			
		||||
#define RIPPLE_SHAMAP_TREENODECACHE_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#include <xrpld/shamap/SHAMapTreeNode.h>
 | 
			
		||||
 | 
			
		||||
#include <xrpl/basics/IntrusivePointer.h>
 | 
			
		||||
#include <xrpl/basics/TaggedCache.h>
 | 
			
		||||
#include <xrpl/shamap/SHAMapTreeNode.h>
 | 
			
		||||
 | 
			
		||||
namespace ripple {
 | 
			
		||||
 | 
			
		||||
@@ -20,9 +20,8 @@
 | 
			
		||||
#ifndef RIPPLE_SHAMAP_TAGGEDPOINTER_H_INCLUDED
 | 
			
		||||
#define RIPPLE_SHAMAP_TAGGEDPOINTER_H_INCLUDED
 | 
			
		||||
 | 
			
		||||
#include <xrpld/shamap/SHAMapTreeNode.h>
 | 
			
		||||
 | 
			
		||||
#include <xrpl/basics/IntrusivePointer.h>
 | 
			
		||||
#include <xrpl/shamap/SHAMapTreeNode.h>
 | 
			
		||||
 | 
			
		||||
#include <array>
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
@@ -17,10 +17,9 @@
 | 
			
		||||
*/
 | 
			
		||||
//==============================================================================
 | 
			
		||||
 | 
			
		||||
#include <xrpld/shamap/SHAMapInnerNode.h>
 | 
			
		||||
#include <xrpld/shamap/detail/TaggedPointer.h>
 | 
			
		||||
 | 
			
		||||
#include <xrpl/basics/ByteUtilities.h>
 | 
			
		||||
#include <xrpl/shamap/SHAMapInnerNode.h>
 | 
			
		||||
#include <xrpl/shamap/detail/TaggedPointer.h>
 | 
			
		||||
 | 
			
		||||
#include <boost/pool/pool_alloc.hpp>
 | 
			
		||||
 | 
			
		||||
@@ -126,10 +126,10 @@ ApplyStateTable::apply(
 | 
			
		||||
    std::optional<TxMeta> metadata;
 | 
			
		||||
    if (!to.open() || isDryRun)
 | 
			
		||||
    {
 | 
			
		||||
        TxMeta meta(tx.getTransactionID(), to.seq(), parentBatchId);
 | 
			
		||||
        TxMeta meta(tx.getTransactionID(), to.seq());
 | 
			
		||||
 | 
			
		||||
        if (deliver)
 | 
			
		||||
            meta.setDeliveredAmount(*deliver);
 | 
			
		||||
        meta.setDeliveredAmount(deliver);
 | 
			
		||||
        meta.setParentBatchID(parentBatchId);
 | 
			
		||||
 | 
			
		||||
        Mods newMod;
 | 
			
		||||
        for (auto& item : items_)
 | 
			
		||||
@@ -682,12 +682,6 @@ ApplyStateTable::threadOwners(
 | 
			
		||||
            if (auto const optSleAcct{(*sle)[~sfAccount]})
 | 
			
		||||
                threadTx(base, meta, *optSleAcct, mods, j);
 | 
			
		||||
 | 
			
		||||
            // Don't thread a check's sfDestination unless the amendment is
 | 
			
		||||
            // enabled
 | 
			
		||||
            if (ledgerType == ltCHECK &&
 | 
			
		||||
                !base.rules().enabled(fixCheckThreading))
 | 
			
		||||
                break;
 | 
			
		||||
 | 
			
		||||
            // If sfDestination is present, thread to that account
 | 
			
		||||
            if (auto const optSleDest{(*sle)[~sfDestination]})
 | 
			
		||||
                threadTx(base, meta, *optSleDest, mods, j);
 | 
			
		||||
 
 | 
			
		||||
@@ -22,6 +22,9 @@
 | 
			
		||||
#include <xrpl/ledger/ApplyView.h>
 | 
			
		||||
#include <xrpl/protocol/Protocol.h>
 | 
			
		||||
 | 
			
		||||
#include <limits>
 | 
			
		||||
#include <type_traits>
 | 
			
		||||
 | 
			
		||||
namespace ripple {
 | 
			
		||||
 | 
			
		||||
std::optional<std::uint64_t>
 | 
			
		||||
@@ -91,8 +94,21 @@ ApplyView::dirAdd(
 | 
			
		||||
        return page;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // We rely on modulo arithmetic of unsigned integers (guaranteed in
 | 
			
		||||
    // [basic.fundamental] paragraph 2) to detect page representation overflow.
 | 
			
		||||
    // For signed integers this would be UB, hence static_assert here.
 | 
			
		||||
    static_assert(std::is_unsigned_v<decltype(page)>);
 | 
			
		||||
    // Defensive check against breaking changes in compiler.
 | 
			
		||||
    static_assert([]<typename T>(std::type_identity<T>) constexpr -> T {
 | 
			
		||||
        T tmp = std::numeric_limits<T>::max();
 | 
			
		||||
        return ++tmp;
 | 
			
		||||
    }(std::type_identity<decltype(page)>{}) == 0);
 | 
			
		||||
    ++page;
 | 
			
		||||
    // Check whether we're out of pages.
 | 
			
		||||
    if (++page >= dirNodeMaxPages)
 | 
			
		||||
    if (page == 0)
 | 
			
		||||
        return std::nullopt;
 | 
			
		||||
    if (!rules().enabled(fixDirectoryLimit) &&
 | 
			
		||||
        page >= dirNodeMaxPages)  // Old pages limit
 | 
			
		||||
        return std::nullopt;
 | 
			
		||||
 | 
			
		||||
    // We are about to create a new node; we'll link it to
 | 
			
		||||
 
 | 
			
		||||
@@ -1242,6 +1242,12 @@ addEmptyHolding(
 | 
			
		||||
    // If the line already exists, don't create it again.
 | 
			
		||||
    if (view.read(index))
 | 
			
		||||
        return tecDUPLICATE;
 | 
			
		||||
 | 
			
		||||
    // Can the account cover the trust line reserve ?
 | 
			
		||||
    std::uint32_t const ownerCount = sleDst->at(sfOwnerCount);
 | 
			
		||||
    if (priorBalance < view.fees().accountReserve(ownerCount + 1))
 | 
			
		||||
        return tecNO_LINE_INSUF_RESERVE;
 | 
			
		||||
 | 
			
		||||
    return trustCreate(
 | 
			
		||||
        view,
 | 
			
		||||
        high,
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,7 @@
 | 
			
		||||
*/
 | 
			
		||||
//==============================================================================
 | 
			
		||||
 | 
			
		||||
#include <xrpld/nodestore/detail/BatchWriter.h>
 | 
			
		||||
#include <xrpl/nodestore/detail/BatchWriter.h>
 | 
			
		||||
 | 
			
		||||
namespace ripple {
 | 
			
		||||
namespace NodeStore {
 | 
			
		||||
@@ -17,11 +17,10 @@
 | 
			
		||||
*/
 | 
			
		||||
//==============================================================================
 | 
			
		||||
 | 
			
		||||
#include <xrpld/nodestore/Database.h>
 | 
			
		||||
 | 
			
		||||
#include <xrpl/basics/chrono.h>
 | 
			
		||||
#include <xrpl/beast/core/CurrentThreadName.h>
 | 
			
		||||
#include <xrpl/json/json_value.h>
 | 
			
		||||
#include <xrpl/nodestore/Database.h>
 | 
			
		||||
#include <xrpl/protocol/HashPrefix.h>
 | 
			
		||||
#include <xrpl/protocol/jss.h>
 | 
			
		||||
 | 
			
		||||
@@ -17,7 +17,7 @@
 | 
			
		||||
*/
 | 
			
		||||
//==============================================================================
 | 
			
		||||
 | 
			
		||||
#include <xrpld/nodestore/detail/DatabaseNodeImp.h>
 | 
			
		||||
#include <xrpl/nodestore/detail/DatabaseNodeImp.h>
 | 
			
		||||
 | 
			
		||||
namespace ripple {
 | 
			
		||||
namespace NodeStore {
 | 
			
		||||
@@ -17,7 +17,7 @@
 | 
			
		||||
*/
 | 
			
		||||
//==============================================================================
 | 
			
		||||
 | 
			
		||||
#include <xrpld/nodestore/detail/DatabaseRotatingImp.h>
 | 
			
		||||
#include <xrpl/nodestore/detail/DatabaseRotatingImp.h>
 | 
			
		||||
 | 
			
		||||
namespace ripple {
 | 
			
		||||
namespace NodeStore {
 | 
			
		||||
@@ -17,10 +17,9 @@
 | 
			
		||||
*/
 | 
			
		||||
//==============================================================================
 | 
			
		||||
 | 
			
		||||
#include <xrpld/nodestore/detail/DecodedBlob.h>
 | 
			
		||||
 | 
			
		||||
#include <xrpl/basics/safe_cast.h>
 | 
			
		||||
#include <xrpl/beast/utility/instrumentation.h>
 | 
			
		||||
#include <xrpl/nodestore/detail/DecodedBlob.h>
 | 
			
		||||
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
 | 
			
		||||
@@ -17,7 +17,7 @@
 | 
			
		||||
*/
 | 
			
		||||
//==============================================================================
 | 
			
		||||
 | 
			
		||||
#include <xrpld/nodestore/DummyScheduler.h>
 | 
			
		||||
#include <xrpl/nodestore/DummyScheduler.h>
 | 
			
		||||
 | 
			
		||||
namespace ripple {
 | 
			
		||||
namespace NodeStore {
 | 
			
		||||
@@ -17,8 +17,8 @@
 | 
			
		||||
*/
 | 
			
		||||
//==============================================================================
 | 
			
		||||
 | 
			
		||||
#include <xrpld/nodestore/detail/DatabaseNodeImp.h>
 | 
			
		||||
#include <xrpld/nodestore/detail/ManagerImp.h>
 | 
			
		||||
#include <xrpl/nodestore/detail/DatabaseNodeImp.h>
 | 
			
		||||
#include <xrpl/nodestore/detail/ManagerImp.h>
 | 
			
		||||
 | 
			
		||||
#include <boost/algorithm/string/predicate.hpp>
 | 
			
		||||
 | 
			
		||||
@@ -41,6 +41,27 @@ ManagerImp::missing_backend()
 | 
			
		||||
        "please see the rippled-example.cfg file!");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// We shouldn't rely on global variables for lifetime management because their
 | 
			
		||||
// lifetime is not well-defined. ManagerImp may get destroyed before the Factory
 | 
			
		||||
// classes, and then, calling Manager::instance().erase() in the destructors of
 | 
			
		||||
// the Factory classes is an undefined behaviour.
 | 
			
		||||
void
 | 
			
		||||
registerNuDBFactory(Manager& manager);
 | 
			
		||||
void
 | 
			
		||||
registerRocksDBFactory(Manager& manager);
 | 
			
		||||
void
 | 
			
		||||
registerNullFactory(Manager& manager);
 | 
			
		||||
void
 | 
			
		||||
registerMemoryFactory(Manager& manager);
 | 
			
		||||
 | 
			
		||||
ManagerImp::ManagerImp()
 | 
			
		||||
{
 | 
			
		||||
    registerNuDBFactory(*this);
 | 
			
		||||
    registerRocksDBFactory(*this);
 | 
			
		||||
    registerNullFactory(*this);
 | 
			
		||||
    registerMemoryFactory(*this);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::unique_ptr<Backend>
 | 
			
		||||
ManagerImp::make_Backend(
 | 
			
		||||
    Section const& parameters,
 | 
			
		||||
@@ -17,7 +17,7 @@
 | 
			
		||||
*/
 | 
			
		||||
//==============================================================================
 | 
			
		||||
 | 
			
		||||
#include <xrpld/nodestore/NodeObject.h>
 | 
			
		||||
#include <xrpl/nodestore/NodeObject.h>
 | 
			
		||||
 | 
			
		||||
#include <memory>
 | 
			
		||||
 | 
			
		||||
@@ -17,10 +17,9 @@
 | 
			
		||||
*/
 | 
			
		||||
//==============================================================================
 | 
			
		||||
 | 
			
		||||
#include <xrpld/nodestore/Factory.h>
 | 
			
		||||
#include <xrpld/nodestore/Manager.h>
 | 
			
		||||
 | 
			
		||||
#include <xrpl/basics/contract.h>
 | 
			
		||||
#include <xrpl/nodestore/Factory.h>
 | 
			
		||||
#include <xrpl/nodestore/Manager.h>
 | 
			
		||||
 | 
			
		||||
#include <boost/beast/core/string.hpp>
 | 
			
		||||
#include <boost/core/ignore_unused.hpp>
 | 
			
		||||
@@ -46,10 +45,10 @@ class MemoryFactory : public Factory
 | 
			
		||||
private:
 | 
			
		||||
    std::mutex mutex_;
 | 
			
		||||
    std::map<std::string, MemoryDB, boost::beast::iless> map_;
 | 
			
		||||
    Manager& manager_;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    MemoryFactory();
 | 
			
		||||
    ~MemoryFactory() override;
 | 
			
		||||
    explicit MemoryFactory(Manager& manager);
 | 
			
		||||
 | 
			
		||||
    std::string
 | 
			
		||||
    getName() const override;
 | 
			
		||||
@@ -75,7 +74,14 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static MemoryFactory memoryFactory;
 | 
			
		||||
MemoryFactory* memoryFactory = nullptr;
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
registerMemoryFactory(Manager& manager)
 | 
			
		||||
{
 | 
			
		||||
    static MemoryFactory instance{manager};
 | 
			
		||||
    memoryFactory = &instance;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
@@ -112,9 +118,9 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void
 | 
			
		||||
    open(bool createIfMissing) override
 | 
			
		||||
    open(bool) override
 | 
			
		||||
    {
 | 
			
		||||
        db_ = &memoryFactory.open(name_);
 | 
			
		||||
        db_ = &memoryFactory->open(name_);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool
 | 
			
		||||
@@ -219,14 +225,9 @@ public:
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
MemoryFactory::MemoryFactory()
 | 
			
		||||
MemoryFactory::MemoryFactory(Manager& manager) : manager_(manager)
 | 
			
		||||
{
 | 
			
		||||
    Manager::instance().insert(*this);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MemoryFactory::~MemoryFactory()
 | 
			
		||||
{
 | 
			
		||||
    Manager::instance().erase(*this);
 | 
			
		||||
    manager_.insert(*this);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string
 | 
			
		||||
@@ -17,14 +17,14 @@
 | 
			
		||||
*/
 | 
			
		||||
//==============================================================================
 | 
			
		||||
 | 
			
		||||
#include <xrpld/nodestore/Factory.h>
 | 
			
		||||
#include <xrpld/nodestore/Manager.h>
 | 
			
		||||
#include <xrpld/nodestore/detail/DecodedBlob.h>
 | 
			
		||||
#include <xrpld/nodestore/detail/EncodedBlob.h>
 | 
			
		||||
#include <xrpld/nodestore/detail/codec.h>
 | 
			
		||||
 | 
			
		||||
#include <xrpl/basics/contract.h>
 | 
			
		||||
#include <xrpl/beast/core/LexicalCast.h>
 | 
			
		||||
#include <xrpl/beast/utility/instrumentation.h>
 | 
			
		||||
#include <xrpl/nodestore/Factory.h>
 | 
			
		||||
#include <xrpl/nodestore/Manager.h>
 | 
			
		||||
#include <xrpl/nodestore/detail/DecodedBlob.h>
 | 
			
		||||
#include <xrpl/nodestore/detail/EncodedBlob.h>
 | 
			
		||||
#include <xrpl/nodestore/detail/codec.h>
 | 
			
		||||
 | 
			
		||||
#include <boost/filesystem.hpp>
 | 
			
		||||
 | 
			
		||||
@@ -52,6 +52,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_;
 | 
			
		||||
@@ -66,6 +67,7 @@ public:
 | 
			
		||||
        , keyBytes_(keyBytes)
 | 
			
		||||
        , burstSize_(burstSize)
 | 
			
		||||
        , name_(get(keyValues, "path"))
 | 
			
		||||
        , blockSize_(parseBlockSize(name_, keyValues, journal))
 | 
			
		||||
        , deletePath_(false)
 | 
			
		||||
        , scheduler_(scheduler)
 | 
			
		||||
    {
 | 
			
		||||
@@ -85,6 +87,7 @@ public:
 | 
			
		||||
        , keyBytes_(keyBytes)
 | 
			
		||||
        , burstSize_(burstSize)
 | 
			
		||||
        , name_(get(keyValues, "path"))
 | 
			
		||||
        , blockSize_(parseBlockSize(name_, keyValues, journal))
 | 
			
		||||
        , db_(context)
 | 
			
		||||
        , deletePath_(false)
 | 
			
		||||
        , scheduler_(scheduler)
 | 
			
		||||
@@ -114,6 +117,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
 | 
			
		||||
@@ -145,7 +154,7 @@ public:
 | 
			
		||||
                uid,
 | 
			
		||||
                salt,
 | 
			
		||||
                keyBytes_,
 | 
			
		||||
                nudb::block_size(kp),
 | 
			
		||||
                blockSize_,
 | 
			
		||||
                0.50,
 | 
			
		||||
                ec);
 | 
			
		||||
            if (ec == nudb::errc::file_exists)
 | 
			
		||||
@@ -361,21 +370,69 @@ 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());
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
class NuDBFactory : public Factory
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    NuDBFactory()
 | 
			
		||||
    {
 | 
			
		||||
        Manager::instance().insert(*this);
 | 
			
		||||
    }
 | 
			
		||||
private:
 | 
			
		||||
    Manager& manager_;
 | 
			
		||||
 | 
			
		||||
    ~NuDBFactory() override
 | 
			
		||||
public:
 | 
			
		||||
    explicit NuDBFactory(Manager& manager) : manager_(manager)
 | 
			
		||||
    {
 | 
			
		||||
        Manager::instance().erase(*this);
 | 
			
		||||
        manager_.insert(*this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::string
 | 
			
		||||
@@ -410,7 +467,11 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static NuDBFactory nuDBFactory;
 | 
			
		||||
void
 | 
			
		||||
registerNuDBFactory(Manager& manager)
 | 
			
		||||
{
 | 
			
		||||
    static NuDBFactory instance{manager};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}  // namespace NodeStore
 | 
			
		||||
}  // namespace ripple
 | 
			
		||||
@@ -17,8 +17,8 @@
 | 
			
		||||
*/
 | 
			
		||||
//==============================================================================
 | 
			
		||||
 | 
			
		||||
#include <xrpld/nodestore/Factory.h>
 | 
			
		||||
#include <xrpld/nodestore/Manager.h>
 | 
			
		||||
#include <xrpl/nodestore/Factory.h>
 | 
			
		||||
#include <xrpl/nodestore/Manager.h>
 | 
			
		||||
 | 
			
		||||
#include <memory>
 | 
			
		||||
 | 
			
		||||
@@ -111,15 +111,13 @@ private:
 | 
			
		||||
 | 
			
		||||
class NullFactory : public Factory
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    NullFactory()
 | 
			
		||||
    {
 | 
			
		||||
        Manager::instance().insert(*this);
 | 
			
		||||
    }
 | 
			
		||||
private:
 | 
			
		||||
    Manager& manager_;
 | 
			
		||||
 | 
			
		||||
    ~NullFactory() override
 | 
			
		||||
public:
 | 
			
		||||
    explicit NullFactory(Manager& manager) : manager_(manager)
 | 
			
		||||
    {
 | 
			
		||||
        Manager::instance().erase(*this);
 | 
			
		||||
        manager_.insert(*this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::string
 | 
			
		||||
@@ -140,7 +138,11 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static NullFactory nullFactory;
 | 
			
		||||
void
 | 
			
		||||
registerNullFactory(Manager& manager)
 | 
			
		||||
{
 | 
			
		||||
    static NullFactory instance{manager};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}  // namespace NodeStore
 | 
			
		||||
}  // namespace ripple
 | 
			
		||||
@@ -17,20 +17,18 @@
 | 
			
		||||
*/
 | 
			
		||||
//==============================================================================
 | 
			
		||||
 | 
			
		||||
#include <xrpld/unity/rocksdb.h>
 | 
			
		||||
#include <xrpl/basics/rocksdb.h>
 | 
			
		||||
 | 
			
		||||
#if RIPPLE_ROCKSDB_AVAILABLE
 | 
			
		||||
#include <xrpld/core/Config.h>  // VFALCO Bad dependency
 | 
			
		||||
#include <xrpld/nodestore/Factory.h>
 | 
			
		||||
#include <xrpld/nodestore/Manager.h>
 | 
			
		||||
#include <xrpld/nodestore/detail/BatchWriter.h>
 | 
			
		||||
#include <xrpld/nodestore/detail/DecodedBlob.h>
 | 
			
		||||
#include <xrpld/nodestore/detail/EncodedBlob.h>
 | 
			
		||||
 | 
			
		||||
#include <xrpl/basics/ByteUtilities.h>
 | 
			
		||||
#include <xrpl/basics/contract.h>
 | 
			
		||||
#include <xrpl/basics/safe_cast.h>
 | 
			
		||||
#include <xrpl/beast/core/CurrentThreadName.h>
 | 
			
		||||
#include <xrpl/nodestore/Factory.h>
 | 
			
		||||
#include <xrpl/nodestore/Manager.h>
 | 
			
		||||
#include <xrpl/nodestore/detail/BatchWriter.h>
 | 
			
		||||
#include <xrpl/nodestore/detail/DecodedBlob.h>
 | 
			
		||||
#include <xrpl/nodestore/detail/EncodedBlob.h>
 | 
			
		||||
 | 
			
		||||
#include <atomic>
 | 
			
		||||
#include <memory>
 | 
			
		||||
@@ -461,17 +459,15 @@ public:
 | 
			
		||||
 | 
			
		||||
class RocksDBFactory : public Factory
 | 
			
		||||
{
 | 
			
		||||
private:
 | 
			
		||||
    Manager& manager_;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    RocksDBEnv m_env;
 | 
			
		||||
 | 
			
		||||
    RocksDBFactory()
 | 
			
		||||
    RocksDBFactory(Manager& manager) : manager_(manager)
 | 
			
		||||
    {
 | 
			
		||||
        Manager::instance().insert(*this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ~RocksDBFactory() override
 | 
			
		||||
    {
 | 
			
		||||
        Manager::instance().erase(*this);
 | 
			
		||||
        manager_.insert(*this);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    std::string
 | 
			
		||||
@@ -493,7 +489,11 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static RocksDBFactory rocksDBFactory;
 | 
			
		||||
void
 | 
			
		||||
registerRocksDBFactory(Manager& manager)
 | 
			
		||||
{
 | 
			
		||||
    static RocksDBFactory instance{manager};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
}  // namespace NodeStore
 | 
			
		||||
}  // namespace ripple
 | 
			
		||||
@@ -174,21 +174,22 @@ Permission::isDelegatable(
 | 
			
		||||
    auto const txType = permissionToTxType(permissionValue);
 | 
			
		||||
    auto const it = delegatableTx_.find(txType);
 | 
			
		||||
 | 
			
		||||
    if (rules.enabled(fixDelegateV1_1))
 | 
			
		||||
    {
 | 
			
		||||
        if (it == delegatableTx_.end())
 | 
			
		||||
            return false;
 | 
			
		||||
    if (it == delegatableTx_.end())
 | 
			
		||||
        return false;
 | 
			
		||||
 | 
			
		||||
        auto const feature = getTxFeature(txType);
 | 
			
		||||
    auto const txFeaturesIt = txFeatureMap_.find(txType);
 | 
			
		||||
    XRPL_ASSERT(
 | 
			
		||||
        txFeaturesIt != txFeatureMap_.end(),
 | 
			
		||||
        "ripple::Permissions::isDelegatable : tx exists in txFeatureMap_");
 | 
			
		||||
 | 
			
		||||
        // fixDelegateV1_1: Delegation is only allowed if the required amendment
 | 
			
		||||
        // for the transaction is enabled. For transactions that do not require
 | 
			
		||||
        // an amendment, delegation is always allowed.
 | 
			
		||||
        if (feature && !rules.enabled(*feature))
 | 
			
		||||
            return false;
 | 
			
		||||
    }
 | 
			
		||||
    // Delegation is only allowed if the required amendment for the transaction
 | 
			
		||||
    // is enabled. For transactions that do not require an amendment, delegation
 | 
			
		||||
    // is always allowed.
 | 
			
		||||
    if (txFeaturesIt->second != uint256{} &&
 | 
			
		||||
        !rules.enabled(txFeaturesIt->second))
 | 
			
		||||
        return false;
 | 
			
		||||
 | 
			
		||||
    if (it != delegatableTx_.end() && it->second == Delegation::notDelegatable)
 | 
			
		||||
    if (it->second == Delegation::notDelegatable)
 | 
			
		||||
        return false;
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
 
 | 
			
		||||
@@ -68,29 +68,6 @@
 | 
			
		||||
 | 
			
		||||
namespace ripple {
 | 
			
		||||
 | 
			
		||||
namespace {
 | 
			
		||||
 | 
			
		||||
// Use a static inside a function to help prevent order-of-initialzation issues
 | 
			
		||||
LocalValue<bool>&
 | 
			
		||||
getStaticSTAmountCanonicalizeSwitchover()
 | 
			
		||||
{
 | 
			
		||||
    static LocalValue<bool> r{true};
 | 
			
		||||
    return r;
 | 
			
		||||
}
 | 
			
		||||
}  // namespace
 | 
			
		||||
 | 
			
		||||
bool
 | 
			
		||||
getSTAmountCanonicalizeSwitchover()
 | 
			
		||||
{
 | 
			
		||||
    return *getStaticSTAmountCanonicalizeSwitchover();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
setSTAmountCanonicalizeSwitchover(bool v)
 | 
			
		||||
{
 | 
			
		||||
    *getStaticSTAmountCanonicalizeSwitchover() = v;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static std::uint64_t const tenTo14 = 100000000000000ull;
 | 
			
		||||
static std::uint64_t const tenTo14m1 = tenTo14 - 1;
 | 
			
		||||
static std::uint64_t const tenTo17 = tenTo14 * 1000;
 | 
			
		||||
@@ -884,18 +861,14 @@ STAmount::canonicalize()
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (getSTAmountCanonicalizeSwitchover())
 | 
			
		||||
        {
 | 
			
		||||
            // log(cMaxNativeN, 10) == 17
 | 
			
		||||
            if (native() && mOffset > 17)
 | 
			
		||||
                Throw<std::runtime_error>(
 | 
			
		||||
                    "Native currency amount out of range");
 | 
			
		||||
            // log(maxMPTokenAmount, 10) ~ 18.96
 | 
			
		||||
            if (mAsset.holds<MPTIssue>() && mOffset > 18)
 | 
			
		||||
                Throw<std::runtime_error>("MPT amount out of range");
 | 
			
		||||
        }
 | 
			
		||||
        // log(cMaxNativeN, 10) == 17
 | 
			
		||||
        if (native() && mOffset > 17)
 | 
			
		||||
            Throw<std::runtime_error>("Native currency amount out of range");
 | 
			
		||||
        // log(maxMPTokenAmount, 10) ~ 18.96
 | 
			
		||||
        if (mAsset.holds<MPTIssue>() && mOffset > 18)
 | 
			
		||||
            Throw<std::runtime_error>("MPT amount out of range");
 | 
			
		||||
 | 
			
		||||
        if (getSTNumberSwitchover() && getSTAmountCanonicalizeSwitchover())
 | 
			
		||||
        if (getSTNumberSwitchover())
 | 
			
		||||
        {
 | 
			
		||||
            Number num(
 | 
			
		||||
                mIsNegative ? -mValue : mValue, mOffset, Number::unchecked{});
 | 
			
		||||
@@ -919,16 +892,14 @@ STAmount::canonicalize()
 | 
			
		||||
 | 
			
		||||
            while (mOffset > 0)
 | 
			
		||||
            {
 | 
			
		||||
                if (getSTAmountCanonicalizeSwitchover())
 | 
			
		||||
                {
 | 
			
		||||
                    // N.B. do not move the overflow check to after the
 | 
			
		||||
                    // multiplication
 | 
			
		||||
                    if (native() && mValue > cMaxNativeN)
 | 
			
		||||
                        Throw<std::runtime_error>(
 | 
			
		||||
                            "Native currency amount out of range");
 | 
			
		||||
                    else if (!native() && mValue > maxMPTokenAmount)
 | 
			
		||||
                        Throw<std::runtime_error>("MPT amount out of range");
 | 
			
		||||
                }
 | 
			
		||||
                // N.B. do not move the overflow check to after the
 | 
			
		||||
                // multiplication
 | 
			
		||||
                if (native() && mValue > cMaxNativeN)
 | 
			
		||||
                    Throw<std::runtime_error>(
 | 
			
		||||
                        "Native currency amount out of range");
 | 
			
		||||
                else if (!native() && mValue > maxMPTokenAmount)
 | 
			
		||||
                    Throw<std::runtime_error>("MPT amount out of range");
 | 
			
		||||
 | 
			
		||||
                mValue *= 10;
 | 
			
		||||
                --mOffset;
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
@@ -688,6 +688,16 @@ STObject::getFieldV256(SField const& field) const
 | 
			
		||||
    return getFieldByConstRef<STVector256>(field, empty);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
STObject
 | 
			
		||||
STObject::getFieldObject(SField const& field) const
 | 
			
		||||
{
 | 
			
		||||
    STObject const empty{field};
 | 
			
		||||
    auto ret = getFieldByConstRef<STObject>(field, empty);
 | 
			
		||||
    if (ret != empty)
 | 
			
		||||
        ret.applyTemplateFromSField(field);
 | 
			
		||||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
STArray const&
 | 
			
		||||
STObject::getFieldArray(SField const& field) const
 | 
			
		||||
{
 | 
			
		||||
@@ -833,6 +843,12 @@ STObject::setFieldArray(SField const& field, STArray const& v)
 | 
			
		||||
    setFieldUsingAssignment(field, v);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
STObject::setFieldObject(SField const& field, STObject const& v)
 | 
			
		||||
{
 | 
			
		||||
    setFieldUsingAssignment(field, v);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Json::Value
 | 
			
		||||
STObject::getJson(JsonOptions options) const
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -200,11 +200,11 @@ STTx::getSigningHash() const
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Blob
 | 
			
		||||
STTx::getSignature() const
 | 
			
		||||
STTx::getSignature(STObject const& sigObject)
 | 
			
		||||
{
 | 
			
		||||
    try
 | 
			
		||||
    {
 | 
			
		||||
        return getFieldVL(sfTxnSignature);
 | 
			
		||||
        return sigObject.getFieldVL(sfTxnSignature);
 | 
			
		||||
    }
 | 
			
		||||
    catch (std::exception const&)
 | 
			
		||||
    {
 | 
			
		||||
@@ -234,35 +234,68 @@ STTx::getSeqValue() const
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
STTx::sign(PublicKey const& publicKey, SecretKey const& secretKey)
 | 
			
		||||
STTx::sign(
 | 
			
		||||
    PublicKey const& publicKey,
 | 
			
		||||
    SecretKey const& secretKey,
 | 
			
		||||
    std::optional<std::reference_wrapper<SField const>> signatureTarget)
 | 
			
		||||
{
 | 
			
		||||
    auto const data = getSigningData(*this);
 | 
			
		||||
 | 
			
		||||
    auto const sig = ripple::sign(publicKey, secretKey, makeSlice(data));
 | 
			
		||||
 | 
			
		||||
    setFieldVL(sfTxnSignature, sig);
 | 
			
		||||
    if (signatureTarget)
 | 
			
		||||
    {
 | 
			
		||||
        auto& target = peekFieldObject(*signatureTarget);
 | 
			
		||||
        target.setFieldVL(sfTxnSignature, sig);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        setFieldVL(sfTxnSignature, sig);
 | 
			
		||||
    }
 | 
			
		||||
    tid_ = getHash(HashPrefix::transactionID);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Expected<void, std::string>
 | 
			
		||||
STTx::checkSign(
 | 
			
		||||
    RequireFullyCanonicalSig requireCanonicalSig,
 | 
			
		||||
    Rules const& rules,
 | 
			
		||||
    STObject const& sigObject) const
 | 
			
		||||
{
 | 
			
		||||
    try
 | 
			
		||||
    {
 | 
			
		||||
        // Determine whether we're single- or multi-signing by looking
 | 
			
		||||
        // at the SigningPubKey.  If it's empty we must be
 | 
			
		||||
        // multi-signing.  Otherwise we're single-signing.
 | 
			
		||||
 | 
			
		||||
        Blob const& signingPubKey = sigObject.getFieldVL(sfSigningPubKey);
 | 
			
		||||
        return signingPubKey.empty()
 | 
			
		||||
            ? checkMultiSign(requireCanonicalSig, rules, sigObject)
 | 
			
		||||
            : checkSingleSign(requireCanonicalSig, sigObject);
 | 
			
		||||
    }
 | 
			
		||||
    catch (std::exception const&)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
    return Unexpected("Internal signature check failure.");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Expected<void, std::string>
 | 
			
		||||
STTx::checkSign(
 | 
			
		||||
    RequireFullyCanonicalSig requireCanonicalSig,
 | 
			
		||||
    Rules const& rules) const
 | 
			
		||||
{
 | 
			
		||||
    try
 | 
			
		||||
    if (auto const ret = checkSign(requireCanonicalSig, rules, *this); !ret)
 | 
			
		||||
        return ret;
 | 
			
		||||
 | 
			
		||||
    /* Placeholder for field that will be added by Lending Protocol
 | 
			
		||||
    if (isFieldPresent(sfCounterpartySignature))
 | 
			
		||||
    {
 | 
			
		||||
        // Determine whether we're single- or multi-signing by looking
 | 
			
		||||
        // at the SigningPubKey.  If it's empty we must be
 | 
			
		||||
        // multi-signing.  Otherwise we're single-signing.
 | 
			
		||||
        Blob const& signingPubKey = getFieldVL(sfSigningPubKey);
 | 
			
		||||
        return signingPubKey.empty()
 | 
			
		||||
            ? checkMultiSign(requireCanonicalSig, rules)
 | 
			
		||||
            : checkSingleSign(requireCanonicalSig);
 | 
			
		||||
        auto const counterSig = getFieldObject(sfCounterpartySignature);
 | 
			
		||||
        if (auto const ret = checkSign(requireCanonicalSig, rules, counterSig);
 | 
			
		||||
            !ret)
 | 
			
		||||
            return Unexpected("Counterparty: " + ret.error());
 | 
			
		||||
    }
 | 
			
		||||
    catch (std::exception const&)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
    return Unexpected("Internal signature check failure.");
 | 
			
		||||
    */
 | 
			
		||||
    return {};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Expected<void, std::string>
 | 
			
		||||
@@ -382,23 +415,23 @@ STTx::getMetaSQL(
 | 
			
		||||
 | 
			
		||||
static Expected<void, std::string>
 | 
			
		||||
singleSignHelper(
 | 
			
		||||
    STObject const& signer,
 | 
			
		||||
    STObject const& sigObject,
 | 
			
		||||
    Slice const& data,
 | 
			
		||||
    bool const fullyCanonical)
 | 
			
		||||
{
 | 
			
		||||
    // We don't allow both a non-empty sfSigningPubKey and an sfSigners.
 | 
			
		||||
    // That would allow the transaction to be signed two ways.  So if both
 | 
			
		||||
    // fields are present the signature is invalid.
 | 
			
		||||
    if (signer.isFieldPresent(sfSigners))
 | 
			
		||||
    if (sigObject.isFieldPresent(sfSigners))
 | 
			
		||||
        return Unexpected("Cannot both single- and multi-sign.");
 | 
			
		||||
 | 
			
		||||
    bool validSig = false;
 | 
			
		||||
    try
 | 
			
		||||
    {
 | 
			
		||||
        auto const spk = signer.getFieldVL(sfSigningPubKey);
 | 
			
		||||
        auto const spk = sigObject.getFieldVL(sfSigningPubKey);
 | 
			
		||||
        if (publicKeyType(makeSlice(spk)))
 | 
			
		||||
        {
 | 
			
		||||
            Blob const signature = signer.getFieldVL(sfTxnSignature);
 | 
			
		||||
            Blob const signature = sigObject.getFieldVL(sfTxnSignature);
 | 
			
		||||
            validSig = verify(
 | 
			
		||||
                PublicKey(makeSlice(spk)),
 | 
			
		||||
                data,
 | 
			
		||||
@@ -418,12 +451,14 @@ singleSignHelper(
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Expected<void, std::string>
 | 
			
		||||
STTx::checkSingleSign(RequireFullyCanonicalSig requireCanonicalSig) const
 | 
			
		||||
STTx::checkSingleSign(
 | 
			
		||||
    RequireFullyCanonicalSig requireCanonicalSig,
 | 
			
		||||
    STObject const& sigObject) const
 | 
			
		||||
{
 | 
			
		||||
    auto const data = getSigningData(*this);
 | 
			
		||||
    bool const fullyCanonical = (getFlags() & tfFullyCanonicalSig) ||
 | 
			
		||||
        (requireCanonicalSig == STTx::RequireFullyCanonicalSig::yes);
 | 
			
		||||
    return singleSignHelper(*this, makeSlice(data), fullyCanonical);
 | 
			
		||||
    return singleSignHelper(sigObject, makeSlice(data), fullyCanonical);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Expected<void, std::string>
 | 
			
		||||
@@ -440,31 +475,29 @@ STTx::checkBatchSingleSign(
 | 
			
		||||
 | 
			
		||||
Expected<void, std::string>
 | 
			
		||||
multiSignHelper(
 | 
			
		||||
    STObject const& signerObj,
 | 
			
		||||
    STObject const& sigObject,
 | 
			
		||||
    std::optional<AccountID> txnAccountID,
 | 
			
		||||
    bool const fullyCanonical,
 | 
			
		||||
    std::function<Serializer(AccountID const&)> makeMsg,
 | 
			
		||||
    Rules const& rules)
 | 
			
		||||
{
 | 
			
		||||
    // Make sure the MultiSigners are present.  Otherwise they are not
 | 
			
		||||
    // attempting multi-signing and we just have a bad SigningPubKey.
 | 
			
		||||
    if (!signerObj.isFieldPresent(sfSigners))
 | 
			
		||||
    if (!sigObject.isFieldPresent(sfSigners))
 | 
			
		||||
        return Unexpected("Empty SigningPubKey.");
 | 
			
		||||
 | 
			
		||||
    // We don't allow both an sfSigners and an sfTxnSignature.  Both fields
 | 
			
		||||
    // being present would indicate that the transaction is signed both ways.
 | 
			
		||||
    if (signerObj.isFieldPresent(sfTxnSignature))
 | 
			
		||||
    if (sigObject.isFieldPresent(sfTxnSignature))
 | 
			
		||||
        return Unexpected("Cannot both single- and multi-sign.");
 | 
			
		||||
 | 
			
		||||
    STArray const& signers{signerObj.getFieldArray(sfSigners)};
 | 
			
		||||
    STArray const& signers{sigObject.getFieldArray(sfSigners)};
 | 
			
		||||
 | 
			
		||||
    // There are well known bounds that the number of signers must be within.
 | 
			
		||||
    if (signers.size() < STTx::minMultiSigners ||
 | 
			
		||||
        signers.size() > STTx::maxMultiSigners(&rules))
 | 
			
		||||
        return Unexpected("Invalid Signers array size.");
 | 
			
		||||
 | 
			
		||||
    // We also use the sfAccount field inside the loop.  Get it once.
 | 
			
		||||
    auto const txnAccountID = signerObj.getAccountID(sfAccount);
 | 
			
		||||
 | 
			
		||||
    // Signers must be in sorted order by AccountID.
 | 
			
		||||
    AccountID lastAccountID(beast::zero);
 | 
			
		||||
 | 
			
		||||
@@ -472,8 +505,10 @@ multiSignHelper(
 | 
			
		||||
    {
 | 
			
		||||
        auto const accountID = signer.getAccountID(sfAccount);
 | 
			
		||||
 | 
			
		||||
        // The account owner may not multisign for themselves.
 | 
			
		||||
        if (accountID == txnAccountID)
 | 
			
		||||
        // The account owner may not usually multisign for themselves.
 | 
			
		||||
        // If they can, txnAccountID will be unseated, which is not equal to any
 | 
			
		||||
        // value.
 | 
			
		||||
        if (txnAccountID == accountID)
 | 
			
		||||
            return Unexpected("Invalid multisigner.");
 | 
			
		||||
 | 
			
		||||
        // No duplicate signers allowed.
 | 
			
		||||
@@ -489,6 +524,7 @@ multiSignHelper(
 | 
			
		||||
 | 
			
		||||
        // Verify the signature.
 | 
			
		||||
        bool validSig = false;
 | 
			
		||||
        std::optional<std::string> errorWhat;
 | 
			
		||||
        try
 | 
			
		||||
        {
 | 
			
		||||
            auto spk = signer.getFieldVL(sfSigningPubKey);
 | 
			
		||||
@@ -502,15 +538,16 @@ multiSignHelper(
 | 
			
		||||
                    fullyCanonical);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        catch (std::exception const&)
 | 
			
		||||
        catch (std::exception const& e)
 | 
			
		||||
        {
 | 
			
		||||
            // We assume any problem lies with the signature.
 | 
			
		||||
            validSig = false;
 | 
			
		||||
            errorWhat = e.what();
 | 
			
		||||
        }
 | 
			
		||||
        if (!validSig)
 | 
			
		||||
            return Unexpected(
 | 
			
		||||
                std::string("Invalid signature on account ") +
 | 
			
		||||
                toBase58(accountID) + ".");
 | 
			
		||||
                toBase58(accountID) + errorWhat.value_or("") + ".");
 | 
			
		||||
    }
 | 
			
		||||
    // All signatures verified.
 | 
			
		||||
    return {};
 | 
			
		||||
@@ -532,8 +569,9 @@ STTx::checkBatchMultiSign(
 | 
			
		||||
    serializeBatch(dataStart, getFlags(), getBatchTransactionIDs());
 | 
			
		||||
    return multiSignHelper(
 | 
			
		||||
        batchSigner,
 | 
			
		||||
        std::nullopt,
 | 
			
		||||
        fullyCanonical,
 | 
			
		||||
        [&dataStart](AccountID const& accountID) mutable -> Serializer {
 | 
			
		||||
        [&dataStart](AccountID const& accountID) -> Serializer {
 | 
			
		||||
            Serializer s = dataStart;
 | 
			
		||||
            finishMultiSigningData(accountID, s);
 | 
			
		||||
            return s;
 | 
			
		||||
@@ -544,19 +582,27 @@ STTx::checkBatchMultiSign(
 | 
			
		||||
Expected<void, std::string>
 | 
			
		||||
STTx::checkMultiSign(
 | 
			
		||||
    RequireFullyCanonicalSig requireCanonicalSig,
 | 
			
		||||
    Rules const& rules) const
 | 
			
		||||
    Rules const& rules,
 | 
			
		||||
    STObject const& sigObject) const
 | 
			
		||||
{
 | 
			
		||||
    bool const fullyCanonical = (getFlags() & tfFullyCanonicalSig) ||
 | 
			
		||||
        (requireCanonicalSig == RequireFullyCanonicalSig::yes);
 | 
			
		||||
 | 
			
		||||
    // Used inside the loop in multiSignHelper to enforce that
 | 
			
		||||
    // the account owner may not multisign for themselves.
 | 
			
		||||
    auto const txnAccountID = &sigObject != this
 | 
			
		||||
        ? std::nullopt
 | 
			
		||||
        : std::optional<AccountID>(getAccountID(sfAccount));
 | 
			
		||||
 | 
			
		||||
    // We can ease the computational load inside the loop a bit by
 | 
			
		||||
    // pre-constructing part of the data that we hash.  Fill a Serializer
 | 
			
		||||
    // with the stuff that stays constant from signature to signature.
 | 
			
		||||
    Serializer dataStart = startMultiSigningData(*this);
 | 
			
		||||
    return multiSignHelper(
 | 
			
		||||
        *this,
 | 
			
		||||
        sigObject,
 | 
			
		||||
        txnAccountID,
 | 
			
		||||
        fullyCanonical,
 | 
			
		||||
        [&dataStart](AccountID const& accountID) mutable -> Serializer {
 | 
			
		||||
        [&dataStart](AccountID const& accountID) -> Serializer {
 | 
			
		||||
            Serializer s = dataStart;
 | 
			
		||||
            finishMultiSigningData(accountID, s);
 | 
			
		||||
            return s;
 | 
			
		||||
@@ -569,7 +615,7 @@ STTx::checkMultiSign(
 | 
			
		||||
 *
 | 
			
		||||
 * This function returns a vector of transaction IDs by extracting them from
 | 
			
		||||
 * the field array `sfRawTransactions` within the STTx. If the batch
 | 
			
		||||
 * transaction IDs have already been computed and cached in `batch_txn_ids_`,
 | 
			
		||||
 * transaction IDs have already been computed and cached in `batchTxnIds_`,
 | 
			
		||||
 * it returns the cached vector. Otherwise, it computes the transaction IDs,
 | 
			
		||||
 * caches them, and then returns the vector.
 | 
			
		||||
 *
 | 
			
		||||
@@ -579,7 +625,7 @@ STTx::checkMultiSign(
 | 
			
		||||
 * empty and that the size of the computed batch transaction IDs matches the
 | 
			
		||||
 * size of the `sfRawTransactions` field array.
 | 
			
		||||
 */
 | 
			
		||||
std::vector<uint256>
 | 
			
		||||
std::vector<uint256> const&
 | 
			
		||||
STTx::getBatchTransactionIDs() const
 | 
			
		||||
{
 | 
			
		||||
    XRPL_ASSERT(
 | 
			
		||||
@@ -588,16 +634,20 @@ STTx::getBatchTransactionIDs() const
 | 
			
		||||
    XRPL_ASSERT(
 | 
			
		||||
        getFieldArray(sfRawTransactions).size() != 0,
 | 
			
		||||
        "STTx::getBatchTransactionIDs : empty raw transactions");
 | 
			
		||||
    if (batch_txn_ids_.size() != 0)
 | 
			
		||||
        return batch_txn_ids_;
 | 
			
		||||
 | 
			
		||||
    for (STObject const& rb : getFieldArray(sfRawTransactions))
 | 
			
		||||
        batch_txn_ids_.push_back(rb.getHash(HashPrefix::transactionID));
 | 
			
		||||
    // The list of inner ids is built once, then reused on subsequent calls.
 | 
			
		||||
    // After the list is built, it must always have the same size as the array
 | 
			
		||||
    // `sfRawTransactions`. The assert below verifies that.
 | 
			
		||||
    if (batchTxnIds_.size() == 0)
 | 
			
		||||
    {
 | 
			
		||||
        for (STObject const& rb : getFieldArray(sfRawTransactions))
 | 
			
		||||
            batchTxnIds_.push_back(rb.getHash(HashPrefix::transactionID));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    XRPL_ASSERT(
 | 
			
		||||
        batch_txn_ids_.size() == getFieldArray(sfRawTransactions).size(),
 | 
			
		||||
        batchTxnIds_.size() == getFieldArray(sfRawTransactions).size(),
 | 
			
		||||
        "STTx::getBatchTransactionIDs : batch transaction IDs size mismatch");
 | 
			
		||||
    return batch_txn_ids_;
 | 
			
		||||
    return batchTxnIds_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 
 | 
			
		||||
@@ -127,7 +127,6 @@ transResults()
 | 
			
		||||
        MAKE_ERROR(tecLIMIT_EXCEEDED,                "Limit exceeded."),
 | 
			
		||||
        MAKE_ERROR(tecPSEUDO_ACCOUNT,                "This operation is not allowed against a pseudo-account."),
 | 
			
		||||
        MAKE_ERROR(tecPRECISION_LOSS,                "The amounts used by the transaction cannot interact."),
 | 
			
		||||
        MAKE_ERROR(tecNO_DELEGATE_PERMISSION,        "Delegated account lacks permission to perform this transaction."),
 | 
			
		||||
 | 
			
		||||
        MAKE_ERROR(tefALREADY,                     "The exact transaction was already in this ledger."),
 | 
			
		||||
        MAKE_ERROR(tefBAD_ADD_AUTH,                "Not authorized to add account."),
 | 
			
		||||
@@ -235,6 +234,7 @@ transResults()
 | 
			
		||||
        MAKE_ERROR(terPRE_TICKET,             "Ticket is not yet in ledger."),
 | 
			
		||||
        MAKE_ERROR(terNO_AMM,                 "AMM doesn't exist for the asset pair."),
 | 
			
		||||
        MAKE_ERROR(terADDRESS_COLLISION,      "Failed to allocate an unique account address."),
 | 
			
		||||
        MAKE_ERROR(terNO_DELEGATE_PERMISSION, "Delegated account lacks permission to perform this transaction."),
 | 
			
		||||
 | 
			
		||||
        MAKE_ERROR(tesSUCCESS,                "The transaction was applied. Only final in a validated ledger."),
 | 
			
		||||
    };
 | 
			
		||||
 
 | 
			
		||||
@@ -39,35 +39,13 @@
 | 
			
		||||
 | 
			
		||||
namespace ripple {
 | 
			
		||||
 | 
			
		||||
template <class T>
 | 
			
		||||
TxMeta::TxMeta(
 | 
			
		||||
    uint256 const& txid,
 | 
			
		||||
    std::uint32_t ledger,
 | 
			
		||||
    T const& data,
 | 
			
		||||
    CtorHelper)
 | 
			
		||||
    : mTransactionID(txid), mLedger(ledger), mNodes(sfAffectedNodes, 32)
 | 
			
		||||
{
 | 
			
		||||
    SerialIter sit(makeSlice(data));
 | 
			
		||||
 | 
			
		||||
    STObject obj(sit, sfMetadata);
 | 
			
		||||
    mResult = obj.getFieldU8(sfTransactionResult);
 | 
			
		||||
    mIndex = obj.getFieldU32(sfTransactionIndex);
 | 
			
		||||
    mNodes = *dynamic_cast<STArray*>(&obj.getField(sfAffectedNodes));
 | 
			
		||||
 | 
			
		||||
    if (obj.isFieldPresent(sfDeliveredAmount))
 | 
			
		||||
        setDeliveredAmount(obj.getFieldAmount(sfDeliveredAmount));
 | 
			
		||||
 | 
			
		||||
    if (obj.isFieldPresent(sfParentBatchID))
 | 
			
		||||
        setParentBatchId(obj.getFieldH256(sfParentBatchID));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TxMeta::TxMeta(uint256 const& txid, std::uint32_t ledger, STObject const& obj)
 | 
			
		||||
    : mTransactionID(txid)
 | 
			
		||||
    , mLedger(ledger)
 | 
			
		||||
    , mNodes(obj.getFieldArray(sfAffectedNodes))
 | 
			
		||||
    : transactionID_(txid)
 | 
			
		||||
    , ledgerSeq_(ledger)
 | 
			
		||||
    , nodes_(obj.getFieldArray(sfAffectedNodes))
 | 
			
		||||
{
 | 
			
		||||
    mResult = obj.getFieldU8(sfTransactionResult);
 | 
			
		||||
    mIndex = obj.getFieldU32(sfTransactionIndex);
 | 
			
		||||
    result_ = obj.getFieldU8(sfTransactionResult);
 | 
			
		||||
    index_ = obj.getFieldU32(sfTransactionIndex);
 | 
			
		||||
 | 
			
		||||
    auto affectedNodes =
 | 
			
		||||
        dynamic_cast<STArray const*>(obj.peekAtPField(sfAffectedNodes));
 | 
			
		||||
@@ -75,40 +53,32 @@ TxMeta::TxMeta(uint256 const& txid, std::uint32_t ledger, STObject const& obj)
 | 
			
		||||
        affectedNodes,
 | 
			
		||||
        "ripple::TxMeta::TxMeta(STObject) : type cast succeeded");
 | 
			
		||||
    if (affectedNodes)
 | 
			
		||||
        mNodes = *affectedNodes;
 | 
			
		||||
        nodes_ = *affectedNodes;
 | 
			
		||||
 | 
			
		||||
    if (obj.isFieldPresent(sfDeliveredAmount))
 | 
			
		||||
        setDeliveredAmount(obj.getFieldAmount(sfDeliveredAmount));
 | 
			
		||||
 | 
			
		||||
    if (obj.isFieldPresent(sfParentBatchID))
 | 
			
		||||
        setParentBatchId(obj.getFieldH256(sfParentBatchID));
 | 
			
		||||
    setAdditionalFields(obj);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TxMeta::TxMeta(uint256 const& txid, std::uint32_t ledger, Blob const& vec)
 | 
			
		||||
    : TxMeta(txid, ledger, vec, CtorHelper())
 | 
			
		||||
    : transactionID_(txid), ledgerSeq_(ledger), nodes_(sfAffectedNodes, 32)
 | 
			
		||||
{
 | 
			
		||||
    SerialIter sit(makeSlice(vec));
 | 
			
		||||
 | 
			
		||||
    STObject obj(sit, sfMetadata);
 | 
			
		||||
    result_ = obj.getFieldU8(sfTransactionResult);
 | 
			
		||||
    index_ = obj.getFieldU32(sfTransactionIndex);
 | 
			
		||||
    nodes_ = obj.getFieldArray(sfAffectedNodes);
 | 
			
		||||
 | 
			
		||||
    setAdditionalFields(obj);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TxMeta::TxMeta(
 | 
			
		||||
    uint256 const& txid,
 | 
			
		||||
    std::uint32_t ledger,
 | 
			
		||||
    std::string const& data)
 | 
			
		||||
    : TxMeta(txid, ledger, data, CtorHelper())
 | 
			
		||||
TxMeta::TxMeta(uint256 const& transactionID, std::uint32_t ledger)
 | 
			
		||||
    : transactionID_(transactionID)
 | 
			
		||||
    , ledgerSeq_(ledger)
 | 
			
		||||
    , index_(std::numeric_limits<std::uint32_t>::max())
 | 
			
		||||
    , result_(255)
 | 
			
		||||
    , nodes_(sfAffectedNodes)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TxMeta::TxMeta(
 | 
			
		||||
    uint256 const& transactionID,
 | 
			
		||||
    std::uint32_t ledger,
 | 
			
		||||
    std::optional<uint256> parentBatchId)
 | 
			
		||||
    : mTransactionID(transactionID)
 | 
			
		||||
    , mLedger(ledger)
 | 
			
		||||
    , mIndex(static_cast<std::uint32_t>(-1))
 | 
			
		||||
    , mResult(255)
 | 
			
		||||
    , mParentBatchId(parentBatchId)
 | 
			
		||||
    , mNodes(sfAffectedNodes)
 | 
			
		||||
{
 | 
			
		||||
    mNodes.reserve(32);
 | 
			
		||||
    nodes_.reserve(32);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
@@ -118,7 +88,7 @@ TxMeta::setAffectedNode(
 | 
			
		||||
    std::uint16_t nodeType)
 | 
			
		||||
{
 | 
			
		||||
    // make sure the node exists and force its type
 | 
			
		||||
    for (auto& n : mNodes)
 | 
			
		||||
    for (auto& n : nodes_)
 | 
			
		||||
    {
 | 
			
		||||
        if (n.getFieldH256(sfLedgerIndex) == node)
 | 
			
		||||
        {
 | 
			
		||||
@@ -128,8 +98,8 @@ TxMeta::setAffectedNode(
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    mNodes.push_back(STObject(type));
 | 
			
		||||
    STObject& obj = mNodes.back();
 | 
			
		||||
    nodes_.push_back(STObject(type));
 | 
			
		||||
    STObject& obj = nodes_.back();
 | 
			
		||||
 | 
			
		||||
    XRPL_ASSERT(
 | 
			
		||||
        obj.getFName() == type,
 | 
			
		||||
@@ -146,14 +116,15 @@ TxMeta::getAffectedAccounts() const
 | 
			
		||||
 | 
			
		||||
    // This code should match the behavior of the JS method:
 | 
			
		||||
    // Meta#getAffectedAccounts
 | 
			
		||||
    for (auto const& it : mNodes)
 | 
			
		||||
    for (auto const& node : nodes_)
 | 
			
		||||
    {
 | 
			
		||||
        int index = it.getFieldIndex(
 | 
			
		||||
            (it.getFName() == sfCreatedNode) ? sfNewFields : sfFinalFields);
 | 
			
		||||
        int index = node.getFieldIndex(
 | 
			
		||||
            (node.getFName() == sfCreatedNode) ? sfNewFields : sfFinalFields);
 | 
			
		||||
 | 
			
		||||
        if (index != -1)
 | 
			
		||||
        {
 | 
			
		||||
            auto inner = dynamic_cast<STObject const*>(&it.peekAtIndex(index));
 | 
			
		||||
            auto const* inner =
 | 
			
		||||
                dynamic_cast<STObject const*>(&node.peekAtIndex(index));
 | 
			
		||||
            XRPL_ASSERT(
 | 
			
		||||
                inner,
 | 
			
		||||
                "ripple::getAffectedAccounts : STObject type cast succeeded");
 | 
			
		||||
@@ -213,13 +184,13 @@ STObject&
 | 
			
		||||
TxMeta::getAffectedNode(SLE::ref node, SField const& type)
 | 
			
		||||
{
 | 
			
		||||
    uint256 index = node->key();
 | 
			
		||||
    for (auto& n : mNodes)
 | 
			
		||||
    for (auto& n : nodes_)
 | 
			
		||||
    {
 | 
			
		||||
        if (n.getFieldH256(sfLedgerIndex) == index)
 | 
			
		||||
            return n;
 | 
			
		||||
    }
 | 
			
		||||
    mNodes.push_back(STObject(type));
 | 
			
		||||
    STObject& obj = mNodes.back();
 | 
			
		||||
    nodes_.push_back(STObject(type));
 | 
			
		||||
    STObject& obj = nodes_.back();
 | 
			
		||||
 | 
			
		||||
    XRPL_ASSERT(
 | 
			
		||||
        obj.getFName() == type,
 | 
			
		||||
@@ -233,7 +204,7 @@ TxMeta::getAffectedNode(SLE::ref node, SField const& type)
 | 
			
		||||
STObject&
 | 
			
		||||
TxMeta::getAffectedNode(uint256 const& node)
 | 
			
		||||
{
 | 
			
		||||
    for (auto& n : mNodes)
 | 
			
		||||
    for (auto& n : nodes_)
 | 
			
		||||
    {
 | 
			
		||||
        if (n.getFieldH256(sfLedgerIndex) == node)
 | 
			
		||||
            return n;
 | 
			
		||||
@@ -241,7 +212,7 @@ TxMeta::getAffectedNode(uint256 const& node)
 | 
			
		||||
    // LCOV_EXCL_START
 | 
			
		||||
    UNREACHABLE("ripple::TxMeta::getAffectedNode(uint256) : node not found");
 | 
			
		||||
    Throw<std::runtime_error>("Affected node not found");
 | 
			
		||||
    return *(mNodes.begin());  // Silence compiler warning.
 | 
			
		||||
    return *(nodes_.begin());  // Silence compiler warning.
 | 
			
		||||
    // LCOV_EXCL_STOP
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -249,15 +220,15 @@ STObject
 | 
			
		||||
TxMeta::getAsObject() const
 | 
			
		||||
{
 | 
			
		||||
    STObject metaData(sfTransactionMetaData);
 | 
			
		||||
    XRPL_ASSERT(mResult != 255, "ripple::TxMeta::getAsObject : result is set");
 | 
			
		||||
    metaData.setFieldU8(sfTransactionResult, mResult);
 | 
			
		||||
    metaData.setFieldU32(sfTransactionIndex, mIndex);
 | 
			
		||||
    metaData.emplace_back(mNodes);
 | 
			
		||||
    if (hasDeliveredAmount())
 | 
			
		||||
        metaData.setFieldAmount(sfDeliveredAmount, getDeliveredAmount());
 | 
			
		||||
    XRPL_ASSERT(result_ != 255, "ripple::TxMeta::getAsObject : result_ is set");
 | 
			
		||||
    metaData.setFieldU8(sfTransactionResult, result_);
 | 
			
		||||
    metaData.setFieldU32(sfTransactionIndex, index_);
 | 
			
		||||
    metaData.emplace_back(nodes_);
 | 
			
		||||
    if (deliveredAmount_.has_value())
 | 
			
		||||
        metaData.setFieldAmount(sfDeliveredAmount, *deliveredAmount_);
 | 
			
		||||
 | 
			
		||||
    if (hasParentBatchId())
 | 
			
		||||
        metaData.setFieldH256(sfParentBatchID, getParentBatchId());
 | 
			
		||||
    if (parentBatchID_.has_value())
 | 
			
		||||
        metaData.setFieldH256(sfParentBatchID, *parentBatchID_);
 | 
			
		||||
 | 
			
		||||
    return metaData;
 | 
			
		||||
}
 | 
			
		||||
@@ -265,13 +236,13 @@ TxMeta::getAsObject() const
 | 
			
		||||
void
 | 
			
		||||
TxMeta::addRaw(Serializer& s, TER result, std::uint32_t index)
 | 
			
		||||
{
 | 
			
		||||
    mResult = TERtoInt(result);
 | 
			
		||||
    mIndex = index;
 | 
			
		||||
    result_ = TERtoInt(result);
 | 
			
		||||
    index_ = index;
 | 
			
		||||
    XRPL_ASSERT(
 | 
			
		||||
        (mResult == 0) || ((mResult > 100) && (mResult <= 255)),
 | 
			
		||||
        (result_ == 0) || ((result_ > 100) && (result_ <= 255)),
 | 
			
		||||
        "ripple::TxMeta::addRaw : valid TER input");
 | 
			
		||||
 | 
			
		||||
    mNodes.sort([](STObject const& o1, STObject const& o2) {
 | 
			
		||||
    nodes_.sort([](STObject const& o1, STObject const& o2) {
 | 
			
		||||
        return o1.getFieldH256(sfLedgerIndex) < o2.getFieldH256(sfLedgerIndex);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -148,6 +148,12 @@ Consumer::entry()
 | 
			
		||||
    return *m_entry;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
Consumer::setPublicKey(PublicKey const& publicKey)
 | 
			
		||||
{
 | 
			
		||||
    m_entry->publicKey = publicKey;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::ostream&
 | 
			
		||||
operator<<(std::ostream& os, Consumer const& v)
 | 
			
		||||
{
 | 
			
		||||
 
 | 
			
		||||
@@ -17,15 +17,14 @@
 | 
			
		||||
*/
 | 
			
		||||
//==============================================================================
 | 
			
		||||
 | 
			
		||||
#include <xrpld/shamap/SHAMap.h>
 | 
			
		||||
#include <xrpld/shamap/SHAMapAccountStateLeafNode.h>
 | 
			
		||||
#include <xrpld/shamap/SHAMapNodeID.h>
 | 
			
		||||
#include <xrpld/shamap/SHAMapSyncFilter.h>
 | 
			
		||||
#include <xrpld/shamap/SHAMapTxLeafNode.h>
 | 
			
		||||
#include <xrpld/shamap/SHAMapTxPlusMetaLeafNode.h>
 | 
			
		||||
 | 
			
		||||
#include <xrpl/basics/TaggedCache.ipp>
 | 
			
		||||
#include <xrpl/basics/contract.h>
 | 
			
		||||
#include <xrpl/shamap/SHAMap.h>
 | 
			
		||||
#include <xrpl/shamap/SHAMapAccountStateLeafNode.h>
 | 
			
		||||
#include <xrpl/shamap/SHAMapNodeID.h>
 | 
			
		||||
#include <xrpl/shamap/SHAMapSyncFilter.h>
 | 
			
		||||
#include <xrpl/shamap/SHAMapTxLeafNode.h>
 | 
			
		||||
#include <xrpl/shamap/SHAMapTxPlusMetaLeafNode.h>
 | 
			
		||||
 | 
			
		||||
namespace ripple {
 | 
			
		||||
 | 
			
		||||
@@ -17,10 +17,9 @@
 | 
			
		||||
*/
 | 
			
		||||
//==============================================================================
 | 
			
		||||
 | 
			
		||||
#include <xrpld/shamap/SHAMap.h>
 | 
			
		||||
 | 
			
		||||
#include <xrpl/basics/IntrusivePointer.ipp>
 | 
			
		||||
#include <xrpl/basics/contract.h>
 | 
			
		||||
#include <xrpl/shamap/SHAMap.h>
 | 
			
		||||
 | 
			
		||||
#include <array>
 | 
			
		||||
#include <stack>
 | 
			
		||||
@@ -17,16 +17,15 @@
 | 
			
		||||
*/
 | 
			
		||||
//==============================================================================
 | 
			
		||||
 | 
			
		||||
#include <xrpld/shamap/SHAMapInnerNode.h>
 | 
			
		||||
#include <xrpld/shamap/SHAMapTreeNode.h>
 | 
			
		||||
#include <xrpld/shamap/detail/TaggedPointer.ipp>
 | 
			
		||||
 | 
			
		||||
#include <xrpl/basics/IntrusivePointer.ipp>
 | 
			
		||||
#include <xrpl/basics/Slice.h>
 | 
			
		||||
#include <xrpl/basics/contract.h>
 | 
			
		||||
#include <xrpl/basics/spinlock.h>
 | 
			
		||||
#include <xrpl/protocol/HashPrefix.h>
 | 
			
		||||
#include <xrpl/protocol/digest.h>
 | 
			
		||||
#include <xrpl/shamap/SHAMapInnerNode.h>
 | 
			
		||||
#include <xrpl/shamap/SHAMapTreeNode.h>
 | 
			
		||||
#include <xrpl/shamap/detail/TaggedPointer.ipp>
 | 
			
		||||
 | 
			
		||||
namespace ripple {
 | 
			
		||||
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user