Compare commits

..

45 Commits

Author SHA1 Message Date
copilot-swe-agent[bot]
f956135e29 Merge remote-tracking branch 'origin/develop' into copilot/refactor-replace-boost-filesystem
# Conflicts:
#	src/test/app/GRPCServerTLS_test.cpp
#	src/test/app/SHAMapStore_test.cpp
#	src/xrpld/app/misc/SHAMapStoreImp.cpp
#	src/xrpld/app/rdb/backend/detail/Node.cpp
#	src/xrpld/core/detail/Config.cpp
2026-06-11 12:28:23 +00:00
Zhiyuan Wang
09c36d066e fix: Correct hybrid offer deletion on credential expiry (#6843)
Co-authored-by: Bart <bthomee@users.noreply.github.com>
2026-06-10 20:42:41 +00:00
Ayaz Salikhov
2f6b466feb ci: Make sanitizer flags lists in the profile, not a string (#7449) 2026-06-10 18:24:34 +00:00
Ayaz Salikhov
8000adfa79 ci: Make configurations launch on certain event types (#7447) 2026-06-10 18:08:34 +00:00
Shi Cheng
1f359f719c fix: Add [[maybe_unused]] to fix320Enabled for assert=OFF builds (#7446)
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 17:24:44 +00:00
Ayaz Salikhov
dd0b6754d4 ci: Add gh and file to nix packages (#7444) 2026-06-10 14:45:51 +00:00
Vito Tumas
83cc5df72e fix: Disable transaction invariants (#7409) 2026-06-10 12:05:53 +00:00
Vito Tumas
97ca7d57bc perf: Dispatch "hasInvalidAmount()" on type tag instead of dynamic_cast (#7402) 2026-06-10 11:44:57 +00:00
Pratik Mankawde
8a4bf2dee6 refactor: Retire fixUniversalNumber amendment (#5962)
Signed-off-by: Pratik Mankawde <pmankawde@ripple.com>
Signed-off-by: Pratik Mankawde <3397372+pratikmankawde@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-10 10:16:03 +00:00
Bart
742aa0878b test: Do not create data directory for memory databases (#7323)
Co-authored-by: Bart <11445373+bthomee@users.noreply.github.com>
2026-06-10 09:16:53 +00:00
Ayaz Salikhov
8617eaeb26 ci: Launch upload-conan-deps on profile change (#7442) 2026-06-10 00:00:19 +00:00
Ed Hennis
2cbc3c139e fix: Fix Number comparison operator (#7406) 2026-06-09 17:46:56 +00:00
Ayaz Salikhov
fccb109e48 feat: Use C++ 23 standard (#7431) 2026-06-09 17:36:17 +00:00
Vito Tumas
0fb1aca461 refactor: Introduce XRPL_ASSERT_IF for amendment-gated assertions (#7378)
Co-authored-by: xrplf-ai-reviewer[bot] <266832837+xrplf-ai-reviewer[bot]@users.noreply.github.com>
2026-06-09 17:02:06 +00:00
Bart
c552eb333f refactor: Change config section and key string literals into constants (#7095)
Co-authored-by: Bart <11445373+bthomee@users.noreply.github.com>
2026-06-09 14:58:21 +00:00
Bart
c9769d1add refactor: Use std::move and std::string_view where possible (#7424)
Co-authored-by: Bart <11445373+bthomee@users.noreply.github.com>
2026-06-09 13:56:32 +00:00
Bart
ee9fbc4e08 refactor: Use const function arguments where possible (#7423)
Co-authored-by: Bart <11445373+bthomee@users.noreply.github.com>
2026-06-09 10:04:09 +00:00
Ayaz Salikhov
577d7457f1 ci: Use XRPLF/actions build-multiarch-image workflow (#7428) 2026-06-08 17:10:05 +00:00
Ayaz Salikhov
a389f922dd ci: Use new packaging images and don't cancel develop builds (#7417)
Co-authored-by: Bart <bthomee@users.noreply.github.com>
2026-06-08 13:41:08 +00:00
copilot-swe-agent[bot]
3e4422df28 Merge remote-tracking branch 'origin/develop' into copilot/refactor-replace-boost-filesystem
# Conflicts:
#	src/xrpld/core/Config.h
#	src/xrpld/core/detail/Config.cpp
2026-05-27 20:55:29 +00:00
copilot-swe-agent[bot]
9f5bf51b31 Merge branch 'develop' of https://github.com/XRPLF/rippled into copilot/refactor-replace-boost-filesystem
# Conflicts:
#	src/libxrpl/server/Vacuum.cpp
#	src/test/app/GRPCServerTLS_test.cpp
#	src/xrpld/app/rdb/backend/detail/Node.cpp
#	src/xrpld/core/detail/Config.cpp

Co-authored-by: mvadari <8029314+mvadari@users.noreply.github.com>
2026-05-15 17:38:01 +00:00
copilot-swe-agent[bot]
9ccb7742ca fix: Use std::filesystem::absolute(base/p) to match boost::filesystem::absolute(p,base) behavior
Agent-Logs-Url: https://github.com/XRPLF/rippled/sessions/41d17280-3340-4246-97d4-06f2bcf365cb

Co-authored-by: mathbunnyru <12270691+mathbunnyru@users.noreply.github.com>
2026-05-07 09:42:04 +00:00
copilot-swe-agent[bot]
336b9c101e refactor: use beast::uniqueRandomPath in SHAMapStoreImp makeBackendRotating
Agent-Logs-Url: https://github.com/XRPLF/rippled/sessions/3807ab03-d6e1-4466-a2b9-b7512b943bba

Co-authored-by: mathbunnyru <12270691+mathbunnyru@users.noreply.github.com>
2026-05-07 09:31:41 +00:00
Ayaz Salikhov
5fdbedf6ac Merge branch 'develop' into copilot/refactor-replace-boost-filesystem 2026-05-07 10:17:31 +01:00
copilot-swe-agent[bot]
ce4490d793 Merge origin/develop: resolve conflicts (keep std::filesystem, add IWYU pragmas)
Agent-Logs-Url: https://github.com/XRPLF/rippled/sessions/56410194-a137-4a12-ad17-fc4fffb31d86

Co-authored-by: mathbunnyru <12270691+mathbunnyru@users.noreply.github.com>
2026-05-07 08:55:53 +00:00
copilot-swe-agent[bot]
ba2ff93d6e style: fix clang-format in temp_dir.h (collapse throw statement to one line)
Agent-Logs-Url: https://github.com/XRPLF/rippled/sessions/8ef69f5f-e752-47b2-a4a3-2746d0dbfe78

Co-authored-by: mathbunnyru <12270691+mathbunnyru@users.noreply.github.com>
2026-05-06 10:21:10 +00:00
copilot-swe-agent[bot]
4714160052 refactor: add prefix param to uniqueRandomPath, use in GRPCServerTLS_test
Agent-Logs-Url: https://github.com/XRPLF/rippled/sessions/a8d8f682-0faf-4cb5-a330-39dc6fb7408f

Co-authored-by: mathbunnyru <12270691+mathbunnyru@users.noreply.github.com>
2026-05-06 10:04:14 +00:00
Ayaz Salikhov
5147825d61 Merge branch 'develop' into copilot/refactor-replace-boost-filesystem 2026-05-06 10:54:52 +01:00
copilot-swe-agent[bot]
719368ae25 fix: Apply pre-commit and clang-tidy fixes (formatting, braces, naming)
Agent-Logs-Url: https://github.com/XRPLF/rippled/sessions/a872065b-cdb8-47a7-8acb-3ece056594ca

Co-authored-by: mvadari <8029314+mvadari@users.noreply.github.com>
2026-05-04 17:20:36 +00:00
copilot-swe-agent[bot]
3e372656d3 Fix comment in temp_dir.h
Co-authored-by: mvadari <8029314+mvadari@users.noreply.github.com>
2026-05-04 16:17:43 +00:00
copilot-swe-agent[bot]
81964068a1 Merge origin/develop: resolve conflicts, keep std::filesystem with develop naming
Co-authored-by: mvadari <8029314+mvadari@users.noreply.github.com>
2026-05-04 16:17:01 +00:00
Ayaz Salikhov
2e0ea38d7d Apply suggestion from @Copilot
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-27 21:14:31 +01:00
Mayukha Vadari
aa1f84e226 fix clang-tidy issues 2026-04-25 12:36:43 -04:00
copilot-swe-agent[bot]
ae7076c054 Address second round of review feedback: non-throwing exists(), direct path streams, errno propagation
Agent-Logs-Url: https://github.com/XRPLF/rippled/sessions/ebfae1ee-800f-4a23-b484-a709c2321693

Co-authored-by: mvadari <8029314+mvadari@users.noreply.github.com>
2026-04-24 21:16:42 +00:00
copilot-swe-agent[bot]
9a221d1291 Address code review feedback: retry loop, comment cleanup, error code improvements
Agent-Logs-Url: https://github.com/XRPLF/rippled/sessions/629eace2-9c23-40d9-89f5-9ef3099cdf14

Co-authored-by: mvadari <8029314+mvadari@users.noreply.github.com>
2026-04-24 18:42:23 +00:00
copilot-swe-agent[bot]
5e6d8a4692 Merge remote-tracking branch 'origin/develop' into copilot/refactor-replace-boost-filesystem
# Conflicts:
#	src/xrpld/core/Config.h

Co-authored-by: mvadari <8029314+mvadari@users.noreply.github.com>
2026-04-24 17:59:58 +00:00
Mayukha Vadari
11c7d912f6 fix build 2026-04-24 12:54:09 -04:00
Mayukha Vadari
b7d6cdf713 fix clang-tidy issues 2026-04-24 12:49:36 -04:00
copilot-swe-agent[bot]
193ddcbfac Fix pre-commit and clang-tidy issues using tools
Agent-Logs-Url: https://github.com/XRPLF/rippled/sessions/e5845adb-dc3f-46cf-8461-0ea7855be1cf

Co-authored-by: mvadari <8029314+mvadari@users.noreply.github.com>
2026-04-24 15:38:40 +00:00
copilot-swe-agent[bot]
3a70d9dfba Fix build error and pre-commit include ordering issues
Agent-Logs-Url: https://github.com/XRPLF/rippled/sessions/e53fe2d3-e57e-4ad9-9d43-5dc1519645fc

Co-authored-by: mvadari <8029314+mvadari@users.noreply.github.com>
2026-04-24 14:13:56 +00:00
Mayukha Vadari
03e8a68670 Merge branch 'develop' into copilot/refactor-replace-boost-filesystem 2026-04-24 09:54:16 -04:00
copilot-swe-agent[bot]
28143d74af Increase entropy in SHAMapStoreImp.cpp unique path generation
Agent-Logs-Url: https://github.com/XRPLF/rippled/sessions/ec2fa57d-2d9c-4388-b4e1-90a40f55b5e8

Co-authored-by: mvadari <8029314+mvadari@users.noreply.github.com>
2026-04-24 13:52:06 +00:00
copilot-swe-agent[bot]
ff4c538a9f Address code review: improve random path generation and fix includes
Agent-Logs-Url: https://github.com/XRPLF/rippled/sessions/ec2fa57d-2d9c-4388-b4e1-90a40f55b5e8

Co-authored-by: mvadari <8029314+mvadari@users.noreply.github.com>
2026-04-24 13:50:38 +00:00
copilot-swe-agent[bot]
9fe94c47c3 Replace boost::filesystem with std::filesystem across codebase
Agent-Logs-Url: https://github.com/XRPLF/rippled/sessions/ec2fa57d-2d9c-4388-b4e1-90a40f55b5e8

Co-authored-by: mvadari <8029314+mvadari@users.noreply.github.com>
2026-04-24 13:47:08 +00:00
copilot-swe-agent[bot]
3f307f8128 Initial plan 2026-04-24 13:24:30 +00:00
236 changed files with 2902 additions and 3303 deletions

View File

@@ -153,7 +153,7 @@ Checks: "-*,
readability-use-std-min-max
"
# ---
# readability-inconsistent-declaration-parameter-name, # in this codebase this check will break a lot of arg names
# readability-inconsistent-declaration-parameter-name, # In this codebase this check will break a lot of arg names
# readability-static-accessed-through-instance, # this check is probably unnecessary. It makes the code less readable
# ---

View File

@@ -1,6 +1,8 @@
libxrpl.basics > xrpl.basics
libxrpl.conditions > xrpl.basics
libxrpl.conditions > xrpl.conditions
libxrpl.config > xrpl.basics
libxrpl.config > xrpl.config
libxrpl.core > xrpl.basics
libxrpl.core > xrpl.core
libxrpl.core > xrpl.json
@@ -17,6 +19,7 @@ libxrpl.ledger > xrpl.shamap
libxrpl.net > xrpl.basics
libxrpl.net > xrpl.net
libxrpl.nodestore > xrpl.basics
libxrpl.nodestore > xrpl.config
libxrpl.nodestore > xrpl.json
libxrpl.nodestore > xrpl.nodestore
libxrpl.nodestore > xrpl.protocol
@@ -24,6 +27,7 @@ libxrpl.protocol > xrpl.basics
libxrpl.protocol > xrpl.json
libxrpl.protocol > xrpl.protocol
libxrpl.rdb > xrpl.basics
libxrpl.rdb > xrpl.config
libxrpl.rdb > xrpl.core
libxrpl.rdb > xrpl.rdb
libxrpl.resource > xrpl.basics
@@ -31,6 +35,7 @@ libxrpl.resource > xrpl.json
libxrpl.resource > xrpl.protocol
libxrpl.resource > xrpl.resource
libxrpl.server > xrpl.basics
libxrpl.server > xrpl.config
libxrpl.server > xrpl.core
libxrpl.server > xrpl.json
libxrpl.server > xrpl.protocol
@@ -52,6 +57,7 @@ libxrpl.tx > xrpl.tx
test.app > test.jtx
test.app > test.unit_test
test.app > xrpl.basics
test.app > xrpl.config
test.app > xrpl.core
test.app > xrpld.app
test.app > xrpld.consensus
@@ -90,6 +96,7 @@ test.consensus > xrpl.tx
test.core > test.jtx
test.core > test.unit_test
test.core > xrpl.basics
test.core > xrpl.config
test.core > xrpl.core
test.core > xrpld.core
test.core > xrpl.json
@@ -104,6 +111,7 @@ test.csf > xrpl.protocol
test.json > test.jtx
test.json > xrpl.json
test.jtx > xrpl.basics
test.jtx > xrpl.config
test.jtx > xrpl.core
test.jtx > xrpld.app
test.jtx > xrpld.core
@@ -126,6 +134,7 @@ test.ledger > xrpl.protocol
test.nodestore > test.jtx
test.nodestore > test.unit_test
test.nodestore > xrpl.basics
test.nodestore > xrpl.config
test.nodestore > xrpld.core
test.nodestore > xrpl.nodestore
test.nodestore > xrpl.protocol
@@ -133,6 +142,7 @@ test.nodestore > xrpl.rdb
test.overlay > test.jtx
test.overlay > test.unit_test
test.overlay > xrpl.basics
test.overlay > xrpl.config
test.overlay > xrpld.app
test.overlay > xrpld.core
test.overlay > xrpld.overlay
@@ -159,6 +169,7 @@ test.resource > xrpl.basics
test.resource > xrpl.resource
test.rpc > test.jtx
test.rpc > xrpl.basics
test.rpc > xrpl.config
test.rpc > xrpl.core
test.rpc > xrpld.app
test.rpc > xrpld.core
@@ -173,6 +184,7 @@ test.rpc > xrpl.tx
test.server > test.jtx
test.server > test.unit_test
test.server > xrpl.basics
test.server > xrpl.config
test.server > xrpld.app
test.server > xrpld.core
test.server > xrpl.json
@@ -180,6 +192,7 @@ test.server > xrpl.protocol
test.server > xrpl.server
test.shamap > test.unit_test
test.shamap > xrpl.basics
test.shamap > xrpl.config
test.shamap > xrpl.nodestore
test.shamap > xrpl.protocol
test.shamap > xrpl.shamap
@@ -188,6 +201,7 @@ test.toplevel > xrpl.json
test.unit_test > xrpl.basics
test.unit_test > xrpl.protocol
tests.libxrpl > xrpl.basics
tests.libxrpl > xrpl.config
tests.libxrpl > xrpl.core
tests.libxrpl > xrpl.json
tests.libxrpl > xrpl.ledger
@@ -200,6 +214,7 @@ tests.libxrpl > xrpl.shamap
tests.libxrpl > xrpl.tx
xrpl.conditions > xrpl.basics
xrpl.conditions > xrpl.protocol
xrpl.config > xrpl.basics
xrpl.core > xrpl.basics
xrpl.core > xrpl.json
xrpl.core > xrpl.protocol
@@ -210,6 +225,7 @@ xrpl.ledger > xrpl.server
xrpl.ledger > xrpl.shamap
xrpl.net > xrpl.basics
xrpl.nodestore > xrpl.basics
xrpl.nodestore > xrpl.config
xrpl.nodestore > xrpl.protocol
xrpl.protocol > xrpl.basics
xrpl.protocol > xrpl.json
@@ -237,6 +253,7 @@ xrpl.tx > xrpl.ledger
xrpl.tx > xrpl.protocol
xrpld.app > test.unit_test
xrpld.app > xrpl.basics
xrpld.app > xrpl.config
xrpld.app > xrpl.core
xrpld.app > xrpld.consensus
xrpld.app > xrpld.core
@@ -255,11 +272,13 @@ xrpld.consensus > xrpl.json
xrpld.consensus > xrpl.ledger
xrpld.consensus > xrpl.protocol
xrpld.core > xrpl.basics
xrpld.core > xrpl.config
xrpld.core > xrpl.core
xrpld.core > xrpl.net
xrpld.core > xrpl.protocol
xrpld.core > xrpl.rdb
xrpld.overlay > xrpl.basics
xrpld.overlay > xrpl.config
xrpld.overlay > xrpl.core
xrpld.overlay > xrpld.consensus
xrpld.overlay > xrpld.core
@@ -272,15 +291,18 @@ xrpld.overlay > xrpl.server
xrpld.overlay > xrpl.shamap
xrpld.overlay > xrpl.tx
xrpld.peerfinder > xrpl.basics
xrpld.peerfinder > xrpl.config
xrpld.peerfinder > xrpld.core
xrpld.peerfinder > xrpl.protocol
xrpld.peerfinder > xrpl.rdb
xrpld.perflog > xrpl.basics
xrpld.perflog > xrpl.config
xrpld.perflog > xrpl.core
xrpld.perflog > xrpld.rpc
xrpld.perflog > xrpl.json
xrpld.perflog > xrpl.protocol
xrpld.rpc > xrpl.basics
xrpld.rpc > xrpl.config
xrpld.rpc > xrpl.core
xrpld.rpc > xrpld.core
xrpld.rpc > xrpl.json

View File

@@ -27,6 +27,19 @@ def get_cmake_args(build_type: str, extra_args: str) -> str:
return " ".join(args)
def runs_on_event(exclude_event_types: list[str], event: str | None) -> bool:
"""Whether a config should run for the current event.
'exclude_event_types' is a list of GitHub event names (e.g.
["pull_request"]) on which the config should NOT run; an empty list means
the config runs on every event. When no event is given (event is None), no
filtering is applied.
"""
if event is None:
return True
return event not in exclude_event_types
# ---------------------------------------------------------------------------
# Input types — shapes of the JSON config files
# ---------------------------------------------------------------------------
@@ -43,6 +56,9 @@ class LinuxConfig:
suffix: str = ""
extra_cmake_args: str = ""
image: str = "" # only used by package_configs entries
# List of GitHub event names (e.g. "pull_request") on which this config
# should NOT run. Empty means it runs on every event.
exclude_event_types: list[str] = dataclasses.field(default_factory=list)
@dataclasses.dataclass
@@ -77,6 +93,9 @@ class PlatformConfig:
build_type: list[str]
build_only: bool = False # if true, skip tests (e.g. macos/Windows Debug)
extra_cmake_args: str = ""
# List of GitHub event names (e.g. "pull_request") on which this config
# should NOT run. Empty means it runs on every event.
exclude_event_types: list[str] = dataclasses.field(default_factory=list)
def __post_init__(self) -> None:
if isinstance(self.build_type, str):
@@ -151,16 +170,21 @@ _ARCHS: dict[str, Architecture] = {
}
def expand_linux_matrix(linux: LinuxFile) -> list[MatrixEntry]:
def expand_linux_matrix(
linux: LinuxFile, event: str | None = None
) -> list[MatrixEntry]:
"""Expand a LinuxFile into a flat list of matrix entries.
Each config entry is expanded over the cross-product of its
compiler, build_type, sanitizers, and architecture lists.
compiler, build_type, sanitizers, and architecture lists. Configs that
exclude the current event are skipped.
"""
entries: list[MatrixEntry] = []
for distro, configs in linux.configs.items():
for cfg in configs:
if not runs_on_event(cfg.exclude_event_types, event):
continue
# An empty sanitizers list means "one entry with no sanitizer".
effective_sanitizers = cfg.sanitizers or [""]
effective_archs = {arch: _ARCHS[arch] for arch in cfg.arch}
@@ -218,13 +242,20 @@ def expand_linux_packaging(linux: LinuxFile) -> list[PackagingEntry]:
return entries
def expand_platform_matrix(pf: PlatformFile) -> list[MatrixEntry]:
"""Expand a PlatformFile (macOS or Windows) into matrix entries."""
def expand_platform_matrix(
pf: PlatformFile, event: str | None = None
) -> list[MatrixEntry]:
"""Expand a PlatformFile (macOS or Windows) into matrix entries.
Configs that exclude the current event are skipped.
"""
platform_name, arch = pf.platform.split("/")
is_windows = platform_name == "windows"
entries: list[MatrixEntry] = []
for cfg in pf.configs:
if not runs_on_event(cfg.exclude_event_types, event):
continue
for build_type in cfg.build_type:
entries.append(
MatrixEntry(
@@ -262,6 +293,14 @@ if __name__ == "__main__":
help="Emit the Linux packaging matrix instead of the build/test matrix.",
action="store_true",
)
parser.add_argument(
"-e",
"--event",
help="The GitHub event name that triggered the workflow (e.g. 'push', "
"'pull_request'). Configs are filtered by their 'event_type'. If "
"omitted, no filtering is applied.",
default=None,
)
args = parser.parse_args()
matrix: list[MatrixEntry] | list[PackagingEntry] = []
@@ -270,12 +309,16 @@ if __name__ == "__main__":
matrix = expand_linux_packaging(LinuxFile.load(THIS_DIR / "linux.json"))
else:
if args.config in ("linux", None):
matrix += expand_linux_matrix(LinuxFile.load(THIS_DIR / "linux.json"))
matrix += expand_linux_matrix(
LinuxFile.load(THIS_DIR / "linux.json"), args.event
)
if args.config in ("macos", None):
matrix += expand_platform_matrix(PlatformFile.load(THIS_DIR / "macos.json"))
matrix += expand_platform_matrix(
PlatformFile.load(THIS_DIR / "macos.json"), args.event
)
if args.config in ("windows", None):
matrix += expand_platform_matrix(
PlatformFile.load(THIS_DIR / "windows.json")
PlatformFile.load(THIS_DIR / "windows.json"), args.event
)
print(f"matrix={json.dumps({'include': [dataclasses.asdict(e) for e in matrix]})}")

View File

@@ -41,7 +41,8 @@
"build_type": ["Debug"],
"arch": ["amd64"],
"suffix": "unity",
"extra_cmake_args": "-Dunity=ON"
"extra_cmake_args": "-Dunity=ON",
"exclude_event_types": ["pull_request"]
}
],

View File

@@ -9,7 +9,8 @@
{
"build_type": "Debug",
"extra_cmake_args": "-DCMAKE_POLICY_VERSION_MINIMUM=3.5",
"build_only": true
"build_only": true,
"exclude_event_types": ["pull_request"]
}
]
}

View File

@@ -3,6 +3,10 @@
"runner": ["self-hosted", "Windows", "devbox"],
"configs": [
{ "build_type": "Release" },
{ "build_type": "Debug", "build_only": true }
{
"build_type": "Debug",
"build_only": true,
"exclude_event_types": ["pull_request"]
}
]
}

View File

@@ -82,7 +82,7 @@ jobs:
name: ${{ inputs.config_name }}
runs-on: ${{ fromJSON(inputs.runs_on) }}
container: ${{ inputs.image != '' && inputs.image || null }}
timeout-minutes: ${{ inputs.sanitizers != '' && 360 || 60 }}
timeout-minutes: ${{ inputs.sanitizers != '' && 360 || 90 }}
env:
# Use a namespace to keep the objects separate for each configuration.
CCACHE_NAMESPACE: ${{ inputs.config_name }}

View File

@@ -35,4 +35,5 @@ jobs:
id: generate
env:
GENERATE_CONFIG: ${{ inputs.os != '' && format('--config={0}', inputs.os) || '' }}
run: ./generate.py ${GENERATE_CONFIG} >>"${GITHUB_OUTPUT}"
GENERATE_EVENT: ${{ github.event_name }}
run: ./generate.py ${GENERATE_CONFIG} --event="${GENERATE_EVENT}" >>"${GITHUB_OUTPUT}"

View File

@@ -30,6 +30,7 @@ on:
- ".github/scripts/strategy-matrix/**"
- conanfile.py
- conan.lock
- conan/profiles/**
env:
CONAN_REMOTE_NAME: xrplf

View File

@@ -45,14 +45,14 @@ found here](./docs/build/environment.md).
It is possible to build with Conan 1.60+, but the instructions are
significantly different, which is why we are not recommending it.
`xrpld` is written in the C++20 dialect and includes the `<concepts>` header.
The [minimum compiler versions][2] required are:
`xrpld` is written in the C++23 dialect and includes the `<concepts>` header.
The [tested compiler versions][2] are:
| Compiler | Version |
| ----------- | --------- |
| GCC | 12 |
| Clang | 16 |
| Apple Clang | 16 |
| GCC | 15 |
| Clang | 22 |
| Apple Clang | 17 |
| MSVC | 19.44[^3] |
### Linux
@@ -232,11 +232,11 @@ name and then creating a new `default` profile for a different compiler.
#### Select language
The default profile created by Conan will typically select different C++ dialect
than C++20 used by this project. You should set `20` in the profile line
than C++23 used by this project. You should set `23` in the profile line
starting with `compiler.cppstd=`. For example:
```bash
sed -i.bak -e 's|^compiler\.cppstd=.*$|compiler.cppstd=20|' $(conan config home)/profiles/default
sed -i.bak -e 's|^compiler\.cppstd=.*$|compiler.cppstd=23|' $(conan config home)/profiles/default
```
#### Select standard library in Linux

View File

@@ -15,7 +15,7 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
project(xrpl)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

View File

@@ -94,6 +94,9 @@ add_module(xrpl basics)
target_link_libraries(xrpl.libxrpl.basics PUBLIC xrpl.libxrpl.beast)
# Level 03
add_module(xrpl config)
target_link_libraries(xrpl.libxrpl.config PUBLIC xrpl.libxrpl.basics)
add_module(xrpl json)
target_link_libraries(xrpl.libxrpl.json PUBLIC xrpl.libxrpl.basics)
@@ -120,6 +123,7 @@ target_link_libraries(
xrpl.libxrpl.core
PUBLIC
xrpl.libxrpl.basics
xrpl.libxrpl.config
xrpl.libxrpl.json
xrpl.libxrpl.protocol
xrpl.libxrpl.protocol_autogen
@@ -143,7 +147,11 @@ target_link_libraries(
add_module(xrpl nodestore)
target_link_libraries(
xrpl.libxrpl.nodestore
PUBLIC xrpl.libxrpl.basics xrpl.libxrpl.json xrpl.libxrpl.protocol
PUBLIC
xrpl.libxrpl.basics
xrpl.libxrpl.config
xrpl.libxrpl.json
xrpl.libxrpl.protocol
)
add_module(xrpl shamap)
@@ -159,13 +167,14 @@ target_link_libraries(
add_module(xrpl rdb)
target_link_libraries(
xrpl.libxrpl.rdb
PUBLIC xrpl.libxrpl.basics xrpl.libxrpl.core
PUBLIC xrpl.libxrpl.basics xrpl.libxrpl.config xrpl.libxrpl.core
)
add_module(xrpl server)
target_link_libraries(
xrpl.libxrpl.server
PUBLIC
xrpl.libxrpl.config
xrpl.libxrpl.protocol
xrpl.libxrpl.core
xrpl.libxrpl.rdb
@@ -210,6 +219,7 @@ target_link_modules(
basics
beast
conditions
config
core
crypto
git

View File

@@ -2,7 +2,7 @@
arch=x86_64
build_type=Release
compiler=gcc
compiler.cppstd=20
compiler.cppstd=23
compiler.libcxx=libstdc++11
compiler.version=13
os=Linux

View File

@@ -2,7 +2,7 @@
arch=armv8
build_type=Release
compiler=apple-clang
compiler.cppstd=20
compiler.cppstd=23
compiler.libcxx=libc++
compiler.version=17.0
os=Macos

View File

@@ -2,7 +2,7 @@
arch=x86_64
build_type=Release
compiler=msvc
compiler.cppstd=20
compiler.cppstd=23
compiler.runtime=dynamic
compiler.runtime_type=Release
compiler.version=194

View File

@@ -12,7 +12,7 @@ arch={{ arch }}
build_type=Debug
compiler={{compiler}}
compiler.version={{ compiler_version }}
compiler.cppstd=20
compiler.cppstd=23
{% if os == "Windows" %}
compiler.runtime=static
{% else %}

View File

@@ -52,52 +52,50 @@ include(default)
{% endif %}
{# Frame pointer required for meaningful stack traces; -O1 for reasonable performance #}
{% set compile_flags = ["-fno-omit-frame-pointer", "-O1"] %}
{% set sanitizer_compiler_flags = ["-fno-omit-frame-pointer", "-O1"] %}
{% if compiler == "gcc" %}
{# Suppress false positive warnings with GCC #}
{% set _ = compile_flags.append("-Wno-stringop-overflow") %}
{% set _ = sanitizer_compiler_flags.append("-Wno-stringop-overflow") %}
{% set relocation_flags = [] %}
{% if arch == "x86_64" and enable_asan %}
{# Large code model prevents relocation errors in instrumented ASAN binaries #}
{% set _ = compile_flags.append("-mcmodel=large") %}
{% set _ = sanitizer_compiler_flags.append("-mcmodel=large") %}
{% set _ = relocation_flags.append("-mcmodel=large") %}
{% elif enable_tsan %}
{# GCC doesn't support atomic_thread_fence with TSAN; suppress warnings #}
{% set _ = compile_flags.append("-Wno-tsan") %}
{% set _ = sanitizer_compiler_flags.append("-Wno-tsan") %}
{% if arch == "x86_64" %}
{# Medium code model for TSAN; large is incompatible #}
{% set _ = compile_flags.append("-mcmodel=medium") %}
{% set _ = sanitizer_compiler_flags.append("-mcmodel=medium") %}
{% set _ = relocation_flags.append("-mcmodel=medium") %}
{% endif %}
{% endif %}
{% set fsanitize = "-fsanitize=" ~ ",".join(sanitizer_types) %}
{% set _ = compile_flags.append(fsanitize) %}
{% set _ = sanitizer_compiler_flags.append(fsanitize) %}
{% set _ = relocation_flags.append(fsanitize) %}
{% set sanitizer_compiler_flags = " ".join(compile_flags) %}
{% set sanitizer_linker_flags = " ".join(relocation_flags) %}
{% set sanitizer_linker_flags = relocation_flags %}
{% elif compiler == "clang" or compiler == "apple-clang" %}
{% set fsanitize = "-fsanitize=" ~ ",".join(sanitizer_types) %}
{% set _ = compile_flags.append(fsanitize) %}
{% set _ = sanitizer_compiler_flags.append(fsanitize) %}
{% set sanitizer_compiler_flags = " ".join(compile_flags) %}
{% set sanitizer_linker_flags = fsanitize %}
{% set sanitizer_linker_flags = [fsanitize] %}
{% endif %}
[conf]
tools.build:defines+={{defines}}
tools.build:cxxflags+=['{{sanitizer_compiler_flags}}']
tools.build:sharedlinkflags+=['{{sanitizer_linker_flags}}']
tools.build:exelinkflags+=['{{sanitizer_linker_flags}}']
tools.build:cxxflags+={{sanitizer_compiler_flags}}
tools.build:sharedlinkflags+={{sanitizer_linker_flags}}
tools.build:exelinkflags+={{sanitizer_linker_flags}}
tools.info.package_id:confs+=["tools.build:cxxflags", "tools.build:exelinkflags", "tools.build:sharedlinkflags", "tools.build:defines"]
# &: means "apply only to the consumer/root package"
&:tools.cmake.cmaketoolchain:extra_variables={"SANITIZERS": "{{sanitizers}}", "SANITIZERS_COMPILER_FLAGS": "{{sanitizer_compiler_flags}}", "SANITIZERS_LINKER_FLAGS": "{{sanitizer_linker_flags}}"}
&:tools.cmake.cmaketoolchain:extra_variables={"SANITIZERS": "{{sanitizers}}", "SANITIZERS_COMPILER_FLAGS": "{{sanitizer_compiler_flags | join(' ')}}", "SANITIZERS_LINKER_FLAGS": "{{sanitizer_linker_flags | join(' ')}}"}
[options]
{% if enable_asan %}

View File

@@ -84,6 +84,7 @@ words:
- coro
- coros
- cowid
- cpack
- cryptocondition
- cryptoconditional
- cryptoconditions

6
flake.lock generated
View File

@@ -2,11 +2,11 @@
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1780243769,
"narHash": "sha256-x5UQuRsH3MqI0U9afaXSNqzTPSeZlRLvFAav2Ux1pNw=",
"lastModified": 1780749050,
"narHash": "sha256-3av0pIjlOWQ6rDbNOmpUSvbNnJkGORQKKjb4LtCZsIY=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "331800de5053fcebacf6813adb5db9c9dca22a0c",
"rev": "a799d3e3886da994fa307f817a6bc705ae538eeb",
"type": "github"
},
"original": {

View File

@@ -1,6 +1,6 @@
#pragma once
#include <boost/filesystem.hpp>
#include <filesystem>
namespace xrpl {
@@ -12,6 +12,6 @@ namespace xrpl {
@throws runtime_error
*/
void
extractTarLz4(boost::filesystem::path const& src, boost::filesystem::path const& dst);
extractTarLz4(std::filesystem::path const& src, std::filesystem::path const& dst);
} // namespace xrpl

View File

@@ -1,248 +0,0 @@
#pragma once
#include <xrpl/basics/contract.h>
#include <boost/outcome.hpp>
#include <stdexcept>
namespace xrpl {
/** Expected is an approximation of std::expected (hoped for in C++23)
See: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0323r10.html
The implementation is entirely based on boost::outcome_v2::result.
*/
// Exception thrown by an invalid access to Expected.
struct BadExpectedAccess : public std::runtime_error
{
BadExpectedAccess() : runtime_error("bad expected access")
{
}
};
namespace detail {
// Custom policy for Expected. Always throw on an invalid access.
struct ThrowPolicy : public boost::outcome_v2::policy::base
{
template <class Impl>
static constexpr void
// NOLINTNEXTLINE(readability-identifier-naming)
wide_value_check(Impl&& self)
{
if (!base::_has_value(std::forward<Impl>(self)))
Throw<BadExpectedAccess>();
}
template <class Impl>
static constexpr void
// NOLINTNEXTLINE(readability-identifier-naming)
wide_error_check(Impl&& self)
{
if (!base::_has_error(std::forward<Impl>(self)))
Throw<BadExpectedAccess>();
}
template <class Impl>
static constexpr void
// NOLINTNEXTLINE(readability-identifier-naming)
wide_exception_check(Impl&& self)
{
if (!base::_has_exception(std::forward<Impl>(self)))
Throw<BadExpectedAccess>();
}
};
} // namespace detail
// Definition of Unexpected, which is used to construct the unexpected
// return type of an Expected.
template <class E>
class Unexpected
{
public:
static_assert(!std::is_same_v<E, void>, "E must not be void");
Unexpected() = delete;
constexpr explicit Unexpected(E const& e) : val_(e)
{
}
constexpr explicit Unexpected(E&& e) : val_(std::move(e))
{
}
[[nodiscard]] constexpr E const&
value() const&
{
return val_;
}
constexpr E&
value() &
{
return val_;
}
constexpr E&&
value() &&
{
return std::move(val_);
}
[[nodiscard]] constexpr E const&&
value() const&&
{
return std::move(val_);
}
private:
E val_;
};
// Unexpected deduction guide that converts array to const*.
template <typename E, std::size_t N>
Unexpected(E (&)[N]) -> Unexpected<E const*>;
// Definition of Expected. All of the machinery comes from boost::result.
template <class T, class E>
class [[nodiscard]] Expected : private boost::outcome_v2::result<T, E, detail::ThrowPolicy>
{
using Base = boost::outcome_v2::result<T, E, detail::ThrowPolicy>;
public:
template <typename U>
requires std::convertible_to<U, T>
constexpr Expected(U&& r) : Base(boost::outcome_v2::in_place_type_t<T>{}, std::forward<U>(r))
{
}
template <typename U>
requires std::convertible_to<U, E> && (!std::is_reference_v<U>)
constexpr Expected(Unexpected<U> e)
: Base(boost::outcome_v2::in_place_type_t<E>{}, std::move(e.value()))
{
}
[[nodiscard]] constexpr bool
// NOLINTNEXTLINE(readability-identifier-naming)
has_value() const
{
return Base::has_value();
}
[[nodiscard]] constexpr T const&
value() const
{
return Base::value();
}
constexpr T&
value()
{
return Base::value();
}
[[nodiscard]] constexpr E const&
error() const&
{
return Base::error();
}
[[nodiscard]] constexpr E&
error() &
{
return Base::error();
}
[[nodiscard]] constexpr E&&
error() &&
{
return std::move(Base::error());
}
constexpr explicit
operator bool() const
{
return has_value();
}
// Add operator* and operator-> so the Expected API looks a bit more like
// what std::expected is likely to look like. See:
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0323r10.html
[[nodiscard]] constexpr T&
operator*()
{
return this->value();
}
[[nodiscard]] constexpr T const&
operator*() const
{
return this->value();
}
[[nodiscard]] constexpr T*
operator->()
{
return &this->value();
}
[[nodiscard]] constexpr T const*
operator->() const
{
return &this->value();
}
};
// Specialization of Expected<void, E>. Allows returning either success
// (without a value) or the reason for the failure.
template <class E>
class [[nodiscard]]
Expected<void, E> : private boost::outcome_v2::result<void, E, detail::ThrowPolicy>
{
using Base = boost::outcome_v2::result<void, E, detail::ThrowPolicy>;
public:
// The default constructor makes a successful Expected<void, E>.
// This aligns with std::expected behavior proposed in P0323R10.
constexpr Expected() : Base(boost::outcome_v2::success())
{
}
template <typename U>
requires std::convertible_to<U, E> && (!std::is_reference_v<U>)
constexpr Expected(Unexpected<U> e) : Base(E(std::move(e.value())))
{
}
[[nodiscard]] constexpr E const&
error() const&
{
return Base::error();
}
[[nodiscard]] constexpr E&
error() &
{
return Base::error();
}
[[nodiscard]] constexpr E&&
error() &&
{
return std::move(Base::error());
}
constexpr explicit
operator bool() const
{
return Base::has_value();
}
};
} // namespace xrpl

View File

@@ -1,22 +1,22 @@
#pragma once
#include <boost/filesystem.hpp>
#include <boost/system/error_code.hpp>
#include <filesystem>
#include <optional>
#include <string>
#include <system_error>
namespace xrpl {
std::string
getFileContents(
boost::system::error_code& ec,
boost::filesystem::path const& sourcePath,
std::error_code& ec,
std::filesystem::path const& sourcePath,
std::optional<std::size_t> maxSize = std::nullopt);
void
writeFileContents(
boost::system::error_code& ec,
boost::filesystem::path const& destPath,
std::error_code& ec,
std::filesystem::path const& destPath,
std::string const& contents);
} // namespace xrpl

View File

@@ -4,8 +4,8 @@
#include <xrpl/beast/utility/Journal.h>
#include <boost/beast/core/string.hpp>
#include <boost/filesystem.hpp>
#include <filesystem>
#include <fstream>
#include <map>
#include <memory>
@@ -76,7 +76,7 @@ private:
@return `true` if the file was opened.
*/
bool
open(boost::filesystem::path const& path);
open(std::filesystem::path const& path);
/** Close and re-open the system file associated with the log
This assists in interoperating with external log management tools.
@@ -118,7 +118,7 @@ private:
private:
std::unique_ptr<std::ofstream> stream_;
boost::filesystem::path path_;
std::filesystem::path path_;
};
std::mutex mutable mutex_;
@@ -137,7 +137,7 @@ public:
virtual ~Logs() = default;
bool
open(boost::filesystem::path const& pathToLogFile);
open(std::filesystem::path const& pathToLogFile);
beast::Journal::Sink&
get(std::string const& name);

View File

@@ -408,33 +408,40 @@ public:
}
friend constexpr bool
operator<(Number const& x, Number const& y) noexcept
operator<(Number const& l, Number const& r) noexcept
{
bool const lneg = l.negative_;
bool const rneg = r.negative_;
// If the two amounts have different signs (zero is treated as positive)
// then the comparison is true iff the left is negative.
bool const lneg = x.negative_;
bool const rneg = y.negative_;
if (lneg != rneg)
return lneg;
// Both have same sign and the left is zero: the right must be
// greater than 0.
if (x.mantissa_ == 0)
return y.mantissa_ > 0;
// Both have same sign and the left is zero: both must be non-negative.
// If the right is greater than 0, then it is larger, so the comparison is true.
if (l.mantissa_ == 0)
return r.mantissa_ > 0;
// Both have same sign, the right is zero and the left is non-zero.
if (y.mantissa_ == 0)
// Both have same sign, the right is zero and the left is non-zero, so the left must be
// positive, and thus is larger, so the comparison is false.
if (r.mantissa_ == 0)
return false;
// Both have the same sign, compare by exponents:
if (x.exponent_ > y.exponent_)
if (l.exponent_ > r.exponent_)
return lneg;
if (x.exponent_ < y.exponent_)
if (l.exponent_ < r.exponent_)
return !lneg;
// If equal exponents, compare mantissas
return x.mantissa_ < y.mantissa_;
// If equal signs and exponents, compare mantissas.
if (lneg)
{
// If negative, the operator is reversed.
return l.mantissa_ > r.mantissa_;
}
return l.mantissa_ < r.mantissa_;
}
/** Return the sign of the amount */

View File

@@ -11,6 +11,7 @@
#include <cstdint>
#include <optional>
#include <string>
#include <string_view>
#include <type_traits>
namespace xrpl {
@@ -95,13 +96,7 @@ strUnHex(std::size_t strSize, Iterator begin, Iterator end)
}
inline std::optional<Blob>
strUnHex(std::string const& strSrc)
{
return strUnHex(strSrc.size(), strSrc.cbegin(), strSrc.cend());
}
inline std::optional<Blob>
strViewUnHex(std::string_view strSrc)
strUnHex(std::string_view strSrc)
{
return strUnHex(strSrc.size(), strSrc.cbegin(), strSrc.cend());
}

View File

@@ -36,6 +36,7 @@
#include <cstdint>
#include <string>
#include <string_view>
namespace xrpl {
@@ -43,7 +44,7 @@ std::string
base64Encode(std::uint8_t const* data, std::size_t len);
inline std::string
base64Encode(std::string const& s)
base64Encode(std::string_view s)
{
return base64Encode(reinterpret_cast<std::uint8_t const*>(s.data()), s.size());
}

View File

@@ -5,7 +5,6 @@
#pragma once
#include <xrpl/basics/Expected.h>
#include <xrpl/basics/Slice.h>
#include <xrpl/basics/contract.h>
#include <xrpl/basics/hardened_hash.h>
@@ -20,6 +19,7 @@
#include <algorithm>
#include <array>
#include <cstring>
#include <expected>
#include <type_traits>
namespace xrpl {
@@ -177,7 +177,7 @@ private:
BadChar,
};
constexpr Expected<decltype(data_), ParseResult>
constexpr std::expected<decltype(data_), ParseResult>
parseFromStringView(std::string_view sv) noexcept
{
// Local lambda that converts a single hex char to four bits and
@@ -216,7 +216,7 @@ private:
}
if (sv.size() != size() * 2)
return Unexpected(ParseResult::BadLength);
return std::unexpected(ParseResult::BadLength);
std::size_t i = 0u;
auto in = sv.begin();
@@ -227,7 +227,7 @@ private:
{
if (auto const result = hexCharToUInt(*in++, shift, accum);
result != ParseResult::Okay)
return Unexpected(result);
return std::unexpected(result);
}
ret[i++] = accum;
}

View File

@@ -1,12 +1,13 @@
#pragma once
#include <string>
#include <string_view>
namespace xrpl {
template <class Stream, class Iter>
Stream&
join(Stream& s, Iter iter, Iter end, std::string const& delimiter)
join(Stream& s, Iter iter, Iter end, std::string_view delimiter)
{
if (iter == end)
return s;

View File

@@ -7,8 +7,11 @@
#include <array>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <new>
#include <optional>
#include <span>
#include <type_traits>
namespace beast {

View File

@@ -3,6 +3,7 @@
#include <xrpl/beast/insight/CounterImpl.h>
#include <memory>
#include <utility>
namespace beast::insight {
@@ -29,7 +30,7 @@ public:
factory function in the Collector interface.
@see Collector.
*/
explicit Counter(std::shared_ptr<CounterImpl> const& impl) : impl_(impl)
explicit Counter(std::shared_ptr<CounterImpl> impl) : impl_(std::move(impl))
{
}

View File

@@ -4,6 +4,7 @@
#include <chrono>
#include <memory>
#include <utility>
namespace beast::insight {
@@ -31,7 +32,7 @@ public:
factory function in the Collector interface.
@see Collector.
*/
explicit Event(std::shared_ptr<EventImpl> const& impl) : impl_(impl)
explicit Event(std::shared_ptr<EventImpl> impl) : impl_(std::move(impl))
{
}

View File

@@ -3,6 +3,7 @@
#include <xrpl/beast/insight/GaugeImpl.h>
#include <memory>
#include <utility>
namespace beast::insight {
@@ -31,7 +32,7 @@ public:
factory function in the Collector interface.
@see Collector.
*/
explicit Gauge(std::shared_ptr<GaugeImpl> const& impl) : impl_(impl)
explicit Gauge(std::shared_ptr<GaugeImpl> impl) : impl_(std::move(impl))
{
}

View File

@@ -3,6 +3,7 @@
#include <xrpl/beast/insight/HookImpl.h>
#include <memory>
#include <utility>
namespace beast::insight {
@@ -20,7 +21,7 @@ public:
factory function in the Collector interface.
@see Collector.
*/
explicit Hook(std::shared_ptr<HookImpl> const& impl) : impl_(impl)
explicit Hook(std::shared_ptr<HookImpl> impl) : impl_(std::move(impl))
{
}

View File

@@ -3,6 +3,7 @@
#include <xrpl/beast/insight/MeterImpl.h>
#include <memory>
#include <utility>
namespace beast::insight {
@@ -28,7 +29,7 @@ public:
factory function in the Collector interface.
@see Collector.
*/
explicit Meter(std::shared_ptr<MeterImpl> const& impl) : impl_(impl)
explicit Meter(std::shared_ptr<MeterImpl> impl) : impl_(std::move(impl))
{
}

View File

@@ -41,7 +41,7 @@ private:
public:
template <class = void>
explicit Selector(ModeT mode, std::string const& pattern = "");
explicit Selector(ModeT mode, std::string pattern = "");
template <class = void>
bool
@@ -51,9 +51,9 @@ public:
//------------------------------------------------------------------------------
template <class>
Selector::Selector(ModeT mode, std::string const& pattern) : mode_(mode), pat_(pattern)
Selector::Selector(ModeT mode, std::string pattern) : mode_(mode), pat_(std::move(pattern))
{
if (mode_ == ModeT::Automatch && pattern.empty())
if (mode_ == ModeT::Automatch && pat_.empty())
mode_ = ModeT::All;
}

View File

@@ -6,10 +6,10 @@
#include <xrpl/beast/unit_test/runner.h>
#include <boost/filesystem.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/throw_exception.hpp>
#include <filesystem>
#include <ostream>
#include <sstream>
#include <string>
@@ -25,7 +25,7 @@ makeReason(String const& reason, char const* file, int line)
std::string s(reason);
if (!s.empty())
s.append(": ");
namespace fs = boost::filesystem;
namespace fs = std::filesystem;
s.append(fs::path{file}.filename().string());
s.append("(");
s.append(boost::lexical_cast<std::string>(line));

View File

@@ -11,6 +11,8 @@
// Macros below are copied from antithesis_sdk.h and slightly simplified
// The duplication is because Visual Studio 2019 cannot compile that header
// even with the option -Zc:__cplusplus added.
// NOTE: cond must not contain bare commas outside () or []. Commas inside {}
// are not protected by the preprocessor and would be parsed as extra arguments.
#define ALWAYS(cond, message, ...) assert((message) && (cond))
#define ALWAYS_OR_UNREACHABLE(cond, message) assert((message) && (cond))
#define SOMETIMES(cond, message, ...)
@@ -22,6 +24,8 @@
#define XRPL_ASSERT_PARTS(cond, function, description, ...) \
XRPL_ASSERT(cond, function " : " description)
#define XRPL_ASSERT_IF(guard, cond, message) XRPL_ASSERT(!(guard) || (cond), message)
// How to use the instrumentation macros:
//
// * XRPL_ASSERT if cond must be true but the line might not be reached during
@@ -29,6 +33,14 @@
// * XRPL_ASSERT_PARTS is for convenience, and works like XRPL_ASSERT, but
// splits the message param into "function" and "description", then joins
// them with " : " before passing to XRPL_ASSERT.
// * XRPL_ASSERT_IF(guard, cond, message) asserts the implication
// `guard => cond`: it can only fail when guard is true (e.g. an amendment
// is enabled) and cond is false. Unlike `if (guard) XRPL_ASSERT(...)`, the
// assertion site is always evaluated, so the fuzzer registers it
// unconditionally; cond itself is short-circuited and only evaluated when
// guard is true. NOTE: do not rely on side effects in guard — in release
// builds the assertion body is stripped, and the compiler may optimize away
// a side-effect-free guard entirely.
// * ALWAYS if cond must be true _and_ the line must be reached during fuzzing.
// Same like `assert` in normal use.
// * REACHABLE if the line must be reached during fuzzing

View File

@@ -1,19 +1,56 @@
#pragma once
#include <boost/filesystem.hpp>
#include <filesystem>
#include <iomanip>
#include <random>
#include <sstream>
#include <stdexcept>
#include <string>
#include <system_error>
namespace beast {
/** Generate a unique, non-existing path under @p base with an optional @p prefix
and a random hex suffix.
Attempts up to @p maxAttempts paths. Throws `std::runtime_error` if a
unique path cannot be found or if the filesystem returns an error while
checking for existence.
*/
inline std::filesystem::path
uniqueRandomPath(
std::filesystem::path const& base,
std::size_t maxAttempts = 100,
std::string const& prefix = "")
{
std::random_device rd;
for (std::size_t attempt = 0; attempt < maxAttempts; ++attempt)
{
std::ostringstream oss;
oss << prefix << std::hex << std::setfill('0') << std::setw(8) << rd() << std::setw(8)
<< rd();
auto candidate = base / oss.str();
std::error_code ec;
bool const exists = std::filesystem::exists(candidate, ec);
if (ec)
{
throw std::runtime_error(
"Unable to check path '" + candidate.string() + "': " + ec.message());
}
if (!exists)
return candidate;
}
throw std::runtime_error("Unable to generate a unique path under '" + base.string() + "'");
}
/** RAII temporary directory.
The directory and all its contents are deleted when
the instance of `temp_dir` is destroyed.
the instance of `TempDir` is destroyed.
*/
class TempDir
{
boost::filesystem::path path_;
std::filesystem::path path_;
public:
#if !GENERATING_DOCS
@@ -25,20 +62,16 @@ public:
/// Construct a temporary directory.
TempDir()
{
auto const dir = boost::filesystem::temp_directory_path();
do
{
path_ = dir / boost::filesystem::unique_path();
} while (boost::filesystem::exists(path_));
boost::filesystem::create_directory(path_);
path_ = uniqueRandomPath(std::filesystem::temp_directory_path());
std::filesystem::create_directory(path_);
}
/// Destroy a temporary directory.
~TempDir()
{
// use non-throwing calls in the destructor
boost::system::error_code ec;
boost::filesystem::remove_all(path_, ec);
std::error_code ec;
std::filesystem::remove_all(path_, ec);
// TODO: warn/notify if ec set ?
}

View File

@@ -0,0 +1,180 @@
#pragma once
namespace xrpl {
struct Sections
{
static constexpr auto kAmendments = "amendments";
static constexpr auto kAmendmentMajorityTime = "amendment_majority_time";
static constexpr auto kBetaRpcApi = "beta_rpc_api";
static constexpr auto kClusterNodes = "cluster_nodes";
static constexpr auto kCompression = "compression";
static constexpr auto kCrawl = "crawl";
static constexpr auto kDatabasePath = "database_path";
static constexpr auto kDebugLogfile = "debug_logfile";
static constexpr auto kElbSupport = "elb_support";
static constexpr auto kFeatures = "features";
static constexpr auto kFeeDefault = "fee_default";
static constexpr auto kFetchDepth = "fetch_depth";
static constexpr auto kHashrouter = "hashrouter";
static constexpr auto kImportNodeDatabase = "import_db";
static constexpr auto kInsight = "insight";
static constexpr auto kIoWorkers = "io_workers";
static constexpr auto kIps = "ips";
static constexpr auto kIpsFixed = "ips_fixed";
static constexpr auto kLedgerHistory = "ledger_history";
static constexpr auto kLedgerReplay = "ledger_replay";
static constexpr auto kLedgerTxTables = "ledger_tx_tables";
static constexpr auto kMaxTransactions = "max_transactions";
static constexpr auto kNetworkId = "network_id";
static constexpr auto kNetworkQuorum = "network_quorum";
static constexpr auto kNodeDatabase = "node_db";
static constexpr auto kNodeSeed = "node_seed";
static constexpr auto kNodeSize = "node_size";
static constexpr auto kOverlay = "overlay";
static constexpr auto kPathSearch = "path_search";
static constexpr auto kPathSearchFast = "path_search_fast";
static constexpr auto kPathSearchMax = "path_search_max";
static constexpr auto kPathSearchOld = "path_search_old";
static constexpr auto kPeerPrivate = "peer_private";
static constexpr auto kPeersInMax = "peers_in_max";
static constexpr auto kPeersMax = "peers_max";
static constexpr auto kPeersOutMax = "peers_out_max";
static constexpr auto kPerf = "perf";
static constexpr auto kPortGrpc = "port_grpc";
static constexpr auto kPortPeer = "port_peer";
static constexpr auto kPortRpc = "port_rpc";
static constexpr auto kPortWs = "port_ws";
static constexpr auto kPortWssAdmin = "port_wss_admin";
static constexpr auto kPrefetchWorkers = "prefetch_workers";
static constexpr auto kReduceRelay = "reduce_relay";
static constexpr auto kRelationalDb = "relational_db";
static constexpr auto kRelayProposals = "relay_proposals";
static constexpr auto kRelayValidations = "relay_validations";
static constexpr auto kRpcStartup = "rpc_startup";
static constexpr auto kServer = "server";
static constexpr auto kServerDomain = "server_domain";
static constexpr auto kSigningSupport = "signing_support";
static constexpr auto kSntp = "sntp_servers";
static constexpr auto kSqdb = "sqdb";
static constexpr auto kSqlite = "sqlite";
static constexpr auto kSslVerify = "ssl_verify";
static constexpr auto kSslVerifyDir = "ssl_verify_dir";
static constexpr auto kSslVerifyFile = "ssl_verify_file";
static constexpr auto kSweepInterval = "sweep_interval";
static constexpr auto kTransactionQueue = "transaction_queue";
static constexpr auto kValidationSeed = "validation_seed";
static constexpr auto kValidatorKeys = "validator_keys";
static constexpr auto kValidatorKeyRevocation = "validator_key_revocation";
static constexpr auto kValidatorListKeys = "validator_list_keys";
static constexpr auto kValidatorListSites = "validator_list_sites";
static constexpr auto kValidatorListThreshold = "validator_list_threshold";
static constexpr auto kValidatorToken = "validator_token";
static constexpr auto kValidators = "validators";
static constexpr auto kValidatorsFile = "validators_file";
static constexpr auto kVetoAmendments = "veto_amendments";
static constexpr auto kVl = "vl";
static constexpr auto kVoting = "voting";
static constexpr auto kWorkers = "workers";
};
struct Keys
{
static constexpr auto kAccountReserve = "account_reserve";
static constexpr auto kAddress = "address";
static constexpr auto kAdmin = "admin";
static constexpr auto kAdminPassword = "admin_password";
static constexpr auto kAdminUser = "admin_user";
static constexpr auto kAdvisoryDelete = "advisory_delete";
static constexpr auto kAgeThresholdSeconds = "age_threshold_seconds";
static constexpr auto kBackOff = "backOff";
static constexpr auto kBackOffMilliseconds = "back_off_milliseconds";
static constexpr auto kBackend = "backend";
static constexpr auto kBbtOptions = "bbt_options";
static constexpr auto kBgThreads = "bg_threads";
static constexpr auto kBlockSize = "block_size";
static constexpr auto kCacheAge = "cache_age";
static constexpr auto kCacheMb = "cache_mb";
static constexpr auto kCacheSize = "cache_size";
static constexpr auto kClientMaxWindowBits = "client_max_window_bits";
static constexpr auto kClientNoContextTakeover = "client_no_context_takeover";
static constexpr auto kCompressLevel = "compress_level";
static constexpr auto kCounts = "counts";
static constexpr auto kDeleteBatch = "delete_batch";
static constexpr auto kEarliestSeq = "earliest_seq";
static constexpr auto kFastLoad = "fast_load";
static constexpr auto kFileSizeMb = "file_size_mb";
static constexpr auto kFileSizeMult = "file_size_mult";
static constexpr auto kFilterBits = "filter_bits";
static constexpr auto kFilterFull = "filter_full";
static constexpr auto kHardSet = "hard_set";
static constexpr auto kHighThreads = "high_threads";
static constexpr auto kHoldTime = "hold_time";
static constexpr auto kIp = "ip";
static constexpr auto kJournalMode = "journal_mode";
static constexpr auto kJournalSizeLimit = "journal_size_limit";
static constexpr auto kLedgersInQueue = "ledgers_in_queue";
static constexpr auto kLimit = "limit";
static constexpr auto kLogInterval = "log_interval";
static constexpr auto kMaxDivergedTime = "max_diverged_time";
static constexpr auto kMaxLedgerCountsToStore = "max_ledger_counts_to_store";
static constexpr auto kMaxUnknownTime = "max_unknown_time";
static constexpr auto kMaximumTxnInLedger = "maximum_txn_in_ledger";
static constexpr auto kMaximumTxnPerAccount = "maximum_txn_per_account";
static constexpr auto kMemoryLevel = "memory_level";
static constexpr auto kMinLedgersToComputeSizeLimit = "min_ledgers_to_compute_size_limit";
static constexpr auto kMinimumEscalationMultiplier = "minimum_escalation_multiplier";
static constexpr auto kMinimumLastLedgerBuffer = "minimum_last_ledger_buffer";
static constexpr auto kMinimumQueueSize = "minimum_queue_size";
static constexpr auto kMinimumTxnInLedger = "minimum_txn_in_ledger";
static constexpr auto kMinimumTxnInLedgerStandalone = "minimum_txn_in_ledger_standalone";
static constexpr auto kNormalConsensusIncreasePercent = "normal_consensus_increase_percent";
static constexpr auto kNudbBlockSize = "nudb_block_size";
static constexpr auto kOnlineDelete = "online_delete";
static constexpr auto kOpenFiles = "open_files";
static constexpr auto kOptions = "options";
static constexpr auto kOverlay = "overlay";
static constexpr auto kOwnerReserve = "owner_reserve";
static constexpr auto kPageSize = "page_size";
static constexpr auto kPassword = "password";
static constexpr auto kPath = "path";
static constexpr auto kPermessageDeflate = "permessage_deflate";
static constexpr auto kPort = "port";
static constexpr auto kPrefix = "prefix";
static constexpr auto kProtocol = "protocol";
static constexpr auto kRecoveryWaitSeconds = "recovery_wait_seconds";
static constexpr auto kReferenceFee = "reference_fee";
static constexpr auto kRelayTime = "relay_time";
static constexpr auto kRetrySequencePercent = "retry_sequence_percent";
static constexpr auto kRqBundle = "rq_bundle";
static constexpr auto kSafetyLevel = "safety_level";
static constexpr auto kSecureGateway = "secure_gateway";
static constexpr auto kSendQueueLimit = "send_queue_limit";
static constexpr auto kServer = "server";
static constexpr auto kServerMaxWindowBits = "server_max_window_bits";
static constexpr auto kServerNoContextTakeover = "server_no_context_takeover";
static constexpr auto kSlowConsensusDecreasePercent = "slow_consensus_decrease_percent";
static constexpr auto kSslCert = "ssl_cert";
static constexpr auto kSslCertChain = "ssl_cert_chain";
static constexpr auto kSslChain = "ssl_chain";
static constexpr auto kSslCiphers = "ssl_ciphers";
static constexpr auto kSslClientCa = "ssl_client_ca";
static constexpr auto kSslKey = "ssl_key";
static constexpr auto kSynchronous = "synchronous";
static constexpr auto kTargetTxnInLedger = "target_txn_in_ledger";
static constexpr auto kTempStore = "temp_store";
static constexpr auto kTxEnable = "tx_enable";
static constexpr auto kTxMetrics = "tx_metrics";
static constexpr auto kTxMinPeers = "tx_min_peers";
static constexpr auto kTxRelayPercentage = "tx_relay_percentage";
static constexpr auto kType = "type";
static constexpr auto kUniversalCompaction = "universal_compaction";
static constexpr auto kUnl = "unl";
static constexpr auto kUseTxTables = "use_tx_tables";
static constexpr auto kUser = "user";
static constexpr auto kVpBaseSquelchEnable = "vp_base_squelch_enable";
static constexpr auto kVpBaseSquelchMaxSelectedPeers = "vp_base_squelch_max_selected_peers";
static constexpr auto kVpEnable = "vp_enable";
};
} // namespace xrpl

View File

@@ -1,13 +1,11 @@
#pragma once
#include <xrpl/basics/BasicConfig.h>
#include <xrpl/core/JobTypes.h>
#include <xrpl/json/json_value.h>
#include <boost/filesystem.hpp>
#include <chrono>
#include <cstdint>
#include <filesystem>
#include <functional>
#include <memory>
#include <string>
@@ -18,6 +16,7 @@ class Journal;
namespace xrpl {
class Application;
class Section;
namespace perf {
/**
@@ -43,7 +42,7 @@ public:
*/
struct Setup
{
boost::filesystem::path perfLog;
std::filesystem::path perfLog;
// log_interval is in milliseconds to support faster testing.
milliseconds logInterval{seconds(1)};
};
@@ -148,7 +147,7 @@ public:
};
PerfLog::Setup
setupPerfLog(Section const& section, boost::filesystem::path const& configDir);
setupPerfLog(Section const& section, std::filesystem::path const& configDir);
std::unique_ptr<PerfLog>
makePerfLog(

View File

@@ -1,6 +1,7 @@
#pragma once
#include <string>
#include <string_view>
#include <vector>
namespace xrpl {
@@ -34,7 +35,7 @@ private:
static void
standard(std::string& strWord);
static int
wsrch(std::string const& strWord, int iMin, int iMax);
wsrch(std::string_view strWord, int iMin, int iMax);
static int
etob(std::string& strData, std::vector<std::string> vsHuman);

View File

@@ -93,7 +93,7 @@ public:
}
void
insert(std::shared_ptr<STTx const> const& txn);
insert(std::shared_ptr<STTx const> txn);
// Pops the next transaction on account that follows seqProx in the
// sort order. Normally called when a transaction is successfully

View File

@@ -1,6 +1,5 @@
#pragma once
#include <xrpl/basics/Expected.h>
#include <xrpl/basics/Log.h>
#include <xrpl/basics/Number.h>
#include <xrpl/beast/utility/Journal.h>
@@ -18,6 +17,8 @@
#include <xrpl/protocol/STAmount.h>
#include <xrpl/protocol/STLedgerEntry.h>
#include <expected>
namespace xrpl {
namespace detail {
@@ -741,7 +742,7 @@ ammPoolHolds(
* provided then they are used as the AMM token pair issues.
* Otherwise the missing issues are fetched from ammSle.
*/
Expected<std::tuple<STAmount, STAmount, STAmount>, TER>
std::expected<std::tuple<STAmount, STAmount, STAmount>, TER>
ammHolds(
ReadView const& view,
SLE const& ammSle,
@@ -801,14 +802,14 @@ initializeFeeAuctionVote(
* otherwise. Return tecINTERNAL if encountered an unexpected condition,
* for instance Liquidity Provider has more than one LPToken trustline.
*/
Expected<bool, TER>
std::expected<bool, TER>
isOnlyLiquidityProvider(ReadView const& view, Issue const& ammIssue, AccountID const& lpAccount);
/** Due to rounding, the LPTokenBalance of the last LP might
* not match the LP's trustline balance. If it's within the tolerance,
* update LPTokenBalance to match the LP's trustline balance.
*/
Expected<bool, TER>
std::expected<bool, TER>
verifyAndAdjustLPTokenBalance(
Sandbox& sb,
STAmount const& lpTokens,

View File

@@ -1,6 +1,5 @@
#pragma once
#include <xrpl/basics/Expected.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/ledger/ApplyView.h>
#include <xrpl/ledger/ReadView.h>
@@ -9,6 +8,7 @@
#include <xrpl/protocol/STLedgerEntry.h>
#include <xrpl/protocol/TER.h>
#include <expected>
#include <set>
#include <vector>
@@ -91,7 +91,7 @@ isPseudoAccount(
* before using a field. The amendment check is **not** performed in
* createPseudoAccount.
*/
[[nodiscard]] Expected<SLE::pointer, TER>
[[nodiscard]] std::expected<SLE::pointer, TER>
createPseudoAccount(ApplyView& view, uint256 const& pseudoOwnerKey, SField const& ownerField);
/** Checks the destination and tag.

View File

@@ -4,6 +4,7 @@
#include <xrpl/protocol/Rules.h>
#include <xrpl/protocol/st.h>
#include <expected>
#include <string_view>
namespace xrpl {
@@ -397,7 +398,7 @@ struct LoanStateDeltas
nonNegative();
};
Expected<std::pair<LoanPaymentParts, LoanProperties>, TER>
std::expected<std::pair<LoanPaymentParts, LoanProperties>, TER>
tryOverpayment(
Rules const& rules,
Asset const& asset,
@@ -523,7 +524,7 @@ isRounded(Asset const& asset, Number const& value, std::int32_t scale);
// potential extra work at the end.
enum class LoanPaymentType { Regular = 0, Late, Full, Overpayment };
Expected<LoanPaymentParts, TER>
std::expected<LoanPaymentParts, TER>
loanMakePayment(
Asset const& asset,
ApplyView& view,

View File

@@ -53,7 +53,7 @@ public:
boost::system::error_code const& ecResult,
int iStatus,
std::string const& strData)> complete,
beast::Journal& j);
beast::Journal const& j);
static void
get(bool bSSL,
@@ -67,7 +67,7 @@ public:
boost::system::error_code const& ecResult,
int iStatus,
std::string const& strData)> complete,
beast::Journal& j);
beast::Journal const& j);
static void
request(
@@ -82,7 +82,7 @@ public:
boost::system::error_code const& ecResult,
int iStatus,
std::string const& strData)> complete,
beast::Journal& j);
beast::Journal const& j);
};
} // namespace xrpl

View File

@@ -1,6 +1,5 @@
#pragma once
#include <xrpl/basics/BasicConfig.h>
#include <xrpl/basics/Log.h>
#include <xrpl/basics/TaggedCache.ipp>
#include <xrpl/nodestore/Backend.h>
@@ -10,6 +9,10 @@
#include <condition_variable>
namespace xrpl {
class Section;
} // namespace xrpl
namespace xrpl::NodeStore {
/** Persistency layer for NodeObject

View File

@@ -1,12 +1,15 @@
#pragma once
#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>
namespace xrpl {
class Section;
} // namespace xrpl
namespace xrpl::NodeStore {
/** Base class for backend factories. */

View File

@@ -2,6 +2,8 @@
#include <xrpl/basics/TaggedCache.h>
#include <xrpl/basics/chrono.h>
#include <xrpl/config/BasicConfig.h>
#include <xrpl/config/Constants.h>
#include <xrpl/nodestore/Database.h>
namespace xrpl::NodeStore {
@@ -24,16 +26,16 @@ public:
{
std::optional<int> cacheSize, cacheAge;
if (config.exists("cache_size"))
if (config.exists(Keys::kCacheSize))
{
cacheSize = get<int>(config, "cache_size");
cacheSize = get<int>(config, Keys::kCacheSize);
if (cacheSize.value() < 0)
Throw<std::runtime_error>("Specified negative value for cache_size");
}
if (config.exists("cache_age"))
if (config.exists(Keys::kCacheAge))
{
cacheAge = get<int>(config, "cache_age");
cacheAge = get<int>(config, Keys::kCacheAge);
if (cacheAge.value() < 0)
Throw<std::runtime_error>("Specified negative value for cache_age");
}

View File

@@ -65,7 +65,7 @@ invalidAMMAssetPair(
std::optional<std::uint8_t>
ammAuctionTimeSlot(std::uint64_t current, STObject const& auctionSlot);
/** Return true if required AMM amendments are enabled
/** Return true if required AMM amendment is enabled
*/
bool
ammEnabled(Rules const&);

View File

@@ -1,6 +1,5 @@
#pragma once
#include <xrpl/basics/LocalValue.h>
#include <xrpl/basics/Number.h>
#include <xrpl/beast/utility/Zero.h>
@@ -179,36 +178,4 @@ to_string(IOUAmount const& amount);
IOUAmount
mulRatio(IOUAmount const& amt, std::uint32_t num, std::uint32_t den, bool roundUp);
// Since many uses of the number class do not have access to a ledger,
// getSTNumberSwitchover needs to be globally accessible.
bool
getSTNumberSwitchover();
void
setSTNumberSwitchover(bool v);
/** RAII class to set and restore the Number switchover.
*/
class NumberSO
{
bool saved_;
public:
~NumberSO()
{
setSTNumberSwitchover(saved_);
}
NumberSO(NumberSO const&) = delete;
NumberSO&
operator=(NumberSO const&) = delete;
explicit NumberSO(bool v) : saved_(getSTNumberSwitchover())
{
setSTNumberSwitchover(v);
}
};
} // namespace xrpl

View File

@@ -122,7 +122,6 @@ private:
std::optional<Rules> saved_;
};
class NumberSO;
class NumberMantissaScaleGuard;
bool
@@ -131,7 +130,6 @@ useRulesGuards(Rules const& rules);
void
createGuards(
Rules const& rules,
std::optional<NumberSO>& stNumberSO,
std::optional<CurrentTransactionRulesGuard>& rulesGuard,
std::optional<NumberMantissaScaleGuard>& mantissaScaleGuard);

View File

@@ -1,6 +1,5 @@
#pragma once
#include <xrpl/basics/Expected.h>
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/PublicKey.h>
#include <xrpl/protocol/Rules.h>
@@ -11,6 +10,7 @@
#include <boost/container/flat_set.hpp>
#include <expected>
#include <functional>
namespace xrpl {
@@ -108,10 +108,10 @@ public:
@param rules The current ledger rules.
@return `true` if valid signature. If invalid, the error message string.
*/
Expected<void, std::string>
std::expected<void, std::string>
checkSign(Rules const& rules) const;
Expected<void, std::string>
std::expected<void, std::string>
checkBatchSign(Rules const& rules) const;
// SQL Functions with metadata.
@@ -138,19 +138,19 @@ private:
Will be *this more often than not.
@return `true` if valid signature. If invalid, the error message string.
*/
Expected<void, std::string>
std::expected<void, std::string>
checkSign(Rules const& rules, STObject const& sigObject) const;
Expected<void, std::string>
std::expected<void, std::string>
checkSingleSign(STObject const& sigObject) const;
Expected<void, std::string>
std::expected<void, std::string>
checkMultiSign(Rules const& rules, STObject const& sigObject) const;
Expected<void, std::string>
std::expected<void, std::string>
checkBatchSingleSign(STObject const& batchSigner) const;
Expected<void, std::string>
std::expected<void, std::string>
checkBatchMultiSign(STObject const& batchSigner, Rules const& rules) const;
STBase*

View File

@@ -17,8 +17,8 @@ public:
STVector256() = default;
explicit STVector256(SField const& n);
explicit STVector256(std::vector<uint256> const& vector);
STVector256(SField const& n, std::vector<uint256> const& vector);
explicit STVector256(std::vector<uint256> vector);
STVector256(SField const& n, std::vector<uint256> vector);
STVector256(SerialIter& sit, SField const& name);
[[nodiscard]] SerializedTypeID
@@ -103,12 +103,12 @@ inline STVector256::STVector256(SField const& n) : STBase(n)
{
}
inline STVector256::STVector256(std::vector<uint256> const& vector) : value_(vector)
inline STVector256::STVector256(std::vector<uint256> vector) : value_(std::move(vector))
{
}
inline STVector256::STVector256(SField const& n, std::vector<uint256> const& vector)
: STBase(n), value_(vector)
inline STVector256::STVector256(SField const& n, std::vector<uint256> vector)
: STBase(n), value_(std::move(vector))
{
}

View File

@@ -1,7 +1,6 @@
#pragma once
#include <xrpl/basics/Buffer.h>
#include <xrpl/basics/Expected.h>
#include <xrpl/protocol/AccountID.h>
#include <xrpl/protocol/Issue.h>
#include <xrpl/protocol/PublicKey.h>
@@ -15,6 +14,7 @@
#include <boost/container/vector.hpp>
#include <cstddef>
#include <expected>
#include <utility>
#include <vector>

View File

@@ -37,7 +37,7 @@ private:
// The largest "small object" we can accommodate
static constexpr std::size_t kMaxSize = 72;
std::aligned_storage<kMaxSize>::type d_ = {};
alignas(std::max_align_t) std::byte d_[kMaxSize] = {};
STBase* p_ = nullptr;
public:

View File

@@ -15,7 +15,7 @@
// Add new amendments to the top of this list.
// Keep it sorted in reverse chronological order.
XRPL_FEATURE(LendingProtocolV1_1, Supported::No, VoteBehavior::DefaultNo)
XRPL_FIX (Cleanup3_3_0, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FIX (Cleanup3_2_0, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(MPTokensV2, Supported::No, VoteBehavior::DefaultNo)
XRPL_FIX (Cleanup3_1_3, Supported::Yes, VoteBehavior::DefaultYes)
@@ -65,7 +65,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 (UniversalNumber, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(XRPFees, Supported::Yes, VoteBehavior::DefaultNo)
XRPL_FIX (RemoveNFTokenAutoTrustLine, Supported::Yes, VoteBehavior::DefaultYes)
@@ -113,6 +112,7 @@ XRPL_RETIRE_FIX(RmSmallIncreasedQOffers)
XRPL_RETIRE_FIX(STAmountCanonicalize)
XRPL_RETIRE_FIX(TakerDryOfferRemoval)
XRPL_RETIRE_FIX(TrustLinesToSelf)
XRPL_RETIRE_FIX(UniversalNumber)
XRPL_RETIRE_FEATURE(Checks)
XRPL_RETIRE_FEATURE(CheckCashMakesTrustLine)

View File

@@ -887,7 +887,6 @@ TRANSACTION(ttVAULT_DELETE, 67, VaultDelete,
MustDeleteAcct | DestroyMptIssuance | MustModifyVault,
({
{sfVaultID, SoeRequired},
{sfMemoData, SoeOptional},
}))
/** This transaction trades assets for shares with a vault. */

View File

@@ -1,10 +1,10 @@
#pragma once
#include <xrpl/basics/Expected.h>
#include <xrpl/basics/contract.h>
#include <xrpl/protocol/detail/token_errors.h>
#include <cstdint>
#include <expected>
#include <optional>
#include <span>
#include <string>
@@ -13,7 +13,7 @@
namespace xrpl {
template <class T>
using B58Result = Expected<T, std::error_code>;
using B58Result = std::expected<T, std::error_code>;
enum class TokenType : std::uint8_t {
None = 1, // unused

View File

@@ -57,32 +57,6 @@ public:
{
return this->tx_->at(sfVaultID);
}
/**
* @brief Get sfMemoData (SoeOptional)
* @return The field value, or std::nullopt if not present.
*/
[[nodiscard]]
protocol_autogen::Optional<SF_VL::type::value_type>
getMemoData() const
{
if (hasMemoData())
{
return this->tx_->at(sfMemoData);
}
return std::nullopt;
}
/**
* @brief Check if sfMemoData is present.
* @return True if the field is present, false otherwise.
*/
[[nodiscard]]
bool
hasMemoData() const
{
return this->tx_->isFieldPresent(sfMemoData);
}
};
/**
@@ -138,17 +112,6 @@ public:
return *this;
}
/**
* @brief Set sfMemoData (SoeOptional)
* @return Reference to this builder for method chaining.
*/
VaultDeleteBuilder&
setMemoData(std::decay_t<typename SF_VL::type::value_type> const& value)
{
object_[sfMemoData] = value;
return *this;
}
/**
* @brief Build and return the VaultDelete wrapper.
* @param publicKey The public key for signing.

View File

@@ -6,8 +6,7 @@
#include <xrpl/rdb/DBInit.h>
#include <xrpl/rdb/SociDB.h>
#include <boost/filesystem/path.hpp>
#include <filesystem>
#include <mutex>
#include <optional>
#include <string>
@@ -72,7 +71,7 @@ public:
StartUpType startUp = StartUpType::Normal;
bool standAlone = false;
boost::filesystem::path dataDir;
std::filesystem::path dataDir;
// Indicates whether or not to return the `globalPragma`
// from commonPragma()
bool useGlobalPragma = false;
@@ -135,7 +134,7 @@ public:
template <std::size_t N, std::size_t M>
DatabaseCon(
boost::filesystem::path const& dataDir,
std::filesystem::path const& dataDir,
std::string const& dbName,
std::array<std::string, N> const& pragma,
std::array<char const*, M> const& initSQL,
@@ -147,7 +146,7 @@ public:
// Use this constructor to setup checkpointing
template <std::size_t N, std::size_t M>
DatabaseCon(
boost::filesystem::path const& dataDir,
std::filesystem::path const& dataDir,
std::string const& dbName,
std::array<std::string, N> const& pragma,
std::array<char const*, M> const& initSQL,
@@ -182,7 +181,7 @@ private:
template <std::size_t N, std::size_t M>
DatabaseCon(
boost::filesystem::path const& pPath,
std::filesystem::path const& pPath,
std::vector<std::string> const* commonPragma,
std::array<std::string, N> const& pragma,
std::array<char const*, M> const& initSQL,

View File

@@ -10,7 +10,6 @@
#include <xrpl/protocol/TxSearched.h>
#include <xrpl/rdb/DatabaseCon.h>
#include <boost/filesystem.hpp>
#include <boost/variant.hpp>
namespace xrpl {

View File

@@ -1,6 +1,5 @@
#pragma once
#include <xrpl/basics/BasicConfig.h>
#include <xrpl/beast/net/IPEndpoint.h>
#include <boost/asio/ip/address.hpp>
@@ -14,6 +13,7 @@
#include <optional>
#include <set>
#include <string>
#include <vector>
namespace boost::asio::ssl {
class context; // NOLINT(readability-identifier-naming) -- external library name
@@ -21,6 +21,8 @@ class context; // NOLINT(readability-identifier-naming) -- external library nam
namespace xrpl {
class Section;
/** Configuration information for a Server listening port. */
struct Port
{

View File

@@ -10,6 +10,7 @@
#include <functional>
#include <memory>
#include <ostream>
#include <string_view>
#include <vector>
namespace xrpl {
@@ -53,10 +54,10 @@ public:
/** Send a copy of data asynchronously. */
/** @{ */
void
write(std::string const& s)
write(std::string_view s)
{
if (!s.empty())
write(&s[0], std::distance(s.begin(), s.end()));
write(s.data(), s.size());
}
template <typename BufferSequence>

View File

@@ -4,8 +4,6 @@
#include <xrpl/rdb/DatabaseCon.h>
#include <xrpl/server/Manifest.h>
#include <boost/filesystem.hpp>
namespace xrpl {
struct SavedState

View File

@@ -161,7 +161,7 @@ public:
setLedgerSeq(std::uint32_t lseq);
bool
fetchRoot(SHAMapHash const& hash, SHAMapSyncFilter* filter);
fetchRoot(SHAMapHash const& hash, SHAMapSyncFilter const* filter);
// normal hash access functions
@@ -248,7 +248,7 @@ public:
@param return The nodes known to be missing
*/
std::vector<std::pair<SHAMapNodeID, uint256>>
getMissingNodes(int maxNodes, SHAMapSyncFilter* filter);
getMissingNodes(int maxNodes, SHAMapSyncFilter const* filter);
bool
getNodeFat(
@@ -281,9 +281,9 @@ public:
serializeRoot(Serializer& s) const;
SHAMapAddNode
addRootNode(SHAMapHash const& hash, Slice const& rootNode, SHAMapSyncFilter* filter);
addRootNode(SHAMapHash const& hash, Slice const& rootNode, SHAMapSyncFilter const* filter);
SHAMapAddNode
addKnownNode(SHAMapNodeID const& nodeID, Slice const& rawNode, SHAMapSyncFilter* filter);
addKnownNode(SHAMapNodeID const& nodeID, Slice const& rawNode, SHAMapSyncFilter const* filter);
// status functions
void
@@ -343,11 +343,11 @@ private:
SHAMapTreeNodePtr
fetchNodeNT(SHAMapHash const& hash) const;
SHAMapTreeNodePtr
fetchNodeNT(SHAMapHash const& hash, SHAMapSyncFilter* filter) const;
fetchNodeNT(SHAMapHash const& hash, SHAMapSyncFilter const* filter) const;
SHAMapTreeNodePtr
fetchNode(SHAMapHash const& hash) const;
SHAMapTreeNodePtr
checkFilter(SHAMapHash const& hash, SHAMapSyncFilter* filter) const;
checkFilter(SHAMapHash const& hash, SHAMapSyncFilter const* filter) const;
/** Update hashes up to the root */
void
@@ -411,7 +411,7 @@ private:
descendAsync(
SHAMapInnerNode* parent,
int branch,
SHAMapSyncFilter* filter,
SHAMapSyncFilter const* filter,
bool& pending,
descendCallback&&) const;
@@ -420,7 +420,7 @@ private:
SHAMapInnerNode* parent,
SHAMapNodeID const& parentID,
int branch,
SHAMapSyncFilter* filter) const;
SHAMapSyncFilter const* filter) const;
// Non-storing
// Does not hook the returned node to its parent
@@ -461,7 +461,7 @@ private:
// basic parameters
int max;
SHAMapSyncFilter* filter;
SHAMapSyncFilter const* filter;
int const maxDefer;
std::uint32_t generation;
@@ -500,7 +500,11 @@ private:
// reads
std::map<SHAMapInnerNode*, SHAMapNodeID> resumes;
MissingNodes(int max, SHAMapSyncFilter* filter, int maxDefer, std::uint32_t generation)
MissingNodes(
int max,
SHAMapSyncFilter const* filter,
int maxDefer,
std::uint32_t generation)
: max(max), filter(filter), maxDefer(maxDefer), generation(generation), deferred(0)
{
missingNodes.reserve(max);

View File

@@ -5,6 +5,7 @@
#include <optional>
#include <string>
#include <string_view>
#include <tuple>
namespace xrpl {
@@ -127,7 +128,7 @@ operator<<(std::ostream& out, SHAMapNodeID const& node)
deserializeSHAMapNodeID(void const* data, std::size_t size);
[[nodiscard]] inline std::optional<SHAMapNodeID>
deserializeSHAMapNodeID(std::string const& s)
deserializeSHAMapNodeID(std::string_view s)
{
return deserializeSHAMapNodeID(s.data(), s.size());
}

View File

@@ -1,11 +1,11 @@
#pragma once
#include <xrpl/basics/Expected.h> //
#include <xrpl/beast/utility/Journal.h> // beast::Journal
#include <xrpl/protocol/TER.h> // temMALFORMED
#include <xrpl/protocol/UintTypes.h> // AccountID
#include <xrpl/tx/Transactor.h> // NotTEC
#include <expected>
#include <optional>
#include <string_view>
@@ -60,7 +60,7 @@ public:
// obj Contains a SignerEntries field that is an STArray.
// journal For reporting error conditions.
// annotation Source of SignerEntries, like "ledger" or "transaction".
static Expected<std::vector<SignerEntry>, NotTEC>
static std::expected<std::vector<SignerEntry>, NotTEC>
deserialize(STObject const& obj, beast::Journal journal, std::string_view annotation);
};

View File

@@ -1,9 +1,10 @@
#pragma once
#include <xrpl/basics/Expected.h>
#include <xrpl/protocol/UintTypes.h>
#include <xrpl/tx/Transactor.h>
#include <expected>
namespace xrpl {
// NOLINTBEGIN(readability-redundant-member-init)
@@ -61,7 +62,7 @@ public:
ReadView const& view,
beast::Journal const& j) override;
static Expected<MPTID, TER>
static std::expected<MPTID, TER>
create(ApplyView& view, beast::Journal journal, MPTCreateArgs const& args);
};

View File

@@ -2,6 +2,8 @@
#include <xrpl/tx/Transactor.h>
#include <expected>
namespace xrpl {
class VaultClawback : public Transactor
@@ -34,7 +36,7 @@ public:
beast::Journal const& j) override;
private:
Expected<std::pair<STAmount, STAmount>, TER>
std::expected<std::pair<STAmount, STAmount>, TER>
assetsToClawback(
SLE::ref vault,
SLE::const_ref sleShareIssuance,

View File

@@ -10,10 +10,12 @@ cmake --version
conan --version
curl --version
doxygen --version
file --version
g++ --version
gcc --version
gcov --version
gcovr --version
gh --version
git --version
git-cliff --version
gpg --version

View File

@@ -13,7 +13,9 @@ in
conan
curlMinimal # needed for codecov/codecov-action
doxygen
file # needed for cpack in Clio
gcovr
gh
git
git-cliff
gnumake

View File

@@ -2,22 +2,20 @@
#include <xrpl/basics/contract.h>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <archive.h>
#include <archive_entry.h>
#include <cstddef>
#include <filesystem>
#include <memory>
#include <stdexcept>
namespace xrpl {
void
extractTarLz4(boost::filesystem::path const& src, boost::filesystem::path const& dst)
extractTarLz4(std::filesystem::path const& src, std::filesystem::path const& dst)
{
if (!is_regular_file(src))
if (!std::filesystem::is_regular_file(src))
Throw<std::runtime_error>("Invalid source file");
using archive_ptr = std::unique_ptr<struct archive, void (*)(struct archive*)>;

View File

@@ -1,29 +1,24 @@
#include <xrpl/basics/FileUtilities.h>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/system/detail/errc.hpp>
#include <boost/system/detail/error_code.hpp>
#include <boost/system/errc.hpp>
#include <cerrno>
#include <cstddef>
#include <filesystem>
#include <fstream>
#include <ios>
#include <iterator>
#include <optional>
#include <string>
#include <system_error>
namespace xrpl {
std::string
getFileContents(
boost::system::error_code& ec,
boost::filesystem::path const& sourcePath,
std::error_code& ec,
std::filesystem::path const& sourcePath,
std::optional<std::size_t> maxSize)
{
using namespace boost::filesystem;
using namespace boost::system::errc;
using namespace std::filesystem;
path const fullPath{canonical(sourcePath, ec)};
if (ec)
@@ -32,15 +27,15 @@ getFileContents(
if (maxSize && (file_size(fullPath, ec) > *maxSize || ec))
{
if (!ec)
ec = make_error_code(file_too_large);
ec = make_error_code(std::errc::file_too_large);
return {};
}
std::ifstream fileStream(fullPath.string(), std::ios::in);
std::ifstream fileStream(fullPath, std::ios::in);
if (!fileStream)
{
ec = make_error_code(static_cast<errc_t>(errno));
ec.assign(errno, std::generic_category());
return {};
}
@@ -49,7 +44,7 @@ getFileContents(
if (fileStream.bad())
{
ec = make_error_code(static_cast<errc_t>(errno));
ec.assign(errno, std::generic_category());
return {};
}
@@ -58,18 +53,15 @@ getFileContents(
void
writeFileContents(
boost::system::error_code& ec,
boost::filesystem::path const& destPath,
std::error_code& ec,
std::filesystem::path const& destPath,
std::string const& contents)
{
using namespace boost::filesystem;
using namespace boost::system::errc;
std::ofstream fileStream(destPath.string(), std::ios::out | std::ios::trunc);
std::ofstream fileStream(destPath, std::ios::out | std::ios::trunc);
if (!fileStream)
{
ec = make_error_code(static_cast<errc_t>(errno));
ec.assign(errno, std::generic_category());
return;
}
@@ -77,7 +69,7 @@ writeFileContents(
if (fileStream.bad())
{
ec = make_error_code(static_cast<errc_t>(errno));
ec.assign(errno, std::generic_category());
return;
}
}

View File

@@ -5,10 +5,10 @@
#include <xrpl/beast/utility/instrumentation.h>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/filesystem/path.hpp>
#include <chrono>
#include <cstring>
#include <filesystem>
#include <fstream>
#include <functional>
#include <iostream>
@@ -54,7 +54,7 @@ Logs::File::isOpen() const noexcept
}
bool
Logs::File::open(boost::filesystem::path const& path)
Logs::File::open(std::filesystem::path const& path)
{
close();
@@ -114,7 +114,7 @@ Logs::Logs(beast::Severity thresh) : thresh_(thresh) // default severity
}
bool
Logs::open(boost::filesystem::path const& pathToLogFile)
Logs::open(std::filesystem::path const& pathToLogFile)
{
return file_.open(pathToLogFile);
}

View File

@@ -66,7 +66,7 @@ public:
class StatsDHookImpl : public HookImpl, public StatsDMetricBase
{
public:
StatsDHookImpl(HandlerType handler, std::shared_ptr<StatsDCollectorImp> const& impl);
StatsDHookImpl(HandlerType handler, std::shared_ptr<StatsDCollectorImp> impl);
~StatsDHookImpl() override;
@@ -86,7 +86,7 @@ private:
class StatsDCounterImpl : public CounterImpl, public StatsDMetricBase
{
public:
StatsDCounterImpl(std::string name, std::shared_ptr<StatsDCollectorImp> const& impl);
StatsDCounterImpl(std::string name, std::shared_ptr<StatsDCollectorImp> impl);
~StatsDCounterImpl() override;
@@ -115,7 +115,7 @@ private:
class StatsDEventImpl : public EventImpl
{
public:
StatsDEventImpl(std::string name, std::shared_ptr<StatsDCollectorImp> const& impl);
StatsDEventImpl(std::string name, std::shared_ptr<StatsDCollectorImp> impl);
~StatsDEventImpl() override = default;
@@ -140,7 +140,7 @@ private:
class StatsDGaugeImpl : public GaugeImpl, public StatsDMetricBase
{
public:
StatsDGaugeImpl(std::string name, std::shared_ptr<StatsDCollectorImp> const& impl);
StatsDGaugeImpl(std::string name, std::shared_ptr<StatsDCollectorImp> impl);
~StatsDGaugeImpl() override;
@@ -174,7 +174,7 @@ private:
class StatsDMeterImpl : public MeterImpl, public StatsDMetricBase
{
public:
explicit StatsDMeterImpl(std::string name, std::shared_ptr<StatsDCollectorImp> const& impl);
explicit StatsDMeterImpl(std::string name, std::shared_ptr<StatsDCollectorImp> impl);
~StatsDMeterImpl() override;
@@ -478,8 +478,8 @@ public:
//------------------------------------------------------------------------------
StatsDHookImpl::StatsDHookImpl(HandlerType handler, std::shared_ptr<StatsDCollectorImp> const& impl)
: impl_(impl), handler_(std::move(handler))
StatsDHookImpl::StatsDHookImpl(HandlerType handler, std::shared_ptr<StatsDCollectorImp> impl)
: impl_(std::move(impl)), handler_(std::move(handler))
{
impl_->add(*this);
}
@@ -497,10 +497,8 @@ StatsDHookImpl::doProcess()
//------------------------------------------------------------------------------
StatsDCounterImpl::StatsDCounterImpl(
std::string name,
std::shared_ptr<StatsDCollectorImp> const& impl)
: impl_(impl), name_(std::move(name))
StatsDCounterImpl::StatsDCounterImpl(std::string name, std::shared_ptr<StatsDCollectorImp> impl)
: impl_(std::move(impl)), name_(std::move(name))
{
impl_->add(*this);
}
@@ -550,8 +548,8 @@ StatsDCounterImpl::doProcess()
//------------------------------------------------------------------------------
StatsDEventImpl::StatsDEventImpl(std::string name, std::shared_ptr<StatsDCollectorImp> const& impl)
: impl_(impl), name_(std::move(name))
StatsDEventImpl::StatsDEventImpl(std::string name, std::shared_ptr<StatsDCollectorImp> impl)
: impl_(std::move(impl)), name_(std::move(name))
{
}
@@ -577,8 +575,8 @@ StatsDEventImpl::doNotify(EventImpl::value_type const& value)
//------------------------------------------------------------------------------
StatsDGaugeImpl::StatsDGaugeImpl(std::string name, std::shared_ptr<StatsDCollectorImp> const& impl)
: impl_(impl), name_(std::move(name))
StatsDGaugeImpl::StatsDGaugeImpl(std::string name, std::shared_ptr<StatsDCollectorImp> impl)
: impl_(std::move(impl)), name_(std::move(name))
{
impl_->add(*this);
}
@@ -664,8 +662,8 @@ StatsDGaugeImpl::doProcess()
//------------------------------------------------------------------------------
StatsDMeterImpl::StatsDMeterImpl(std::string name, std::shared_ptr<StatsDCollectorImp> const& impl)
: impl_(impl), name_(std::move(name))
StatsDMeterImpl::StatsDMeterImpl(std::string name, std::shared_ptr<StatsDCollectorImp> impl)
: impl_(std::move(impl)), name_(std::move(name))
{
impl_->add(*this);
}

View File

@@ -1,4 +1,4 @@
#include <xrpl/basics/BasicConfig.h>
#include <xrpl/config/BasicConfig.h>
#include <xrpl/basics/StringUtilities.h>

View File

@@ -13,6 +13,7 @@
#include <cstdint>
#include <cstring>
#include <string>
#include <string_view>
#include <vector>
namespace xrpl {
@@ -306,7 +307,7 @@ RFC1751::standard(std::string& strWord)
// Binary search of dictionary.
int
RFC1751::wsrch(std::string const& strWord, int iMin, int iMax)
RFC1751::wsrch(std::string_view strWord, int iMin, int iMax)
{
int iResult = -1;

View File

@@ -40,14 +40,10 @@ CanonicalTXSet::accountKey(AccountID const& account)
}
void
CanonicalTXSet::insert(std::shared_ptr<STTx const> const& txn)
CanonicalTXSet::insert(std::shared_ptr<STTx const> txn)
{
map_.insert(
std::make_pair(
Key(accountKey(txn->getAccountID(sfAccount)),
txn->getSeqProxy(),
txn->getTransactionID()),
txn));
Key key(accountKey(txn->getAccountID(sfAccount)), txn->getSeqProxy(), txn->getTransactionID());
map_.emplace(key, std::move(txn));
}
std::shared_ptr<STTx const>

View File

@@ -1,6 +1,5 @@
#include <xrpl/ledger/helpers/AMMHelpers.h>
#include <xrpl/basics/Expected.h>
#include <xrpl/basics/Log.h>
#include <xrpl/basics/Number.h>
#include <xrpl/basics/base_uint.h>
@@ -34,6 +33,7 @@
#include <algorithm>
#include <chrono>
#include <cstdint>
#include <expected>
#include <functional>
#include <optional>
#include <tuple>
@@ -433,7 +433,7 @@ ammPoolHolds(
return std::make_pair(assetInBalance, assetOutBalance);
}
Expected<std::tuple<STAmount, STAmount, STAmount>, TER>
std::expected<std::tuple<STAmount, STAmount, STAmount>, TER>
ammHolds(
ReadView const& view,
SLE const& ammSle,
@@ -489,7 +489,7 @@ ammHolds(
return std::make_optional(std::make_pair(asset1, asset2));
}();
if (!assets)
return Unexpected(tecAMM_INVALID_TOKENS);
return std::unexpected(tecAMM_INVALID_TOKENS);
auto const [amount1, amount2] = ammPoolHolds(
view,
ammSle.getAccountID(sfAccount),
@@ -821,7 +821,7 @@ initializeFeeAuctionVote(
auctionSlot.makeFieldAbsent(sfAuthAccounts);
}
Expected<bool, TER>
std::expected<bool, TER>
isOnlyLiquidityProvider(ReadView const& view, Issue const& ammIssue, AccountID const& lpAccount)
{
// Liquidity Provider (LP) must have one LPToken trustline
@@ -852,18 +852,18 @@ isOnlyLiquidityProvider(ReadView const& view, Issue const& ammIssue, AccountID c
{
auto const ownerDir = view.read(currentIndex);
if (!ownerDir)
return Unexpected<TER>(tecINTERNAL); // LCOV_EXCL_LINE
return std::unexpected<TER>(tecINTERNAL); // LCOV_EXCL_LINE
for (auto const& key : ownerDir->getFieldV256(sfIndexes))
{
auto const sle = view.read(keylet::child(key));
if (!sle)
return Unexpected<TER>(tecINTERNAL); // LCOV_EXCL_LINE
return std::unexpected<TER>(tecINTERNAL); // LCOV_EXCL_LINE
auto const entryType = sle->getFieldU16(sfLedgerEntryType);
// Only one AMM object
if (entryType == ltAMM)
{
if (hasAMM)
return Unexpected<TER>(tecINTERNAL); // LCOV_EXCL_LINE
return std::unexpected<TER>(tecINTERNAL); // LCOV_EXCL_LINE
hasAMM = true;
continue;
}
@@ -873,7 +873,7 @@ isOnlyLiquidityProvider(ReadView const& view, Issue const& ammIssue, AccountID c
continue;
}
if (entryType != ltRIPPLE_STATE)
return Unexpected<TER>(tecINTERNAL); // LCOV_EXCL_LINE
return std::unexpected<TER>(tecINTERNAL); // LCOV_EXCL_LINE
auto const lowLimit = sle->getFieldAmount(sfLowLimit);
auto const highLimit = sle->getFieldAmount(sfHighLimit);
auto const isLPTrustline =
@@ -889,12 +889,12 @@ isOnlyLiquidityProvider(ReadView const& view, Issue const& ammIssue, AccountID c
{
// LP has exactly one LPToken trustline
if (++nLPTokenTrustLines > 1)
return Unexpected<TER>(tecINTERNAL); // LCOV_EXCL_LINE
return std::unexpected<TER>(tecINTERNAL); // LCOV_EXCL_LINE
}
// AMM account has at most two IOU trustlines
else if (++nIOUTrustLines > 2)
{
return Unexpected<TER>(tecINTERNAL); // LCOV_EXCL_LINE
return std::unexpected<TER>(tecINTERNAL); // LCOV_EXCL_LINE
}
}
// Another Liquidity Provider LPToken trustline
@@ -905,7 +905,7 @@ isOnlyLiquidityProvider(ReadView const& view, Issue const& ammIssue, AccountID c
// AMM account has at most two IOU trustlines
else if (++nIOUTrustLines > 2)
{
return Unexpected<TER>(tecINTERNAL); // LCOV_EXCL_LINE
return std::unexpected<TER>(tecINTERNAL); // LCOV_EXCL_LINE
}
}
auto const uNodeNext = ownerDir->getFieldU64(sfIndexNext);
@@ -913,15 +913,15 @@ isOnlyLiquidityProvider(ReadView const& view, Issue const& ammIssue, AccountID c
{
if (nLPTokenTrustLines != 1 || (nIOUTrustLines == 0 && nMPT == 0) ||
(nIOUTrustLines > 2 || nMPT > 2) || (nIOUTrustLines + nMPT) > 2)
return Unexpected<TER>(tecINTERNAL); // LCOV_EXCL_LINE
return std::unexpected<TER>(tecINTERNAL); // LCOV_EXCL_LINE
return true;
}
currentIndex = keylet::page(root, uNodeNext);
}
return Unexpected<TER>(tecINTERNAL); // LCOV_EXCL_LINE
return std::unexpected<TER>(tecINTERNAL); // LCOV_EXCL_LINE
}
Expected<bool, TER>
std::expected<bool, TER>
verifyAndAdjustLPTokenBalance(
Sandbox& sb,
STAmount const& lpTokens,
@@ -931,7 +931,7 @@ verifyAndAdjustLPTokenBalance(
auto const res = isOnlyLiquidityProvider(sb, lpTokens.get<Issue>(), account);
if (!res.has_value())
{
return Unexpected<TER>(res.error());
return std::unexpected<TER>(res.error());
}
if (res.value())
@@ -944,7 +944,7 @@ verifyAndAdjustLPTokenBalance(
}
else
{
return Unexpected<TER>(tecAMM_INVALID_TOKENS);
return std::unexpected<TER>(tecAMM_INVALID_TOKENS);
}
}
return true;

View File

@@ -1,6 +1,5 @@
#include <xrpl/ledger/helpers/AccountRootHelpers.h>
#include <xrpl/basics/Expected.h>
#include <xrpl/basics/Log.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/basics/contract.h>
@@ -22,6 +21,7 @@
#include <algorithm>
#include <cstdint>
#include <expected>
#include <limits>
#include <memory>
#include <optional>
@@ -202,7 +202,7 @@ isPseudoAccount(SLE::const_pointer sleAcct, std::set<SField const*> const& pseud
}) > 0;
}
Expected<SLE::pointer, TER>
std::expected<SLE::pointer, TER>
createPseudoAccount(ApplyView& view, uint256 const& pseudoOwnerKey, SField const& ownerField)
{
[[maybe_unused]]
@@ -216,7 +216,7 @@ createPseudoAccount(ApplyView& view, uint256 const& pseudoOwnerKey, SField const
auto const accountId = pseudoAccountAddress(view, pseudoOwnerKey);
if (accountId == beast::kZero)
return Unexpected(tecDUPLICATE);
return std::unexpected(tecDUPLICATE);
// Create pseudo-account.
auto account = std::make_shared<SLE>(keylet::account(accountId));

View File

@@ -1,6 +1,5 @@
#include <xrpl/ledger/helpers/CredentialHelpers.h>
#include <xrpl/basics/Expected.h>
#include <xrpl/basics/Log.h>
#include <xrpl/basics/Slice.h>
#include <xrpl/basics/base_uint.h>
@@ -24,6 +23,7 @@
#include <xrpl/protocol/digest.h>
#include <cstdint>
#include <expected>
#include <limits>
#include <set>
#include <unordered_set>
@@ -43,7 +43,7 @@ checkExpired(SLE const& sleCredential, NetClock::time_point const& closed)
}
[[nodiscard]]
static Expected<bool, TER>
static std::expected<bool, TER>
removeExpired(ApplyView& view, STVector256 const& arr, beast::Journal const j)
{
auto const closeTime = view.header().parentCloseTime;
@@ -61,7 +61,7 @@ removeExpired(ApplyView& view, STVector256 const& arr, beast::Journal const j)
// delete expired credentials even if the transaction failed
auto const err = deleteSLE(view, sleCred, j);
if (view.rules().enabled(fixCleanup3_1_3) && !isTesSuccess(err))
return Unexpected(err);
return std::unexpected(err);
foundExpired = true;
}
}

View File

@@ -1,6 +1,5 @@
#include <xrpl/ledger/helpers/LendingHelpers.h>
#include <xrpl/basics/Expected.h>
#include <xrpl/basics/Log.h>
#include <xrpl/basics/Number.h>
#include <xrpl/basics/chrono.h>
@@ -25,6 +24,7 @@
#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <expected>
#include <string_view>
#include <utility>
@@ -514,7 +514,7 @@ doPayment(
* The function preserves accumulated rounding errors across the re-amortization
* to ensure the loan state remains consistent with its payment history.
*/
Expected<std::pair<LoanPaymentParts, LoanProperties>, TER>
std::expected<std::pair<LoanPaymentParts, LoanProperties>, TER>
tryOverpayment(
Rules const& rules,
Asset const& asset,
@@ -643,7 +643,7 @@ tryOverpayment(
JLOG(j.warn()) << "Principal overpayment would cause the loan to be in "
"an invalid state. Ignore the overpayment";
return Unexpected(tesSUCCESS);
return std::unexpected(tesSUCCESS);
}
// Validate that all computed properties are reasonable. These checks should
@@ -660,7 +660,7 @@ tryOverpayment(
<< ", PeriodicPayment : " << newLoanProperties.periodicPayment
<< ", ManagementFeeOwedToBroker: "
<< newLoanProperties.loanState.managementFeeDue;
return Unexpected(tesSUCCESS);
return std::unexpected(tesSUCCESS);
// LCOV_EXCL_STOP
}
@@ -685,7 +685,7 @@ tryOverpayment(
{
JLOG(j.warn()) << "Principal overpayment would increase the value of "
"the loan. Ignore the overpayment";
return Unexpected(tesSUCCESS);
return std::unexpected(tesSUCCESS);
}
return std::make_pair(
@@ -718,7 +718,7 @@ tryOverpayment(
* gracefully without corrupting the ledger data.
*/
template <class NumberProxy>
Expected<LoanPaymentParts, TER>
std::expected<LoanPaymentParts, TER>
doOverpayment(
Rules const& rules,
Asset const& asset,
@@ -760,7 +760,7 @@ doOverpayment(
managementFeeRate,
j);
if (!ret)
return Unexpected(ret.error());
return std::unexpected(ret.error());
auto const& [loanPaymentParts, newLoanProperties] = *ret;
auto const newRoundedLoanState = newLoanProperties.loanState;
@@ -774,7 +774,7 @@ doOverpayment(
JLOG(j.warn()) << "Overpayment not allowed: principal "
<< "outstanding did not decrease. Before: " << *principalOutstandingProxy
<< ". After: " << newRoundedLoanState.principalOutstanding;
return Unexpected(tesSUCCESS);
return std::unexpected(tesSUCCESS);
// LCOV_EXCL_STOP
}
@@ -798,44 +798,44 @@ doOverpayment(
// (P * factor) / factor round-trip can leave the new principal one
// scale-unit high, so these equalities do not hold on the pre-amendment
// code path and must be gated to match the fix they verify.
if (rules.enabled(fixCleanup3_2_0))
{
// The valueChange returned by tryOverpayment satisfies
// valueChange = (newInterestDue - oldInterestDue) + untrackedInterest.
// Using the loan-state identity v = p + i + m and the adjacent
// `principal change agrees` assertion (dp = oldP - newP), this
// rearranges into three independently-computable terms:
//
// 1. TVO change beyond what principal repayment alone explains:
// newTVO - (oldTVO - dp)
// 2. Management fee released by re-amortization (positive when
// mfee decreased; zero when managementFeeRate == 0):
// oldMfee - newMfee
// 3. The overpayment's penalty interest part (= untrackedInterest
// for the overpayment path; see computeOverpaymentComponents):
// trackedInterestPart()
[[maybe_unused]] Number const tvoChange = newRoundedLoanState.valueOutstanding -
(totalValueOutstandingProxy - overpaymentComponents.trackedPrincipalDelta);
[[maybe_unused]] Number const managementFeeReleased =
managementFeeOutstandingProxy - newRoundedLoanState.managementFeeDue;
[[maybe_unused]] Number const interestPart = overpaymentComponents.trackedInterestPart();
//
// The valueChange returned by tryOverpayment satisfies
// valueChange = (newInterestDue - oldInterestDue) + untrackedInterest.
// Using the loan-state identity v = p + i + m and the adjacent
// `principal change agrees` assertion (dp = oldP - newP), this
// rearranges into three independently-computable terms:
//
// 1. TVO change beyond what principal repayment alone explains:
// newTVO - (oldTVO - dp)
// 2. Management fee released by re-amortization (positive when
// mfee decreased; zero when managementFeeRate == 0):
// oldMfee - newMfee
// 3. The overpayment's penalty interest part (= untrackedInterest
// for the overpayment path; see computeOverpaymentComponents):
// trackedInterestPart()
[[maybe_unused]] bool const fix320Enabled = rules.enabled(fixCleanup3_2_0);
XRPL_ASSERT_IF(
fix320Enabled,
overpaymentComponents.trackedPrincipalDelta ==
principalOutstandingProxy - newRoundedLoanState.principalOutstanding,
"xrpl::detail::doOverpayment : principal change agrees");
XRPL_ASSERT_PARTS(
overpaymentComponents.trackedPrincipalDelta ==
principalOutstandingProxy - newRoundedLoanState.principalOutstanding,
"xrpl::detail::doOverpayment",
"principal change agrees");
XRPL_ASSERT_IF(
fix320Enabled,
[&] {
Number const tvoChange = newRoundedLoanState.valueOutstanding -
(totalValueOutstandingProxy - overpaymentComponents.trackedPrincipalDelta);
Number const managementFeeReleased =
managementFeeOutstandingProxy - newRoundedLoanState.managementFeeDue;
Number const interestPart = overpaymentComponents.trackedInterestPart();
return loanPaymentParts.valueChange == tvoChange + managementFeeReleased + interestPart;
}(),
"xrpl::detail::doOverpayment : interest paid agrees");
XRPL_ASSERT_PARTS(
loanPaymentParts.valueChange == tvoChange + managementFeeReleased + interestPart,
"xrpl::detail::doOverpayment",
"interest paid agrees");
XRPL_ASSERT_PARTS(
overpaymentComponents.trackedPrincipalDelta == loanPaymentParts.principalPaid,
"xrpl::detail::doOverpayment",
"principal payment matches");
}
XRPL_ASSERT_IF(
fix320Enabled,
overpaymentComponents.trackedPrincipalDelta == loanPaymentParts.principalPaid,
"xrpl::detail::doOverpayment : principal payment matches");
// All validations passed, so update the proxy objects (which will
// modify the actual Loan ledger object)
@@ -860,7 +860,7 @@ doOverpayment(
*
* Implements equation (15) from XLS-66 spec, Section A-2 Equation Glossary
*/
Expected<ExtendedPaymentComponents, TER>
std::expected<ExtendedPaymentComponents, TER>
computeLatePayment(
Asset const& asset,
ApplyView const& view,
@@ -877,7 +877,7 @@ computeLatePayment(
// Check if the due date has passed. If not, reject the payment as
// being too soon
if (!hasExpired(view, nextDueDate))
return Unexpected(tecTOO_SOON);
return std::unexpected(tecTOO_SOON);
// Calculate the penalty interest based on how long the payment is overdue.
auto const latePaymentInterest = loanLatePaymentInterest(
@@ -929,7 +929,7 @@ computeLatePayment(
{
JLOG(j.warn()) << "Late loan payment amount is insufficient. Due: " << late.totalDue
<< ", paid: " << amount;
return Unexpected(tecINSUFFICIENT_PAYMENT);
return std::unexpected(tecINSUFFICIENT_PAYMENT);
}
return late;
@@ -954,7 +954,7 @@ computeLatePayment(
*
* Implements equation (26) from XLS-66 spec, Section A-2 Equation Glossary
*/
Expected<ExtendedPaymentComponents, TER>
std::expected<ExtendedPaymentComponents, TER>
computeFullPayment(
Asset const& asset,
ApplyView& view,
@@ -979,7 +979,7 @@ computeFullPayment(
{
// If this is the last payment, it has to be a regular payment
JLOG(j.warn()) << "Last payment cannot be a full payment.";
return Unexpected(tecKILLED);
return std::unexpected(tecKILLED);
}
// Calculate the theoretical principal based on the payment schedule.
@@ -1059,7 +1059,7 @@ computeFullPayment(
{
// If the payment is less than the full payment amount, it's not
// sufficient to be a full payment.
return Unexpected(tecINSUFFICIENT_PAYMENT);
return std::unexpected(tecINSUFFICIENT_PAYMENT);
}
return full;
@@ -1326,13 +1326,11 @@ computeOverpaymentComponents(
TenthBips32 const overpaymentFeeRate,
TenthBips16 const managementFeeRate)
{
if (rules.enabled(fixCleanup3_2_0))
{
XRPL_ASSERT(
overpayment > 0 && isRounded(asset, overpayment, loanScale),
"xrpl::detail::computeOverpaymentComponents : valid overpayment "
"amount");
}
XRPL_ASSERT_IF(
rules.enabled(fixCleanup3_2_0),
overpayment > 0 && isRounded(asset, overpayment, loanScale),
"xrpl::detail::computeOverpaymentComponents : valid overpayment "
"amount");
// First, deduct the fixed overpayment fee from the total amount.
// This reduces the effective payment that will be applied to the loan.
@@ -1782,7 +1780,7 @@ computeLoanProperties(
* It is an implementation of the make_payment function from the XLS-66
* spec. Section 3.2.4.4
*/
Expected<LoanPaymentParts, TER>
std::expected<LoanPaymentParts, TER>
loanMakePayment(
Asset const& asset,
ApplyView& view,
@@ -1802,7 +1800,7 @@ loanMakePayment(
// Loan complete this is already checked in LoanPay::preclaim()
// LCOV_EXCL_START
JLOG(j.warn()) << "Loan is already paid off.";
return Unexpected(tecKILLED);
return std::unexpected(tecKILLED);
// LCOV_EXCL_STOP
}
@@ -1814,7 +1812,7 @@ loanMakePayment(
if (*nextDueDateProxy == 0)
{
JLOG(j.warn()) << "Loan next payment due date is not set.";
return Unexpected(tecINTERNAL);
return std::unexpected(tecINTERNAL);
}
std::int32_t const loanScale = loan->at(sfLoanScale);
@@ -1852,7 +1850,7 @@ loanMakePayment(
<< startDate << ", prev payment due date is " << prevPaymentDateProxy
<< ", next payment due date is " << nextDueDateProxy << ", ledger time is "
<< view.parentCloseTime().time_since_epoch().count();
return Unexpected(tecEXPIRED);
return std::unexpected(tecEXPIRED);
}
// -------------------------------------------------------------
@@ -1902,13 +1900,13 @@ loanMakePayment(
// error() will be the TER returned if a payment is not made. It
// will only evaluate to true if it's unsuccessful. Otherwise,
// tesSUCCESS means nothing was done, so continue.
return Unexpected(fullPaymentComponents.error());
return std::unexpected(fullPaymentComponents.error());
}
// LCOV_EXCL_START
UNREACHABLE("xrpl::loanMakePayment : invalid full payment result");
JLOG(j.error()) << "Full payment computation failed unexpectedly.";
return Unexpected(tecINTERNAL);
return std::unexpected(tecINTERNAL);
// LCOV_EXCL_STOP
}
@@ -1970,13 +1968,13 @@ loanMakePayment(
{
// error() will be the TER returned if a payment is not made. It
// will only evaluate to true if it's unsuccessful.
return Unexpected(latePaymentComponents.error());
return std::unexpected(latePaymentComponents.error());
}
// LCOV_EXCL_START
UNREACHABLE("xrpl::loanMakePayment : invalid late payment result");
JLOG(j.error()) << "Late payment computation failed unexpectedly.";
return Unexpected(tecINTERNAL);
return std::unexpected(tecINTERNAL);
// LCOV_EXCL_STOP
}
@@ -2043,7 +2041,7 @@ loanMakePayment(
{
JLOG(j.warn()) << "Regular loan payment amount is insufficient. Due: " << periodic.totalDue
<< ", paid: " << amount;
return Unexpected(tecINSUFFICIENT_PAYMENT);
return std::unexpected(tecINSUFFICIENT_PAYMENT);
}
XRPL_ASSERT_PARTS(
@@ -2129,7 +2127,7 @@ loanMakePayment(
// made. It will only evaluate to true if it's unsuccessful.
// Otherwise, tesSUCCESS means nothing was done, so
// continue.
return Unexpected(overResult.error());
return std::unexpected(overResult.error());
}
}
}

View File

@@ -736,10 +736,10 @@ unlockEscrowMPT(
STAmount const& grossAmount,
beast::Journal j)
{
if (!view.rules().enabled(fixTokenEscrowV1))
{
XRPL_ASSERT(netAmount == grossAmount, "xrpl::unlockEscrowMPT : netAmount == grossAmount");
}
XRPL_ASSERT_IF(
!view.rules().enabled(fixTokenEscrowV1),
netAmount == grossAmount,
"xrpl::unlockEscrowMPT : netAmount == grossAmount");
auto const& issuer = netAmount.getIssuer();
auto const& mptIssue = netAmount.get<MPTIssue>();

View File

@@ -64,7 +64,7 @@ public:
boost::asio::io_context& ioContext,
unsigned short const port,
std::size_t maxResponseSize,
beast::Journal& j)
beast::Journal const& j)
: socket_(
ioContext,
gHttpClientSslContext->context()) // NOLINT(bugprone-unchecked-optional-access)
@@ -552,7 +552,7 @@ HTTPClient::get(
std::function<
bool(boost::system::error_code const& ecResult, int iStatus, std::string const& strData)>
complete,
beast::Journal& j)
beast::Journal const& j)
{
auto client = std::make_shared<HTTPClientImp>(ioContext, port, responseMax, j);
client->get(bSSL, deqSites, strPath, timeout, complete);
@@ -570,7 +570,7 @@ HTTPClient::get(
std::function<
bool(boost::system::error_code const& ecResult, int iStatus, std::string const& strData)>
complete,
beast::Journal& j)
beast::Journal const& j)
{
std::deque<std::string> const deqSites(1, strSite);
@@ -590,7 +590,7 @@ HTTPClient::request(
std::function<
bool(boost::system::error_code const& ecResult, int iStatus, std::string const& strData)>
complete,
beast::Journal& j)
beast::Journal const& j)
{
std::deque<std::string> const deqSites(1, strSite);

View File

@@ -1,12 +1,13 @@
#include <xrpl/nodestore/Database.h>
#include <xrpl/basics/BasicConfig.h>
#include <xrpl/basics/Log.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/basics/contract.h>
#include <xrpl/beast/core/CurrentThreadName.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/config/BasicConfig.h>
#include <xrpl/config/Constants.h>
#include <xrpl/json/json_forwards.h>
#include <xrpl/json/json_value.h>
#include <xrpl/nodestore/Backend.h>
@@ -38,8 +39,8 @@ Database::Database(
beast::Journal journal)
: j_(journal)
, scheduler_(scheduler)
, earliestLedgerSeq_(get<std::uint32_t>(config, "earliest_seq", kXrpLedgerEarliestSeq))
, requestBundle_(get<int>(config, "rq_bundle", 4))
, earliestLedgerSeq_(get<std::uint32_t>(config, Keys::kEarliestSeq, kXrpLedgerEarliestSeq))
, requestBundle_(get<int>(config, Keys::kRqBundle, 4))
, readThreads_(std::max(1, readThreads))
{
XRPL_ASSERT(readThreads, "xrpl::NodeStore::Database::Database : nonzero threads input");

View File

@@ -1,11 +1,11 @@
#include <xrpl/nodestore/detail/DatabaseRotatingImp.h>
#include <xrpl/basics/BasicConfig.h>
#include <xrpl/basics/Blob.h>
#include <xrpl/basics/Log.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/basics/contract.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/config/BasicConfig.h>
#include <xrpl/nodestore/Backend.h>
#include <xrpl/nodestore/Database.h>
#include <xrpl/nodestore/DatabaseRotating.h>

View File

@@ -1,9 +1,10 @@
#include <xrpl/nodestore/detail/ManagerImp.h>
#include <xrpl/basics/BasicConfig.h>
#include <xrpl/basics/contract.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/config/BasicConfig.h>
#include <xrpl/config/Constants.h>
#include <xrpl/nodestore/Backend.h>
#include <xrpl/nodestore/Database.h>
#include <xrpl/nodestore/Manager.h>
@@ -66,7 +67,7 @@ ManagerImp::makeBackend(
Scheduler& scheduler,
beast::Journal journal)
{
std::string const type{get(parameters, "type")};
std::string const type{get(parameters, Keys::kType)};
if (type.empty())
missingBackend();

View File

@@ -1,8 +1,9 @@
#include <xrpl/basics/BasicConfig.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/basics/contract.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/config/BasicConfig.h>
#include <xrpl/config/Constants.h>
#include <xrpl/nodestore/Backend.h>
#include <xrpl/nodestore/Factory.h>
#include <xrpl/nodestore/Manager.h>
@@ -90,7 +91,7 @@ private:
public:
MemoryBackend(size_t keyBytes, Section const& keyValues, beast::Journal journal)
: name_(get(keyValues, "path")), journal_(journal)
: name_(get(keyValues, Keys::kPath)), journal_(journal)
{
boost::ignore_unused(journal_); // Keep unused journal_ just in case.
if (name_.empty())

View File

@@ -1,10 +1,11 @@
#include <xrpl/basics/BasicConfig.h>
#include <xrpl/basics/Log.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/basics/contract.h>
#include <xrpl/beast/core/LexicalCast.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/config/BasicConfig.h>
#include <xrpl/config/Constants.h>
#include <xrpl/nodestore/Backend.h>
#include <xrpl/nodestore/Factory.h>
#include <xrpl/nodestore/Manager.h>
@@ -15,8 +16,6 @@
#include <xrpl/nodestore/detail/EncodedBlob.h>
#include <xrpl/nodestore/detail/codec.h>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/system/detail/errc.hpp>
#include <nudb/context.hpp>
@@ -35,12 +34,14 @@
#include <cstdint>
#include <cstdio>
#include <exception>
#include <filesystem>
#include <functional>
#include <memory>
#include <optional>
#include <sstream>
#include <stdexcept>
#include <string>
#include <system_error>
#include <utility>
namespace xrpl::NodeStore {
@@ -72,7 +73,7 @@ public:
: j(journal)
, keyBytes(keyBytes)
, burstSize(burstSize)
, name(get(keyValues, "path"))
, name(get(keyValues, Keys::kPath))
, blockSize(parseBlockSize(name, keyValues, journal))
, deletePath(false)
, scheduler(scheduler)
@@ -91,7 +92,7 @@ public:
: j(journal)
, keyBytes(keyBytes)
, burstSize(burstSize)
, name(get(keyValues, "path"))
, name(get(keyValues, Keys::kPath))
, blockSize(parseBlockSize(name, keyValues, journal))
, db(context)
, deletePath(false)
@@ -130,7 +131,7 @@ public:
void
open(bool createIfMissing, uint64_t appType, uint64_t uid, uint64_t salt) override
{
using namespace boost::filesystem;
using namespace std::filesystem;
if (db.is_open())
{
// LCOV_EXCL_START
@@ -193,11 +194,12 @@ public:
if (deletePath)
{
boost::filesystem::remove_all(name, ec);
if (ec)
std::error_code fsec;
std::filesystem::remove_all(name, fsec);
if (fsec)
{
JLOG(j.fatal())
<< "Filesystem remove_all of " << name << " failed with: " << ec.message();
JLOG(j.fatal()) << "Filesystem remove_all of " << name
<< " failed with: " << fsec.message();
}
}
}
@@ -351,7 +353,7 @@ private:
static std::size_t
parseBlockSize(std::string const& name, Section const& keyValues, beast::Journal journal)
{
using namespace boost::filesystem;
using namespace std::filesystem;
auto const folder = path(name);
auto const kp = (folder / "nudb.key").string();
@@ -359,7 +361,7 @@ private:
std::size_t const blockSize = defaultSize;
std::string blockSizeStr;
if (!getIfExists(keyValues, "nudb_block_size", blockSizeStr))
if (!getIfExists(keyValues, Keys::kNudbBlockSize, blockSizeStr))
{
return blockSize; // Early return with default
}

View File

@@ -1,6 +1,6 @@
#include <xrpl/basics/BasicConfig.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/config/BasicConfig.h>
#include <xrpl/nodestore/Backend.h>
#include <xrpl/nodestore/Factory.h>
#include <xrpl/nodestore/Manager.h>

View File

@@ -1,16 +1,14 @@
#include <xrpl/basics/BasicConfig.h>
#include <xrpl/basics/Log.h>
#include <xrpl/basics/base_uint.h>
#include <xrpl/beast/utility/Journal.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/config/BasicConfig.h>
#include <xrpl/config/Constants.h>
#include <xrpl/nodestore/Backend.h>
#include <xrpl/nodestore/NodeObject.h>
#include <xrpl/nodestore/Scheduler.h>
#include <xrpl/nodestore/Types.h>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <rocksdb/advanced_options.h>
#include <rocksdb/cache.h>
#include <rocksdb/compression_type.h>
@@ -26,6 +24,7 @@
#include <bit>
#include <cstddef>
#include <filesystem>
#include <functional>
#include <stdexcept>
#include <string>
@@ -111,17 +110,18 @@ public:
RocksDBEnv* env)
: deletePath_(false), journal(journal), keyBytes(keyBytes), batch(*this, scheduler)
{
if (!getIfExists(keyValues, "path", name))
if (!getIfExists(keyValues, Keys::kPath, name))
Throw<std::runtime_error>("Missing path in RocksDBFactory backend");
rocksdb::BlockBasedTableOptions tableOptions;
options.env = env;
bool const hardSet = keyValues.exists("hard_set") && get<bool>(keyValues, "hard_set");
bool const hardSet =
keyValues.exists(Keys::kHardSet) && get<bool>(keyValues, Keys::kHardSet);
if (keyValues.exists("cache_mb"))
if (keyValues.exists(Keys::kCacheMb))
{
auto size = get<int>(keyValues, "cache_mb");
auto size = get<int>(keyValues, Keys::kCacheMb);
if (!hardSet && size == 256)
size = 1024;
@@ -129,14 +129,14 @@ public:
tableOptions.block_cache = rocksdb::NewLRUCache(megabytes(size));
}
if (auto const v = get<int>(keyValues, "filter_bits"))
if (auto const v = get<int>(keyValues, Keys::kFilterBits))
{
bool const filterBlocks =
!keyValues.exists("filter_full") || (get<int>(keyValues, "filter_full") == 0);
bool const filterBlocks = !keyValues.exists(Keys::kFilterFull) ||
(get<int>(keyValues, Keys::kFilterFull) == 0);
tableOptions.filter_policy.reset(rocksdb::NewBloomFilterPolicy(v, filterBlocks));
}
if (getIfExists(keyValues, "open_files", options.max_open_files))
if (getIfExists(keyValues, Keys::kOpenFiles, options.max_open_files))
{
if (!hardSet && options.max_open_files == 2000)
options.max_open_files = 8000;
@@ -144,9 +144,9 @@ public:
fdMinRequired = options.max_open_files + 128;
}
if (keyValues.exists("file_size_mb"))
if (keyValues.exists(Keys::kFileSizeMb))
{
auto fileSizeMb = get<int>(keyValues, "file_size_mb");
auto fileSizeMb = get<int>(keyValues, Keys::kFileSizeMb);
if (!hardSet && fileSizeMb == 8)
fileSizeMb = 256;
@@ -156,16 +156,17 @@ public:
options.write_buffer_size = 2 * options.target_file_size_base;
}
getIfExists(keyValues, "file_size_mult", options.target_file_size_multiplier);
getIfExists(keyValues, Keys::kFileSizeMult, options.target_file_size_multiplier);
if (keyValues.exists("bg_threads"))
if (keyValues.exists(Keys::kBgThreads))
{
options.env->SetBackgroundThreads(get<int>(keyValues, "bg_threads"), rocksdb::Env::LOW);
options.env->SetBackgroundThreads(
get<int>(keyValues, Keys::kBgThreads), rocksdb::Env::LOW);
}
if (keyValues.exists("high_threads"))
if (keyValues.exists(Keys::kHighThreads))
{
auto const highThreads = get<int>(keyValues, "high_threads");
auto const highThreads = get<int>(keyValues, Keys::kHighThreads);
options.env->SetBackgroundThreads(highThreads, rocksdb::Env::HIGH);
// If we have high-priority threads, presumably we want to
@@ -176,10 +177,10 @@ public:
options.compression = rocksdb::kSnappyCompression;
getIfExists(keyValues, "block_size", tableOptions.block_size);
getIfExists(keyValues, Keys::kBlockSize, tableOptions.block_size);
if (keyValues.exists("universal_compaction") &&
(get<int>(keyValues, "universal_compaction") != 0))
if (keyValues.exists(Keys::kUniversalCompaction) &&
(get<int>(keyValues, Keys::kUniversalCompaction) != 0))
{
options.compaction_style = rocksdb::kCompactionStyleUniversal;
options.min_write_buffer_number_to_merge = 2;
@@ -187,11 +188,11 @@ public:
options.write_buffer_size = 6 * options.target_file_size_base;
}
if (keyValues.exists("bbt_options"))
if (keyValues.exists(Keys::kBbtOptions))
{
rocksdb::ConfigOptions const configOptions;
auto const s = rocksdb::GetBlockBasedTableOptionsFromString(
configOptions, tableOptions, get(keyValues, "bbt_options"), &tableOptions);
configOptions, tableOptions, get(keyValues, Keys::kBbtOptions), &tableOptions);
if (!s.ok())
{
Throw<std::runtime_error>(
@@ -201,10 +202,10 @@ public:
options.table_factory.reset(NewBlockBasedTableFactory(tableOptions));
if (keyValues.exists("options"))
if (keyValues.exists(Keys::kOptions))
{
auto const s =
rocksdb::GetOptionsFromString(options, get(keyValues, "options"), &options);
rocksdb::GetOptionsFromString(options, get(keyValues, Keys::kOptions), &options);
if (!s.ok())
{
Throw<std::runtime_error>(
@@ -262,8 +263,8 @@ public:
db.reset();
if (deletePath_)
{
boost::filesystem::path const dir = name;
boost::filesystem::remove_all(dir);
std::filesystem::path const dir = name;
std::filesystem::remove_all(dir);
}
}
}

View File

@@ -127,7 +127,7 @@ ammAuctionTimeSlot(std::uint64_t current, STObject const& auctionSlot)
bool
ammEnabled(Rules const& rules)
{
return rules.enabled(featureAMM) && rules.enabled(fixUniversalNumber);
return rules.enabled(featureAMM);
}
} // namespace xrpl

View File

@@ -1,6 +1,5 @@
#include <xrpl/protocol/IOUAmount.h>
#include <xrpl/basics/LocalValue.h>
#include <xrpl/basics/Number.h>
#include <xrpl/basics/contract.h>
#include <xrpl/beast/utility/Zero.h>
@@ -17,29 +16,6 @@
namespace xrpl {
namespace {
// Use a static inside a function to help prevent order-of-initialization issues
LocalValue<bool>&
getStaticSTNumberSwitchover()
{
static LocalValue<bool> kR{true};
return kR;
}
} // namespace
bool
getSTNumberSwitchover()
{
return *getStaticSTNumberSwitchover();
}
void
setSTNumberSwitchover(bool v)
{
*getStaticSTNumberSwitchover() = v;
}
/* The range for the mantissa when normalized */
// log(2^63,10) ~ 18.96
//
@@ -75,56 +51,20 @@ IOUAmount::normalize()
return;
}
if (getSTNumberSwitchover())
{
Number const v{mantissa_, exponent_};
*this = fromNumber(v);
if (exponent_ > kMaxExponent)
Throw<std::overflow_error>("value overflow");
if (exponent_ < kMinExponent)
*this = beast::kZero;
return;
}
bool const negative = (mantissa_ < 0);
if (negative)
mantissa_ = -mantissa_;
while ((mantissa_ < kMinMantissa) && (exponent_ > kMinExponent))
{
mantissa_ *= 10;
--exponent_;
}
while (mantissa_ > kMaxMantissa)
{
if (exponent_ >= kMaxExponent)
Throw<std::overflow_error>("IOUAmount::normalize");
mantissa_ /= 10;
++exponent_;
}
if ((exponent_ < kMinExponent) || (mantissa_ < kMinMantissa))
{
*this = beast::kZero;
return;
}
if (exponent_ > kMaxExponent)
Throw<std::overflow_error>("value overflow");
if (negative)
mantissa_ = -mantissa_;
Number const v{mantissa_, exponent_};
*this = IOUAmount(v);
}
IOUAmount::IOUAmount(Number const& other) : IOUAmount(fromNumber(other))
{
if (exponent_ > kMaxExponent)
{
Throw<std::overflow_error>("value overflow");
}
if (exponent_ < kMinExponent)
{
*this = beast::kZero;
}
}
IOUAmount&
@@ -139,37 +79,7 @@ IOUAmount::operator+=(IOUAmount const& other)
return *this;
}
if (getSTNumberSwitchover())
{
*this = IOUAmount{Number{*this} + Number{other}};
return *this;
}
auto m = other.mantissa_;
auto e = other.exponent_;
while (exponent_ < e)
{
mantissa_ /= 10;
++exponent_;
}
while (e < exponent_)
{
m /= 10;
++e;
}
// This addition cannot overflow an std::int64_t but we may throw from
// normalize if the result isn't representable.
mantissa_ += m;
if (mantissa_ >= -10 && mantissa_ <= 10)
{
*this = beast::kZero;
return *this;
}
normalize();
*this = IOUAmount{Number{*this} + Number{other}};
return *this;
}

View File

@@ -7,7 +7,6 @@
#include <xrpl/beast/hash/uhash.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/protocol/Feature.h>
#include <xrpl/protocol/IOUAmount.h>
#include <xrpl/protocol/STVector256.h>
#include <memory>
@@ -83,15 +82,12 @@ useRulesGuards(Rules const& rules)
void
createGuards(
Rules const& rules,
std::optional<NumberSO>& stNumberSO,
std::optional<CurrentTransactionRulesGuard>& rulesGuard,
std::optional<NumberMantissaScaleGuard>& mantissaScaleGuard)
{
if (useRulesGuards(rules))
{
// raii classes for the current ledger rules.
// fixUniversalNumber predates the rulesGuard and should be replaced.
stNumberSO.emplace(rules.enabled(fixUniversalNumber));
rulesGuard.emplace(rules);
}
else

View File

@@ -388,47 +388,9 @@ operator+(STAmount const& v1, STAmount const& v2)
if (v1.holds<MPTIssue>())
return {v1.asset_, v1.mpt().value() + v2.mpt().value()};
if (getSTNumberSwitchover())
{
auto x = v1;
x = v1.iou() + v2.iou();
return x;
}
int ov1 = v1.exponent(), ov2 = v2.exponent();
std::int64_t vv1 = static_cast<std::int64_t>(v1.mantissa());
std::int64_t vv2 = static_cast<std::int64_t>(v2.mantissa());
if (v1.negative())
vv1 = -vv1;
if (v2.negative())
vv2 = -vv2;
while (ov1 < ov2)
{
vv1 /= 10;
++ov1;
}
while (ov2 < ov1)
{
vv2 /= 10;
++ov2;
}
// This addition cannot overflow an std::int64_t. It can overflow an
// STAmount and the constructor will throw.
std::int64_t const fv = vv1 + vv2;
if ((fv >= -10) && (fv <= 10))
return {v1.getFName(), v1.asset()};
if (fv >= 0)
return STAmount{v1.getFName(), v1.asset(), static_cast<std::uint64_t>(fv), ov1, false};
return STAmount{v1.getFName(), v1.asset(), static_cast<std::uint64_t>(-fv), ov1, true};
auto x = v1;
x = v1.iou() + v2.iou();
return x;
}
STAmount
@@ -877,53 +839,25 @@ STAmount::canonicalize()
if (asset_.holds<MPTIssue>() && offset_ > 18)
Throw<std::runtime_error>("MPT amount out of range");
if (getSTNumberSwitchover())
Number const num(isNegative_, value_, offset_, Number::Unchecked{});
auto set = [&](auto const& val) {
auto const value = val.value();
isNegative_ = value < 0;
value_ = isNegative_ ? -value : value;
};
if (native())
{
Number const num(isNegative_, value_, offset_, Number::Unchecked{});
auto set = [&](auto const& val) {
auto const value = val.value();
isNegative_ = value < 0;
value_ = isNegative_ ? -value : value;
};
if (native())
{
set(XRPAmount{num});
}
else if (asset_.holds<MPTIssue>())
{
set(MPTAmount{num});
}
else
{
Throw<std::runtime_error>("Unknown integral asset type");
}
offset_ = 0;
set(XRPAmount{num});
}
else if (asset_.holds<MPTIssue>())
{
set(MPTAmount{num});
}
else
{
while (offset_ < 0)
{
value_ /= 10;
++offset_;
}
while (offset_ > 0)
{
// N.B. do not move the overflow check to after the
// multiplication
if (native() && value_ > kMaxNativeN)
{
Throw<std::runtime_error>("Native currency amount out of range");
}
else if (!native() && value_ > kMaxMpTokenAmount)
{
Throw<std::runtime_error>("MPT amount out of range");
}
value_ *= 10;
--offset_;
}
Throw<std::runtime_error>("Unknown integral asset type"); // LCOV_EXCL_LINE
}
offset_ = 0;
if (native() && value_ > kMaxNativeN)
{
@@ -937,53 +871,7 @@ STAmount::canonicalize()
return;
}
if (getSTNumberSwitchover())
{
*this = iou();
return;
}
if (value_ == 0)
{
offset_ = -100;
isNegative_ = false;
return;
}
while ((value_ < kMinValue) && (offset_ > kMinOffset))
{
value_ *= 10;
--offset_;
}
while (value_ > kMaxValue)
{
if (offset_ >= kMaxOffset)
Throw<std::runtime_error>("value overflow");
value_ /= 10;
++offset_;
}
if ((offset_ < kMinOffset) || (value_ < kMinValue))
{
value_ = 0;
isNegative_ = false;
offset_ = -100;
return;
}
if (offset_ > kMaxOffset)
Throw<std::runtime_error>("value overflow");
XRPL_ASSERT(
(value_ == 0) || ((value_ >= kMinValue) && (value_ <= kMaxValue)),
"xrpl::STAmount::canonicalize : value inside range");
XRPL_ASSERT(
(value_ == 0) || ((offset_ >= kMinOffset) && (offset_ <= kMaxOffset)),
"xrpl::STAmount::canonicalize : offset inside range");
XRPL_ASSERT(
(value_ != 0) || (offset_ != -100), "xrpl::STAmount::canonicalize : value or offset set");
*this = iou();
}
void
@@ -1250,16 +1138,34 @@ hasInvalidAmount(STBase const& field, int depth, beast::Journal j)
return true;
}
if (auto const amount = dynamic_cast<STAmount const*>(&field))
return !isLegalMPT(*amount) || !isLegalNet(*amount);
// Dispatch on the serialized type tag rather than RTTI: this is on the invariant-checking path
// and a dynamic_cast chain over every field of every modified entry is measurably expensive.
// The object-like tags below all denote STObject subclasses (STLedgerEntry, STTx), so the
// downcast is sound; nested fields are only ever plain STI_OBJECT / STI_ARRAY containers.
// safeDowncast keeps a dynamic_cast validity assert in debug builds while compiling to
// static_cast in release.
switch (field.getSType())
{
case STI_AMOUNT: {
auto const& amount = safeDowncast<STAmount const&>(field);
return !isLegalMPT(amount) || !isLegalNet(amount);
}
if (auto const object = dynamic_cast<STObject const*>(&field))
return hasInvalidAmount(*object, depth + 1, j);
case STI_OBJECT:
case STI_LEDGERENTRY:
case STI_TRANSACTION:
return hasInvalidAmount(safeDowncast<STObject const&>(field), depth + 1, j);
if (auto const array = dynamic_cast<STArray const*>(&field))
return hasInvalidAmount(*array, depth + 1, j);
case STI_ARRAY:
return hasInvalidAmount(safeDowncast<STArray const&>(field), depth + 1, j);
return false;
default: {
XRPL_ASSERT(
dynamic_cast<STObject const*>(&field) == nullptr,
"xrpl::hasInvalidAmount : unhandled STObject type");
return false;
}
}
}
bool
@@ -1395,44 +1301,8 @@ multiply(STAmount const& v1, STAmount const& v2, Asset const& asset)
return STAmount(asset, minV * maxV);
}
if (getSTNumberSwitchover())
{
auto const r = Number{v1} * Number{v2};
return STAmount{asset, r};
}
std::uint64_t value1 = v1.mantissa();
std::uint64_t value2 = v2.mantissa();
int offset1 = v1.exponent();
int offset2 = v2.exponent();
if (v1.integral())
{
while (value1 < STAmount::kMinValue)
{
value1 *= 10;
--offset1;
}
}
if (v2.integral())
{
while (value2 < STAmount::kMinValue)
{
value2 *= 10;
--offset2;
}
}
// We multiply the two mantissas (each is between 10^15
// and 10^16), so their product is in the 10^30 to 10^32
// range. Dividing their product by 10^14 maintains the
// precision, by scaling the result to 10^16 to 10^18.
return STAmount(
asset,
muldiv(value1, value2, kTenTO14) + 7,
offset1 + offset2 + 14,
v1.negative() != v2.negative());
auto const r = Number{v1} * Number{v2};
return STAmount{asset, r};
}
// This is the legacy version of canonicalizeRound. It's been in use

View File

@@ -1,7 +1,6 @@
#include <xrpl/protocol/STTx.h>
#include <xrpl/basics/Blob.h>
#include <xrpl/basics/Expected.h>
#include <xrpl/basics/Log.h>
#include <xrpl/basics/Slice.h>
#include <xrpl/basics/StringUtilities.h>
@@ -40,6 +39,7 @@
#include <cstddef>
#include <cstdint>
#include <exception>
#include <expected>
#include <functional>
#include <memory>
#include <optional>
@@ -248,7 +248,7 @@ STTx::sign(
tid_ = getHash(HashPrefix::TransactionId);
}
Expected<void, std::string>
std::expected<void, std::string>
STTx::checkSign(Rules const& rules, STObject const& sigObject) const
{
try
@@ -263,11 +263,11 @@ STTx::checkSign(Rules const& rules, STObject const& sigObject) const
}
catch (...)
{
return Unexpected("Internal signature check failure.");
return std::unexpected("Internal signature check failure.");
}
}
Expected<void, std::string>
std::expected<void, std::string>
STTx::checkSign(Rules const& rules) const
{
if (auto const ret = checkSign(rules, *this); !ret)
@@ -277,12 +277,12 @@ STTx::checkSign(Rules const& rules) const
{
auto const counterSig = getFieldObject(sfCounterpartySignature);
if (auto const ret = checkSign(rules, counterSig); !ret)
return Unexpected("Counterparty: " + ret.error());
return std::unexpected("Counterparty: " + ret.error());
}
return {};
}
Expected<void, std::string>
std::expected<void, std::string>
STTx::checkBatchSign(Rules const& rules) const
{
try
@@ -291,7 +291,7 @@ STTx::checkBatchSign(Rules const& rules) const
if (getTxnType() != ttBATCH)
{
JLOG(debugLog().fatal()) << "not a batch transaction";
return Unexpected("Not a batch transaction.");
return std::unexpected("Not a batch transaction.");
}
STArray const& signers{getFieldArray(sfBatchSigners)};
for (auto const& signer : signers)
@@ -309,7 +309,7 @@ STTx::checkBatchSign(Rules const& rules) const
{
JLOG(debugLog().error()) << "Batch signature check failed: " << e.what();
}
return Unexpected("Internal batch signature check failure.");
return std::unexpected("Internal batch signature check failure.");
}
json::Value
@@ -389,14 +389,14 @@ STTx::getMetaSQL(
safeCast<char>(status) % rTxn % escapedMetaData);
}
static Expected<void, std::string>
static std::expected<void, std::string>
singleSignHelper(STObject const& sigObject, Slice const& data)
{
// 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 (sigObject.isFieldPresent(sfSigners))
return Unexpected("Cannot both single- and multi-sign.");
return std::unexpected("Cannot both single- and multi-sign.");
bool validSig = false;
try
@@ -414,19 +414,19 @@ singleSignHelper(STObject const& sigObject, Slice const& data)
}
if (!validSig)
return Unexpected("Invalid signature.");
return std::unexpected("Invalid signature.");
return {};
}
Expected<void, std::string>
std::expected<void, std::string>
STTx::checkSingleSign(STObject const& sigObject) const
{
auto const data = getSigningData(*this);
return singleSignHelper(sigObject, makeSlice(data));
}
Expected<void, std::string>
std::expected<void, std::string>
STTx::checkBatchSingleSign(STObject const& batchSigner) const
{
Serializer msg;
@@ -434,7 +434,7 @@ STTx::checkBatchSingleSign(STObject const& batchSigner) const
return singleSignHelper(batchSigner, msg.slice());
}
Expected<void, std::string>
std::expected<void, std::string>
multiSignHelper(
STObject const& sigObject,
std::optional<AccountID> txnAccountID,
@@ -444,18 +444,18 @@ multiSignHelper(
// Make sure the MultiSigners are present. Otherwise they are not
// attempting multi-signing and we just have a bad SigningPubKey.
if (!sigObject.isFieldPresent(sfSigners))
return Unexpected("Empty SigningPubKey.");
return std::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 (sigObject.isFieldPresent(sfTxnSignature))
return Unexpected("Cannot both single- and multi-sign.");
return std::unexpected("Cannot both single- and multi-sign.");
STArray const& signers{sigObject.getFieldArray(sfSigners)};
// There are well known bounds that the number of signers must be within.
if (signers.size() < STTx::kMinMultiSigners || signers.size() > STTx::kMaxMultiSigners)
return Unexpected("Invalid Signers array size.");
return std::unexpected("Invalid Signers array size.");
// Signers must be in sorted order by AccountID.
AccountID lastAccountID(beast::kZero);
@@ -468,15 +468,15 @@ multiSignHelper(
// If they can, txnAccountID will be unseated, which is not equal to any
// value.
if (txnAccountID == accountID)
return Unexpected("Invalid multisigner.");
return std::unexpected("Invalid multisigner.");
// No duplicate signers allowed.
if (lastAccountID == accountID)
return Unexpected("Duplicate Signers not allowed.");
return std::unexpected("Duplicate Signers not allowed.");
// Accounts must be in order by account ID. No duplicates allowed.
if (lastAccountID > accountID)
return Unexpected("Unsorted Signers array.");
return std::unexpected("Unsorted Signers array.");
// The next signature must be greater than this one.
lastAccountID = accountID;
@@ -502,7 +502,7 @@ multiSignHelper(
}
if (!validSig)
{
return Unexpected(
return std::unexpected(
std::string("Invalid signature on account ") + toBase58(accountID) +
errorWhat.value_or("") + ".");
}
@@ -511,7 +511,7 @@ multiSignHelper(
return {};
}
Expected<void, std::string>
std::expected<void, std::string>
STTx::checkBatchMultiSign(STObject const& batchSigner, Rules const& rules) const
{
// We can ease the computational load inside the loop a bit by
@@ -530,7 +530,7 @@ STTx::checkBatchMultiSign(STObject const& batchSigner, Rules const& rules) const
rules);
}
Expected<void, std::string>
std::expected<void, std::string>
STTx::checkMultiSign(Rules const& rules, STObject const& sigObject) const
{
// Used inside the loop in multiSignHelper to enforce that

View File

@@ -9,7 +9,6 @@
#include <xrpl/protocol/tokens.h>
#include <xrpl/basics/Expected.h>
#include <xrpl/basics/safe_cast.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/protocol/detail/b58_utils.h>
@@ -23,6 +22,7 @@
#include <array>
#include <cstdint>
#include <cstring>
#include <expected>
#include <span>
#include <string>
#include <string_view>
@@ -353,7 +353,7 @@ b256ToB58Be(std::span<std::uint8_t const> input, std::span<std::uint8_t> out)
// (33 bytes for nodepublic + 1 byte token + 4 bytes checksum)
if (input.size() > 38)
{
return Unexpected(TokenCodecErrc::InputTooLarge);
return std::unexpected(TokenCodecErrc::InputTooLarge);
};
auto countLeadingZeros = [](std::span<std::uint8_t const> const& col) -> std::size_t {
@@ -441,7 +441,7 @@ b256ToB58Be(std::span<std::uint8_t const> input, std::span<std::uint8_t> out)
static constexpr std::uint64_t kB5810 = 430804206899405824; // 58^10;
if (base5810Coeff[i] >= kB5810)
{
return Unexpected(TokenCodecErrc::InputTooLarge);
return std::unexpected(TokenCodecErrc::InputTooLarge);
}
std::array<std::uint8_t, 10> const b58Be =
xrpl::b58_fast::detail::b5810ToB58Be(base5810Coeff[i]);
@@ -453,7 +453,7 @@ b256ToB58Be(std::span<std::uint8_t const> input, std::span<std::uint8_t> out)
skipZeros = false;
if (out.size() < ((i + 1) * 10) - toSkip)
{
return Unexpected(TokenCodecErrc::OutputTooSmall);
return std::unexpected(TokenCodecErrc::OutputTooSmall);
}
}
for (auto b58Coeff : b58BeS.subspan(toSkip))
@@ -476,11 +476,11 @@ b58ToB256Be(std::string_view input, std::span<std::uint8_t> out)
// log(2^(38*8),58) ~= 51.9
if (input.size() > 52)
{
return Unexpected(TokenCodecErrc::InputTooLarge);
return std::unexpected(TokenCodecErrc::InputTooLarge);
};
if (out.size() < 8)
{
return Unexpected(TokenCodecErrc::OutputTooSmall);
return std::unexpected(TokenCodecErrc::OutputTooSmall);
}
auto countLeadingZeros = [&](auto const& col) -> std::size_t {
@@ -513,7 +513,7 @@ b58ToB256Be(std::string_view input, std::span<std::uint8_t> out)
auto curVal = ::xrpl::kAlphabetReverse[c];
if (curVal < 0)
{
return Unexpected(TokenCodecErrc::InvalidEncodingChar);
return std::unexpected(TokenCodecErrc::InvalidEncodingChar);
}
b5810Coeff[0] *= 58;
b5810Coeff[0] += curVal;
@@ -526,7 +526,7 @@ b58ToB256Be(std::string_view input, std::span<std::uint8_t> out)
auto curVal = ::xrpl::kAlphabetReverse[c];
if (curVal < 0)
{
return Unexpected(TokenCodecErrc::InvalidEncodingChar);
return std::unexpected(TokenCodecErrc::InvalidEncodingChar);
}
b5810Coeff[numPartialCoeffs + j] *= 58;
b5810Coeff[numPartialCoeffs + j] += curVal;
@@ -548,7 +548,7 @@ b58ToB256Be(std::string_view input, std::span<std::uint8_t> out)
std::span(&result[0], curResultSize + 1), kB5810);
if (code != TokenCodecErrc::Success)
{
return Unexpected(code);
return std::unexpected(code);
}
}
{
@@ -556,7 +556,7 @@ b58ToB256Be(std::string_view input, std::span<std::uint8_t> out)
std::span(&result[0], curResultSize + 1), c);
if (code != TokenCodecErrc::Success)
{
return Unexpected(code);
return std::unexpected(code);
}
}
if (result[curResultSize] != 0)
@@ -589,7 +589,7 @@ b58ToB256Be(std::string_view input, std::span<std::uint8_t> out)
}
if ((curOutI + (8 * (curResultSize - 1))) > out.size())
{
return Unexpected(TokenCodecErrc::OutputTooSmall);
return std::unexpected(TokenCodecErrc::OutputTooSmall);
}
for (int i = curResultSize - 2; i >= 0; --i)
@@ -614,11 +614,11 @@ encodeBase58Token(
std::array<std::uint8_t, kTmpBufSize> buf{};
if (input.size() > kTmpBufSize - 5)
{
return Unexpected(TokenCodecErrc::InputTooLarge);
return std::unexpected(TokenCodecErrc::InputTooLarge);
}
if (input.empty())
{
return Unexpected(TokenCodecErrc::InputTooSmall);
return std::unexpected(TokenCodecErrc::InputTooSmall);
}
// <type (1 byte)><token (input len)><checksum (4 bytes)>
buf[0] = static_cast<std::uint8_t>(tokenType);
@@ -648,23 +648,23 @@ decodeBase58Token(TokenType type, std::string_view s, std::span<std::uint8_t> ou
// Reject zero length tokens
if (ret.size() < 6)
return Unexpected(TokenCodecErrc::InputTooSmall);
return std::unexpected(TokenCodecErrc::InputTooSmall);
// The type must match.
if (type != static_cast<TokenType>(static_cast<std::uint8_t>(ret[0])))
return Unexpected(TokenCodecErrc::MismatchedTokenType);
return std::unexpected(TokenCodecErrc::MismatchedTokenType);
// And the checksum must as well.
std::array<std::uint8_t, 4> guard{};
checksum(guard.data(), ret.data(), ret.size() - guard.size());
if (!std::equal(guard.rbegin(), guard.rend(), ret.rbegin()))
{
return Unexpected(TokenCodecErrc::MismatchedChecksum);
return std::unexpected(TokenCodecErrc::MismatchedChecksum);
}
std::size_t const outSize = ret.size() - 1 - guard.size();
if (outBuf.size() < outSize)
return Unexpected(TokenCodecErrc::OutputTooSmall);
return std::unexpected(TokenCodecErrc::OutputTooSmall);
// Skip the leading type byte and the trailing checksum.
std::copy(ret.begin() + 1, ret.begin() + outSize + 1, outBuf.begin());
return outBuf.subspan(0, outSize);

View File

@@ -1,16 +1,15 @@
#include <xrpl/basics/BasicConfig.h>
#include <xrpl/basics/Log.h>
#include <xrpl/config/BasicConfig.h>
#include <xrpl/config/Constants.h>
#include <xrpl/core/Job.h>
#include <xrpl/core/JobQueue.h>
#include <xrpl/core/ServiceRegistry.h>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <soci/blob.h>
#include <cstddef>
#include <cstdint>
#include <filesystem>
#include <mutex>
#include <stdexcept>
#include <string>
@@ -44,8 +43,8 @@ getSociSqliteInit(std::string const& name, std::string const& dir, std::string c
Throw<std::runtime_error>(
"Sqlite databases must specify a dir and a name. Name: " + name + " Dir: " + dir);
}
boost::filesystem::path file(dir);
if (is_directory(file))
std::filesystem::path file(dir);
if (std::filesystem::is_directory(file))
file /= name + ext;
return file.string();
}
@@ -53,13 +52,13 @@ getSociSqliteInit(std::string const& name, std::string const& dir, std::string c
std::string
getSociInit(BasicConfig const& config, std::string const& dbName)
{
auto const& section = config.section("sqdb");
auto const backendName = get(section, "backend", "sqlite");
auto const& section = config.section(Sections::kSqdb);
auto const backendName = get(section, Keys::kBackend, "sqlite");
if (backendName != "sqlite")
Throw<std::runtime_error>("Unsupported soci backend: " + backendName);
auto const path = config.legacy("database_path");
auto const path = config.legacy(Sections::kDatabasePath);
auto const ext = dbName == "validators" || dbName == "peerfinder" ? ".sqlite" : ".db";
return detail::getSociSqliteInit(dbName, path, ext);
}

Some files were not shown because too many files have changed in this diff Show More