mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-05 03:35:51 +00:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5883d756db | ||
|
|
49e0d54c76 | ||
|
|
7506852a99 | ||
|
|
bcbfb04992 | ||
|
|
5cd72f2431 | ||
|
|
eabca8439f | ||
|
|
ea1fffeebf | ||
|
|
6d58065909 | ||
|
|
47b0543461 | ||
|
|
8215c605b4 | ||
|
|
d7e949193f | ||
|
|
f64cf9187a | ||
|
|
b54d85d862 | ||
|
|
f419c18056 | ||
|
|
0ec17b6026 | ||
|
|
df8d8796f5 |
103
.github/workflows/instrumentation.yml
vendored
Normal file
103
.github/workflows/instrumentation.yml
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
name: instrumentation
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
# If the branches list is ever changed, be sure to change it on all
|
||||
# build/test jobs (nix, macos, windows, instrumentation)
|
||||
branches:
|
||||
# Always build the package branches
|
||||
- develop
|
||||
- release
|
||||
- master
|
||||
# Branches that opt-in to running
|
||||
- 'ci/**'
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
|
||||
# NOTE we are not using dependencies built inside nix because nix is lagging
|
||||
# with compiler versions. Instrumentation requires clang version 16 or later
|
||||
|
||||
instrumentation-build:
|
||||
env:
|
||||
CLANG_RELEASE: 16
|
||||
strategy:
|
||||
fail-fast: false
|
||||
runs-on: [self-hosted, heavy]
|
||||
container: debian:bookworm
|
||||
steps:
|
||||
- name: install prerequisites
|
||||
env:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
run: |
|
||||
apt-get update
|
||||
apt-get install --yes --no-install-recommends \
|
||||
clang-${CLANG_RELEASE} clang++-${CLANG_RELEASE} \
|
||||
python3-pip python-is-python3 make cmake git wget
|
||||
apt-get clean
|
||||
update-alternatives --install \
|
||||
/usr/bin/clang clang /usr/bin/clang-${CLANG_RELEASE} 100 \
|
||||
--slave /usr/bin/clang++ clang++ /usr/bin/clang++-${CLANG_RELEASE}
|
||||
update-alternatives --auto clang
|
||||
pip install --no-cache --break-system-packages "conan<2"
|
||||
|
||||
- name: checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: prepare environment
|
||||
run: |
|
||||
mkdir ${GITHUB_WORKSPACE}/.build
|
||||
echo "SOURCE_DIR=$GITHUB_WORKSPACE" >> $GITHUB_ENV
|
||||
echo "BUILD_DIR=$GITHUB_WORKSPACE/.build" >> $GITHUB_ENV
|
||||
echo "CC=/usr/bin/clang" >> $GITHUB_ENV
|
||||
echo "CXX=/usr/bin/clang++" >> $GITHUB_ENV
|
||||
|
||||
- name: configure Conan
|
||||
run: |
|
||||
conan profile new --detect default
|
||||
conan profile update settings.compiler=clang default
|
||||
conan profile update settings.compiler.version=${CLANG_RELEASE} default
|
||||
conan profile update settings.compiler.libcxx=libstdc++11 default
|
||||
conan profile update settings.compiler.cppstd=20 default
|
||||
conan profile update options.rocksdb=False default
|
||||
conan profile update \
|
||||
'conf.tools.build:compiler_executables={"c": "/usr/bin/clang", "cpp": "/usr/bin/clang++"}' default
|
||||
conan profile update 'env.CXXFLAGS="-DBOOST_ASIO_DISABLE_CONCEPTS"' default
|
||||
conan profile update 'conf.tools.build:cxxflags+=["-DBOOST_ASIO_DISABLE_CONCEPTS"]' default
|
||||
conan export external/snappy snappy/1.1.10@
|
||||
conan export external/soci soci/4.0.3@
|
||||
|
||||
- name: build dependencies
|
||||
run: |
|
||||
cd ${BUILD_DIR}
|
||||
conan install ${SOURCE_DIR} \
|
||||
--output-folder ${BUILD_DIR} \
|
||||
--install-folder ${BUILD_DIR} \
|
||||
--build missing \
|
||||
--settings build_type=Debug
|
||||
|
||||
- name: build with instrumentation
|
||||
run: |
|
||||
cd ${BUILD_DIR}
|
||||
cmake -S ${SOURCE_DIR} -B ${BUILD_DIR} \
|
||||
-Dvoidstar=ON \
|
||||
-Dtests=ON \
|
||||
-Dxrpld=ON \
|
||||
-DCMAKE_BUILD_TYPE=Debug \
|
||||
-DSECP256K1_BUILD_BENCHMARK=OFF \
|
||||
-DSECP256K1_BUILD_TESTS=OFF \
|
||||
-DSECP256K1_BUILD_EXHAUSTIVE_TESTS=OFF \
|
||||
-DCMAKE_TOOLCHAIN_FILE=${BUILD_DIR}/build/generators/conan_toolchain.cmake
|
||||
cmake --build . --parallel $(nproc)
|
||||
|
||||
- name: verify instrumentation enabled
|
||||
run: |
|
||||
cd ${BUILD_DIR}
|
||||
./rippled --version | grep libvoidstar
|
||||
|
||||
- name: run unit tests
|
||||
run: |
|
||||
cd ${BUILD_DIR}
|
||||
./rippled -u --unittest-jobs $(( $(nproc)/4 ))
|
||||
2
.github/workflows/macos.yml
vendored
2
.github/workflows/macos.yml
vendored
@@ -3,7 +3,7 @@ on:
|
||||
pull_request:
|
||||
push:
|
||||
# If the branches list is ever changed, be sure to change it on all
|
||||
# build/test jobs (nix, macos, windows)
|
||||
# build/test jobs (nix, macos, windows, instrumentation)
|
||||
branches:
|
||||
# Always build the package branches
|
||||
- develop
|
||||
|
||||
2
.github/workflows/nix.yml
vendored
2
.github/workflows/nix.yml
vendored
@@ -3,7 +3,7 @@ on:
|
||||
pull_request:
|
||||
push:
|
||||
# If the branches list is ever changed, be sure to change it on all
|
||||
# build/test jobs (nix, macos, windows)
|
||||
# build/test jobs (nix, macos, windows, instrumentation)
|
||||
branches:
|
||||
# Always build the package branches
|
||||
- develop
|
||||
|
||||
2
.github/workflows/windows.yml
vendored
2
.github/workflows/windows.yml
vendored
@@ -4,7 +4,7 @@ on:
|
||||
pull_request:
|
||||
push:
|
||||
# If the branches list is ever changed, be sure to change it on all
|
||||
# build/test jobs (nix, macos, windows)
|
||||
# build/test jobs (nix, macos, windows, instrumentation)
|
||||
branches:
|
||||
# Always build the package branches
|
||||
- develop
|
||||
|
||||
@@ -83,11 +83,13 @@ The [commandline](https://xrpl.org/docs/references/http-websocket-apis/api-conve
|
||||
|
||||
The `network_id` field was added in the `server_info` response in version 1.5.0 (2019), but it is not returned in [reporting mode](https://xrpl.org/rippled-server-modes.html#reporting-mode). However, use of reporting mode is now discouraged, in favor of using [Clio](https://github.com/XRPLF/clio) instead.
|
||||
|
||||
## XRP Ledger server version 2.2.0
|
||||
## XRP Ledger server version 2.4.0
|
||||
|
||||
The following is a non-breaking addition to the API.
|
||||
### Addition in 2.4
|
||||
|
||||
- The `feature` method now has a non-admin mode for users. (It was previously only available to admin connections.) The method returns an updated list of amendments, including their names and other information. ([#4781](https://github.com/XRPLF/rippled/pull/4781))
|
||||
- `ledger_entry`: `state` is added an alias for `ripple_state`.
|
||||
|
||||
## XRP Ledger server version 2.3.0
|
||||
|
||||
### Breaking change in 2.3
|
||||
|
||||
@@ -105,6 +107,12 @@ The following additions are non-breaking (because they are purely additive).
|
||||
- In `Payment` transactions, `DeliverMax` has been added. This is a replacement for the `Amount` field, which should not be used. Typically, the `delivered_amount` (in transaction metadata) should be used. To ease the transition, `DeliverMax` is present regardless of API version, since adding a field is non-breaking.
|
||||
- API version 2 has been moved from beta to supported, meaning that it is generally available (regardless of the `beta_rpc_api` setting).
|
||||
|
||||
## XRP Ledger server version 2.2.0
|
||||
|
||||
The following is a non-breaking addition to the API.
|
||||
|
||||
- The `feature` method now has a non-admin mode for users. (It was previously only available to admin connections.) The method returns an updated list of amendments, including their names and other information. ([#4781](https://github.com/XRPLF/rippled/pull/4781))
|
||||
|
||||
## XRP Ledger server version 1.12.0
|
||||
|
||||
[Version 1.12.0](https://github.com/XRPLF/rippled/releases/tag/1.12.0) was released on Sep 6, 2023. The following additions are non-breaking (because they are purely additive).
|
||||
|
||||
@@ -4,9 +4,6 @@ Loop: test.jtx test.toplevel
|
||||
Loop: test.jtx test.unit_test
|
||||
test.unit_test == test.jtx
|
||||
|
||||
Loop: xrpl.basics xrpl.json
|
||||
xrpl.json == xrpl.basics
|
||||
|
||||
Loop: xrpld.app xrpld.core
|
||||
xrpld.app > xrpld.core
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
libxrpl.basics > xrpl.basics
|
||||
libxrpl.basics > xrpl.protocol
|
||||
libxrpl.crypto > xrpl.basics
|
||||
libxrpl.json > xrpl.basics
|
||||
libxrpl.json > xrpl.json
|
||||
@@ -130,6 +129,7 @@ test.shamap > xrpl.protocol
|
||||
test.toplevel > test.csf
|
||||
test.toplevel > xrpl.json
|
||||
test.unit_test > xrpl.basics
|
||||
xrpl.json > xrpl.basics
|
||||
xrpl.protocol > xrpl.basics
|
||||
xrpl.protocol > xrpl.json
|
||||
xrpl.resource > xrpl.basics
|
||||
|
||||
@@ -16,6 +16,8 @@ set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
set(Boost_NO_BOOST_CMAKE ON)
|
||||
|
||||
# make GIT_COMMIT_HASH define available to all sources
|
||||
find_package(Git)
|
||||
if(Git_FOUND)
|
||||
@@ -73,6 +75,7 @@ set(SECP256K1_INSTALL TRUE)
|
||||
add_subdirectory(external/secp256k1)
|
||||
add_library(secp256k1::secp256k1 ALIAS secp256k1)
|
||||
add_subdirectory(external/ed25519-donna)
|
||||
add_subdirectory(external/antithesis-sdk)
|
||||
find_package(gRPC REQUIRED)
|
||||
find_package(lz4 REQUIRED)
|
||||
# Target names with :: are not allowed in a generator expression.
|
||||
@@ -82,6 +85,17 @@ find_package(LibArchive REQUIRED)
|
||||
find_package(SOCI REQUIRED)
|
||||
find_package(SQLite3 REQUIRED)
|
||||
|
||||
# https://conan.io/center/recipes/wasmedge?version=0.9.0
|
||||
option(wasmedge "Enable WASM" ON)
|
||||
if(wasmedge)
|
||||
find_package(wasmedge REQUIRED)
|
||||
set_target_properties(wasmedge::wasmedge PROPERTIES
|
||||
INTERFACE_COMPILE_DEFINITIONS RIPPLE_WASMEDGE_AVAILABLE=1
|
||||
)
|
||||
target_link_libraries(ripple_libs INTERFACE wasmedge::wasmedge)
|
||||
# include(deps/WasmEdge)
|
||||
endif()
|
||||
|
||||
option(rocksdb "Enable RocksDB" ON)
|
||||
if(rocksdb)
|
||||
find_package(RocksDB REQUIRED)
|
||||
|
||||
@@ -343,6 +343,68 @@ pip3 install pre-commit
|
||||
pre-commit install
|
||||
```
|
||||
|
||||
## Contracts and instrumentation
|
||||
|
||||
We are using [Antithesis](https://antithesis.com/) for continuous fuzzing,
|
||||
and keep a copy of [Antithesis C++ SDK](https://github.com/antithesishq/antithesis-sdk-cpp/)
|
||||
in `external/antithesis-sdk`. One of the aims of fuzzing is to identify bugs
|
||||
by finding external conditions which cause contracts violations inside `rippled`.
|
||||
The contracts are expressed as `XRPL_ASSERT` or `UNREACHABLE` (defined in
|
||||
`include/xrpl/beast/utility/instrumentation.h`), which are effectively (outside
|
||||
of Antithesis) wrappers for `assert(...)` with added name. The purpose of name
|
||||
is to provide contracts with stable identity which does not rely on line numbers.
|
||||
|
||||
When `rippled` is built with the Antithesis instrumentation enabled
|
||||
(using `voidstar` CMake option) and ran on the Antithesis platform, the
|
||||
contracts become
|
||||
[test properties](https://antithesis.com/docs/using_antithesis/properties.html);
|
||||
otherwise they are just like a regular `assert`.
|
||||
To learn more about Antithesis, see
|
||||
[How Antithesis Works](https://antithesis.com/docs/introduction/how_antithesis_works.html)
|
||||
and [C++ SDK](https://antithesis.com/docs/using_antithesis/sdk/cpp/overview.html#)
|
||||
|
||||
We continue to use the old style `assert` or `assert(false)` in certain
|
||||
locations, where the reporting of contract violations on the Antithesis
|
||||
platform is either not possible or not useful.
|
||||
|
||||
For this reason:
|
||||
* The locations where `assert` or `assert(false)` contracts should continue to be used:
|
||||
* `constexpr` functions
|
||||
* unit tests i.e. files under `src/test`
|
||||
* unit tests-related modules (files under `beast/test` and `beast/unit_test`)
|
||||
* Outside of the listed locations, do not use `assert`; use `XRPL_ASSERT` instead,
|
||||
giving it unique name, with the short description of the contract.
|
||||
* Outside of the listed locations, do not use `assert(false)`; use
|
||||
`UNREACHABLE` instead, giving it unique name, with the description of the
|
||||
condition being violated
|
||||
* The contract name should start with a full name (including scope) of the
|
||||
function, optionally a named lambda, followed by a colon ` : ` and a brief
|
||||
(typically at most five words) description. `UNREACHABLE` contracts
|
||||
can use slightly longer descriptions. If there are multiple overloads of the
|
||||
function, use common sense to balance both brevity and unambiguity of the
|
||||
function name. NOTE: the purpose of name is to provide stable means of
|
||||
unique identification of every contract; for this reason try to avoid elements
|
||||
which can change in some obvious refactors or when reinforcing the condition.
|
||||
* Contract description typically (except for `UNREACHABLE`) should describe the
|
||||
_expected_ condition, as in "I assert that _expected_ is true".
|
||||
* Contract description for `UNREACHABLE` should describe the _unexpected_
|
||||
situation which caused the line to have been reached.
|
||||
* Example good name for an
|
||||
`UNREACHABLE` macro `"Json::operator==(Value, Value) : invalid type"`; example
|
||||
good name for an `XRPL_ASSERT` macro `"Json::Value::asCString : valid type"`.
|
||||
* Example **bad** name
|
||||
`"RFC1751::insert(char* s, int x, int start, int length) : length is greater than or equal zero"`
|
||||
(missing namespace, unnecessary full function signature, description too verbose).
|
||||
Good name: `"ripple::RFC1751::insert : minimum length"`.
|
||||
* In **few** well-justified cases a non-standard name can be used, in which case a
|
||||
comment should be placed to explain the rationale (example in `contract.cpp`)
|
||||
* Do **not** rename a contract without a good reason (e.g. the name no longer
|
||||
reflects the location or the condition being checked)
|
||||
* Do not use `std::unreachable`
|
||||
* Do not put contracts where they can be violated by an external condition
|
||||
(e.g. timing, data payload before mandatory validation etc.) as this creates
|
||||
bogus bug reports (and causes crashes of Debug builds)
|
||||
|
||||
## Unit Tests
|
||||
To execute all unit tests:
|
||||
|
||||
|
||||
@@ -6,6 +6,79 @@ This document contains the release notes for `rippled`, the reference server imp
|
||||
|
||||
Have new ideas? Need help with setting up your node? [Please open an issue here](https://github.com/xrplf/rippled/issues/new/choose).
|
||||
|
||||
# Version 2.3.0
|
||||
|
||||
Version 2.3.0 of `rippled`, the reference server implementation of the XRP Ledger protocol, is now available. This release includes 8 new amendments, including Multi-Purpose Tokens, Credentials, Clawback support for AMMs, and the ability to make offers as part of minting NFTs. Additionally, this release includes important fixes for stability, so server operators are encouraged to upgrade as soon as possible.
|
||||
|
||||
|
||||
## Action Required
|
||||
|
||||
If you run an XRP Ledger server, upgrade to version 2.3.0 as soon as possible to ensure service continuity.
|
||||
|
||||
Additionally, new amendments are now open for voting according to the XRP Ledger's [amendment process](https://xrpl.org/amendments.html), which enables protocol changes following two weeks of >80% support from trusted validators. The exact time that protocol changes take effect depends on the voting decisions of the decentralized network.
|
||||
|
||||
## Full Changelog
|
||||
|
||||
### Amendments
|
||||
|
||||
The following amendments are open for voting with this release:
|
||||
|
||||
- **XLS-70 Credentials** - Users can issue Credentials on the ledger and use Credentials to pre-approve incoming payments when using Deposit Authorization instead of individually approving payers. ([#5103](https://github.com/XRPLF/rippled/pull/5103))
|
||||
- related fix: #5189 (https://github.com/XRPLF/rippled/pull/5189)
|
||||
- **XLS-33 Multi-Purpose Tokens** - A new type of fungible token optimized for institutional DeFi including stablecoins. ([#5143](https://github.com/XRPLF/rippled/pull/5143))
|
||||
- **XLS-37 AMM Clawback** - Allows clawback-enabled tokens to be used in AMMs, with appropriate guardrails. ([#5142](https://github.com/XRPLF/rippled/pull/5142))
|
||||
- **XLS-52 NFTokenMintOffer** - Allows creating an NFT sell offer as part of minting a new NFT. ([#4845](https://github.com/XRPLF/rippled/pull/4845))
|
||||
- **fixAMMv1_2** - Fixes two bugs in Automated Market Maker (AMM) transaction processing. ([#5176](https://github.com/XRPLF/rippled/pull/5176))
|
||||
- **fixNFTokenPageLinks** - Fixes a bug that can cause NFT directories to have missing links, and introduces a transaction to repair corrupted ledger state. ([#4945](https://github.com/XRPLF/rippled/pull/4945))
|
||||
- **fixEnforceNFTokenTrustline** - Fixes two bugs in the interaction between NFT offers and trust lines. ([#4946](https://github.com/XRPLF/rippled/pull/4946))
|
||||
- **fixInnerObjTemplate2** - Standardizes the way inner objects are enforced across all transaction and ledger data. ([#5047](https://github.com/XRPLF/rippled/pull/5047))
|
||||
|
||||
The following amendment is partially implemented but not open for voting:
|
||||
|
||||
- **InvariantsV1_1** - Adds new invariants to ensure transactions process as intended, starting with an invariant to ensure that ledger entries owned by an account are deleted when the account is deleted. ([#4663](https://github.com/XRPLF/rippled/pull/4663))
|
||||
|
||||
### New Features
|
||||
|
||||
- Allow configuration of SQLite database page size. ([#5135](https://github.com/XRPLF/rippled/pull/5135), [#5140](https://github.com/XRPLF/rippled/pull/5140))
|
||||
- In the `libxrpl` C++ library, provide a list of known amendments. ([#5026](https://github.com/XRPLF/rippled/pull/5026))
|
||||
|
||||
### Deprecations
|
||||
|
||||
- History Shards are removed. ([#5066](https://github.com/XRPLF/rippled/pull/5066))
|
||||
- Reporting mode is removed. ([#5092](https://github.com/XRPLF/rippled/pull/5092))
|
||||
|
||||
For users wanting to store more ledger history, it is recommended to run a Clio server instead.
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- Fix a crash in debug builds when amm_info request contains an invalid AMM account ID. ([#5188](https://github.com/XRPLF/rippled/pull/5188))
|
||||
- Fix a crash caused by a race condition in peer-to-peer code. ([#5071](https://github.com/XRPLF/rippled/pull/5071))
|
||||
- Fix a crash in certain situations
|
||||
- Fix several bugs in the book_changes API method. ([#5096](https://github.com/XRPLF/rippled/pull/5096))
|
||||
- Fix bug triggered by providing an invalid marker to the account_nfts API method. ([#5045](https://github.com/XRPLF/rippled/pull/5045))
|
||||
- Accept lower-case hexadecimal in compact transaction identifier (CTID) parameters in API methods. ([#5049](https://github.com/XRPLF/rippled/pull/5049))
|
||||
- Disallow filtering by types that an account can't own in the account_objects API method. ([#5056](https://github.com/XRPLF/rippled/pull/5056))
|
||||
- Fix error code returned by the feature API method when providing an invalid parameter. ([#5063](https://github.com/XRPLF/rippled/pull/5063))
|
||||
- (API v3) Fix error code returned by amm_info when providing invalid parameters. ([#4924](https://github.com/XRPLF/rippled/pull/4924))
|
||||
|
||||
### Other Improvements
|
||||
|
||||
- Adds a new default hub, hubs.xrpkuwait.com, to the config file and bootstrapping code. ([#5169](https://github.com/XRPLF/rippled/pull/5169))
|
||||
- Improve error message when commandline interface fails with `rpcInternal` because there was no response from the server. ([#4959](https://github.com/XRPLF/rippled/pull/4959))
|
||||
- Add tools for debugging specific transactions via replay. ([#5027](https://github.com/XRPLF/rippled/pull/5027), [#5087](https://github.com/XRPLF/rippled/pull/5087))
|
||||
- Major reorganization of source code files. ([#4997](https://github.com/XRPLF/rippled/pull/4997))
|
||||
- Add new unit tests. ([#4886](https://github.com/XRPLF/rippled/pull/4886))
|
||||
- Various improvements to build tools and contributor documentation. ([#5001](https://github.com/XRPLF/rippled/pull/5001), [#5028](https://github.com/XRPLF/rippled/pull/5028), [#5052](https://github.com/XRPLF/rippled/pull/5052), [#5091](https://github.com/XRPLF/rippled/pull/5091), [#5084](https://github.com/XRPLF/rippled/pull/5084), [#5120](https://github.com/XRPLF/rippled/pull/5120), [#5010](https://github.com/XRPLF/rippled/pull/5010). [#5055](https://github.com/XRPLF/rippled/pull/5055), [#5067](https://github.com/XRPLF/rippled/pull/5067), [#5061](https://github.com/XRPLF/rippled/pull/5061), [#5072](https://github.com/XRPLF/rippled/pull/5072), [#5044](https://github.com/XRPLF/rippled/pull/5044) )
|
||||
- Various code cleanup and refactoring. ([#4509](https://github.com/XRPLF/rippled/pull/4509), [#4521](https://github.com/XRPLF/rippled/pull/4521), [#4856](https://github.com/XRPLF/rippled/pull/4856), [#5190](https://github.com/XRPLF/rippled/pull/5190), [#5081](https://github.com/XRPLF/rippled/pull/5081), [#5053](https://github.com/XRPLF/rippled/pull/5053), [#5058](https://github.com/XRPLF/rippled/pull/5058), [#5122](https://github.com/XRPLF/rippled/pull/5122), [#5059](https://github.com/XRPLF/rippled/pull/5059), [#5041](https://github.com/XRPLF/rippled/pull/5041))
|
||||
|
||||
|
||||
Bug Bounties and Responsible Disclosures:
|
||||
|
||||
We welcome reviews of the `rippled` code and urge researchers to responsibly disclose any issues they may find.
|
||||
|
||||
To report a bug, please send a detailed report to: <bugs@xrpl.org>
|
||||
|
||||
|
||||
# Version 2.2.3
|
||||
|
||||
Version 2.2.3 of `rippled`, the reference server implementation of the XRP Ledger protocol, is now available. This release fixes a problem that can cause full-history servers to run out of space in their SQLite databases, depending on configuration. There are no new amendments in this release.
|
||||
|
||||
@@ -120,7 +120,7 @@ else ()
|
||||
target_link_libraries (common
|
||||
INTERFACE
|
||||
-rdynamic
|
||||
$<$<BOOL:${is_linux}>:-Wl,-z,relro,-z,now>
|
||||
$<$<BOOL:${is_linux}>:-Wl,-z,relro,-z,now,--build-id>
|
||||
# link to static libc/c++ iff:
|
||||
# * static option set and
|
||||
# * NOT APPLE (AppleClang does not support static libc/c++) and
|
||||
@@ -131,6 +131,17 @@ else ()
|
||||
>)
|
||||
endif ()
|
||||
|
||||
# Antithesis instrumentation will only be built and deployed using machines running Linux.
|
||||
if (voidstar)
|
||||
if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
message(FATAL_ERROR "Antithesis instrumentation requires Debug build type, aborting...")
|
||||
elseif (NOT is_linux)
|
||||
message(FATAL_ERROR "Antithesis instrumentation requires Linux, aborting...")
|
||||
elseif (NOT (is_clang AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 16.0))
|
||||
message(FATAL_ERROR "Antithesis instrumentation requires Clang version 16 or later, aborting...")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (use_mold)
|
||||
# use mold linker if available
|
||||
execute_process (
|
||||
|
||||
@@ -47,6 +47,57 @@ target_link_libraries(xrpl.libpb
|
||||
gRPC::grpc++
|
||||
)
|
||||
|
||||
# TODO: Clean up the number of library targets later.
|
||||
add_library(xrpl.imports.main INTERFACE)
|
||||
target_link_libraries(xrpl.imports.main INTERFACE
|
||||
LibArchive::LibArchive
|
||||
OpenSSL::Crypto
|
||||
Ripple::boost
|
||||
Ripple::opts
|
||||
Ripple::syslibs
|
||||
absl::random_random
|
||||
date::date
|
||||
ed25519::ed25519
|
||||
secp256k1::secp256k1
|
||||
xxHash::xxhash
|
||||
)
|
||||
|
||||
include(add_module)
|
||||
include(target_link_modules)
|
||||
|
||||
# Level 01
|
||||
add_module(xrpl beast)
|
||||
target_link_libraries(xrpl.libxrpl.beast PUBLIC
|
||||
xrpl.imports.main
|
||||
xrpl.libpb
|
||||
)
|
||||
|
||||
# Level 02
|
||||
add_module(xrpl basics)
|
||||
target_link_libraries(xrpl.libxrpl.basics PUBLIC xrpl.libxrpl.beast)
|
||||
|
||||
# Level 03
|
||||
add_module(xrpl json)
|
||||
target_link_libraries(xrpl.libxrpl.json PUBLIC xrpl.libxrpl.basics)
|
||||
|
||||
add_module(xrpl crypto)
|
||||
target_link_libraries(xrpl.libxrpl.crypto PUBLIC xrpl.libxrpl.basics)
|
||||
|
||||
# Level 04
|
||||
add_module(xrpl protocol)
|
||||
target_link_libraries(xrpl.libxrpl.protocol PUBLIC
|
||||
xrpl.libxrpl.crypto
|
||||
xrpl.libxrpl.json
|
||||
)
|
||||
|
||||
# Level 05
|
||||
add_module(xrpl resource)
|
||||
target_link_libraries(xrpl.libxrpl.resource PUBLIC xrpl.libxrpl.protocol)
|
||||
|
||||
add_module(xrpl server)
|
||||
target_link_libraries(xrpl.libxrpl.server PUBLIC xrpl.libxrpl.protocol)
|
||||
|
||||
|
||||
add_library(xrpl.libxrpl)
|
||||
set_target_properties(xrpl.libxrpl PROPERTIES OUTPUT_NAME xrpl)
|
||||
if(unity)
|
||||
@@ -60,10 +111,24 @@ file(GLOB_RECURSE sources CONFIGURE_DEPENDS
|
||||
)
|
||||
target_sources(xrpl.libxrpl PRIVATE ${sources})
|
||||
|
||||
target_include_directories(xrpl.libxrpl
|
||||
PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||
$<INSTALL_INTERFACE:include>)
|
||||
target_link_modules(xrpl PUBLIC
|
||||
basics
|
||||
beast
|
||||
crypto
|
||||
json
|
||||
protocol
|
||||
resource
|
||||
server
|
||||
)
|
||||
|
||||
# All headers in libxrpl are in modules.
|
||||
# Uncomment this stanza if you have not yet moved new headers into a module.
|
||||
# target_include_directories(xrpl.libxrpl
|
||||
# PRIVATE
|
||||
# $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
|
||||
# PUBLIC
|
||||
# $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||
# $<INSTALL_INTERFACE:include>)
|
||||
|
||||
target_compile_definitions(xrpl.libxrpl
|
||||
PUBLIC
|
||||
@@ -74,6 +139,7 @@ target_compile_definitions(xrpl.libxrpl
|
||||
target_compile_options(xrpl.libxrpl
|
||||
PUBLIC
|
||||
$<$<BOOL:${is_gcc}>:-Wno-maybe-uninitialized>
|
||||
$<$<BOOL:${voidstar}>:-DENABLE_VOIDSTAR>
|
||||
)
|
||||
|
||||
target_link_libraries(xrpl.libxrpl
|
||||
@@ -89,6 +155,7 @@ target_link_libraries(xrpl.libxrpl
|
||||
secp256k1::secp256k1
|
||||
xrpl.libpb
|
||||
xxHash::xxhash
|
||||
$<$<BOOL:${voidstar}>:antithesis-sdk-cpp>
|
||||
)
|
||||
|
||||
if(xrpld)
|
||||
@@ -129,12 +196,32 @@ if(xrpld)
|
||||
target_compile_definitions(rippled PRIVATE RIPPLED_RUNNING_IN_CI)
|
||||
endif ()
|
||||
|
||||
if(voidstar)
|
||||
target_compile_options(rippled
|
||||
PRIVATE
|
||||
-fsanitize-coverage=trace-pc-guard
|
||||
)
|
||||
# rippled requires access to antithesis-sdk-cpp implementation file
|
||||
# antithesis_instrumentation.h, which is not exported as INTERFACE
|
||||
target_include_directories(rippled
|
||||
PRIVATE
|
||||
${CMAKE_SOURCE_DIR}/external/antithesis-sdk
|
||||
)
|
||||
endif()
|
||||
|
||||
# any files that don't play well with unity should be added here
|
||||
if(tests)
|
||||
set_source_files_properties(
|
||||
# these two seem to produce conflicts in beast teardown template methods
|
||||
src/test/rpc/ValidatorRPC_test.cpp
|
||||
src/test/ledger/Invariants_test.cpp
|
||||
# These depend on wasmedge.h, which has some duplicate declarations
|
||||
src/ripple/app/hook/impl/applyHook.cpp
|
||||
src/ripple/app/misc/NetworkOPs.cpp
|
||||
src/ripple/app/tx/impl/applySteps.cpp
|
||||
src/ripple/app/tx/impl/SetHook.cpp
|
||||
src/ripple/app/tx/impl/Transactor.cpp
|
||||
src/ripple/rpc/handlers/Fee1.cpp
|
||||
PROPERTIES SKIP_UNITY_BUILD_INCLUSION TRUE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -2,14 +2,25 @@
|
||||
install stuff
|
||||
#]===================================================================]
|
||||
|
||||
include(create_symbolic_link)
|
||||
|
||||
install (
|
||||
TARGETS
|
||||
common
|
||||
opts
|
||||
ripple_syslibs
|
||||
ripple_boost
|
||||
xrpl.imports.main
|
||||
xrpl.libpb
|
||||
xrpl.libxrpl.basics
|
||||
xrpl.libxrpl.beast
|
||||
xrpl.libxrpl.crypto
|
||||
xrpl.libxrpl.json
|
||||
xrpl.libxrpl.protocol
|
||||
xrpl.libxrpl.resource
|
||||
xrpl.libxrpl.server
|
||||
xrpl.libxrpl
|
||||
antithesis-sdk-cpp
|
||||
EXPORT RippleExports
|
||||
LIBRARY DESTINATION lib
|
||||
ARCHIVE DESTINATION lib
|
||||
@@ -21,12 +32,12 @@ install(
|
||||
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
||||
)
|
||||
|
||||
if(NOT WIN32)
|
||||
install(
|
||||
CODE "file(CREATE_LINK xrpl \
|
||||
\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/ripple SYMBOLIC)"
|
||||
)
|
||||
endif()
|
||||
install(CODE "
|
||||
set(CMAKE_MODULE_PATH \"${CMAKE_MODULE_PATH}\")
|
||||
include(create_symbolic_link)
|
||||
create_symbolic_link(xrpl \
|
||||
\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}/ripple)
|
||||
")
|
||||
|
||||
install (EXPORT RippleExports
|
||||
FILE RippleTargets.cmake
|
||||
@@ -55,12 +66,12 @@ if (is_root_project AND TARGET rippled)
|
||||
copy_if_not_exists(\"${CMAKE_CURRENT_SOURCE_DIR}/cfg/rippled-example.cfg\" etc rippled.cfg)
|
||||
copy_if_not_exists(\"${CMAKE_CURRENT_SOURCE_DIR}/cfg/validators-example.txt\" etc validators.txt)
|
||||
")
|
||||
if(NOT WIN32)
|
||||
install(
|
||||
CODE "file(CREATE_LINK rippled${suffix} \
|
||||
\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}/xrpld${suffix} SYMBOLIC)"
|
||||
)
|
||||
endif()
|
||||
install(CODE "
|
||||
set(CMAKE_MODULE_PATH \"${CMAKE_MODULE_PATH}\")
|
||||
include(create_symbolic_link)
|
||||
create_symbolic_link(rippled${suffix} \
|
||||
\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}/xrpld${suffix})
|
||||
")
|
||||
endif ()
|
||||
|
||||
install (
|
||||
|
||||
@@ -18,6 +18,9 @@ if(unity)
|
||||
set(CMAKE_UNITY_BUILD_BATCH_SIZE 15 CACHE STRING "")
|
||||
endif()
|
||||
endif()
|
||||
if(is_clang AND is_linux)
|
||||
option(voidstar "Enable Antithesis instrumentation." OFF)
|
||||
endif()
|
||||
if(is_gcc OR is_clang)
|
||||
option(coverage "Generates coverage info." OFF)
|
||||
option(profile "Add profiling flags" OFF)
|
||||
|
||||
37
cmake/add_module.cmake
Normal file
37
cmake/add_module.cmake
Normal file
@@ -0,0 +1,37 @@
|
||||
include(isolate_headers)
|
||||
|
||||
# Create an OBJECT library target named
|
||||
#
|
||||
# ${PROJECT_NAME}.lib${parent}.${name}
|
||||
#
|
||||
# with sources in src/lib${parent}/${name}
|
||||
# and headers in include/${parent}/${name}
|
||||
# that cannot include headers from other directories in include/
|
||||
# unless they come through linked libraries.
|
||||
#
|
||||
# add_module(parent a)
|
||||
# add_module(parent b)
|
||||
# target_link_libraries(project.libparent.b PUBLIC project.libparent.a)
|
||||
function(add_module parent name)
|
||||
set(target ${PROJECT_NAME}.lib${parent}.${name})
|
||||
add_library(${target} OBJECT)
|
||||
file(GLOB_RECURSE sources CONFIGURE_DEPENDS
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/lib${parent}/${name}/*.cpp"
|
||||
)
|
||||
target_sources(${target} PRIVATE ${sources})
|
||||
target_include_directories(${target} PUBLIC
|
||||
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
|
||||
)
|
||||
isolate_headers(
|
||||
${target}
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/${parent}/${name}"
|
||||
PUBLIC
|
||||
)
|
||||
isolate_headers(
|
||||
${target}
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/lib${parent}/${name}"
|
||||
PRIVATE
|
||||
)
|
||||
endfunction()
|
||||
20
cmake/create_symbolic_link.cmake
Normal file
20
cmake/create_symbolic_link.cmake
Normal file
@@ -0,0 +1,20 @@
|
||||
# file(CREATE_SYMLINK) only works on Windows with administrator privileges.
|
||||
# https://stackoverflow.com/a/61244115/618906
|
||||
function(create_symbolic_link target link)
|
||||
if(WIN32)
|
||||
if(NOT IS_SYMLINK "${link}")
|
||||
if(NOT IS_ABSOLUTE "${target}")
|
||||
# Relative links work do not work on Windows.
|
||||
set(target "${link}/../${target}")
|
||||
endif()
|
||||
file(TO_NATIVE_PATH "${target}" target)
|
||||
file(TO_NATIVE_PATH "${link}" link)
|
||||
execute_process(COMMAND cmd.exe /c mklink /J "${link}" "${target}")
|
||||
endif()
|
||||
else()
|
||||
file(CREATE_LINK "${target}" "${link}" SYMBOLIC)
|
||||
endif()
|
||||
if(NOT IS_SYMLINK "${link}")
|
||||
message(ERROR "failed to create symlink: <${link}>")
|
||||
endif()
|
||||
endfunction()
|
||||
52
cmake/deps/WasmEdge.cmake
Normal file
52
cmake/deps/WasmEdge.cmake
Normal file
@@ -0,0 +1,52 @@
|
||||
#[===================================================================[
|
||||
NIH dep: wasmedge: web assembly runtime for hooks.
|
||||
#]===================================================================]
|
||||
|
||||
if (is_root_project) # WasmEdge not needed in the case of xrpl_core inclusion build
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
set(OLD_DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
|
||||
set(CMAKE_DEBUG_POSTFIX _d)
|
||||
endif ()
|
||||
add_library (wasmedge INTERFACE)
|
||||
ExternalProject_Add (wasmedge_src
|
||||
PREFIX ${nih_cache_path}
|
||||
GIT_REPOSITORY https://github.com/WasmEdge/WasmEdge.git
|
||||
GIT_TAG 0.9.0
|
||||
CMAKE_ARGS
|
||||
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
|
||||
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
|
||||
$<$<BOOL:${CMAKE_VERBOSE_MAKEFILE}>:-DCMAKE_VERBOSE_MAKEFILE=ON>
|
||||
-DCMAKE_DEBUG_POSTFIX=_d
|
||||
$<$<NOT:$<BOOL:${is_multiconfig}>>:-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}>
|
||||
$<$<BOOL:${MSVC}>:
|
||||
"-DCMAKE_C_FLAGS=-GR -Gd -fp:precise -FS -MP"
|
||||
"-DCMAKE_C_FLAGS_DEBUG=-MTd"
|
||||
"-DCMAKE_C_FLAGS_RELEASE=-MT"
|
||||
>
|
||||
LOG_BUILD ON
|
||||
LOG_CONFIGURE ON
|
||||
BUILD_COMMAND
|
||||
${CMAKE_COMMAND}
|
||||
--build .
|
||||
--config $<CONFIG>
|
||||
$<$<VERSION_GREATER_EQUAL:${CMAKE_VERSION},3.12>:--parallel ${ep_procs}>
|
||||
TEST_COMMAND ""
|
||||
INSTALL_COMMAND ""
|
||||
BUILD_BYPRODUCTS
|
||||
<BINARY_DIR>/lib/api/libwasmedge_c_${CMAKE_DEBUG_POSTFIX}.so
|
||||
)
|
||||
ExternalProject_Get_Property (wasmedge_src BINARY_DIR)
|
||||
set (wasmedge_src_BINARY_DIR "${BINARY_DIR}")
|
||||
add_dependencies (wasmedge wasmedge_src)
|
||||
target_include_directories (ripple_libs SYSTEM INTERFACE "${wasmedge_src_BINARY_DIR}/include/api")
|
||||
target_link_libraries (wasmedge
|
||||
INTERFACE
|
||||
Boost::thread
|
||||
Boost::system)
|
||||
target_link_libraries (wasmedge INTERFACE
|
||||
"${wasmedge_src_BINARY_DIR}/lib/api/libwasmedge_c${CMAKE_DEBUG_POSTFIX}.so")
|
||||
target_link_libraries (ripple_libs INTERFACE wasmedge)
|
||||
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
set(CMAKE_DEBUG_POSTFIX ${OLD_DEBUG_POSTFIX})
|
||||
endif ()
|
||||
endif ()
|
||||
48
cmake/isolate_headers.cmake
Normal file
48
cmake/isolate_headers.cmake
Normal file
@@ -0,0 +1,48 @@
|
||||
include(create_symbolic_link)
|
||||
|
||||
# Consider include directory B nested under prefix A:
|
||||
#
|
||||
# /path/to/A/then/to/B/...
|
||||
#
|
||||
# Call C the relative path from A to B.
|
||||
# C is what we want to write in `#include` directives:
|
||||
#
|
||||
# #include <then/to/B/...>
|
||||
#
|
||||
# Examples, all from the `jobqueue` module:
|
||||
#
|
||||
# - Library public headers:
|
||||
# B = /include/xrpl/jobqueue
|
||||
# A = /include/
|
||||
# C = xrpl/jobqueue
|
||||
#
|
||||
# - Library private headers:
|
||||
# B = /src/libxrpl/jobqueue
|
||||
# A = /src/
|
||||
# C = libxrpl/jobqueue
|
||||
#
|
||||
# - Test private headers:
|
||||
# B = /tests/jobqueue
|
||||
# A = /
|
||||
# C = tests/jobqueue
|
||||
#
|
||||
# To isolate headers from each other,
|
||||
# we want to create a symlink Y that points to B,
|
||||
# within a subdirectory X of the `CMAKE_BINARY_DIR`,
|
||||
# that has the same relative path C between X and Y,
|
||||
# and then add X as an include directory of the target,
|
||||
# sometimes `PUBLIC` and sometimes `PRIVATE`.
|
||||
# The Cs are all guaranteed to be unique.
|
||||
# We can guarantee a unique X per target by using
|
||||
# `${CMAKE_CURRENT_BINARY_DIR}/include/${target}`.
|
||||
#
|
||||
# isolate_headers(target A B scope)
|
||||
function(isolate_headers target A B scope)
|
||||
file(RELATIVE_PATH C "${A}" "${B}")
|
||||
set(X "${CMAKE_CURRENT_BINARY_DIR}/modules/${target}")
|
||||
set(Y "${X}/${C}")
|
||||
cmake_path(GET Y PARENT_PATH parent)
|
||||
file(MAKE_DIRECTORY "${parent}")
|
||||
create_symbolic_link("${B}" "${Y}")
|
||||
target_include_directories(${target} ${scope} "$<BUILD_INTERFACE:${X}>")
|
||||
endfunction()
|
||||
24
cmake/target_link_modules.cmake
Normal file
24
cmake/target_link_modules.cmake
Normal file
@@ -0,0 +1,24 @@
|
||||
# Link a library to its modules (see: `add_module`)
|
||||
# and remove the module sources from the library's sources.
|
||||
#
|
||||
# add_module(parent a)
|
||||
# add_module(parent b)
|
||||
# target_link_libraries(project.libparent.b PUBLIC project.libparent.a)
|
||||
# add_library(project.libparent)
|
||||
# target_link_modules(parent PUBLIC a b)
|
||||
function(target_link_modules parent scope)
|
||||
set(library ${PROJECT_NAME}.lib${parent})
|
||||
foreach(name ${ARGN})
|
||||
set(module ${library}.${name})
|
||||
get_target_property(sources ${library} SOURCES)
|
||||
list(LENGTH sources before)
|
||||
get_target_property(dupes ${module} SOURCES)
|
||||
list(LENGTH dupes expected)
|
||||
list(REMOVE_ITEM sources ${dupes})
|
||||
list(LENGTH sources after)
|
||||
math(EXPR actual "${before} - ${after}")
|
||||
message(STATUS "${module} with ${expected} sources took ${actual} sources from ${library}")
|
||||
set_target_properties(${library} PROPERTIES SOURCES "${sources}")
|
||||
target_link_libraries(${library} ${scope} ${module})
|
||||
endforeach()
|
||||
endfunction()
|
||||
@@ -30,6 +30,7 @@ class Xrpl(ConanFile):
|
||||
'nudb/2.0.8',
|
||||
'openssl/1.1.1u',
|
||||
'soci/4.0.3',
|
||||
'wasmedge/0.9.0',
|
||||
'xxhash/0.8.2',
|
||||
'zlib/1.2.13',
|
||||
]
|
||||
|
||||
1
external/README.md
vendored
1
external/README.md
vendored
@@ -6,6 +6,7 @@ The Conan recipes include patches we have not yet pushed upstream.
|
||||
|
||||
| Folder | Upstream | Description |
|
||||
|:----------------|:---------------------------------------------|:------------|
|
||||
| `antithesis-sdk`| [Project](https://github.com/antithesishq/antithesis-sdk-cpp/) | [Antithesis](https://antithesis.com/docs/using_antithesis/sdk/cpp/overview.html) SDK for C++ |
|
||||
| `ed25519-donna` | [Project](https://github.com/floodyberry/ed25519-donna) | [Ed25519](http://ed25519.cr.yp.to/) digital signatures |
|
||||
| `rocksdb` | [Recipe](https://github.com/conan-io/conan-center-index/tree/master/recipes/rocksdb) | Fast key/value database. (Supports rotational disks better than NuDB.) |
|
||||
| `secp256k1` | [Project](https://github.com/bitcoin-core/secp256k1) | ECDSA digital signatures using the **secp256k1** curve |
|
||||
|
||||
3
external/antithesis-sdk/.clang-format
vendored
Normal file
3
external/antithesis-sdk/.clang-format
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
---
|
||||
DisableFormat: true
|
||||
SortIncludes: false
|
||||
17
external/antithesis-sdk/CMakeLists.txt
vendored
Normal file
17
external/antithesis-sdk/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
cmake_minimum_required(VERSION 3.25)
|
||||
|
||||
# Note, version set explicitly by rippled project
|
||||
project(antithesis-sdk-cpp VERSION 0.4.4 LANGUAGES CXX)
|
||||
|
||||
add_library(antithesis-sdk-cpp INTERFACE antithesis_sdk.h)
|
||||
|
||||
# Note, both sections below created by rippled project
|
||||
target_include_directories(antithesis-sdk-cpp INTERFACE
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
||||
)
|
||||
|
||||
install(
|
||||
FILES antithesis_sdk.h
|
||||
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}"
|
||||
)
|
||||
BIN
external/antithesis-sdk/LICENSE
vendored
Normal file
BIN
external/antithesis-sdk/LICENSE
vendored
Normal file
Binary file not shown.
8
external/antithesis-sdk/README.md
vendored
Normal file
8
external/antithesis-sdk/README.md
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
# Antithesis C++ SDK
|
||||
|
||||
This library provides methods for C++ programs to configure the [Antithesis](https://antithesis.com) platform. It contains three kinds of functionality:
|
||||
* Assertion macros that allow you to define test properties about your software or workload.
|
||||
* Randomness functions for requesting both structured and unstructured randomness from the Antithesis platform.
|
||||
* Lifecycle functions that inform the Antithesis environment that particular test phases or milestones have been reached.
|
||||
|
||||
For general usage guidance see the [Antithesis C++ SDK Documentation](https://antithesis.com/docs/using_antithesis/sdk/cpp/overview/)
|
||||
113
external/antithesis-sdk/antithesis_instrumentation.h
vendored
Normal file
113
external/antithesis-sdk/antithesis_instrumentation.h
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
#pragma once
|
||||
|
||||
/*
|
||||
This header file enables code coverage instrumentation. It is distributed with the Antithesis C++ SDK.
|
||||
|
||||
This header file can be used in both C and C++ programs. (The rest of the SDK works only for C++ programs.)
|
||||
|
||||
You should include it in a single .cpp or .c file.
|
||||
|
||||
The instructions (such as required compiler flags) and usage guidance are found at https://antithesis.com/docs/using_antithesis/sdk/cpp/overview/.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <dlfcn.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#ifndef __cplusplus
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#endif
|
||||
|
||||
// If the libvoidstar(determ) library is present,
|
||||
// pass thru trace_pc_guard related callbacks to it
|
||||
typedef void (*trace_pc_guard_init_fn)(uint32_t *start, uint32_t *stop);
|
||||
typedef void (*trace_pc_guard_fn)(uint32_t *guard, uint64_t edge);
|
||||
|
||||
static trace_pc_guard_init_fn trace_pc_guard_init = NULL;
|
||||
static trace_pc_guard_fn trace_pc_guard = NULL;
|
||||
static bool did_check_libvoidstar = false;
|
||||
static bool has_libvoidstar = false;
|
||||
|
||||
static __attribute__((no_sanitize("coverage"))) void debug_message_out(const char *msg) {
|
||||
(void)printf("%s\n", msg);
|
||||
return;
|
||||
}
|
||||
|
||||
extern
|
||||
#ifdef __cplusplus
|
||||
"C"
|
||||
#endif
|
||||
__attribute__((no_sanitize("coverage"))) void antithesis_load_libvoidstar() {
|
||||
#ifdef __cplusplus
|
||||
constexpr
|
||||
#endif
|
||||
const char* LIB_PATH = "/usr/lib/libvoidstar.so";
|
||||
|
||||
if (did_check_libvoidstar) {
|
||||
return;
|
||||
}
|
||||
debug_message_out("TRYING TO LOAD libvoidstar");
|
||||
did_check_libvoidstar = true;
|
||||
void* shared_lib = dlopen(LIB_PATH, RTLD_NOW);
|
||||
if (!shared_lib) {
|
||||
debug_message_out("Can not load the Antithesis native library");
|
||||
return;
|
||||
}
|
||||
|
||||
void* trace_pc_guard_init_sym = dlsym(shared_lib, "__sanitizer_cov_trace_pc_guard_init");
|
||||
if (!trace_pc_guard_init_sym) {
|
||||
debug_message_out("Can not forward calls to libvoidstar for __sanitizer_cov_trace_pc_guard_init");
|
||||
return;
|
||||
}
|
||||
|
||||
void* trace_pc_guard_sym = dlsym(shared_lib, "__sanitizer_cov_trace_pc_guard_internal");
|
||||
if (!trace_pc_guard_sym) {
|
||||
debug_message_out("Can not forward calls to libvoidstar for __sanitizer_cov_trace_pc_guard");
|
||||
return;
|
||||
}
|
||||
|
||||
trace_pc_guard_init = (trace_pc_guard_init_fn)(trace_pc_guard_init_sym);
|
||||
trace_pc_guard = (trace_pc_guard_fn)(trace_pc_guard_sym);
|
||||
has_libvoidstar = true;
|
||||
debug_message_out("LOADED libvoidstar");
|
||||
}
|
||||
|
||||
// The following symbols are indeed reserved identifiers, since we're implementing functions defined
|
||||
// in the compiler runtime. Not clear how to get Clang on board with that besides narrowly suppressing
|
||||
// the warning in this case. The sample code on the CoverageSanitizer documentation page fails this
|
||||
// warning!
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wreserved-identifier"
|
||||
extern
|
||||
#ifdef __cplusplus
|
||||
"C"
|
||||
#endif
|
||||
void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
|
||||
debug_message_out("SDK forwarding to libvoidstar for __sanitizer_cov_trace_pc_guard_init()");
|
||||
if (!did_check_libvoidstar) {
|
||||
antithesis_load_libvoidstar();
|
||||
}
|
||||
if (has_libvoidstar) {
|
||||
trace_pc_guard_init(start, stop);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
extern
|
||||
#ifdef __cplusplus
|
||||
"C"
|
||||
#endif
|
||||
void __sanitizer_cov_trace_pc_guard( uint32_t *guard ) {
|
||||
if (has_libvoidstar) {
|
||||
uint64_t edge = (uint64_t)(__builtin_return_address(0));
|
||||
trace_pc_guard(guard, edge);
|
||||
} else {
|
||||
if (guard) {
|
||||
*guard = 0;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
#pragma clang diagnostic pop
|
||||
1105
external/antithesis-sdk/antithesis_sdk.h
vendored
Normal file
1105
external/antithesis-sdk/antithesis_sdk.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
194
external/wasmedge/conandata.yml
vendored
Normal file
194
external/wasmedge/conandata.yml
vendored
Normal file
@@ -0,0 +1,194 @@
|
||||
sources:
|
||||
"0.13.5":
|
||||
Windows:
|
||||
"x86_64":
|
||||
Visual Studio:
|
||||
- url: "https://github.com/WasmEdge/WasmEdge/releases/download/0.13.5/WasmEdge-0.13.5-windows.zip"
|
||||
sha256: "db533289ba26ec557b5193593c9ed03db75be3bc7aa737e2caa5b56b8eef888a"
|
||||
- url: "https://raw.githubusercontent.com/WasmEdge/WasmEdge/0.13.5/LICENSE"
|
||||
sha256: "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4"
|
||||
Linux:
|
||||
"x86_64":
|
||||
"gcc":
|
||||
- url: "https://github.com/WasmEdge/WasmEdge/releases/download/0.13.5/WasmEdge-0.13.5-manylinux2014_x86_64.tar.gz"
|
||||
sha256: "3686e0226871bf17b62ec57e1c15778c2947834b90af0dfad14f2e0202bf9284"
|
||||
- url: "https://raw.githubusercontent.com/WasmEdge/WasmEdge/0.13.5/LICENSE"
|
||||
sha256: "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4"
|
||||
"armv8":
|
||||
"gcc":
|
||||
- url: "https://github.com/WasmEdge/WasmEdge/releases/download/0.13.5/WasmEdge-0.13.5-manylinux2014_aarch64.tar.gz"
|
||||
sha256: "472de88e0257c539c120b33fdd1805e1e95063121acc2df1d5626e4676b93529"
|
||||
- url: "https://raw.githubusercontent.com/WasmEdge/WasmEdge/0.11.1/LICENSE"
|
||||
sha256: "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4"
|
||||
Macos:
|
||||
"x86_64":
|
||||
"gcc":
|
||||
- url: "https://github.com/WasmEdge/WasmEdge/releases/download/0.13.5/WasmEdge-0.13.5-darwin_x86_64.tar.gz"
|
||||
sha256: "b7fdfaf59805951241f47690917b501ddfa06d9b6f7e0262e44e784efe4a7b33"
|
||||
- url: "https://raw.githubusercontent.com/WasmEdge/WasmEdge/0.13.5/LICENSE"
|
||||
sha256: "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4"
|
||||
"armv8":
|
||||
"gcc":
|
||||
- url: "https://github.com/WasmEdge/WasmEdge/releases/download/0.13.5/WasmEdge-0.13.5-darwin_arm64.tar.gz"
|
||||
sha256: "acc93721210294ced0887352f360e42e46dcc05332e6dd78c1452fb3a35d5255"
|
||||
- url: "https://raw.githubusercontent.com/WasmEdge/WasmEdge/0.13.5/LICENSE"
|
||||
sha256: "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4"
|
||||
Android:
|
||||
"armv8":
|
||||
"gcc":
|
||||
- url: "https://github.com/WasmEdge/WasmEdge/releases/download/0.13.5/WasmEdge-0.13.5-android_aarch64.tar.gz"
|
||||
sha256: "59a0d68a0c7368b51cc65cb5a44a68037d79fd449883ef42792178d57c8784a8"
|
||||
- url: "https://raw.githubusercontent.com/WasmEdge/WasmEdge/0.13.5/LICENSE"
|
||||
sha256: "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4"
|
||||
"0.11.2":
|
||||
Windows:
|
||||
"x86_64":
|
||||
Visual Studio:
|
||||
- url: "https://github.com/WasmEdge/WasmEdge/releases/download/0.11.2/WasmEdge-0.11.2-windows.zip"
|
||||
sha256: "ca49b98c0cf5f187e08c3ba71afc8d71365fde696f10b4219379a4a4d1a91e6d"
|
||||
- url: "https://raw.githubusercontent.com/WasmEdge/WasmEdge/0.11.2/LICENSE"
|
||||
sha256: "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4"
|
||||
Linux:
|
||||
"x86_64":
|
||||
"gcc":
|
||||
- url: "https://github.com/WasmEdge/WasmEdge/releases/download/0.11.2/WasmEdge-0.11.2-manylinux2014_x86_64.tar.gz"
|
||||
sha256: "784bf1eb25928e2cf02aa88e9372388fad682b4a188485da3cd9162caeedf143"
|
||||
- url: "https://raw.githubusercontent.com/WasmEdge/WasmEdge/0.11.2/LICENSE"
|
||||
sha256: "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4"
|
||||
"armv8":
|
||||
"gcc":
|
||||
- url: "https://github.com/WasmEdge/WasmEdge/releases/download/0.11.2/WasmEdge-0.11.2-manylinux2014_aarch64.tar.gz"
|
||||
sha256: "a2766a4c1edbaea298a30e5431a4e795003a10d8398a933d923f23d4eb4fa5d1"
|
||||
- url: "https://raw.githubusercontent.com/WasmEdge/WasmEdge/0.11.1/LICENSE"
|
||||
sha256: "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4"
|
||||
Macos:
|
||||
"x86_64":
|
||||
"gcc":
|
||||
- url: "https://github.com/WasmEdge/WasmEdge/releases/download/0.11.2/WasmEdge-0.11.2-darwin_x86_64.tar.gz"
|
||||
sha256: "aedec53f29b1e0b657e46e67dba3e2f32a2924f4d9136e60073ea1aba3073e70"
|
||||
- url: "https://raw.githubusercontent.com/WasmEdge/WasmEdge/0.11.2/LICENSE"
|
||||
sha256: "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4"
|
||||
"armv8":
|
||||
"gcc":
|
||||
- url: "https://github.com/WasmEdge/WasmEdge/releases/download/0.11.2/WasmEdge-0.11.2-darwin_arm64.tar.gz"
|
||||
sha256: "fe391df90e1eee69cf1e976f5ddf60c20f29b651710aaa4fc03e2ab4fe52c0d3"
|
||||
- url: "https://raw.githubusercontent.com/WasmEdge/WasmEdge/0.11.2/LICENSE"
|
||||
sha256: "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4"
|
||||
Android:
|
||||
"armv8":
|
||||
"gcc":
|
||||
- url: "https://github.com/WasmEdge/WasmEdge/releases/download/0.11.2/WasmEdge-0.11.2-android_aarch64.tar.gz"
|
||||
sha256: "69e308f5927c753b2bb5639569d10219b60598174d8b304bdf310093fd7b2464"
|
||||
- url: "https://raw.githubusercontent.com/WasmEdge/WasmEdge/0.11.2/LICENSE"
|
||||
sha256: "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4"
|
||||
"0.11.1":
|
||||
Windows:
|
||||
"x86_64":
|
||||
Visual Studio:
|
||||
- url: "https://github.com/WasmEdge/WasmEdge/releases/download/0.11.1/WasmEdge-0.11.1-windows.zip"
|
||||
sha256: "c86f6384555a0484a5dd81faba5636bba78f5e3d6eaf627d880e34843f9e24bf"
|
||||
- url: "https://raw.githubusercontent.com/WasmEdge/WasmEdge/0.11.1/LICENSE"
|
||||
sha256: "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4"
|
||||
Linux:
|
||||
"x86_64":
|
||||
"gcc":
|
||||
- url: "https://github.com/WasmEdge/WasmEdge/releases/download/0.11.1/WasmEdge-0.11.1-manylinux2014_x86_64.tar.gz"
|
||||
sha256: "76ce4ea0eb86adfa52c73f6c6b44383626d94990e0923cae8b1e6f060ef2bf5b"
|
||||
- url: "https://raw.githubusercontent.com/WasmEdge/WasmEdge/0.11.1/LICENSE"
|
||||
sha256: "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4"
|
||||
"armv8":
|
||||
"gcc":
|
||||
- url: "https://github.com/WasmEdge/WasmEdge/releases/download/0.11.1/WasmEdge-0.11.1-manylinux2014_aarch64.tar.gz"
|
||||
sha256: "cb9ea32932360463991cfda80e09879b2cf6c69737f12f3f2b371cd0af4e9ce8"
|
||||
- url: "https://raw.githubusercontent.com/WasmEdge/WasmEdge/0.11.1/LICENSE"
|
||||
sha256: "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4"
|
||||
Macos:
|
||||
"x86_64":
|
||||
"gcc":
|
||||
- url: "https://github.com/WasmEdge/WasmEdge/releases/download/0.11.1/WasmEdge-0.11.1-darwin_x86_64.tar.gz"
|
||||
sha256: "56df2b00669c25b8143ea2c17370256cd6a33f3b316d3b47857dd38d603cb69a"
|
||||
- url: "https://raw.githubusercontent.com/WasmEdge/WasmEdge/0.11.1/LICENSE"
|
||||
sha256: "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4"
|
||||
"armv8":
|
||||
"gcc":
|
||||
- url: "https://github.com/WasmEdge/WasmEdge/releases/download/0.11.1/WasmEdge-0.11.1-darwin_arm64.tar.gz"
|
||||
sha256: "82f7da1a7a36ec1923fb045193784dd090a03109e84da042af97297205a71f08"
|
||||
- url: "https://raw.githubusercontent.com/WasmEdge/WasmEdge/0.11.1/LICENSE"
|
||||
sha256: "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4"
|
||||
Android:
|
||||
"armv8":
|
||||
"gcc":
|
||||
- url: "https://github.com/WasmEdge/WasmEdge/releases/download/0.11.1/WasmEdge-0.11.1-android_aarch64.tar.gz"
|
||||
sha256: "af8694e93bf72ac5506450d4caebccc340fbba254dca3d58ec0712e96ec9dedd"
|
||||
- url: "https://raw.githubusercontent.com/WasmEdge/WasmEdge/0.11.1/LICENSE"
|
||||
sha256: "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4"
|
||||
"0.10.0":
|
||||
Windows:
|
||||
"x86_64":
|
||||
Visual Studio:
|
||||
- url: "https://github.com/WasmEdge/WasmEdge/releases/download/0.10.0/WasmEdge-0.10.0-windows.zip"
|
||||
sha256: "63b8a02cced52a723aa283dba02bbe887656256ecca69bb0fff17872c0fb5ebc"
|
||||
- url: "https://raw.githubusercontent.com/WasmEdge/WasmEdge/0.10.0/LICENSE"
|
||||
sha256: "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4"
|
||||
Linux:
|
||||
"x86_64":
|
||||
"gcc":
|
||||
- url: "https://github.com/WasmEdge/WasmEdge/releases/download/0.10.0/WasmEdge-0.10.0-manylinux2014_x86_64.tar.gz"
|
||||
sha256: "4c1ffca9fd8cbdeb8f0951ddaffbbefe81ae123d5b80f61e80ea8d9b56853cde"
|
||||
- url: "https://raw.githubusercontent.com/WasmEdge/WasmEdge/0.10.0/LICENSE"
|
||||
sha256: "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4"
|
||||
"armv8":
|
||||
"gcc":
|
||||
- url: "https://github.com/WasmEdge/WasmEdge/releases/download/0.10.0/WasmEdge-0.10.0-manylinux2014_aarch64.tar.gz"
|
||||
sha256: "c000bf96d0a73a1d360659246c0806c2ce78620b6f78c1147fbf9e2be0280bd9"
|
||||
- url: "https://raw.githubusercontent.com/WasmEdge/WasmEdge/0.10.0/LICENSE"
|
||||
sha256: "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4"
|
||||
"0.9.1":
|
||||
Windows:
|
||||
"x86_64":
|
||||
Visual Studio:
|
||||
- url: "https://github.com/WasmEdge/WasmEdge/releases/download/0.9.1/WasmEdge-0.9.1-windows.zip"
|
||||
sha256: "68240d8aee23d44db5cc252d8c1cf5d0c77ab709a122af2747a4b836ba461671"
|
||||
- url: "https://raw.githubusercontent.com/WasmEdge/WasmEdge/0.9.1/LICENSE"
|
||||
sha256: "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4"
|
||||
Linux:
|
||||
"x86_64":
|
||||
"gcc":
|
||||
- url: "https://github.com/WasmEdge/WasmEdge/releases/download/0.9.1/WasmEdge-0.9.1-manylinux2014_x86_64.tar.gz"
|
||||
sha256: "bcb6fe3d6e30db0d0aa267ec3bd9b7248f8c8c387620cef4049d682d293c8371"
|
||||
- url: "https://raw.githubusercontent.com/WasmEdge/WasmEdge/0.9.1/LICENSE"
|
||||
sha256: "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4"
|
||||
"armv8":
|
||||
"gcc":
|
||||
- url: "https://github.com/WasmEdge/WasmEdge/releases/download/0.9.1/WasmEdge-0.9.1-manylinux2014_aarch64.tar.gz"
|
||||
sha256: "515bcac3520cd546d9d14372b7930ab48b43f1c5dc258a9f61a82b22c0107eef"
|
||||
- url: "https://raw.githubusercontent.com/WasmEdge/WasmEdge/0.9.1/LICENSE"
|
||||
sha256: "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4"
|
||||
"0.9.0":
|
||||
Windows:
|
||||
"x86_64":
|
||||
Visual Studio:
|
||||
- url: "https://github.com/WasmEdge/WasmEdge/releases/download/0.9.0/WasmEdge-0.9.0-windows.zip"
|
||||
sha256: "f81bfea4cf09053510e3e74c16c1ee010fc93def8a7e78744443b950f0011c3b"
|
||||
- url: "https://raw.githubusercontent.com/WasmEdge/WasmEdge/0.9.0/LICENSE"
|
||||
sha256: "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4"
|
||||
Linux:
|
||||
"x86_64":
|
||||
"gcc":
|
||||
- url: "https://github.com/WasmEdge/WasmEdge/releases/download/0.9.0/WasmEdge-0.9.0-manylinux2014_x86_64.tar.gz"
|
||||
sha256: "27847f15e4294e707486458e857d7cb11806481bb67a26f076a717a1446827ed"
|
||||
- url: "https://raw.githubusercontent.com/WasmEdge/WasmEdge/0.9.0/LICENSE"
|
||||
sha256: "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4"
|
||||
"armv8":
|
||||
"gcc":
|
||||
- url: "https://github.com/WasmEdge/WasmEdge/releases/download/0.9.0/WasmEdge-0.9.0-manylinux2014_aarch64.tar.gz"
|
||||
sha256: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
||||
- url: "https://raw.githubusercontent.com/WasmEdge/WasmEdge/0.9.0/LICENSE"
|
||||
sha256: "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4"
|
||||
Macos:
|
||||
"armv8":
|
||||
"gcc":
|
||||
- url: "https://github.com/WasmEdge/WasmEdge/releases/download/0.9.0/WasmEdge-0.9.0-darwin_arm64.tar.gz"
|
||||
sha256: "236a407a646f746ab78a1d0a39fa4e85fe28eae219b1635ba49f908d7944686d"
|
||||
- url: "https://raw.githubusercontent.com/WasmEdge/WasmEdge/0.9.0/LICENSE"
|
||||
sha256: "c71d239df91726fc519c6eb72d318ec65820627232b2f796219e87dcf35d0ab4"
|
||||
92
external/wasmedge/conanfile.py
vendored
Normal file
92
external/wasmedge/conanfile.py
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
from conan import ConanFile
|
||||
from conan.tools.files import get, copy, download
|
||||
from conan.tools.scm import Version
|
||||
from conan.errors import ConanInvalidConfiguration
|
||||
|
||||
import os
|
||||
|
||||
required_conan_version = ">=1.53.0"
|
||||
|
||||
class WasmedgeConan(ConanFile):
|
||||
name = "wasmedge"
|
||||
description = ("WasmEdge is a lightweight, high-performance, and extensible WebAssembly runtime"
|
||||
"for cloud native, edge, and decentralized applications."
|
||||
"It powers serverless apps, embedded functions, microservices, smart contracts, and IoT devices.")
|
||||
license = "Apache-2.0"
|
||||
url = "https://github.com/conan-io/conan-center-index"
|
||||
homepage = "https://github.com/WasmEdge/WasmEdge/"
|
||||
topics = ("webassembly", "wasm", "wasi", "emscripten")
|
||||
package_type = "shared-library"
|
||||
settings = "os", "arch", "compiler", "build_type"
|
||||
|
||||
@property
|
||||
def _compiler_alias(self):
|
||||
return {
|
||||
"Visual Studio": "Visual Studio",
|
||||
# "Visual Studio": "msvc",
|
||||
"msvc": "msvc",
|
||||
}.get(str(self.info.settings.compiler), "gcc")
|
||||
|
||||
def configure(self):
|
||||
self.settings.compiler.rm_safe("libcxx")
|
||||
self.settings.compiler.rm_safe("cppstd")
|
||||
|
||||
def validate(self):
|
||||
try:
|
||||
self.conan_data["sources"][self.version][str(self.settings.os)][str(self.settings.arch)][self._compiler_alias]
|
||||
except KeyError:
|
||||
raise ConanInvalidConfiguration("Binaries for this combination of version/os/arch/compiler are not available")
|
||||
|
||||
def package_id(self):
|
||||
del self.info.settings.compiler.version
|
||||
self.info.settings.compiler = self._compiler_alias
|
||||
|
||||
def build(self):
|
||||
# This is packaging binaries so the download needs to be in build
|
||||
get(self, **self.conan_data["sources"][self.version][str(self.settings.os)][str(self.settings.arch)][self._compiler_alias][0],
|
||||
destination=self.source_folder, strip_root=True)
|
||||
download(self, filename="LICENSE",
|
||||
**self.conan_data["sources"][self.version][str(self.settings.os)][str(self.settings.arch)][self._compiler_alias][1])
|
||||
|
||||
def package(self):
|
||||
copy(self, pattern="*.h", dst=os.path.join(self.package_folder, "include"), src=os.path.join(self.source_folder, "include"), keep_path=True)
|
||||
copy(self, pattern="*.inc", dst=os.path.join(self.package_folder, "include"), src=os.path.join(self.source_folder, "include"), keep_path=True)
|
||||
|
||||
srclibdir = os.path.join(self.source_folder, "lib64" if self.settings.os == "Linux" else "lib")
|
||||
srcbindir = os.path.join(self.source_folder, "bin")
|
||||
dstlibdir = os.path.join(self.package_folder, "lib")
|
||||
dstbindir = os.path.join(self.package_folder, "bin")
|
||||
if Version(self.version) >= "0.11.1":
|
||||
copy(self, pattern="wasmedge.lib", src=srclibdir, dst=dstlibdir, keep_path=False)
|
||||
copy(self, pattern="wasmedge.dll", src=srcbindir, dst=dstbindir, keep_path=False)
|
||||
copy(self, pattern="libwasmedge.so*", src=srclibdir, dst=dstlibdir, keep_path=False)
|
||||
copy(self, pattern="libwasmedge*.dylib", src=srclibdir, dst=dstlibdir, keep_path=False)
|
||||
else:
|
||||
copy(self, pattern="wasmedge_c.lib", src=srclibdir, dst=dstlibdir, keep_path=False)
|
||||
copy(self, pattern="wasmedge_c.dll", src=srcbindir, dst=dstbindir, keep_path=False)
|
||||
copy(self, pattern="libwasmedge_c.so*", src=srclibdir, dst=dstlibdir, keep_path=False)
|
||||
copy(self, pattern="libwasmedge_c*.dylib", src=srclibdir, dst=dstlibdir, keep_path=False)
|
||||
|
||||
copy(self, pattern="wasmedge*", src=srcbindir, dst=dstbindir, keep_path=False)
|
||||
copy(self, pattern="LICENSE", src=self.source_folder, dst=os.path.join(self.package_folder, "licenses"), keep_path=False)
|
||||
|
||||
def package_info(self):
|
||||
if Version(self.version) >= "0.11.1":
|
||||
self.cpp_info.libs = ["wasmedge"]
|
||||
else:
|
||||
self.cpp_info.libs = ["wasmedge_c"]
|
||||
|
||||
bindir = os.path.join(self.package_folder, "bin")
|
||||
self.output.info("Appending PATH environment variable: {}".format(bindir))
|
||||
self.env_info.PATH.append(bindir)
|
||||
|
||||
if self.settings.os == "Windows":
|
||||
self.cpp_info.system_libs.append("ws2_32")
|
||||
self.cpp_info.system_libs.append("wsock32")
|
||||
self.cpp_info.system_libs.append("shlwapi")
|
||||
|
||||
if self.settings.os in ["Linux", "FreeBSD"]:
|
||||
self.cpp_info.system_libs.append("m")
|
||||
self.cpp_info.system_libs.append("dl")
|
||||
self.cpp_info.system_libs.append("rt")
|
||||
self.cpp_info.system_libs.append("pthread")
|
||||
@@ -21,7 +21,7 @@
|
||||
#define RIPPLE_BASICS_BUFFER_H_INCLUDED
|
||||
|
||||
#include <xrpl/basics/Slice.h>
|
||||
#include <cassert>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
@@ -112,9 +112,10 @@ public:
|
||||
operator=(Slice s)
|
||||
{
|
||||
// Ensure the slice isn't a subset of the buffer.
|
||||
assert(
|
||||
XRPL_ASSERT(
|
||||
s.size() == 0 || size_ == 0 || s.data() < p_.get() ||
|
||||
s.data() >= p_.get() + size_);
|
||||
s.data() >= p_.get() + size_,
|
||||
"ripple::Buffer::operator=(Slice) : input not a subset");
|
||||
|
||||
if (auto p = alloc(s.size()))
|
||||
std::memcpy(p, s.data(), s.size());
|
||||
|
||||
@@ -137,13 +137,15 @@ class [[nodiscard]] Expected
|
||||
public:
|
||||
template <typename U>
|
||||
requires std::convertible_to<U, T>
|
||||
constexpr Expected(U&& r) : Base(T(std::forward<U>(r)))
|
||||
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(E(std::move(e.value())))
|
||||
constexpr Expected(Unexpected<U> e)
|
||||
: Base(boost::outcome_v2::in_place_type_t<E>{}, std::move(e.value()))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace ripple {
|
||||
constexpr std::size_t
|
||||
calculatePercent(std::size_t count, std::size_t total)
|
||||
{
|
||||
assert(total != 0);
|
||||
assert(total != 0); // NOTE No XRPL_ASSERT here, because constexpr
|
||||
return ((std::min(count, total) * 100) + total - 1) / total;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,8 +20,6 @@
|
||||
#ifndef RIPPLE_BASICS_NUMBER_H_INCLUDED
|
||||
#define RIPPLE_BASICS_NUMBER_H_INCLUDED
|
||||
|
||||
#include <xrpl/basics/MPTAmount.h>
|
||||
#include <xrpl/basics/XRPAmount.h>
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
#include <ostream>
|
||||
@@ -41,6 +39,14 @@ class Number
|
||||
int exponent_{std::numeric_limits<int>::lowest()};
|
||||
|
||||
public:
|
||||
// The range for the mantissa when normalized
|
||||
constexpr static std::int64_t minMantissa = 1'000'000'000'000'000LL;
|
||||
constexpr static std::int64_t maxMantissa = 9'999'999'999'999'999LL;
|
||||
|
||||
// The range for the exponent when normalized
|
||||
constexpr static int minExponent = -32768;
|
||||
constexpr static int maxExponent = 32768;
|
||||
|
||||
struct unchecked
|
||||
{
|
||||
explicit unchecked() = default;
|
||||
@@ -52,9 +58,6 @@ public:
|
||||
explicit Number(rep mantissa, int exponent);
|
||||
explicit constexpr Number(rep mantissa, int exponent, unchecked) noexcept;
|
||||
|
||||
Number(XRPAmount const& x);
|
||||
Number(MPTAmount const& x);
|
||||
|
||||
constexpr rep
|
||||
mantissa() const noexcept;
|
||||
constexpr int
|
||||
@@ -96,10 +99,6 @@ public:
|
||||
* "mixed mode" more convenient, e.g. MPTAmount + Number.
|
||||
*/
|
||||
explicit
|
||||
operator XRPAmount() const; // round to nearest, even on tie
|
||||
explicit
|
||||
operator MPTAmount() const; // round to nearest, even on tie
|
||||
explicit
|
||||
operator rep() const; // round to nearest, even on tie
|
||||
|
||||
friend constexpr bool
|
||||
@@ -191,14 +190,6 @@ private:
|
||||
constexpr bool
|
||||
isnormal() const noexcept;
|
||||
|
||||
// The range for the mantissa when normalized
|
||||
constexpr static std::int64_t minMantissa = 1'000'000'000'000'000LL;
|
||||
constexpr static std::int64_t maxMantissa = 9'999'999'999'999'999LL;
|
||||
|
||||
// The range for the exponent when normalized
|
||||
constexpr static int minExponent = -32768;
|
||||
constexpr static int maxExponent = 32768;
|
||||
|
||||
class Guard;
|
||||
};
|
||||
|
||||
@@ -217,14 +208,6 @@ inline Number::Number(rep mantissa) : Number{mantissa, 0}
|
||||
{
|
||||
}
|
||||
|
||||
inline Number::Number(XRPAmount const& x) : Number{x.drops()}
|
||||
{
|
||||
}
|
||||
|
||||
inline Number::Number(MPTAmount const& x) : Number{x.value()}
|
||||
{
|
||||
}
|
||||
|
||||
inline constexpr Number::rep
|
||||
Number::mantissa() const noexcept
|
||||
{
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#define RIPPLE_BASICS_SHAMAP_HASH_H_INCLUDED
|
||||
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/basics/partitioned_unordered_map.h>
|
||||
|
||||
#include <ostream>
|
||||
|
||||
@@ -108,6 +109,13 @@ operator!=(SHAMapHash const& x, SHAMapHash const& y)
|
||||
return !(x == y);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline std::size_t
|
||||
extract(SHAMapHash const& key)
|
||||
{
|
||||
return *reinterpret_cast<std::size_t const*>(key.as_uint256().data());
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif // RIPPLE_BASICS_SHAMAP_HASH_H_INCLUDED
|
||||
|
||||
@@ -20,7 +20,9 @@
|
||||
#ifndef RIPPLE_BASICS_SLABALLOCATOR_H_INCLUDED
|
||||
#define RIPPLE_BASICS_SLABALLOCATOR_H_INCLUDED
|
||||
|
||||
#include <xrpl/basics/ByteUtilities.h>
|
||||
#include <xrpl/beast/type_name.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
|
||||
#include <boost/align.hpp>
|
||||
#include <boost/container/static_vector.hpp>
|
||||
@@ -28,10 +30,10 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
#if BOOST_OS_LINUX
|
||||
#include <sys/mman.h>
|
||||
@@ -141,7 +143,9 @@ class SlabAllocator
|
||||
void
|
||||
deallocate(std::uint8_t* ptr) noexcept
|
||||
{
|
||||
assert(own(ptr));
|
||||
XRPL_ASSERT(
|
||||
own(ptr),
|
||||
"ripple::SlabAllocator::SlabBlock::deallocate : own input");
|
||||
|
||||
std::lock_guard l(m_);
|
||||
|
||||
@@ -184,7 +188,9 @@ public:
|
||||
boost::alignment::align_up(sizeof(Type) + extra, itemAlignment_))
|
||||
, slabSize_(alloc)
|
||||
{
|
||||
assert((itemAlignment_ & (itemAlignment_ - 1)) == 0);
|
||||
XRPL_ASSERT(
|
||||
(itemAlignment_ & (itemAlignment_ - 1)) == 0,
|
||||
"ripple::SlabAllocator::SlabAllocator : valid alignment");
|
||||
}
|
||||
|
||||
SlabAllocator(SlabAllocator const& other) = delete;
|
||||
@@ -294,7 +300,10 @@ public:
|
||||
bool
|
||||
deallocate(std::uint8_t* ptr) noexcept
|
||||
{
|
||||
assert(ptr);
|
||||
XRPL_ASSERT(
|
||||
ptr,
|
||||
"ripple::SlabAllocator::SlabAllocator::deallocate : non-null "
|
||||
"input");
|
||||
|
||||
for (auto slab = slabs_.load(); slab != nullptr; slab = slab->next_)
|
||||
{
|
||||
|
||||
@@ -22,9 +22,9 @@
|
||||
|
||||
#include <xrpl/basics/contract.h>
|
||||
#include <xrpl/basics/strHex.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
@@ -103,7 +103,9 @@ public:
|
||||
std::uint8_t
|
||||
operator[](std::size_t i) const noexcept
|
||||
{
|
||||
assert(i < size_);
|
||||
XRPL_ASSERT(
|
||||
i < size_,
|
||||
"ripple::Slice::operator[](std::size_t) const : valid input");
|
||||
return data_[i];
|
||||
}
|
||||
|
||||
|
||||
@@ -29,8 +29,10 @@
|
||||
#include <xrpl/basics/Slice.h>
|
||||
#include <xrpl/basics/contract.h>
|
||||
#include <xrpl/basics/hardened_hash.h>
|
||||
#include <xrpl/basics/partitioned_unordered_map.h>
|
||||
#include <xrpl/basics/strHex.h>
|
||||
#include <xrpl/beast/utility/Zero.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <boost/endian/conversion.hpp>
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <algorithm>
|
||||
@@ -289,7 +291,9 @@ public:
|
||||
std::is_trivially_copyable<typename Container::value_type>::value>>
|
||||
explicit base_uint(Container const& c)
|
||||
{
|
||||
assert(c.size() * sizeof(typename Container::value_type) == size());
|
||||
XRPL_ASSERT(
|
||||
c.size() * sizeof(typename Container::value_type) == size(),
|
||||
"ripple::base_uint::base_uint(Container auto) : input size match");
|
||||
std::memcpy(data_.data(), c.data(), size());
|
||||
}
|
||||
|
||||
@@ -300,7 +304,9 @@ public:
|
||||
base_uint&>
|
||||
operator=(Container const& c)
|
||||
{
|
||||
assert(c.size() * sizeof(typename Container::value_type) == size());
|
||||
XRPL_ASSERT(
|
||||
c.size() * sizeof(typename Container::value_type) == size(),
|
||||
"ripple::base_uint::operator=(Container auto) : input size match");
|
||||
std::memcpy(data_.data(), c.data(), size());
|
||||
return *this;
|
||||
}
|
||||
@@ -632,6 +638,17 @@ operator<<(std::ostream& out, base_uint<Bits, Tag> const& u)
|
||||
return out << to_string(u);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline std::size_t
|
||||
extract(uint256 const& key)
|
||||
{
|
||||
std::size_t result;
|
||||
// Use memcpy to avoid unaligned UB
|
||||
// (will optimize to equivalent code)
|
||||
std::memcpy(&result, key.data(), sizeof(std::size_t));
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifndef __INTELLISENSE__
|
||||
static_assert(sizeof(uint128) == 128 / 8, "There should be no padding bytes");
|
||||
static_assert(sizeof(uint160) == 160 / 8, "There should be no padding bytes");
|
||||
|
||||
@@ -20,9 +20,11 @@
|
||||
#ifndef RIPPLE_BASICS_PARTITIONED_UNORDERED_MAP_H
|
||||
#define RIPPLE_BASICS_PARTITIONED_UNORDERED_MAP_H
|
||||
|
||||
#include <cassert>
|
||||
#include <xrpl/beast/hash/uhash.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
@@ -31,8 +33,18 @@
|
||||
namespace ripple {
|
||||
|
||||
template <typename Key>
|
||||
std::size_t
|
||||
partitioner(Key const& key, std::size_t const numPartitions);
|
||||
static std::size_t
|
||||
extract(Key const& key)
|
||||
{
|
||||
return key;
|
||||
}
|
||||
|
||||
template <>
|
||||
inline std::size_t
|
||||
extract(std::string const& key)
|
||||
{
|
||||
return ::beast::uhash<>{}(key);
|
||||
}
|
||||
|
||||
template <
|
||||
typename Key,
|
||||
@@ -211,7 +223,7 @@ private:
|
||||
std::size_t
|
||||
partitioner(Key const& key) const
|
||||
{
|
||||
return ripple::partitioner(key, partitions_);
|
||||
return extract(key) % partitions_;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
@@ -246,7 +258,10 @@ public:
|
||||
? *partitions
|
||||
: std::thread::hardware_concurrency();
|
||||
map_.resize(partitions_);
|
||||
assert(partitions_);
|
||||
XRPL_ASSERT(
|
||||
partitions_,
|
||||
"ripple::partitioned_unordered_map::partitioned_unordered_map : "
|
||||
"nonzero partitions");
|
||||
}
|
||||
|
||||
std::size_t
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
#ifndef RIPPLE_BASICS_RANDOM_H_INCLUDED
|
||||
#define RIPPLE_BASICS_RANDOM_H_INCLUDED
|
||||
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/beast/xor_shift_engine.h>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
@@ -114,7 +114,7 @@ std::enable_if_t<
|
||||
Integral>
|
||||
rand_int(Engine& engine, Integral min, Integral max)
|
||||
{
|
||||
assert(max > min);
|
||||
XRPL_ASSERT(max > min, "ripple::rand_int : max over min inputs");
|
||||
|
||||
// This should have no state and constructing it should
|
||||
// be very cheap. If that turns out not to be the case
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#ifndef RIPPLE_BASICS_SCOPE_H_INCLUDED
|
||||
#define RIPPLE_BASICS_SCOPE_H_INCLUDED
|
||||
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
|
||||
#include <exception>
|
||||
#include <mutex>
|
||||
#include <type_traits>
|
||||
@@ -233,7 +235,9 @@ public:
|
||||
explicit scope_unlock(std::unique_lock<Mutex>& lock) noexcept(true)
|
||||
: plock(&lock)
|
||||
{
|
||||
assert(plock->owns_lock());
|
||||
XRPL_ASSERT(
|
||||
plock->owns_lock(),
|
||||
"ripple::scope_unlock::scope_unlock : mutex must be locked");
|
||||
plock->unlock();
|
||||
}
|
||||
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
#ifndef RIPPLE_BASICS_SPINLOCK_H_INCLUDED
|
||||
#define RIPPLE_BASICS_SPINLOCK_H_INCLUDED
|
||||
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <atomic>
|
||||
#include <cassert>
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
|
||||
@@ -117,7 +117,9 @@ public:
|
||||
packed_spinlock(std::atomic<T>& lock, int index)
|
||||
: bits_(lock), mask_(static_cast<T>(1) << index)
|
||||
{
|
||||
assert(index >= 0 && (mask_ != 0));
|
||||
XRPL_ASSERT(
|
||||
index >= 0 && (mask_ != 0),
|
||||
"ripple::packed_spinlock::packed_spinlock : valid index and mask");
|
||||
}
|
||||
|
||||
[[nodiscard]] bool
|
||||
|
||||
@@ -20,8 +20,10 @@
|
||||
#ifndef BEAST_ASIO_IO_LATENCY_PROBE_H_INCLUDED
|
||||
#define BEAST_ASIO_IO_LATENCY_PROBE_H_INCLUDED
|
||||
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <boost/asio/basic_waitable_timer.hpp>
|
||||
#include <boost/asio/io_service.hpp>
|
||||
|
||||
#include <chrono>
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
@@ -172,7 +174,10 @@ private:
|
||||
, m_repeat(repeat)
|
||||
, m_probe(probe)
|
||||
{
|
||||
assert(m_probe);
|
||||
XRPL_ASSERT(
|
||||
m_probe,
|
||||
"beast::io_latency_probe::sample_op::sample_op : non-null "
|
||||
"probe input");
|
||||
m_probe->addref();
|
||||
}
|
||||
|
||||
@@ -182,7 +187,10 @@ private:
|
||||
, m_repeat(from.m_repeat)
|
||||
, m_probe(from.m_probe)
|
||||
{
|
||||
assert(m_probe);
|
||||
XRPL_ASSERT(
|
||||
m_probe,
|
||||
"beast::io_latency_probe::sample_op::sample_op(sample_op&&) : "
|
||||
"non-null probe input");
|
||||
from.m_probe = nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#define BEAST_CHRONO_MANUAL_CLOCK_H_INCLUDED
|
||||
|
||||
#include <xrpl/beast/clock/abstract_clock.h>
|
||||
#include <cassert>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
|
||||
namespace beast {
|
||||
|
||||
@@ -61,7 +61,9 @@ public:
|
||||
void
|
||||
set(time_point const& when)
|
||||
{
|
||||
assert(!Clock::is_steady || when >= now_);
|
||||
XRPL_ASSERT(
|
||||
!Clock::is_steady || when >= now_,
|
||||
"beast::manual_clock::set(time_point) : forward input");
|
||||
now_ = when;
|
||||
}
|
||||
|
||||
@@ -78,7 +80,9 @@ public:
|
||||
void
|
||||
advance(std::chrono::duration<Rep, Period> const& elapsed)
|
||||
{
|
||||
assert(!Clock::is_steady || (now_ + elapsed) >= now_);
|
||||
XRPL_ASSERT(
|
||||
!Clock::is_steady || (now_ + elapsed) >= now_,
|
||||
"beast::manual_clock::advance(duration) : forward input");
|
||||
now_ += elapsed;
|
||||
}
|
||||
|
||||
|
||||
@@ -1330,7 +1330,10 @@ public:
|
||||
size_type
|
||||
bucket(Key const& k) const
|
||||
{
|
||||
assert(bucket_count() != 0);
|
||||
XRPL_ASSERT(
|
||||
bucket_count() != 0,
|
||||
"beast::detail::aged_unordered_container::bucket : nonzero bucket "
|
||||
"count");
|
||||
return m_cont.bucket(k, std::cref(m_config.hash_function()));
|
||||
}
|
||||
|
||||
@@ -1471,7 +1474,10 @@ private:
|
||||
{
|
||||
if (would_exceed(additional))
|
||||
m_buck.resize(size() + additional, m_cont);
|
||||
assert(load_factor() <= max_load_factor());
|
||||
XRPL_ASSERT(
|
||||
load_factor() <= max_load_factor(),
|
||||
"beast::detail::aged_unordered_container::maybe_rehash : maximum "
|
||||
"load factor");
|
||||
}
|
||||
|
||||
// map, set
|
||||
|
||||
@@ -20,9 +20,10 @@
|
||||
#ifndef BEAST_MODULE_CORE_TEXT_LEXICALCAST_H_INCLUDED
|
||||
#define BEAST_MODULE_CORE_TEXT_LEXICALCAST_H_INCLUDED
|
||||
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
|
||||
#include <boost/core/detail/string_view.hpp>
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cerrno>
|
||||
#include <charconv>
|
||||
#include <cstdlib>
|
||||
@@ -159,7 +160,8 @@ struct LexicalCast<Out, char const*>
|
||||
bool
|
||||
operator()(Out& out, char const* in) const
|
||||
{
|
||||
assert(in);
|
||||
XRPL_ASSERT(
|
||||
in, "beast::detail::LexicalCast(char const*) : non-null input");
|
||||
return LexicalCast<Out, std::string_view>()(out, in);
|
||||
}
|
||||
};
|
||||
@@ -174,7 +176,7 @@ struct LexicalCast<Out, char*>
|
||||
bool
|
||||
operator()(Out& out, char* in) const
|
||||
{
|
||||
assert(in);
|
||||
XRPL_ASSERT(in, "beast::detail::LexicalCast(char*) : non-null input");
|
||||
return LexicalCast<Out, std::string_view>()(out, in);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <utility>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
namespace beast {
|
||||
@@ -454,6 +455,16 @@ hash_append(Hasher& h, std::tuple<T...> const& t) noexcept
|
||||
detail::tuple_hash(h, t, std::index_sequence_for<T...>{});
|
||||
}
|
||||
|
||||
// variant
|
||||
|
||||
template <class Hasher, class... T>
|
||||
inline std::enable_if_t<
|
||||
!is_contiguously_hashable<std::variant<T...>, Hasher>::value>
|
||||
hash_append(Hasher& h, std::variant<T...> const& v) noexcept
|
||||
{
|
||||
std::visit([&](auto const& arg) { hash_append(h, arg); }, v);
|
||||
}
|
||||
|
||||
// shared_ptr
|
||||
|
||||
template <class Hasher, class T>
|
||||
|
||||
@@ -24,9 +24,9 @@
|
||||
#include <xrpl/beast/hash/uhash.h>
|
||||
#include <xrpl/beast/net/IPAddressV4.h>
|
||||
#include <xrpl/beast/net/IPAddressV6.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <boost/asio/ip/address.hpp>
|
||||
#include <boost/functional/hash.hpp>
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <ios>
|
||||
#include <sstream>
|
||||
@@ -96,7 +96,7 @@ hash_append(Hasher& h, beast::IP::Address const& addr) noexcept
|
||||
else if (addr.is_v6())
|
||||
hash_append(h, addr.to_v6().to_bytes());
|
||||
else
|
||||
assert(false);
|
||||
UNREACHABLE("beast::hash_append : invalid address type");
|
||||
}
|
||||
} // namespace beast
|
||||
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
#ifndef BEAST_NET_IPADDRESSV6_H_INCLUDED
|
||||
#define BEAST_NET_IPADDRESSV6_H_INCLUDED
|
||||
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <boost/asio/ip/address_v6.hpp>
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <ios>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#ifndef BEAST_UTILITY_JOURNAL_H_INCLUDED
|
||||
#define BEAST_UTILITY_JOURNAL_H_INCLUDED
|
||||
|
||||
#include <cassert>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <sstream>
|
||||
|
||||
namespace beast {
|
||||
@@ -205,7 +205,9 @@ public:
|
||||
*/
|
||||
Stream(Sink& sink, Severity level) : m_sink(sink), m_level(level)
|
||||
{
|
||||
assert(m_level < severities::kDisabled);
|
||||
XRPL_ASSERT(
|
||||
m_level < severities::kDisabled,
|
||||
"beast::Journal::Stream::Stream : maximum level");
|
||||
}
|
||||
|
||||
/** Construct or copy another Stream. */
|
||||
|
||||
70
include/xrpl/beast/utility/instrumentation.h
Normal file
70
include/xrpl/beast/utility/instrumentation.h
Normal file
@@ -0,0 +1,70 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2024 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef BEAST_UTILITY_INSTRUMENTATION_H_INCLUDED
|
||||
#define BEAST_UTILITY_INSTRUMENTATION_H_INCLUDED
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#ifdef ENABLE_VOIDSTAR
|
||||
#ifdef NDEBUG
|
||||
#error "Antithesis instrumentation requires Debug build"
|
||||
#endif
|
||||
#include <antithesis_sdk.h>
|
||||
#else
|
||||
// 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.
|
||||
#define ALWAYS(cond, message, ...) assert((message) && (cond))
|
||||
#define ALWAYS_OR_UNREACHABLE(cond, message, ...) assert((message) && (cond))
|
||||
#define SOMETIMES(cond, message, ...)
|
||||
#define REACHABLE(message, ...)
|
||||
#define UNREACHABLE(message, ...) assert((message) && false)
|
||||
#endif
|
||||
|
||||
#define XRPL_ASSERT ALWAYS_OR_UNREACHABLE
|
||||
|
||||
// How to use the instrumentation macros:
|
||||
//
|
||||
// * XRPL_ASSERT if cond must be true but the line might not be reached during
|
||||
// fuzzing. Same like `assert` in normal use.
|
||||
// * 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
|
||||
// * SOMETIMES a hint for the fuzzer to try to make the cond true
|
||||
// * UNREACHABLE if the line must not be reached (in fuzzing or in normal use).
|
||||
// Same like `assert(false)` in normal use.
|
||||
//
|
||||
// NOTE: XRPL_ASSERT has similar semantics as C `assert` macro, with only minor
|
||||
// differences:
|
||||
// * XRPL_ASSERT must have an unique name (naming convention in CONTRIBUTING.md)
|
||||
// * during fuzzing, the program will continue execution past failed XRPL_ASSERT
|
||||
//
|
||||
// We continue to use regular C `assert` inside unit tests and inside constexpr
|
||||
// functions.
|
||||
//
|
||||
// NOTE: UNREACHABLE does *not* have the same semantics as std::unreachable.
|
||||
// The program will continue execution past an UNREACHABLE in a Release build
|
||||
// and during fuzzing (similar to failed XRPL_ASSERT).
|
||||
// Also, the naming convention in UNREACHABLE is subtly different from other
|
||||
// instrumentation macros - its name describes the condition which was _not_
|
||||
// meant to happen, while name in other macros describes the condition that is
|
||||
// meant to happen (e.g. as in "assert that this happens").
|
||||
|
||||
#endif
|
||||
@@ -20,8 +20,8 @@
|
||||
#ifndef BEAST_RANDOM_RNGFILL_H_INCLUDED
|
||||
#define BEAST_RANDOM_RNGFILL_H_INCLUDED
|
||||
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <array>
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <type_traits>
|
||||
@@ -42,7 +42,8 @@ rngfill(void* buffer, std::size_t bytes, Generator& g)
|
||||
bytes -= sizeof(v);
|
||||
}
|
||||
|
||||
assert(bytes < sizeof(result_type));
|
||||
XRPL_ASSERT(
|
||||
bytes < sizeof(result_type), "beast::rngfill(void*) : maximum bytes");
|
||||
|
||||
#ifdef __GNUC__
|
||||
// gcc 11.1 (falsely) warns about an array-bounds overflow in release mode.
|
||||
|
||||
@@ -22,9 +22,6 @@
|
||||
|
||||
#include <xrpl/json/json_errors.h>
|
||||
|
||||
#define JSON_ASSERT_UNREACHABLE assert(false)
|
||||
#define JSON_ASSERT(condition) \
|
||||
assert(condition); // @todo <= change this into an exception throw
|
||||
#define JSON_ASSERT_MESSAGE(condition, message) \
|
||||
if (!(condition)) \
|
||||
ripple::Throw<Json::error>(message);
|
||||
|
||||
@@ -20,9 +20,9 @@
|
||||
#ifndef RIPPLE_PROTOCOL_AMOUNTCONVERSION_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_AMOUNTCONVERSION_H_INCLUDED
|
||||
|
||||
#include <xrpl/basics/IOUAmount.h>
|
||||
#include <xrpl/basics/XRPAmount.h>
|
||||
#include <xrpl/protocol/IOUAmount.h>
|
||||
#include <xrpl/protocol/STAmount.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
@@ -53,7 +53,9 @@ toSTAmount(XRPAmount const& xrp)
|
||||
inline STAmount
|
||||
toSTAmount(XRPAmount const& xrp, Issue const& iss)
|
||||
{
|
||||
assert(isXRP(iss.account) && isXRP(iss.currency));
|
||||
XRPL_ASSERT(
|
||||
isXRP(iss.account) && isXRP(iss.currency),
|
||||
"ripple::toSTAmount : is XRP");
|
||||
return toSTAmount(xrp);
|
||||
}
|
||||
|
||||
@@ -72,12 +74,14 @@ template <>
|
||||
inline IOUAmount
|
||||
toAmount<IOUAmount>(STAmount const& amt)
|
||||
{
|
||||
assert(amt.mantissa() < std::numeric_limits<std::int64_t>::max());
|
||||
XRPL_ASSERT(
|
||||
amt.mantissa() < std::numeric_limits<std::int64_t>::max(),
|
||||
"ripple::toAmount<IOUAmount> : maximum mantissa");
|
||||
bool const isNeg = amt.negative();
|
||||
std::int64_t const sMant =
|
||||
isNeg ? -std::int64_t(amt.mantissa()) : amt.mantissa();
|
||||
|
||||
assert(!isXRP(amt));
|
||||
XRPL_ASSERT(!isXRP(amt), "ripple::toAmount<IOUAmount> : is not XRP");
|
||||
return IOUAmount(sMant, amt.exponent());
|
||||
}
|
||||
|
||||
@@ -85,12 +89,14 @@ template <>
|
||||
inline XRPAmount
|
||||
toAmount<XRPAmount>(STAmount const& amt)
|
||||
{
|
||||
assert(amt.mantissa() < std::numeric_limits<std::int64_t>::max());
|
||||
XRPL_ASSERT(
|
||||
amt.mantissa() < std::numeric_limits<std::int64_t>::max(),
|
||||
"ripple::toAmount<XRPAmount> : maximum mantissa");
|
||||
bool const isNeg = amt.negative();
|
||||
std::int64_t const sMant =
|
||||
isNeg ? -std::int64_t(amt.mantissa()) : amt.mantissa();
|
||||
|
||||
assert(isXRP(amt));
|
||||
XRPL_ASSERT(isXRP(amt), "ripple::toAmount<XRPAmount> : is XRP");
|
||||
return XRPAmount(sMant);
|
||||
}
|
||||
|
||||
|
||||
@@ -26,10 +26,17 @@
|
||||
|
||||
namespace ripple {
|
||||
|
||||
class Asset;
|
||||
|
||||
template <typename TIss>
|
||||
concept ValidIssueType =
|
||||
std::is_same_v<TIss, Issue> || std::is_same_v<TIss, MPTIssue>;
|
||||
|
||||
template <typename A>
|
||||
concept AssetType =
|
||||
std::is_convertible_v<A, Asset> || std::is_convertible_v<A, Issue> ||
|
||||
std::is_convertible_v<A, MPTIssue> || std::is_convertible_v<A, MPTID>;
|
||||
|
||||
/* Asset is an abstraction of three different issue types: XRP, IOU, MPT.
|
||||
* For historical reasons, two issue types XRP and IOU are wrapped in Issue
|
||||
* type. Many functions and classes there were first written for Issue
|
||||
@@ -37,8 +44,10 @@ concept ValidIssueType =
|
||||
*/
|
||||
class Asset
|
||||
{
|
||||
private:
|
||||
public:
|
||||
using value_type = std::variant<Issue, MPTIssue>;
|
||||
|
||||
private:
|
||||
value_type issue_;
|
||||
|
||||
public:
|
||||
@@ -92,8 +101,8 @@ public:
|
||||
friend constexpr bool
|
||||
operator==(Asset const& lhs, Asset const& rhs);
|
||||
|
||||
friend constexpr bool
|
||||
operator!=(Asset const& lhs, Asset const& rhs);
|
||||
friend constexpr std::weak_ordering
|
||||
operator<=>(Asset const& lhs, Asset const& rhs);
|
||||
|
||||
friend constexpr bool
|
||||
operator==(Currency const& lhs, Asset const& rhs);
|
||||
@@ -151,10 +160,22 @@ operator==(Asset const& lhs, Asset const& rhs)
|
||||
rhs.issue_);
|
||||
}
|
||||
|
||||
constexpr bool
|
||||
operator!=(Asset const& lhs, Asset const& rhs)
|
||||
constexpr std::weak_ordering
|
||||
operator<=>(Asset const& lhs, Asset const& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
return std::visit(
|
||||
[]<ValidIssueType TLhs, ValidIssueType TRhs>(
|
||||
TLhs const& lhs_, TRhs const& rhs_) {
|
||||
if constexpr (std::is_same_v<TLhs, TRhs>)
|
||||
return std::weak_ordering(lhs_ <=> rhs_);
|
||||
else if constexpr (
|
||||
std::is_same_v<TLhs, Issue> && std::is_same_v<TRhs, MPTIssue>)
|
||||
return std::weak_ordering::greater;
|
||||
else
|
||||
return std::weak_ordering::less;
|
||||
},
|
||||
lhs.issue_,
|
||||
rhs.issue_);
|
||||
}
|
||||
|
||||
constexpr bool
|
||||
|
||||
@@ -68,7 +68,8 @@ enum error_code_i {
|
||||
|
||||
// Ledger state
|
||||
rpcACT_NOT_FOUND = 19,
|
||||
// unused 20,
|
||||
rpcNAMESPACE_NOT_FOUND = 20,
|
||||
|
||||
rpcLGR_NOT_FOUND = 21,
|
||||
rpcLGR_NOT_VALIDATED = 22,
|
||||
rpcMASTER_DISABLED = 23,
|
||||
@@ -90,7 +91,7 @@ enum error_code_i {
|
||||
rpcACT_MALFORMED = 35,
|
||||
rpcALREADY_MULTISIG = 36,
|
||||
rpcALREADY_SINGLE_SIG = 37,
|
||||
// unused 38,
|
||||
rpcNAMESPACE_MALFORMED = 38,
|
||||
// unused 39,
|
||||
rpcBAD_FEATURE = 40,
|
||||
rpcBAD_ISSUER = 41,
|
||||
|
||||
@@ -80,7 +80,7 @@ namespace detail {
|
||||
// Feature.cpp. Because it's only used to reserve storage, and determine how
|
||||
// large to make the FeatureBitset, it MAY be larger. It MUST NOT be less than
|
||||
// the actual number of amendments. A LogicError on startup will verify this.
|
||||
static constexpr std::size_t numFeatures = 83;
|
||||
static constexpr std::size_t numFeatures = 85;
|
||||
|
||||
/** Amendments that this server supports and the default voting behavior.
|
||||
Whether they are enabled depends on the Rules defined in the validated
|
||||
@@ -151,14 +151,19 @@ public:
|
||||
|
||||
explicit FeatureBitset(base const& b) : base(b)
|
||||
{
|
||||
assert(b.count() == count());
|
||||
XRPL_ASSERT(
|
||||
b.count() == count(),
|
||||
"ripple::FeatureBitset::FeatureBitset(base) : count match");
|
||||
}
|
||||
|
||||
template <class... Fs>
|
||||
explicit FeatureBitset(uint256 const& f, Fs&&... fs)
|
||||
{
|
||||
initFromFeatures(f, std::forward<Fs>(fs)...);
|
||||
assert(count() == (sizeof...(fs) + 1));
|
||||
XRPL_ASSERT(
|
||||
count() == (sizeof...(fs) + 1),
|
||||
"ripple::FeatureBitset::FeatureBitset(uint256) : count and "
|
||||
"sizeof... do match");
|
||||
}
|
||||
|
||||
template <class Col>
|
||||
@@ -166,7 +171,10 @@ public:
|
||||
{
|
||||
for (auto const& f : fs)
|
||||
set(featureToBitsetIndex(f));
|
||||
assert(fs.size() == count());
|
||||
XRPL_ASSERT(
|
||||
fs.size() == count(),
|
||||
"ripple::FeatureBitset::FeatureBitset(Container auto) : count and "
|
||||
"size do match");
|
||||
}
|
||||
|
||||
auto
|
||||
|
||||
@@ -19,22 +19,29 @@
|
||||
#ifndef BASICS_FEES_H_INCLUDED
|
||||
#define BASICS_FEES_H_INCLUDED
|
||||
|
||||
#include <xrpl/basics/XRPAmount.h>
|
||||
#include <xrpl/basics/safe_cast.h>
|
||||
#include <xrpl/beast/utility/Zero.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
#include <boost/multiprecision/cpp_int.hpp>
|
||||
#include <limits>
|
||||
#include <utility>
|
||||
#include <boost/operators.hpp>
|
||||
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <ios>
|
||||
#include <iosfwd>
|
||||
#include <limits>
|
||||
#include <optional>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
namespace feeunit {
|
||||
|
||||
/** "drops" are the smallest divisible amount of XRP. This is what most
|
||||
of the code uses. */
|
||||
struct dropTag;
|
||||
/** "fee units" calculations are a not-really-unitless value that is used
|
||||
to express the cost of a given transaction vs. a reference transaction.
|
||||
They are primarily used by the Transactor classes. */
|
||||
@@ -419,9 +426,13 @@ mulDivU(Source1 value, Dest mul, Source2 div)
|
||||
{
|
||||
// split the asserts so if one hits, the user can tell which
|
||||
// without a debugger.
|
||||
assert(value.value() >= 0);
|
||||
assert(mul.value() >= 0);
|
||||
assert(div.value() >= 0);
|
||||
XRPL_ASSERT(
|
||||
value.value() >= 0,
|
||||
"ripple::feeunit::mulDivU : minimum value input");
|
||||
XRPL_ASSERT(
|
||||
mul.value() >= 0, "ripple::feeunit::mulDivU : minimum mul input");
|
||||
XRPL_ASSERT(
|
||||
div.value() >= 0, "ripple::feeunit::mulDivU : minimum div input");
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#ifndef RIPPLE_PROTOCOL_FEES_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_FEES_H_INCLUDED
|
||||
|
||||
#include <xrpl/basics/XRPAmount.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
|
||||
@@ -85,6 +85,15 @@ enum class HashPrefix : std::uint32_t {
|
||||
/** Payment Channel Claim */
|
||||
paymentChannelClaim = detail::make_hash_prefix('C', 'L', 'M'),
|
||||
|
||||
/** Emit Transaction Nonce */
|
||||
emitTxnNonce = detail::make_hash_prefix('E', 'T', 'X'),
|
||||
|
||||
/** Random entropy for hook developers to use */
|
||||
hookNonce = detail::make_hash_prefix('N', 'C', 'E'),
|
||||
|
||||
/* Hash of a Hook's actual code */
|
||||
hookDefinition = detail::make_hash_prefix('W', 'S', 'M'),
|
||||
|
||||
/** Credentials signature */
|
||||
credential = detail::make_hash_prefix('C', 'R', 'D'),
|
||||
};
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
|
||||
namespace ripple {
|
||||
|
||||
using UInt32or256 = std::variant<uint32_t, uint256>;
|
||||
|
||||
class SeqProxy;
|
||||
/** Keylet computation funclets.
|
||||
|
||||
@@ -52,6 +54,26 @@ class SeqProxy;
|
||||
*/
|
||||
namespace keylet {
|
||||
|
||||
/** The (fixed) index of the object containing the emitted txns for the ledger.
|
||||
*/
|
||||
Keylet const&
|
||||
emittedDir() noexcept;
|
||||
|
||||
Keylet
|
||||
emitted(uint256 const& id) noexcept;
|
||||
|
||||
Keylet
|
||||
hookDefinition(uint256 const& hash) noexcept;
|
||||
|
||||
Keylet
|
||||
hook(AccountID const& id) noexcept;
|
||||
|
||||
Keylet
|
||||
hookState(AccountID const& id, uint256 const& key, uint256 const& ns) noexcept;
|
||||
|
||||
Keylet
|
||||
hookStateDir(AccountID const& id, uint256 const& ns) noexcept;
|
||||
|
||||
/** AccountID root */
|
||||
Keylet
|
||||
account(AccountID const& id) noexcept;
|
||||
@@ -127,7 +149,7 @@ line(AccountID const& id, Issue const& issue) noexcept
|
||||
/** An offer from an account */
|
||||
/** @{ */
|
||||
Keylet
|
||||
offer(AccountID const& id, std::uint32_t seq) noexcept;
|
||||
offer(AccountID const& id, UInt32or256 const& seq) noexcept;
|
||||
|
||||
inline Keylet
|
||||
offer(uint256 const& key) noexcept
|
||||
@@ -176,7 +198,7 @@ signers(AccountID const& account) noexcept;
|
||||
/** A Check */
|
||||
/** @{ */
|
||||
Keylet
|
||||
check(AccountID const& id, std::uint32_t seq) noexcept;
|
||||
check(AccountID const& id, UInt32or256 const& seq) noexcept;
|
||||
|
||||
inline Keylet
|
||||
check(uint256 const& key) noexcept
|
||||
@@ -220,18 +242,22 @@ page(uint256 const& root, std::uint64_t index = 0) noexcept;
|
||||
inline Keylet
|
||||
page(Keylet const& root, std::uint64_t index = 0) noexcept
|
||||
{
|
||||
assert(root.type == ltDIR_NODE);
|
||||
XRPL_ASSERT(
|
||||
root.type == ltDIR_NODE, "ripple::keylet::page : valid root type");
|
||||
return page(root.key, index);
|
||||
}
|
||||
/** @} */
|
||||
|
||||
/** An escrow entry */
|
||||
Keylet
|
||||
escrow(AccountID const& src, std::uint32_t seq) noexcept;
|
||||
escrow(AccountID const& src, UInt32or256 const& seq) noexcept;
|
||||
|
||||
/** A PaymentChannel */
|
||||
Keylet
|
||||
payChan(AccountID const& src, AccountID const& dst, std::uint32_t seq) noexcept;
|
||||
payChan(
|
||||
AccountID const& src,
|
||||
AccountID const& dst,
|
||||
UInt32or256 const& seq) noexcept;
|
||||
|
||||
/** NFT page keylets
|
||||
|
||||
@@ -255,7 +281,7 @@ nftpage(Keylet const& k, uint256 const& token);
|
||||
|
||||
/** An offer from an account to buy or sell an NFT */
|
||||
Keylet
|
||||
nftoffer(AccountID const& owner, std::uint32_t seq);
|
||||
nftoffer(AccountID const& owner, UInt32or256 const& seq);
|
||||
|
||||
inline Keylet
|
||||
nftoffer(uint256 const& offer)
|
||||
@@ -273,7 +299,7 @@ nft_sells(uint256 const& id) noexcept;
|
||||
|
||||
/** AMM entry */
|
||||
Keylet
|
||||
amm(Issue const& issue1, Issue const& issue2) noexcept;
|
||||
amm(Asset const& issue1, Asset const& issue2) noexcept;
|
||||
|
||||
Keylet
|
||||
amm(uint256 const& amm) noexcept;
|
||||
|
||||
@@ -20,10 +20,10 @@
|
||||
#ifndef RIPPLE_PROTOCOL_ISSUE_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_ISSUE_H_INCLUDED
|
||||
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
#include <xrpl/protocol/UintTypes.h>
|
||||
|
||||
#include <cassert>
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
|
||||
@@ -58,6 +58,9 @@ public:
|
||||
|
||||
bool
|
||||
native() const;
|
||||
|
||||
friend constexpr std::weak_ordering
|
||||
operator<=>(Issue const& lhs, Issue const& rhs);
|
||||
};
|
||||
|
||||
bool
|
||||
@@ -95,7 +98,7 @@ operator==(Issue const& lhs, Issue const& rhs)
|
||||
|
||||
/** Strict weak ordering. */
|
||||
/** @{ */
|
||||
[[nodiscard]] inline constexpr std::weak_ordering
|
||||
[[nodiscard]] constexpr std::weak_ordering
|
||||
operator<=>(Issue const& lhs, Issue const& rhs)
|
||||
{
|
||||
if (auto const c{lhs.currency <=> rhs.currency}; c != 0)
|
||||
|
||||
@@ -107,8 +107,8 @@ enum LedgerEntryType : std::uint16_t
|
||||
*/
|
||||
ltCONTRACT [[deprecated("This object type is not supported and should not be used.")]] = 0x0063,
|
||||
|
||||
/** A legacy, deprecated type.
|
||||
|
||||
/** A legacy, deprecated type.
|
||||
\deprecated **This object type is not supported and should not be used.**
|
||||
Support for this type of object was never implemented.
|
||||
No objects of this type were ever created.
|
||||
@@ -134,9 +134,7 @@ enum LedgerSpecificFlags {
|
||||
lsfDefaultRipple =
|
||||
0x00800000, // True, trust lines allow rippling by default
|
||||
lsfDepositAuth = 0x01000000, // True, all deposits require authorization
|
||||
/* // reserved for Hooks amendment
|
||||
lsfTshCollect = 0x02000000, // True, allow TSH collect-calls to acc hooks
|
||||
*/
|
||||
lsfDisallowIncomingNFTokenOffer =
|
||||
0x04000000, // True, reject new incoming NFT offers
|
||||
lsfDisallowIncomingCheck =
|
||||
@@ -171,6 +169,7 @@ enum LedgerSpecificFlags {
|
||||
// ltDIR_NODE
|
||||
lsfNFTokenBuyOffers = 0x00000001,
|
||||
lsfNFTokenSellOffers = 0x00000002,
|
||||
lsfEmittedDir = 0x00000004,
|
||||
|
||||
// ltNFTOKEN_OFFER
|
||||
lsfSellNFToken = 0x00000001,
|
||||
|
||||
@@ -21,11 +21,11 @@
|
||||
#define RIPPLE_PROTOCOL_LEDGERHEADER_H_INCLUDED
|
||||
|
||||
#include <xrpl/basics/Slice.h>
|
||||
#include <xrpl/basics/XRPAmount.h>
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/basics/chrono.h>
|
||||
#include <xrpl/protocol/Protocol.h>
|
||||
#include <xrpl/protocol/Serializer.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
|
||||
@@ -17,9 +17,10 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_BASICS_MPTAMOUNT_H_INCLUDED
|
||||
#define RIPPLE_BASICS_MPTAMOUNT_H_INCLUDED
|
||||
#ifndef RIPPLE_PROTOCOL_MPTAMOUNT_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_MPTAMOUNT_H_INCLUDED
|
||||
|
||||
#include <xrpl/basics/Number.h>
|
||||
#include <xrpl/basics/contract.h>
|
||||
#include <xrpl/basics/safe_cast.h>
|
||||
#include <xrpl/beast/utility/Zero.h>
|
||||
@@ -52,6 +53,11 @@ public:
|
||||
constexpr MPTAmount&
|
||||
operator=(MPTAmount const& other) = default;
|
||||
|
||||
// Round to nearest, even on tie.
|
||||
explicit MPTAmount(Number const& x) : MPTAmount(static_cast<value_type>(x))
|
||||
{
|
||||
}
|
||||
|
||||
constexpr explicit MPTAmount(value_type value);
|
||||
|
||||
constexpr MPTAmount& operator=(beast::Zero);
|
||||
@@ -78,6 +84,11 @@ public:
|
||||
explicit constexpr
|
||||
operator bool() const noexcept;
|
||||
|
||||
operator Number() const noexcept
|
||||
{
|
||||
return value();
|
||||
}
|
||||
|
||||
/** Return the sign of the amount */
|
||||
constexpr int
|
||||
signum() const noexcept;
|
||||
@@ -54,8 +54,8 @@ public:
|
||||
friend constexpr bool
|
||||
operator==(MPTIssue const& lhs, MPTIssue const& rhs);
|
||||
|
||||
friend constexpr bool
|
||||
operator!=(MPTIssue const& lhs, MPTIssue const& rhs);
|
||||
friend constexpr std::weak_ordering
|
||||
operator<=>(MPTIssue const& lhs, MPTIssue const& rhs);
|
||||
|
||||
bool
|
||||
native() const
|
||||
@@ -70,10 +70,10 @@ operator==(MPTIssue const& lhs, MPTIssue const& rhs)
|
||||
return lhs.mptID_ == rhs.mptID_;
|
||||
}
|
||||
|
||||
constexpr bool
|
||||
operator!=(MPTIssue const& lhs, MPTIssue const& rhs)
|
||||
constexpr std::weak_ordering
|
||||
operator<=>(MPTIssue const& lhs, MPTIssue const& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
return lhs.mptID_ <=> rhs.mptID_;
|
||||
}
|
||||
|
||||
/** MPT is a non-native token.
|
||||
|
||||
@@ -23,8 +23,8 @@
|
||||
#include <xrpl/json/json_value.h>
|
||||
#include <xrpl/protocol/ApiVersion.h>
|
||||
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <array>
|
||||
#include <cassert>
|
||||
#include <concepts>
|
||||
#include <cstdlib>
|
||||
#include <functional>
|
||||
@@ -159,8 +159,10 @@ struct MultiApiJson
|
||||
-> std::
|
||||
invoke_result_t<Fn, decltype(json.val[0]), Version, Args&&...>
|
||||
{
|
||||
assert(
|
||||
valid(version) && index(version) >= 0 && index(version) < size);
|
||||
XRPL_ASSERT(
|
||||
valid(version) && index(version) >= 0 && index(version) < size,
|
||||
"ripple::detail::MultiApiJson::operator<Args...>() : valid "
|
||||
"version");
|
||||
return std::invoke(
|
||||
fn,
|
||||
json.val[index(version)],
|
||||
@@ -177,8 +179,9 @@ struct MultiApiJson
|
||||
operator()(Json& json, Version version, Fn fn) const
|
||||
-> std::invoke_result_t<Fn, decltype(json.val[0])>
|
||||
{
|
||||
assert(
|
||||
valid(version) && index(version) >= 0 && index(version) < size);
|
||||
XRPL_ASSERT(
|
||||
valid(version) && index(version) >= 0 && index(version) < size,
|
||||
"ripple::detail::MultiApiJson::operator() : valid version");
|
||||
return std::invoke(fn, json.val[index(version)]);
|
||||
}
|
||||
} visitor = {};
|
||||
|
||||
@@ -20,10 +20,10 @@
|
||||
#ifndef RIPPLE_PROTOCOL_PAYCHAN_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_PAYCHAN_H_INCLUDED
|
||||
|
||||
#include <xrpl/basics/XRPAmount.h>
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/protocol/HashPrefix.h>
|
||||
#include <xrpl/protocol/Serializer.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
@@ -38,6 +38,32 @@ serializePayChanAuthorization(
|
||||
msg.add64(amt.drops());
|
||||
}
|
||||
|
||||
inline void
|
||||
serializePayChanAuthorization(
|
||||
Serializer& msg,
|
||||
uint256 const& key,
|
||||
IOUAmount const& amt,
|
||||
Currency const& cur,
|
||||
AccountID const& iss)
|
||||
{
|
||||
msg.add32(HashPrefix::paymentChannelClaim);
|
||||
msg.addBitString(key);
|
||||
if (amt == beast::zero)
|
||||
msg.add64(STAmount::cIssuedCurrency);
|
||||
else if (amt.signum() == -1) // 512 = not native
|
||||
msg.add64(
|
||||
amt.mantissa() |
|
||||
(static_cast<std::uint64_t>(amt.exponent() + 512 + 97)
|
||||
<< (64 - 10)));
|
||||
else // 256 = positive
|
||||
msg.add64(
|
||||
amt.mantissa() |
|
||||
(static_cast<std::uint64_t>(amt.exponent() + 512 + 256 + 97)
|
||||
<< (64 - 10)));
|
||||
msg.addBitString(cur);
|
||||
msg.addBitString(iss);
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#include <xrpl/basics/ByteUtilities.h>
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/basics/partitioned_unordered_map.h>
|
||||
#include <cstdint>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
@@ -20,10 +20,10 @@
|
||||
#ifndef RIPPLE_PROTOCOL_QUALITY_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_QUALITY_H_INCLUDED
|
||||
|
||||
#include <xrpl/basics/IOUAmount.h>
|
||||
#include <xrpl/basics/XRPAmount.h>
|
||||
#include <xrpl/protocol/AmountConversions.h>
|
||||
#include <xrpl/protocol/IOUAmount.h>
|
||||
#include <xrpl/protocol/STAmount.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
@@ -298,7 +298,9 @@ public:
|
||||
friend double
|
||||
relativeDistance(Quality const& q1, Quality const& q2)
|
||||
{
|
||||
assert(q1.m_value > 0 && q2.m_value > 0);
|
||||
XRPL_ASSERT(
|
||||
q1.m_value > 0 && q2.m_value > 0,
|
||||
"ripple::Quality::relativeDistance : minimum inputs");
|
||||
|
||||
if (q1.m_value == q2.m_value) // make expected common case fast
|
||||
return 0;
|
||||
|
||||
@@ -20,9 +20,9 @@
|
||||
#ifndef RIPPLE_PROTOCOL_RATE_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_RATE_H_INCLUDED
|
||||
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/protocol/STAmount.h>
|
||||
#include <boost/operators.hpp>
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <ostream>
|
||||
|
||||
|
||||
@@ -72,6 +72,7 @@ private:
|
||||
DigestAwareReadView const& ledger,
|
||||
std::unordered_set<uint256, beast::uhash<>> const& presets);
|
||||
|
||||
public:
|
||||
Rules(
|
||||
std::unordered_set<uint256, beast::uhash<>> const& presets,
|
||||
std::optional<uint256> const& digest,
|
||||
|
||||
@@ -49,6 +49,7 @@ template <int>
|
||||
class STBitString;
|
||||
template <class>
|
||||
class STInteger;
|
||||
class STNumber;
|
||||
class STXChainBridge;
|
||||
class STVector256;
|
||||
class STCurrency;
|
||||
@@ -70,8 +71,9 @@ class STCurrency;
|
||||
STYPE(STI_AMOUNT, 6) \
|
||||
STYPE(STI_VL, 7) \
|
||||
STYPE(STI_ACCOUNT, 8) \
|
||||
STYPE(STI_NUMBER, 9) \
|
||||
\
|
||||
/* 9-13 are reserved */ \
|
||||
/* 10-13 are reserved */ \
|
||||
STYPE(STI_OBJECT, 14) \
|
||||
STYPE(STI_ARRAY, 15) \
|
||||
\
|
||||
@@ -355,6 +357,7 @@ using SF_ACCOUNT = TypedField<STAccount>;
|
||||
using SF_AMOUNT = TypedField<STAmount>;
|
||||
using SF_ISSUE = TypedField<STIssue>;
|
||||
using SF_CURRENCY = TypedField<STCurrency>;
|
||||
using SF_NUMBER = TypedField<STNumber>;
|
||||
using SF_VL = TypedField<STBlob>;
|
||||
using SF_VECTOR256 = TypedField<STVector256>;
|
||||
using SF_XCHAIN_BRIDGE = TypedField<STXChainBridge>;
|
||||
|
||||
@@ -40,7 +40,7 @@ enum SOEStyle {
|
||||
};
|
||||
|
||||
/** Amount fields that can support MPT */
|
||||
enum SOETxMPTAmount { soeMPTNone, soeMPTSupported, soeMPTNotSupported };
|
||||
enum SOETxMPTIssue { soeMPTNone, soeMPTSupported, soeMPTNotSupported };
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -50,7 +50,7 @@ class SOElement
|
||||
// Use std::reference_wrapper so SOElement can be stored in a std::vector.
|
||||
std::reference_wrapper<SField const> sField_;
|
||||
SOEStyle style_;
|
||||
SOETxMPTAmount supportMpt_ = soeMPTNone;
|
||||
SOETxMPTIssue supportMpt_ = soeMPTNone;
|
||||
|
||||
private:
|
||||
void
|
||||
@@ -72,10 +72,13 @@ public:
|
||||
{
|
||||
init(fieldName);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
requires(std::is_same_v<T, STAmount> || std::is_same_v<T, STIssue>)
|
||||
SOElement(
|
||||
TypedField<STAmount> const& fieldName,
|
||||
TypedField<T> const& fieldName,
|
||||
SOEStyle style,
|
||||
SOETxMPTAmount supportMpt = soeMPTNotSupported)
|
||||
SOETxMPTIssue supportMpt = soeMPTNotSupported)
|
||||
: sField_(fieldName), style_(style), supportMpt_(supportMpt)
|
||||
{
|
||||
init(fieldName);
|
||||
@@ -93,7 +96,7 @@ public:
|
||||
return style_;
|
||||
}
|
||||
|
||||
SOETxMPTAmount
|
||||
SOETxMPTIssue
|
||||
supportMPT() const
|
||||
{
|
||||
return supportMpt_;
|
||||
|
||||
@@ -21,24 +21,21 @@
|
||||
#define RIPPLE_PROTOCOL_STAMOUNT_H_INCLUDED
|
||||
|
||||
#include <xrpl/basics/CountedObject.h>
|
||||
#include <xrpl/basics/IOUAmount.h>
|
||||
#include <xrpl/basics/LocalValue.h>
|
||||
#include <xrpl/basics/MPTAmount.h>
|
||||
#include <xrpl/basics/Number.h>
|
||||
#include <xrpl/basics/XRPAmount.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/protocol/Asset.h>
|
||||
#include <xrpl/protocol/IOUAmount.h>
|
||||
#include <xrpl/protocol/Issue.h>
|
||||
#include <xrpl/protocol/MPTAmount.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STBase.h>
|
||||
#include <xrpl/protocol/Serializer.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
#include <xrpl/protocol/json_get_or_throw.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
template <typename A>
|
||||
concept AssetType =
|
||||
std::is_same_v<A, Asset> || std::is_convertible_v<A, Issue> ||
|
||||
std::is_convertible_v<A, MPTIssue> || std::is_convertible_v<A, MPTID>;
|
||||
|
||||
// Internal form:
|
||||
// 1: If amount is zero, then value is zero and offset is -100
|
||||
// 2: Otherwise:
|
||||
@@ -353,7 +350,10 @@ STAmount::STAmount(
|
||||
, mIsNegative(negative)
|
||||
{
|
||||
// mValue is uint64, but needs to fit in the range of int64
|
||||
assert(mValue <= std::numeric_limits<std::int64_t>::max());
|
||||
XRPL_ASSERT(
|
||||
mValue <= std::numeric_limits<std::int64_t>::max(),
|
||||
"ripple::STAmount::STAmount(SField, A, std::uint64_t, int, bool) : "
|
||||
"maximum mantissa input");
|
||||
canonicalize();
|
||||
}
|
||||
|
||||
@@ -684,6 +684,57 @@ isXRP(STAmount const& amount)
|
||||
return amount.native();
|
||||
}
|
||||
|
||||
inline bool
|
||||
isFakeXRP(STAmount const& amount)
|
||||
{
|
||||
if (amount.native())
|
||||
return false;
|
||||
|
||||
return isFakeXRP(amount.issue().currency);
|
||||
}
|
||||
|
||||
/** returns true iff adding or subtracting results in less than or equal to
|
||||
* 0.01% precision loss **/
|
||||
inline bool
|
||||
isAddable(STAmount const& amt1, STAmount const& amt2)
|
||||
{
|
||||
// special case: adding anything to zero is always fine
|
||||
if (amt1 == beast::zero || amt2 == beast::zero)
|
||||
return true;
|
||||
|
||||
// special case: adding two xrp amounts together.
|
||||
// this is just an overflow check
|
||||
if (isXRP(amt1) && isXRP(amt2))
|
||||
{
|
||||
XRPAmount A = (amt1.signum() == -1 ? -(amt1.xrp()) : amt1.xrp());
|
||||
XRPAmount B = (amt2.signum() == -1 ? -(amt2.xrp()) : amt2.xrp());
|
||||
|
||||
XRPAmount finalAmt = A + B;
|
||||
return (finalAmt >= A && finalAmt >= B);
|
||||
}
|
||||
|
||||
static const STAmount one{IOUAmount{1, 0}, noIssue()};
|
||||
static const STAmount maxLoss{IOUAmount{1, -4}, noIssue()};
|
||||
|
||||
STAmount A = amt1;
|
||||
STAmount B = amt2;
|
||||
|
||||
if (isXRP(A))
|
||||
A = STAmount{IOUAmount{A.xrp().drops(), -6}, noIssue()};
|
||||
|
||||
if (isXRP(B))
|
||||
B = STAmount{IOUAmount{B.xrp().drops(), -6}, noIssue()};
|
||||
|
||||
A.setIssue(noIssue());
|
||||
B.setIssue(noIssue());
|
||||
|
||||
STAmount lhs = divide((A - B) + B, A, noIssue()) - one;
|
||||
STAmount rhs = divide((B - A) + A, B, noIssue()) - one;
|
||||
|
||||
return ((rhs.negative() ? -rhs : rhs) + (lhs.negative() ? -lhs : lhs)) <=
|
||||
maxLoss;
|
||||
}
|
||||
|
||||
// Since `canonicalize` does not have access to a ledger, this is needed to put
|
||||
// the low-level routine stAmountCanonicalize on an amendment switch. Only
|
||||
// transactions need to use this switchover. Outside of a transaction it's safe
|
||||
|
||||
@@ -38,6 +38,9 @@ public:
|
||||
using iterator = list_type::iterator;
|
||||
using const_iterator = list_type::const_iterator;
|
||||
|
||||
// RH NOTE: please don't delete this constructor
|
||||
STArray(std::vector<STObject> const& v, SField const& f);
|
||||
|
||||
STArray() = default;
|
||||
STArray(STArray const&) = default;
|
||||
|
||||
|
||||
@@ -170,8 +170,11 @@ template <int Bits>
|
||||
void
|
||||
STBitString<Bits>::add(Serializer& s) const
|
||||
{
|
||||
assert(getFName().isBinary());
|
||||
assert(getFName().fieldType == getSType());
|
||||
XRPL_ASSERT(
|
||||
getFName().isBinary(), "ripple::STBitString::add : field is binary");
|
||||
XRPL_ASSERT(
|
||||
getFName().fieldType == getSType(),
|
||||
"ripple::STBitString::add : field type match");
|
||||
s.addBitString<Bits>(value_);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,9 +23,9 @@
|
||||
#include <xrpl/basics/Buffer.h>
|
||||
#include <xrpl/basics/CountedObject.h>
|
||||
#include <xrpl/basics/Slice.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/protocol/STBase.h>
|
||||
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
|
||||
|
||||
@@ -110,8 +110,11 @@ template <typename Integer>
|
||||
inline void
|
||||
STInteger<Integer>::add(Serializer& s) const
|
||||
{
|
||||
assert(getFName().isBinary());
|
||||
assert(getFName().fieldType == getSType());
|
||||
XRPL_ASSERT(
|
||||
getFName().isBinary(), "ripple::STInteger::add : field is binary");
|
||||
XRPL_ASSERT(
|
||||
getFName().fieldType == getSType(),
|
||||
"ripple::STInteger::add : field type match");
|
||||
s.addInteger(value_);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#define RIPPLE_PROTOCOL_STISSUE_H_INCLUDED
|
||||
|
||||
#include <xrpl/basics/CountedObject.h>
|
||||
#include <xrpl/protocol/Issue.h>
|
||||
#include <xrpl/protocol/Asset.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STBase.h>
|
||||
#include <xrpl/protocol/Serializer.h>
|
||||
@@ -31,31 +31,40 @@ namespace ripple {
|
||||
class STIssue final : public STBase, CountedObject<STIssue>
|
||||
{
|
||||
private:
|
||||
Issue issue_{xrpIssue()};
|
||||
Asset asset_{xrpIssue()};
|
||||
|
||||
public:
|
||||
using value_type = Issue;
|
||||
using value_type = Asset;
|
||||
|
||||
STIssue() = default;
|
||||
|
||||
explicit STIssue(SerialIter& sit, SField const& name);
|
||||
|
||||
explicit STIssue(SField const& name, Issue const& issue);
|
||||
template <AssetType A>
|
||||
explicit STIssue(SField const& name, A const& issue);
|
||||
|
||||
explicit STIssue(SField const& name);
|
||||
|
||||
Issue const&
|
||||
issue() const;
|
||||
template <ValidIssueType TIss>
|
||||
TIss const&
|
||||
get() const;
|
||||
|
||||
Issue const&
|
||||
template <ValidIssueType TIss>
|
||||
bool
|
||||
holds() const;
|
||||
|
||||
value_type const&
|
||||
value() const noexcept;
|
||||
|
||||
void
|
||||
setIssue(Issue const& issue);
|
||||
setIssue(Asset const& issue);
|
||||
|
||||
SerializedTypeID
|
||||
getSType() const override;
|
||||
|
||||
std::string
|
||||
getText() const override;
|
||||
|
||||
Json::Value getJson(JsonOptions) const override;
|
||||
|
||||
void
|
||||
@@ -67,6 +76,18 @@ public:
|
||||
bool
|
||||
isDefault() const override;
|
||||
|
||||
friend constexpr bool
|
||||
operator==(STIssue const& lhs, STIssue const& rhs);
|
||||
|
||||
friend constexpr std::weak_ordering
|
||||
operator<=>(STIssue const& lhs, STIssue const& rhs);
|
||||
|
||||
friend constexpr bool
|
||||
operator==(STIssue const& lhs, Asset const& rhs);
|
||||
|
||||
friend constexpr std::weak_ordering
|
||||
operator<=>(STIssue const& lhs, Asset const& rhs);
|
||||
|
||||
private:
|
||||
STBase*
|
||||
copy(std::size_t n, void* buf) const override;
|
||||
@@ -76,59 +97,72 @@ private:
|
||||
friend class detail::STVar;
|
||||
};
|
||||
|
||||
template <AssetType A>
|
||||
STIssue::STIssue(SField const& name, A const& asset)
|
||||
: STBase{name}, asset_{asset}
|
||||
{
|
||||
if (holds<Issue>() && !isConsistent(asset_.get<Issue>()))
|
||||
Throw<std::runtime_error>(
|
||||
"Invalid asset: currency and account native mismatch");
|
||||
}
|
||||
|
||||
STIssue
|
||||
issueFromJson(SField const& name, Json::Value const& v);
|
||||
|
||||
inline Issue const&
|
||||
STIssue::issue() const
|
||||
template <ValidIssueType TIss>
|
||||
bool
|
||||
STIssue::holds() const
|
||||
{
|
||||
return issue_;
|
||||
return asset_.holds<TIss>();
|
||||
}
|
||||
|
||||
inline Issue const&
|
||||
template <ValidIssueType TIss>
|
||||
TIss const&
|
||||
STIssue::get() const
|
||||
{
|
||||
if (!holds<TIss>(asset_))
|
||||
Throw<std::runtime_error>("Asset doesn't hold the requested issue");
|
||||
return std::get<TIss>(asset_);
|
||||
}
|
||||
|
||||
inline STIssue::value_type const&
|
||||
STIssue::value() const noexcept
|
||||
{
|
||||
return issue_;
|
||||
return asset_;
|
||||
}
|
||||
|
||||
inline void
|
||||
STIssue::setIssue(Issue const& issue)
|
||||
STIssue::setIssue(Asset const& asset)
|
||||
{
|
||||
if (isXRP(issue_.currency) != isXRP(issue_.account))
|
||||
if (holds<Issue>() && !isConsistent(asset_.get<Issue>()))
|
||||
Throw<std::runtime_error>(
|
||||
"invalid issue: currency and account native mismatch");
|
||||
"Invalid asset: currency and account native mismatch");
|
||||
|
||||
issue_ = issue;
|
||||
asset_ = asset;
|
||||
}
|
||||
|
||||
inline bool
|
||||
constexpr bool
|
||||
operator==(STIssue const& lhs, STIssue const& rhs)
|
||||
{
|
||||
return lhs.issue() == rhs.issue();
|
||||
return lhs.asset_ == rhs.asset_;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator!=(STIssue const& lhs, STIssue const& rhs)
|
||||
constexpr std::weak_ordering
|
||||
operator<=>(STIssue const& lhs, STIssue const& rhs)
|
||||
{
|
||||
return !operator==(lhs, rhs);
|
||||
return lhs.asset_ <=> rhs.asset_;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator<(STIssue const& lhs, STIssue const& rhs)
|
||||
constexpr bool
|
||||
operator==(STIssue const& lhs, Asset const& rhs)
|
||||
{
|
||||
return lhs.issue() < rhs.issue();
|
||||
return lhs.asset_ == rhs;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator==(STIssue const& lhs, Issue const& rhs)
|
||||
constexpr std::weak_ordering
|
||||
operator<=>(STIssue const& lhs, Asset const& rhs)
|
||||
{
|
||||
return lhs.issue() == rhs;
|
||||
}
|
||||
|
||||
inline bool
|
||||
operator<(STIssue const& lhs, Issue const& rhs)
|
||||
{
|
||||
return lhs.issue() < rhs;
|
||||
return lhs.asset_ <=> rhs;
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
88
include/xrpl/protocol/STNumber.h
Normal file
88
include/xrpl/protocol/STNumber.h
Normal file
@@ -0,0 +1,88 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2024 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef XRPL_PROTOCOL_STNUMBER_H_INCLUDED
|
||||
#define XRPL_PROTOCOL_STNUMBER_H_INCLUDED
|
||||
|
||||
#include <xrpl/basics/CountedObject.h>
|
||||
#include <xrpl/basics/Number.h>
|
||||
#include <xrpl/protocol/STBase.h>
|
||||
|
||||
#include <ostream>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
/**
|
||||
* A serializable number.
|
||||
*
|
||||
* This type is-a `Number`, and can be used everywhere that is accepted.
|
||||
* This type simply integrates `Number` with the serialization framework,
|
||||
* letting it be used for fields in ledger entries and transactions.
|
||||
* It is effectively an `STAmount` sans `Asset`:
|
||||
* it can represent a value of any token type (XRP, IOU, or MPT)
|
||||
* without paying the storage cost of duplicating asset information
|
||||
* that may be deduced from the context.
|
||||
*/
|
||||
class STNumber : public STBase, public CountedObject<STNumber>
|
||||
{
|
||||
private:
|
||||
Number value_;
|
||||
|
||||
public:
|
||||
using value_type = Number;
|
||||
|
||||
STNumber() = default;
|
||||
explicit STNumber(SField const& field, Number const& value = Number());
|
||||
STNumber(SerialIter& sit, SField const& field);
|
||||
|
||||
SerializedTypeID
|
||||
getSType() const override;
|
||||
std::string
|
||||
getText() const override;
|
||||
void
|
||||
add(Serializer& s) const override;
|
||||
|
||||
Number const&
|
||||
value() const;
|
||||
void
|
||||
setValue(Number const& v);
|
||||
|
||||
bool
|
||||
isEquivalent(STBase const& t) const override;
|
||||
bool
|
||||
isDefault() const override;
|
||||
|
||||
operator Number() const
|
||||
{
|
||||
return value_;
|
||||
}
|
||||
|
||||
private:
|
||||
STBase*
|
||||
copy(std::size_t n, void* buf) const override;
|
||||
STBase*
|
||||
move(std::size_t n, void* buf) override;
|
||||
};
|
||||
|
||||
std::ostream&
|
||||
operator<<(std::ostream& out, STNumber const& rhs);
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
@@ -21,10 +21,11 @@
|
||||
#define RIPPLE_PROTOCOL_STOBJECT_H_INCLUDED
|
||||
|
||||
#include <xrpl/basics/CountedObject.h>
|
||||
#include <xrpl/basics/FeeUnits.h>
|
||||
#include <xrpl/basics/Slice.h>
|
||||
#include <xrpl/basics/chrono.h>
|
||||
#include <xrpl/basics/contract.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/protocol/FeeUnits.h>
|
||||
#include <xrpl/protocol/HashPrefix.h>
|
||||
#include <xrpl/protocol/SOTemplate.h>
|
||||
#include <xrpl/protocol/STAmount.h>
|
||||
@@ -35,7 +36,6 @@
|
||||
#include <xrpl/protocol/STVector256.h>
|
||||
#include <xrpl/protocol/detail/STVar.h>
|
||||
#include <boost/iterator/transform_iterator.hpp>
|
||||
#include <cassert>
|
||||
#include <optional>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
@@ -245,6 +245,8 @@ public:
|
||||
getFieldArray(SField const& field) const;
|
||||
const STCurrency&
|
||||
getFieldCurrency(SField const& field) const;
|
||||
STNumber const&
|
||||
getFieldNumber(SField const& field) const;
|
||||
|
||||
/** Get the value of a field.
|
||||
@param A TypedField built from an SField value representing the desired
|
||||
@@ -376,6 +378,8 @@ public:
|
||||
void
|
||||
setFieldCurrency(SField const& field, STCurrency const&);
|
||||
void
|
||||
setFieldNumber(SField const& field, STNumber const&);
|
||||
void
|
||||
setFieldPathSet(SField const& field, STPathSet const&);
|
||||
void
|
||||
setFieldV256(SField const& field, STVector256 const& v);
|
||||
@@ -733,7 +737,7 @@ STObject::Proxy<T>::assign(U&& u)
|
||||
t = dynamic_cast<T*>(st_->getPField(*f_, true));
|
||||
else
|
||||
t = dynamic_cast<T*>(st_->makeFieldPresent(*f_));
|
||||
assert(t);
|
||||
XRPL_ASSERT(t, "ripple::STObject::Proxy::assign : type cast succeeded");
|
||||
*t = std::forward<U>(u);
|
||||
}
|
||||
|
||||
@@ -1029,13 +1033,19 @@ STObject::at(TypedField<T> const& f) const
|
||||
if (auto const u = dynamic_cast<T const*>(b))
|
||||
return u->value();
|
||||
|
||||
assert(mType);
|
||||
assert(b->getSType() == STI_NOTPRESENT);
|
||||
XRPL_ASSERT(
|
||||
mType,
|
||||
"ripple::STObject::at(TypedField auto) : field template non-null");
|
||||
XRPL_ASSERT(
|
||||
b->getSType() == STI_NOTPRESENT,
|
||||
"ripple::STObject::at(TypedField auto) : type not present");
|
||||
|
||||
if (mType->style(f) == soeOPTIONAL)
|
||||
Throw<STObject::FieldErr>("Missing optional field: " + f.getName());
|
||||
|
||||
assert(mType->style(f) == soeDEFAULT);
|
||||
XRPL_ASSERT(
|
||||
mType->style(f) == soeDEFAULT,
|
||||
"ripple::STObject::at(TypedField auto) : template style is default");
|
||||
|
||||
// Used to help handle the case where value_type is a const reference,
|
||||
// otherwise we would return the address of a temporary.
|
||||
@@ -1053,11 +1063,19 @@ STObject::at(OptionaledField<T> const& of) const
|
||||
auto const u = dynamic_cast<T const*>(b);
|
||||
if (!u)
|
||||
{
|
||||
assert(mType);
|
||||
assert(b->getSType() == STI_NOTPRESENT);
|
||||
XRPL_ASSERT(
|
||||
mType,
|
||||
"ripple::STObject::at(OptionaledField auto) : field template "
|
||||
"non-null");
|
||||
XRPL_ASSERT(
|
||||
b->getSType() == STI_NOTPRESENT,
|
||||
"ripple::STObject::at(OptionaledField auto) : type not present");
|
||||
if (mType->style(*of.f) == soeOPTIONAL)
|
||||
return std::nullopt;
|
||||
assert(mType->style(*of.f) == soeDEFAULT);
|
||||
XRPL_ASSERT(
|
||||
mType->style(*of.f) == soeDEFAULT,
|
||||
"ripple::STObject::at(OptionaledField auto) : template style is "
|
||||
"default");
|
||||
return typename T::value_type{};
|
||||
}
|
||||
return u->value();
|
||||
|
||||
@@ -21,11 +21,11 @@
|
||||
#define RIPPLE_PROTOCOL_STPATHSET_H_INCLUDED
|
||||
|
||||
#include <xrpl/basics/CountedObject.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <xrpl/protocol/STBase.h>
|
||||
#include <xrpl/protocol/UintTypes.h>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <optional>
|
||||
|
||||
@@ -257,7 +257,9 @@ inline STPathElement::STPathElement(
|
||||
is_offer_ = false;
|
||||
mAccountID = *account;
|
||||
mType |= typeAccount;
|
||||
assert(mAccountID != noAccount());
|
||||
XRPL_ASSERT(
|
||||
mAccountID != noAccount(),
|
||||
"ripple::STPathElement::STPathElement : account is set");
|
||||
}
|
||||
|
||||
if (currency)
|
||||
@@ -270,7 +272,9 @@ inline STPathElement::STPathElement(
|
||||
{
|
||||
mIssuerID = *issuer;
|
||||
mType |= typeIssuer;
|
||||
assert(mIssuerID != noAccount());
|
||||
XRPL_ASSERT(
|
||||
mIssuerID != noAccount(),
|
||||
"ripple::STPathElement::STPathElement : issuer is set");
|
||||
}
|
||||
|
||||
hash_value_ = get_hash(*this);
|
||||
|
||||
@@ -20,12 +20,12 @@
|
||||
#ifndef RIPPLE_PROTOCOL_STVALIDATION_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_STVALIDATION_H_INCLUDED
|
||||
|
||||
#include <xrpl/basics/FeeUnits.h>
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/protocol/FeeUnits.h>
|
||||
#include <xrpl/protocol/PublicKey.h>
|
||||
#include <xrpl/protocol/STObject.h>
|
||||
#include <xrpl/protocol/SecretKey.h>
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
@@ -176,7 +176,9 @@ STValidation::STValidation(
|
||||
Throw<std::runtime_error>("Invalid signature in validation");
|
||||
}
|
||||
|
||||
assert(nodeID_.isNonZero());
|
||||
XRPL_ASSERT(
|
||||
nodeID_.isNonZero(),
|
||||
"ripple::STValidation::STValidation(SerialIter) : nonzero node");
|
||||
}
|
||||
|
||||
/** Construct, sign and trust a new STValidation issued by this node.
|
||||
@@ -199,7 +201,10 @@ STValidation::STValidation(
|
||||
, nodeID_(nodeID)
|
||||
, seenTime_(signTime)
|
||||
{
|
||||
assert(nodeID_.isNonZero());
|
||||
XRPL_ASSERT(
|
||||
nodeID_.isNonZero(),
|
||||
"ripple::STValidation::STValidation(PublicKey, SecretKey) : nonzero "
|
||||
"node");
|
||||
|
||||
// First, set our own public key:
|
||||
if (publicKeyType(pk) != KeyType::secp256k1)
|
||||
|
||||
@@ -170,7 +170,7 @@ STXChainBridge::lockingChainDoor() const
|
||||
inline Issue const&
|
||||
STXChainBridge::lockingChainIssue() const
|
||||
{
|
||||
return lockingChainIssue_.value();
|
||||
return lockingChainIssue_.value().get<Issue>();
|
||||
};
|
||||
|
||||
inline AccountID const&
|
||||
@@ -182,7 +182,7 @@ STXChainBridge::issuingChainDoor() const
|
||||
inline Issue const&
|
||||
STXChainBridge::issuingChainIssue() const
|
||||
{
|
||||
return issuingChainIssue_.value();
|
||||
return issuingChainIssue_.value().get<Issue>();
|
||||
};
|
||||
|
||||
inline STXChainBridge::value_type const&
|
||||
|
||||
@@ -27,9 +27,9 @@
|
||||
#include <xrpl/basics/contract.h>
|
||||
#include <xrpl/basics/safe_cast.h>
|
||||
#include <xrpl/basics/strHex.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/protocol/HashPrefix.h>
|
||||
#include <xrpl/protocol/SField.h>
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <iomanip>
|
||||
@@ -55,7 +55,9 @@ public:
|
||||
|
||||
if (size)
|
||||
{
|
||||
assert(data != nullptr);
|
||||
XRPL_ASSERT(
|
||||
data,
|
||||
"ripple::Serializer::Serializer(void const*) : non-null input");
|
||||
std::memcpy(mData.data(), data, size);
|
||||
}
|
||||
}
|
||||
@@ -83,12 +85,43 @@ public:
|
||||
add8(unsigned char i);
|
||||
int
|
||||
add16(std::uint16_t i);
|
||||
|
||||
template <typename T>
|
||||
requires(std::is_same_v<
|
||||
std::make_unsigned_t<std::remove_cv_t<T>>,
|
||||
std::uint32_t>)
|
||||
int
|
||||
add32(std::uint32_t i); // ledger indexes, account sequence, timestamps
|
||||
add32(T i)
|
||||
{
|
||||
int ret = mData.size();
|
||||
mData.push_back(static_cast<unsigned char>((i >> 24) & 0xff));
|
||||
mData.push_back(static_cast<unsigned char>((i >> 16) & 0xff));
|
||||
mData.push_back(static_cast<unsigned char>((i >> 8) & 0xff));
|
||||
mData.push_back(static_cast<unsigned char>(i & 0xff));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
add32(HashPrefix p);
|
||||
|
||||
template <typename T>
|
||||
requires(std::is_same_v<
|
||||
std::make_unsigned_t<std::remove_cv_t<T>>,
|
||||
std::uint64_t>)
|
||||
int
|
||||
add64(std::uint64_t i); // native currency amounts
|
||||
add64(T i)
|
||||
{
|
||||
int ret = mData.size();
|
||||
mData.push_back(static_cast<unsigned char>((i >> 56) & 0xff));
|
||||
mData.push_back(static_cast<unsigned char>((i >> 48) & 0xff));
|
||||
mData.push_back(static_cast<unsigned char>((i >> 40) & 0xff));
|
||||
mData.push_back(static_cast<unsigned char>((i >> 32) & 0xff));
|
||||
mData.push_back(static_cast<unsigned char>((i >> 24) & 0xff));
|
||||
mData.push_back(static_cast<unsigned char>((i >> 16) & 0xff));
|
||||
mData.push_back(static_cast<unsigned char>((i >> 8) & 0xff));
|
||||
mData.push_back(static_cast<unsigned char>(i & 0xff));
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename Integer>
|
||||
int addInteger(Integer);
|
||||
@@ -300,7 +333,8 @@ Serializer::addVL(Iter begin, Iter end, int len)
|
||||
len -= begin->size();
|
||||
#endif
|
||||
}
|
||||
assert(len == 0);
|
||||
XRPL_ASSERT(
|
||||
len == 0, "ripple::Serializer::addVL : length matches distance");
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -353,9 +387,13 @@ public:
|
||||
|
||||
std::uint32_t
|
||||
get32();
|
||||
std::int32_t
|
||||
geti32();
|
||||
|
||||
std::uint64_t
|
||||
get64();
|
||||
std::int64_t
|
||||
geti64();
|
||||
|
||||
template <std::size_t Bits, class Tag = void>
|
||||
base_uint<Bits, Tag>
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
#ifndef RIPPLE_PROTOCOL_SYSTEMPARAMETERS_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_SYSTEMPARAMETERS_H_INCLUDED
|
||||
|
||||
#include <xrpl/basics/XRPAmount.h>
|
||||
#include <xrpl/basics/chrono.h>
|
||||
#include <xrpl/protocol/XRPAmount.h>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
|
||||
@@ -119,6 +119,8 @@ enum TEMcodes : TERUnderlyingType {
|
||||
temINVALID_ACCOUNT_ID,
|
||||
temCANNOT_PREAUTH_SELF,
|
||||
temINVALID_COUNT,
|
||||
temHOOK_DATA_TOO_LARGE,
|
||||
temHOOK_REJECTED,
|
||||
|
||||
temUNCERTAIN, // An internal intermediate result; should never be returned.
|
||||
temUNKNOWN, // An internal intermediate result; should never be returned.
|
||||
@@ -225,6 +227,8 @@ enum TERcodes : TERUnderlyingType {
|
||||
terQUEUED, // Transaction is being held in TxQ until fee drops
|
||||
terPRE_TICKET, // Ticket is not yet in ledger but might be on its way
|
||||
terNO_AMM, // AMM doesn't exist for the asset pair
|
||||
terNO_HOOK // Transaction requires a non-existent hook definition
|
||||
// (referenced by sfHookHash)
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -344,6 +348,8 @@ enum TECcodes : TERUnderlyingType {
|
||||
tecARRAY_TOO_LARGE = 191,
|
||||
tecLOCKED = 192,
|
||||
tecBAD_CREDENTIALS = 193,
|
||||
tecREQUIRES_FLAG = 194,
|
||||
tecPRECISION_LOSS = 195,
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@@ -83,9 +83,7 @@ constexpr std::uint32_t asfGlobalFreeze = 7;
|
||||
constexpr std::uint32_t asfDefaultRipple = 8;
|
||||
constexpr std::uint32_t asfDepositAuth = 9;
|
||||
constexpr std::uint32_t asfAuthorizedNFTokenMinter = 10;
|
||||
/* // reserved for Hooks amendment
|
||||
constexpr std::uint32_t asfTshCollect = 11;
|
||||
*/
|
||||
constexpr std::uint32_t asfDisallowIncomingNFTokenOffer = 12;
|
||||
constexpr std::uint32_t asfDisallowIncomingCheck = 13;
|
||||
constexpr std::uint32_t asfDisallowIncomingPayChan = 14;
|
||||
|
||||
@@ -74,9 +74,6 @@ enum TxType : std::uint16_t
|
||||
|
||||
/** This identifier was never used, but the slot is reserved for historical purposes. */
|
||||
ttSPINAL_TAP [[deprecated("This transaction type is not supported and should not be used.")]] = 11,
|
||||
|
||||
/** This transaction type installs a hook. */
|
||||
ttHOOK_SET [[maybe_unused]] = 22,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
|
||||
@@ -75,6 +75,9 @@ public:
|
||||
return mIndex;
|
||||
}
|
||||
|
||||
void
|
||||
setResult(TER res, int index);
|
||||
|
||||
void
|
||||
setAffectedNode(uint256 const&, SField const& type, std::uint16_t nodeType);
|
||||
STObject&
|
||||
@@ -113,10 +116,30 @@ public:
|
||||
mDelivered = delivered;
|
||||
}
|
||||
|
||||
STArray const&
|
||||
getHookExecutions() const
|
||||
{
|
||||
return *mHookExecutions;
|
||||
}
|
||||
|
||||
void
|
||||
setHookExecutions(STArray const& hookExecutions)
|
||||
{
|
||||
mHookExecutions = hookExecutions;
|
||||
}
|
||||
|
||||
bool
|
||||
hasHookExecutions() const
|
||||
{
|
||||
return static_cast<bool>(mHookExecutions);
|
||||
}
|
||||
|
||||
STAmount
|
||||
getDeliveredAmount() const
|
||||
{
|
||||
assert(hasDeliveredAmount());
|
||||
XRPL_ASSERT(
|
||||
hasDeliveredAmount(),
|
||||
"ripple::TxMeta::getDeliveredAmount : non-null delivered amount");
|
||||
return *mDelivered;
|
||||
}
|
||||
|
||||
@@ -133,6 +156,7 @@ private:
|
||||
int mResult;
|
||||
|
||||
std::optional<STAmount> mDelivered;
|
||||
std::optional<STArray> mHookExecutions;
|
||||
|
||||
STArray mNodes;
|
||||
};
|
||||
|
||||
@@ -82,6 +82,12 @@ isXRP(Currency const& c)
|
||||
return c == beast::zero;
|
||||
}
|
||||
|
||||
inline bool
|
||||
isFakeXRP(Currency const& c)
|
||||
{
|
||||
return c == badCurrency();
|
||||
}
|
||||
|
||||
/** Returns "", "XRP", or three letter ISO code. */
|
||||
std::string
|
||||
to_string(Currency const& c);
|
||||
|
||||
@@ -17,13 +17,14 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_BASICS_XRPAMOUNT_H_INCLUDED
|
||||
#define RIPPLE_BASICS_XRPAMOUNT_H_INCLUDED
|
||||
#ifndef RIPPLE_PROTOCOL_XRPAMOUNT_H_INCLUDED
|
||||
#define RIPPLE_PROTOCOL_XRPAMOUNT_H_INCLUDED
|
||||
|
||||
#include <xrpl/basics/Number.h>
|
||||
#include <xrpl/basics/contract.h>
|
||||
#include <xrpl/basics/safe_cast.h>
|
||||
#include <xrpl/beast/utility/Zero.h>
|
||||
#include <xrpl/json/json_value.h>
|
||||
#include <xrpl/protocol/FeeUnits.h>
|
||||
|
||||
#include <boost/multiprecision/cpp_int.hpp>
|
||||
#include <boost/operators.hpp>
|
||||
@@ -35,14 +36,6 @@
|
||||
|
||||
namespace ripple {
|
||||
|
||||
namespace feeunit {
|
||||
|
||||
/** "drops" are the smallest divisible amount of XRP. This is what most
|
||||
of the code uses. */
|
||||
struct dropTag;
|
||||
|
||||
} // namespace feeunit
|
||||
|
||||
class XRPAmount : private boost::totally_ordered<XRPAmount>,
|
||||
private boost::additive<XRPAmount>,
|
||||
private boost::equality_comparable<XRPAmount, std::int64_t>,
|
||||
@@ -61,6 +54,11 @@ public:
|
||||
constexpr XRPAmount&
|
||||
operator=(XRPAmount const& other) = default;
|
||||
|
||||
// Round to nearest, even on tie.
|
||||
explicit XRPAmount(Number const& x) : XRPAmount(static_cast<value_type>(x))
|
||||
{
|
||||
}
|
||||
|
||||
constexpr XRPAmount(beast::Zero) : drops_(0)
|
||||
{
|
||||
}
|
||||
@@ -162,6 +160,11 @@ public:
|
||||
return drops_ != 0;
|
||||
}
|
||||
|
||||
operator Number() const noexcept
|
||||
{
|
||||
return drops();
|
||||
}
|
||||
|
||||
/** Return the sign of the amount */
|
||||
constexpr int
|
||||
signum() const noexcept
|
||||
@@ -21,12 +21,12 @@
|
||||
#define RIPPLE_PROTOCOL_B58_UTILS_H_INCLUDED
|
||||
|
||||
#include <xrpl/basics/contract.h>
|
||||
#include <xrpl/beast/utility/instrumentation.h>
|
||||
#include <xrpl/protocol/detail/token_errors.h>
|
||||
|
||||
#include <boost/outcome.hpp>
|
||||
#include <boost/outcome/result.hpp>
|
||||
|
||||
#include <cassert>
|
||||
#include <cinttypes>
|
||||
#include <span>
|
||||
#include <system_error>
|
||||
@@ -130,7 +130,9 @@ inplace_bigint_div_rem(std::span<uint64_t> numerator, std::uint64_t divisor)
|
||||
{
|
||||
// should never happen, but if it does then it seems natural to define
|
||||
// the a null set of numbers to be zero, so the remainder is also zero.
|
||||
assert(0);
|
||||
UNREACHABLE(
|
||||
"ripple::b58_fast::detail::inplace_bigint_div_rem : empty "
|
||||
"numerator");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -146,8 +148,14 @@ inplace_bigint_div_rem(std::span<uint64_t> numerator, std::uint64_t divisor)
|
||||
unsigned __int128 const denom128 = denom;
|
||||
unsigned __int128 const d = num / denom128;
|
||||
unsigned __int128 const r = num - (denom128 * d);
|
||||
assert(d >> 64 == 0);
|
||||
assert(r >> 64 == 0);
|
||||
XRPL_ASSERT(
|
||||
d >> 64 == 0,
|
||||
"ripple::b58_fast::detail::inplace_bigint_div_rem::div_rem_64 : "
|
||||
"valid division result");
|
||||
XRPL_ASSERT(
|
||||
r >> 64 == 0,
|
||||
"ripple::b58_fast::detail::inplace_bigint_div_rem::div_rem_64 : "
|
||||
"valid remainder");
|
||||
return {static_cast<std::uint64_t>(d), static_cast<std::uint64_t>(r)};
|
||||
};
|
||||
|
||||
@@ -169,8 +177,11 @@ inplace_bigint_div_rem(std::span<uint64_t> numerator, std::uint64_t divisor)
|
||||
[[nodiscard]] inline std::array<std::uint8_t, 10>
|
||||
b58_10_to_b58_be(std::uint64_t input)
|
||||
{
|
||||
constexpr std::uint64_t B_58_10 = 430804206899405824; // 58^10;
|
||||
assert(input < B_58_10);
|
||||
[[maybe_unused]] static constexpr std::uint64_t B_58_10 =
|
||||
430804206899405824; // 58^10;
|
||||
XRPL_ASSERT(
|
||||
input < B_58_10,
|
||||
"ripple::b58_fast::detail::b58_10_to_b58_be : valid input");
|
||||
constexpr std::size_t resultSize = 10;
|
||||
std::array<std::uint8_t, resultSize> result{};
|
||||
int i = 0;
|
||||
|
||||
@@ -29,12 +29,14 @@
|
||||
// If you add an amendment here, then do not forget to increment `numFeatures`
|
||||
// in include/xrpl/protocol/Feature.h.
|
||||
|
||||
XRPL_FEATURE(Hooks, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(PaychanAndEscrowForTokens, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(Credentials, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(AMMClawback, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (AMMv1_2, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(MPTokensV1, Supported::yes, VoteBehavior::DefaultNo)
|
||||
// InvariantsV1_1 will be changes to Supported::yes when all the
|
||||
// invariants expected to be included under it are complete.
|
||||
XRPL_FEATURE(MPTokensV1, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(InvariantsV1_1, Supported::no, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (NFTokenPageLinks, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (InnerObjTemplate2, Supported::yes, VoteBehavior::DefaultNo)
|
||||
|
||||
@@ -62,6 +62,32 @@ LEDGER_ENTRY(ltCHECK, 0x0043, Check, ({
|
||||
{sfPreviousTxnLgrSeq, soeREQUIRED},
|
||||
}))
|
||||
|
||||
LEDGER_ENTRY(ltHOOK_DEFINITION, 0x0044, HookDefinition, ({
|
||||
{sfHookHash, soeREQUIRED},
|
||||
{sfHookOn, soeREQUIRED},
|
||||
{sfHookNamespace, soeREQUIRED},
|
||||
{sfHookParameters, soeREQUIRED},
|
||||
{sfHookApiVersion, soeREQUIRED},
|
||||
{sfCreateCode, soeREQUIRED},
|
||||
{sfHookSetTxnID, soeREQUIRED},
|
||||
{sfReferenceCount, soeREQUIRED},
|
||||
{sfFee, soeREQUIRED},
|
||||
{sfHookCallbackFee, soeOPTIONAL}
|
||||
}))
|
||||
|
||||
LEDGER_ENTRY(ltEMITTED, 0x0045, Emitted, ({
|
||||
{sfEmittedTxn, soeOPTIONAL},
|
||||
{sfOwnerNode, soeREQUIRED},
|
||||
}))
|
||||
|
||||
LEDGER_ENTRY(ltHOOK, 0x0048, Hook, ({
|
||||
{sfAccount, soeOPTIONAL},
|
||||
{sfOwnerNode, soeREQUIRED},
|
||||
{sfPreviousTxnID, soeREQUIRED},
|
||||
{sfPreviousTxnLgrSeq, soeREQUIRED},
|
||||
{sfHooks, soeREQUIRED}
|
||||
}))
|
||||
|
||||
/** The ledger object which tracks the DID.
|
||||
|
||||
\sa keylet::did
|
||||
@@ -155,6 +181,8 @@ LEDGER_ENTRY(ltACCOUNT_ROOT, 0x0061, AccountRoot, ({
|
||||
{sfBurnedNFTokens, soeDEFAULT},
|
||||
{sfFirstNFTokenSequence, soeOPTIONAL},
|
||||
{sfAMMID, soeOPTIONAL},
|
||||
{sfHookStateCount, soeOPTIONAL},
|
||||
{sfHookNamespaces, soeOPTIONAL},
|
||||
}))
|
||||
|
||||
/** A ledger object which contains a list of object identifiers.
|
||||
@@ -169,6 +197,7 @@ LEDGER_ENTRY(ltDIR_NODE, 0x0064, DirectoryNode, ({
|
||||
{sfTakerGetsCurrency, soeOPTIONAL}, // order book directories
|
||||
{sfTakerGetsIssuer, soeOPTIONAL}, // order book directories
|
||||
{sfExchangeRate, soeOPTIONAL}, // order book directories
|
||||
{sfReferenceCount, soeOPTIONAL}, // for hook state directories
|
||||
{sfIndexes, soeREQUIRED},
|
||||
{sfRootIndex, soeREQUIRED},
|
||||
{sfIndexNext, soeOPTIONAL},
|
||||
@@ -286,6 +315,8 @@ LEDGER_ENTRY(ltRIPPLE_STATE, 0x0072, RippleState, ({
|
||||
{sfHighNode, soeOPTIONAL},
|
||||
{sfHighQualityIn, soeOPTIONAL},
|
||||
{sfHighQualityOut, soeOPTIONAL},
|
||||
{sfLockedBalance, soeOPTIONAL},
|
||||
{sfLockCount, soeOPTIONAL},
|
||||
}))
|
||||
|
||||
/** The ledger object which lists the network's fee settings.
|
||||
@@ -341,6 +372,12 @@ LEDGER_ENTRY(ltESCROW, 0x0075, Escrow, ({
|
||||
{sfDestinationNode, soeOPTIONAL},
|
||||
}))
|
||||
|
||||
LEDGER_ENTRY(ltHOOK_STATE, 0x0076, HookState, ({
|
||||
{sfOwnerNode, soeREQUIRED},
|
||||
{sfHookStateKey, soeREQUIRED},
|
||||
{sfHookStateData, soeREQUIRED},
|
||||
}))
|
||||
|
||||
/** A ledger object describing a single unidirectional XRP payment channel.
|
||||
|
||||
\sa keylet::payChan
|
||||
|
||||
@@ -108,7 +108,7 @@ TYPED_SFIELD(sfMintedNFTokens, UINT32, 43)
|
||||
TYPED_SFIELD(sfBurnedNFTokens, UINT32, 44)
|
||||
TYPED_SFIELD(sfHookStateCount, UINT32, 45)
|
||||
TYPED_SFIELD(sfEmitGeneration, UINT32, 46)
|
||||
// 47 reserved for Hooks
|
||||
TYPED_SFIELD(sfLockCount, UINT32, 47)
|
||||
TYPED_SFIELD(sfVoteWeight, UINT32, 48)
|
||||
TYPED_SFIELD(sfFirstNFTokenSequence, UINT32, 50)
|
||||
TYPED_SFIELD(sfOracleDocumentID, UINT32, 51)
|
||||
@@ -190,6 +190,12 @@ TYPED_SFIELD(sfHookStateKey, UINT256, 30)
|
||||
TYPED_SFIELD(sfHookHash, UINT256, 31)
|
||||
TYPED_SFIELD(sfHookNamespace, UINT256, 32)
|
||||
TYPED_SFIELD(sfHookSetTxnID, UINT256, 33)
|
||||
TYPED_SFIELD(sfOfferID, UINT256, 34)
|
||||
TYPED_SFIELD(sfEscrowID, UINT256, 35)
|
||||
|
||||
|
||||
// number (common)
|
||||
TYPED_SFIELD(sfNumber, NUMBER, 1)
|
||||
|
||||
// currency amount (common)
|
||||
TYPED_SFIELD(sfAmount, AMOUNT, 1)
|
||||
@@ -211,8 +217,8 @@ TYPED_SFIELD(sfMinimumOffer, AMOUNT, 16)
|
||||
TYPED_SFIELD(sfRippleEscrow, AMOUNT, 17)
|
||||
TYPED_SFIELD(sfDeliveredAmount, AMOUNT, 18)
|
||||
TYPED_SFIELD(sfNFTokenBrokerFee, AMOUNT, 19)
|
||||
|
||||
// Reserve 20 & 21 for Hooks.
|
||||
TYPED_SFIELD(sfHookCallbackFee, AMOUNT, 20)
|
||||
TYPED_SFIELD(sfLockedBalance, AMOUNT, 21)
|
||||
|
||||
// currency amount (fees)
|
||||
TYPED_SFIELD(sfBaseFeeDrops, AMOUNT, 22)
|
||||
@@ -291,6 +297,7 @@ TYPED_SFIELD(sfHashes, VECTOR256, 2)
|
||||
TYPED_SFIELD(sfAmendments, VECTOR256, 3)
|
||||
TYPED_SFIELD(sfNFTokenOffers, VECTOR256, 4)
|
||||
TYPED_SFIELD(sfCredentialIDs, VECTOR256, 5)
|
||||
TYPED_SFIELD(sfHookNamespaces, VECTOR256, 6)
|
||||
|
||||
// path set
|
||||
UNTYPED_SFIELD(sfPaths, PATHSET, 1)
|
||||
|
||||
@@ -54,6 +54,7 @@ TRANSACTION(ttESCROW_CREATE, 1, EscrowCreate, ({
|
||||
TRANSACTION(ttESCROW_FINISH, 2, EscrowFinish, ({
|
||||
{sfOwner, soeREQUIRED},
|
||||
{sfOfferSequence, soeREQUIRED},
|
||||
{sfEscrowID, soeOPTIONAL}, // keylet as alternative to offerseq
|
||||
{sfFulfillment, soeOPTIONAL},
|
||||
{sfCondition, soeOPTIONAL},
|
||||
{sfCredentialIDs, soeOPTIONAL},
|
||||
@@ -78,6 +79,7 @@ TRANSACTION(ttACCOUNT_SET, 3, AccountSet, ({
|
||||
TRANSACTION(ttESCROW_CANCEL, 4, EscrowCancel, ({
|
||||
{sfOwner, soeREQUIRED},
|
||||
{sfOfferSequence, soeREQUIRED},
|
||||
{sfEscrowID, soeOPTIONAL}, // keylet as alternative to offerseq
|
||||
}))
|
||||
|
||||
/** This transaction type sets or clears an account's "regular key". */
|
||||
@@ -93,11 +95,13 @@ TRANSACTION(ttOFFER_CREATE, 7, OfferCreate, ({
|
||||
{sfTakerGets, soeREQUIRED},
|
||||
{sfExpiration, soeOPTIONAL},
|
||||
{sfOfferSequence, soeOPTIONAL},
|
||||
{sfOfferID, soeOPTIONAL}, // keylet as alternative to offerseq
|
||||
}))
|
||||
|
||||
/** This transaction type cancels existing offers to trade one asset for another. */
|
||||
TRANSACTION(ttOFFER_CANCEL, 8, OfferCancel, ({
|
||||
{sfOfferSequence, soeREQUIRED},
|
||||
{sfOfferID, soeOPTIONAL}, // keylet as alternative to offerseq
|
||||
}))
|
||||
|
||||
// 9 deprecated
|
||||
@@ -187,7 +191,10 @@ TRANSACTION(ttACCOUNT_DELETE, 21, AccountDelete, ({
|
||||
{sfCredentialIDs, soeOPTIONAL},
|
||||
}))
|
||||
|
||||
// 22 reserved
|
||||
/** This transaction type installs a hook. */
|
||||
TRANSACTION(ttHOOK_SET, 22, SetHook, ({
|
||||
{sfHooks, soeREQUIRED},
|
||||
}))
|
||||
|
||||
/** This transaction mints a new NFT. */
|
||||
TRANSACTION(ttNFTOKEN_MINT, 25, NFTokenMint, ({
|
||||
@@ -484,3 +491,7 @@ TRANSACTION(ttUNL_MODIFY, 102, UNLModify, ({
|
||||
{sfUNLModifyValidator, soeREQUIRED},
|
||||
}))
|
||||
|
||||
TRANSACTION(ttEMIT_FAILURE, 103, EmitFailure, ({
|
||||
{sfLedgerSequence, soeREQUIRED},
|
||||
{sfTransactionHash, soeREQUIRED},
|
||||
}))
|
||||
|
||||
@@ -69,12 +69,16 @@ JSS(DeliverMax); // out: alias to Amount
|
||||
JSS(DeliverMin); // in: TransactionSign
|
||||
JSS(Destination); // in: TransactionSign; field.
|
||||
JSS(DirectoryNode); // ledger type.
|
||||
JSS(Emitted); // ledger type.
|
||||
JSS(EPrice); // in: AMM Deposit option
|
||||
JSS(Escrow); // ledger type.
|
||||
JSS(Fee); // in/out: TransactionSign; field.
|
||||
JSS(FeeSettings); // ledger type.
|
||||
JSS(Flags); // in/out: TransactionSign; field.
|
||||
JSS(Holder); // field.
|
||||
JSS(Hook); // ledger type.
|
||||
JSS(HookState); // ledger type.
|
||||
JSS(HookDefinition);
|
||||
JSS(Invalid); //
|
||||
JSS(Issuer); // in: Credential transactions
|
||||
JSS(LastLedgerSequence); // in: TransactionSign; field
|
||||
@@ -303,6 +307,7 @@ JSS(features); // out: Feature
|
||||
JSS(fee); // out: NetworkOPs, Peers
|
||||
JSS(fee_base); // out: NetworkOPs
|
||||
JSS(fee_div_max); // in: TransactionSign
|
||||
JSS(fee_hooks_drops); // out: Fee rpc call
|
||||
JSS(fee_level); // out: AccountInfo
|
||||
JSS(fee_mult_max); // in: TransactionSign
|
||||
JSS(fee_ref); // out: NetworkOPs, DEPRECATED
|
||||
@@ -332,6 +337,7 @@ JSS(high); // out: BookChanges
|
||||
JSS(highest_sequence); // out: AccountInfo
|
||||
JSS(highest_ticket); // out: AccountInfo
|
||||
JSS(historical_perminute); // historical_perminute.
|
||||
JSS(hook_hash); // in: LedgerEntry
|
||||
JSS(holders); // out: MPTHolders
|
||||
JSS(hostid); // out: NetworkOPs
|
||||
JSS(hotwallet); // in: GatewayBalances
|
||||
@@ -456,6 +462,8 @@ JSS(minimum_fee); // out: TxQ
|
||||
JSS(minimum_level); // out: TxQ
|
||||
JSS(missingCommand); // error
|
||||
JSS(name); // out: AmendmentTableImpl, PeerImp
|
||||
JSS(namespace_entries); // out: AccountNamespace
|
||||
JSS(namespace_id); // in/out: AccountNamespace
|
||||
JSS(needed_state_hashes); // out: InboundLedger
|
||||
JSS(needed_transaction_hashes); // out: InboundLedger
|
||||
JSS(network_id); // out: NetworkOPs
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <xrpl/protocol/STBlob.h>
|
||||
#include <xrpl/protocol/STInteger.h>
|
||||
#include <xrpl/protocol/STLedgerEntry.h>
|
||||
#include <xrpl/protocol/STNumber.h>
|
||||
#include <xrpl/protocol/STObject.h>
|
||||
#include <xrpl/protocol/STParsedJSON.h>
|
||||
#include <xrpl/protocol/STPathSet.h>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user