Add Antithesis intrumentation (#5042)

* Copy Antithesis SDK version 0.4.0 to directory external/
* Add build option `voidstar` to enable instrumentation with Antithesis SDK
* Define instrumentation macros ASSERT and UNREACHABLE in terms of regular C assert
* Replace asserts with named ASSERT or UNREACHABLE
* Add UNREACHABLE to LogicError
* Document instrumentation macros in CONTRIBUTING.md
This commit is contained in:
Bronek Kozicki
2024-12-03 14:52:21 -05:00
committed by Ed Hennis
parent f64cf9187a
commit d7e949193f
261 changed files with 3827 additions and 1034 deletions

View File

@@ -73,6 +73,7 @@ set(SECP256K1_INSTALL TRUE)
add_subdirectory(external/secp256k1) add_subdirectory(external/secp256k1)
add_library(secp256k1::secp256k1 ALIAS secp256k1) add_library(secp256k1::secp256k1 ALIAS secp256k1)
add_subdirectory(external/ed25519-donna) add_subdirectory(external/ed25519-donna)
add_subdirectory(external/antithesis-sdk)
find_package(gRPC REQUIRED) find_package(gRPC REQUIRED)
find_package(lz4 REQUIRED) find_package(lz4 REQUIRED)
# Target names with :: are not allowed in a generator expression. # Target names with :: are not allowed in a generator expression.

View File

@@ -343,6 +343,68 @@ pip3 install pre-commit
pre-commit install 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 `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 `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 `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 ## Unit Tests
To execute all unit tests: To execute all unit tests:

View File

@@ -120,7 +120,7 @@ else ()
target_link_libraries (common target_link_libraries (common
INTERFACE INTERFACE
-rdynamic -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: # link to static libc/c++ iff:
# * static option set and # * static option set and
# * NOT APPLE (AppleClang does not support static libc/c++) and # * NOT APPLE (AppleClang does not support static libc/c++) and
@@ -131,6 +131,17 @@ else ()
>) >)
endif () 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) if (use_mold)
# use mold linker if available # use mold linker if available
execute_process ( execute_process (

View File

@@ -74,6 +74,7 @@ target_compile_definitions(xrpl.libxrpl
target_compile_options(xrpl.libxrpl target_compile_options(xrpl.libxrpl
PUBLIC PUBLIC
$<$<BOOL:${is_gcc}>:-Wno-maybe-uninitialized> $<$<BOOL:${is_gcc}>:-Wno-maybe-uninitialized>
$<$<BOOL:${voidstar}>:-DENABLE_VOIDSTAR>
) )
target_link_libraries(xrpl.libxrpl target_link_libraries(xrpl.libxrpl
@@ -89,6 +90,7 @@ target_link_libraries(xrpl.libxrpl
secp256k1::secp256k1 secp256k1::secp256k1
xrpl.libpb xrpl.libpb
xxHash::xxhash xxHash::xxhash
$<$<BOOL:${voidstar}>:antithesis-sdk-cpp>
) )
if(xrpld) if(xrpld)
@@ -129,6 +131,19 @@ if(xrpld)
target_compile_definitions(rippled PRIVATE RIPPLED_RUNNING_IN_CI) target_compile_definitions(rippled PRIVATE RIPPLED_RUNNING_IN_CI)
endif () 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 # any files that don't play well with unity should be added here
if(tests) if(tests)
set_source_files_properties( set_source_files_properties(

View File

@@ -10,6 +10,7 @@ install (
ripple_boost ripple_boost
xrpl.libpb xrpl.libpb
xrpl.libxrpl xrpl.libxrpl
antithesis-sdk-cpp
EXPORT RippleExports EXPORT RippleExports
LIBRARY DESTINATION lib LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib ARCHIVE DESTINATION lib

View File

@@ -18,6 +18,9 @@ if(unity)
set(CMAKE_UNITY_BUILD_BATCH_SIZE 15 CACHE STRING "") set(CMAKE_UNITY_BUILD_BATCH_SIZE 15 CACHE STRING "")
endif() endif()
endif() endif()
if(is_clang AND is_linux)
option(voidstar "Enable Antithesis instrumentation." OFF)
endif()
if(is_gcc OR is_clang) if(is_gcc OR is_clang)
option(coverage "Generates coverage info." OFF) option(coverage "Generates coverage info." OFF)
option(profile "Add profiling flags" OFF) option(profile "Add profiling flags" OFF)

1
external/README.md vendored
View File

@@ -6,6 +6,7 @@ The Conan recipes include patches we have not yet pushed upstream.
| Folder | Upstream | Description | | 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 | | `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.) | | `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 | | `secp256k1` | [Project](https://github.com/bitcoin-core/secp256k1) | ECDSA digital signatures using the **secp256k1** curve |

3
external/antithesis-sdk/.clang-format vendored Normal file
View File

@@ -0,0 +1,3 @@
---
DisableFormat: true
SortIncludes: false

17
external/antithesis-sdk/CMakeLists.txt vendored Normal file
View 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.2 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

Binary file not shown.

8
external/antithesis-sdk/README.md vendored Normal file
View 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.html)

View 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.html.
*/
#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

1093
external/antithesis-sdk/antithesis_sdk.h vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -21,7 +21,7 @@
#define RIPPLE_BASICS_BUFFER_H_INCLUDED #define RIPPLE_BASICS_BUFFER_H_INCLUDED
#include <xrpl/basics/Slice.h> #include <xrpl/basics/Slice.h>
#include <cassert> #include <xrpl/beast/utility/instrumentation.h>
#include <cstdint> #include <cstdint>
#include <cstring> #include <cstring>
#include <memory> #include <memory>
@@ -112,9 +112,10 @@ public:
operator=(Slice s) operator=(Slice s)
{ {
// Ensure the slice isn't a subset of the buffer. // Ensure the slice isn't a subset of the buffer.
assert( ASSERT(
s.size() == 0 || size_ == 0 || s.data() < p_.get() || 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())) if (auto p = alloc(s.size()))
std::memcpy(p, s.data(), s.size()); std::memcpy(p, s.data(), s.size());

View File

@@ -20,16 +20,16 @@
#define BASICS_FEES_H_INCLUDED #define BASICS_FEES_H_INCLUDED
#include <xrpl/basics/XRPAmount.h> #include <xrpl/basics/XRPAmount.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <boost/multiprecision/cpp_int.hpp> #include <boost/multiprecision/cpp_int.hpp>
#include <limits>
#include <utility>
#include <cassert>
#include <cmath> #include <cmath>
#include <ios> #include <ios>
#include <iosfwd> #include <iosfwd>
#include <limits>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <utility>
namespace ripple { namespace ripple {
@@ -419,9 +419,13 @@ mulDivU(Source1 value, Dest mul, Source2 div)
{ {
// split the asserts so if one hits, the user can tell which // split the asserts so if one hits, the user can tell which
// without a debugger. // without a debugger.
assert(value.value() >= 0); ASSERT(
assert(mul.value() >= 0); value.value() >= 0,
assert(div.value() >= 0); "ripple::feeunit::mulDivU : minimum value input");
ASSERT(
mul.value() >= 0, "ripple::feeunit::mulDivU : minimum mul input");
ASSERT(
div.value() >= 0, "ripple::feeunit::mulDivU : minimum div input");
return std::nullopt; return std::nullopt;
} }

View File

@@ -43,7 +43,7 @@ namespace ripple {
constexpr std::size_t constexpr std::size_t
calculatePercent(std::size_t count, std::size_t total) calculatePercent(std::size_t count, std::size_t total)
{ {
assert(total != 0); assert(total != 0); // NOTE No ASSERT here, because constexpr
return ((std::min(count, total) * 100) + total - 1) / total; return ((std::min(count, total) * 100) + total - 1) / total;
} }

View File

@@ -20,7 +20,9 @@
#ifndef RIPPLE_BASICS_SLABALLOCATOR_H_INCLUDED #ifndef RIPPLE_BASICS_SLABALLOCATOR_H_INCLUDED
#define 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/type_name.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <boost/align.hpp> #include <boost/align.hpp>
#include <boost/container/static_vector.hpp> #include <boost/container/static_vector.hpp>
@@ -28,10 +30,10 @@
#include <algorithm> #include <algorithm>
#include <atomic> #include <atomic>
#include <cassert>
#include <cstdint> #include <cstdint>
#include <cstring> #include <cstring>
#include <mutex> #include <mutex>
#include <vector>
#if BOOST_OS_LINUX #if BOOST_OS_LINUX
#include <sys/mman.h> #include <sys/mman.h>
@@ -141,7 +143,9 @@ class SlabAllocator
void void
deallocate(std::uint8_t* ptr) noexcept deallocate(std::uint8_t* ptr) noexcept
{ {
assert(own(ptr)); ASSERT(
own(ptr),
"ripple::SlabAllocator::SlabBlock::deallocate : own input");
std::lock_guard l(m_); std::lock_guard l(m_);
@@ -184,7 +188,9 @@ public:
boost::alignment::align_up(sizeof(Type) + extra, itemAlignment_)) boost::alignment::align_up(sizeof(Type) + extra, itemAlignment_))
, slabSize_(alloc) , slabSize_(alloc)
{ {
assert((itemAlignment_ & (itemAlignment_ - 1)) == 0); ASSERT(
(itemAlignment_ & (itemAlignment_ - 1)) == 0,
"ripple::SlabAllocator::SlabAllocator : valid alignment");
} }
SlabAllocator(SlabAllocator const& other) = delete; SlabAllocator(SlabAllocator const& other) = delete;
@@ -294,7 +300,10 @@ public:
bool bool
deallocate(std::uint8_t* ptr) noexcept deallocate(std::uint8_t* ptr) noexcept
{ {
assert(ptr); ASSERT(
ptr != nullptr,
"ripple::SlabAllocator::SlabAllocator::deallocate : non-null "
"input");
for (auto slab = slabs_.load(); slab != nullptr; slab = slab->next_) for (auto slab = slabs_.load(); slab != nullptr; slab = slab->next_)
{ {

View File

@@ -22,9 +22,9 @@
#include <xrpl/basics/contract.h> #include <xrpl/basics/contract.h>
#include <xrpl/basics/strHex.h> #include <xrpl/basics/strHex.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <algorithm> #include <algorithm>
#include <array> #include <array>
#include <cassert>
#include <cstdint> #include <cstdint>
#include <cstring> #include <cstring>
#include <limits> #include <limits>
@@ -103,7 +103,9 @@ public:
std::uint8_t std::uint8_t
operator[](std::size_t i) const noexcept operator[](std::size_t i) const noexcept
{ {
assert(i < size_); ASSERT(
i < size_,
"ripple::Slice::operator[](std::size_t) const : valid input");
return data_[i]; return data_[i];
} }

View File

@@ -31,6 +31,7 @@
#include <xrpl/basics/hardened_hash.h> #include <xrpl/basics/hardened_hash.h>
#include <xrpl/basics/strHex.h> #include <xrpl/basics/strHex.h>
#include <xrpl/beast/utility/Zero.h> #include <xrpl/beast/utility/Zero.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <boost/endian/conversion.hpp> #include <boost/endian/conversion.hpp>
#include <boost/functional/hash.hpp> #include <boost/functional/hash.hpp>
#include <algorithm> #include <algorithm>
@@ -289,7 +290,9 @@ public:
std::is_trivially_copyable<typename Container::value_type>::value>> std::is_trivially_copyable<typename Container::value_type>::value>>
explicit base_uint(Container const& c) explicit base_uint(Container const& c)
{ {
assert(c.size() * sizeof(typename Container::value_type) == size()); 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()); std::memcpy(data_.data(), c.data(), size());
} }
@@ -300,7 +303,9 @@ public:
base_uint&> base_uint&>
operator=(Container const& c) operator=(Container const& c)
{ {
assert(c.size() * sizeof(typename Container::value_type) == size()); 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()); std::memcpy(data_.data(), c.data(), size());
return *this; return *this;
} }

View File

@@ -20,7 +20,7 @@
#ifndef RIPPLE_BASICS_PARTITIONED_UNORDERED_MAP_H #ifndef RIPPLE_BASICS_PARTITIONED_UNORDERED_MAP_H
#define RIPPLE_BASICS_PARTITIONED_UNORDERED_MAP_H #define RIPPLE_BASICS_PARTITIONED_UNORDERED_MAP_H
#include <cassert> #include <xrpl/beast/utility/instrumentation.h>
#include <functional> #include <functional>
#include <optional> #include <optional>
#include <thread> #include <thread>
@@ -246,7 +246,10 @@ public:
? *partitions ? *partitions
: std::thread::hardware_concurrency(); : std::thread::hardware_concurrency();
map_.resize(partitions_); map_.resize(partitions_);
assert(partitions_); ASSERT(
partitions_ != 0,
"ripple::partitioned_unordered_map::partitioned_unordered_map : "
"nonzero partitions");
} }
std::size_t std::size_t

View File

@@ -20,8 +20,8 @@
#ifndef RIPPLE_BASICS_RANDOM_H_INCLUDED #ifndef RIPPLE_BASICS_RANDOM_H_INCLUDED
#define 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 <xrpl/beast/xor_shift_engine.h>
#include <cassert>
#include <cstddef> #include <cstddef>
#include <cstdint> #include <cstdint>
#include <cstring> #include <cstring>
@@ -114,7 +114,7 @@ std::enable_if_t<
Integral> Integral>
rand_int(Engine& engine, Integral min, Integral max) rand_int(Engine& engine, Integral min, Integral max)
{ {
assert(max > min); ASSERT(max > min, "ripple::rand_int : max over min inputs");
// This should have no state and constructing it should // This should have no state and constructing it should
// be very cheap. If that turns out not to be the case // be very cheap. If that turns out not to be the case

View File

@@ -20,6 +20,8 @@
#ifndef RIPPLE_BASICS_SCOPE_H_INCLUDED #ifndef RIPPLE_BASICS_SCOPE_H_INCLUDED
#define RIPPLE_BASICS_SCOPE_H_INCLUDED #define RIPPLE_BASICS_SCOPE_H_INCLUDED
#include <xrpl/beast/utility/instrumentation.h>
#include <exception> #include <exception>
#include <mutex> #include <mutex>
#include <type_traits> #include <type_traits>
@@ -233,7 +235,9 @@ public:
explicit scope_unlock(std::unique_lock<Mutex>& lock) noexcept(true) explicit scope_unlock(std::unique_lock<Mutex>& lock) noexcept(true)
: plock(&lock) : plock(&lock)
{ {
assert(plock->owns_lock()); ASSERT(
plock->owns_lock(),
"ripple::scope_unlock::scope_unlock : mutex must be locked");
plock->unlock(); plock->unlock();
} }

View File

@@ -18,8 +18,8 @@
#ifndef RIPPLE_BASICS_SPINLOCK_H_INCLUDED #ifndef RIPPLE_BASICS_SPINLOCK_H_INCLUDED
#define RIPPLE_BASICS_SPINLOCK_H_INCLUDED #define RIPPLE_BASICS_SPINLOCK_H_INCLUDED
#include <xrpl/beast/utility/instrumentation.h>
#include <atomic> #include <atomic>
#include <cassert>
#include <limits> #include <limits>
#include <type_traits> #include <type_traits>
@@ -117,7 +117,9 @@ public:
packed_spinlock(std::atomic<T>& lock, int index) packed_spinlock(std::atomic<T>& lock, int index)
: bits_(lock), mask_(static_cast<T>(1) << index) : bits_(lock), mask_(static_cast<T>(1) << index)
{ {
assert(index >= 0 && (mask_ != 0)); ASSERT(
index >= 0 && (mask_ != 0),
"ripple::packed_spinlock::packed_spinlock : valid index and mask");
} }
[[nodiscard]] bool [[nodiscard]] bool

View File

@@ -20,8 +20,10 @@
#ifndef BEAST_ASIO_IO_LATENCY_PROBE_H_INCLUDED #ifndef BEAST_ASIO_IO_LATENCY_PROBE_H_INCLUDED
#define 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/basic_waitable_timer.hpp>
#include <boost/asio/io_service.hpp> #include <boost/asio/io_service.hpp>
#include <chrono> #include <chrono>
#include <condition_variable> #include <condition_variable>
#include <mutex> #include <mutex>
@@ -172,7 +174,10 @@ private:
, m_repeat(repeat) , m_repeat(repeat)
, m_probe(probe) , m_probe(probe)
{ {
assert(m_probe); ASSERT(
m_probe != nullptr,
"beast::io_latency_probe::sample_op::sample_op : non-null "
"probe input");
m_probe->addref(); m_probe->addref();
} }
@@ -182,7 +187,10 @@ private:
, m_repeat(from.m_repeat) , m_repeat(from.m_repeat)
, m_probe(from.m_probe) , m_probe(from.m_probe)
{ {
assert(m_probe); ASSERT(
m_probe != nullptr,
"beast::io_latency_probe::sample_op::sample_op(sample_op&&) : "
"non-null probe input");
from.m_probe = nullptr; from.m_probe = nullptr;
} }

View File

@@ -21,7 +21,7 @@
#define BEAST_CHRONO_MANUAL_CLOCK_H_INCLUDED #define BEAST_CHRONO_MANUAL_CLOCK_H_INCLUDED
#include <xrpl/beast/clock/abstract_clock.h> #include <xrpl/beast/clock/abstract_clock.h>
#include <cassert> #include <xrpl/beast/utility/instrumentation.h>
namespace beast { namespace beast {
@@ -61,7 +61,9 @@ public:
void void
set(time_point const& when) set(time_point const& when)
{ {
assert(!Clock::is_steady || when >= now_); ASSERT(
!Clock::is_steady || when >= now_,
"beast::manual_clock::set(time_point) : forward input");
now_ = when; now_ = when;
} }
@@ -78,7 +80,9 @@ public:
void void
advance(std::chrono::duration<Rep, Period> const& elapsed) advance(std::chrono::duration<Rep, Period> const& elapsed)
{ {
assert(!Clock::is_steady || (now_ + elapsed) >= now_); ASSERT(
!Clock::is_steady || (now_ + elapsed) >= now_,
"beast::manual_clock::advance(duration) : forward input");
now_ += elapsed; now_ += elapsed;
} }

View File

@@ -1330,7 +1330,10 @@ public:
size_type size_type
bucket(Key const& k) const bucket(Key const& k) const
{ {
assert(bucket_count() != 0); ASSERT(
bucket_count() != 0,
"beast::detail::aged_unordered_container::bucket : nonzero bucket "
"count");
return m_cont.bucket(k, std::cref(m_config.hash_function())); return m_cont.bucket(k, std::cref(m_config.hash_function()));
} }
@@ -1471,7 +1474,10 @@ private:
{ {
if (would_exceed(additional)) if (would_exceed(additional))
m_buck.resize(size() + additional, m_cont); m_buck.resize(size() + additional, m_cont);
assert(load_factor() <= max_load_factor()); ASSERT(
load_factor() <= max_load_factor(),
"beast::detail::aged_unordered_container::maybe_rehash : maximum "
"load factor");
} }
// map, set // map, set

View File

@@ -20,9 +20,10 @@
#ifndef BEAST_MODULE_CORE_TEXT_LEXICALCAST_H_INCLUDED #ifndef BEAST_MODULE_CORE_TEXT_LEXICALCAST_H_INCLUDED
#define 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 <boost/core/detail/string_view.hpp>
#include <algorithm> #include <algorithm>
#include <cassert>
#include <cerrno> #include <cerrno>
#include <charconv> #include <charconv>
#include <cstdlib> #include <cstdlib>
@@ -159,7 +160,9 @@ struct LexicalCast<Out, char const*>
bool bool
operator()(Out& out, char const* in) const operator()(Out& out, char const* in) const
{ {
assert(in); ASSERT(
in != nullptr,
"beast::detail::LexicalCast(char const*) : non-null input");
return LexicalCast<Out, std::string_view>()(out, in); return LexicalCast<Out, std::string_view>()(out, in);
} }
}; };
@@ -174,7 +177,9 @@ struct LexicalCast<Out, char*>
bool bool
operator()(Out& out, char* in) const operator()(Out& out, char* in) const
{ {
assert(in); ASSERT(
in != nullptr,
"beast::detail::LexicalCast(char*) : non-null input");
return LexicalCast<Out, std::string_view>()(out, in); return LexicalCast<Out, std::string_view>()(out, in);
} }
}; };

View File

@@ -24,9 +24,9 @@
#include <xrpl/beast/hash/uhash.h> #include <xrpl/beast/hash/uhash.h>
#include <xrpl/beast/net/IPAddressV4.h> #include <xrpl/beast/net/IPAddressV4.h>
#include <xrpl/beast/net/IPAddressV6.h> #include <xrpl/beast/net/IPAddressV6.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <boost/asio/ip/address.hpp> #include <boost/asio/ip/address.hpp>
#include <boost/functional/hash.hpp> #include <boost/functional/hash.hpp>
#include <cassert>
#include <cstdint> #include <cstdint>
#include <ios> #include <ios>
#include <sstream> #include <sstream>
@@ -96,7 +96,7 @@ hash_append(Hasher& h, beast::IP::Address const& addr) noexcept
else if (addr.is_v6()) else if (addr.is_v6())
hash_append(h, addr.to_v6().to_bytes()); hash_append(h, addr.to_v6().to_bytes());
else else
assert(false); UNREACHABLE("beast::hash_append : invalid address type");
} }
} // namespace beast } // namespace beast

View File

@@ -20,8 +20,8 @@
#ifndef BEAST_NET_IPADDRESSV6_H_INCLUDED #ifndef BEAST_NET_IPADDRESSV6_H_INCLUDED
#define 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 <boost/asio/ip/address_v6.hpp>
#include <cassert>
#include <cstdint> #include <cstdint>
#include <functional> #include <functional>
#include <ios> #include <ios>

View File

@@ -20,7 +20,7 @@
#ifndef BEAST_UTILITY_JOURNAL_H_INCLUDED #ifndef BEAST_UTILITY_JOURNAL_H_INCLUDED
#define BEAST_UTILITY_JOURNAL_H_INCLUDED #define BEAST_UTILITY_JOURNAL_H_INCLUDED
#include <cassert> #include <xrpl/beast/utility/instrumentation.h>
#include <sstream> #include <sstream>
namespace beast { namespace beast {
@@ -205,7 +205,9 @@ public:
*/ */
Stream(Sink& sink, Severity level) : m_sink(sink), m_level(level) Stream(Sink& sink, Severity level) : m_sink(sink), m_level(level)
{ {
assert(m_level < severities::kDisabled); ASSERT(
m_level < severities::kDisabled,
"beast::Journal::Stream::Stream : maximum level");
} }
/** Construct or copy another Stream. */ /** Construct or copy another Stream. */

View File

@@ -0,0 +1,64 @@
//------------------------------------------------------------------------------
/*
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
#define ALWAYS(cond, name, ...) assert((name) && (cond))
#define ALWAYS_OR_UNREACHABLE(cond, name, ...) assert((name) && (cond))
#define SOMETIMES(cond, name, ...)
#define REACHABLE(name, ...)
#define UNREACHABLE(name, ...) assert((name) && false)
#endif
#define ASSERT ALWAYS_OR_UNREACHABLE
// How to use the instrumentation macros:
//
// ALWAYS if cond must be true and the line must be reached during fuzzing
// ASSERT if cond must be true but the line might not be reached during fuzzing
// 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)
//
// NOTE: ASSERT has similar semantics as C assert macro, with minor differences:
// * ASSERT must have an unique name (naming convention in CONTRIBUTING.md)
// * the condition (which comes first) must be *implicitly* convertible to bool
// * during fuzzing, the program will continue execution past a failed 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 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 describe the condition that is
// meant to happen (e.g. as in "assert that this happens").
#endif

View File

@@ -20,8 +20,8 @@
#ifndef BEAST_RANDOM_RNGFILL_H_INCLUDED #ifndef BEAST_RANDOM_RNGFILL_H_INCLUDED
#define BEAST_RANDOM_RNGFILL_H_INCLUDED #define BEAST_RANDOM_RNGFILL_H_INCLUDED
#include <xrpl/beast/utility/instrumentation.h>
#include <array> #include <array>
#include <cassert>
#include <cstdint> #include <cstdint>
#include <cstring> #include <cstring>
#include <type_traits> #include <type_traits>
@@ -42,7 +42,8 @@ rngfill(void* buffer, std::size_t bytes, Generator& g)
bytes -= sizeof(v); bytes -= sizeof(v);
} }
assert(bytes < sizeof(result_type)); ASSERT(
bytes < sizeof(result_type), "beast::rngfill(void*) : maximum bytes");
#ifdef __GNUC__ #ifdef __GNUC__
// gcc 11.1 (falsely) warns about an array-bounds overflow in release mode. // gcc 11.1 (falsely) warns about an array-bounds overflow in release mode.

View File

@@ -22,9 +22,6 @@
#include <xrpl/json/json_errors.h> #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) \ #define JSON_ASSERT_MESSAGE(condition, message) \
if (!(condition)) \ if (!(condition)) \
ripple::Throw<Json::error>(message); ripple::Throw<Json::error>(message);

View File

@@ -53,7 +53,9 @@ toSTAmount(XRPAmount const& xrp)
inline STAmount inline STAmount
toSTAmount(XRPAmount const& xrp, Issue const& iss) toSTAmount(XRPAmount const& xrp, Issue const& iss)
{ {
assert(isXRP(iss.account) && isXRP(iss.currency)); ASSERT(
isXRP(iss.account) && isXRP(iss.currency),
"ripple::toSTAmount : is XRP");
return toSTAmount(xrp); return toSTAmount(xrp);
} }
@@ -72,12 +74,14 @@ template <>
inline IOUAmount inline IOUAmount
toAmount<IOUAmount>(STAmount const& amt) toAmount<IOUAmount>(STAmount const& amt)
{ {
assert(amt.mantissa() < std::numeric_limits<std::int64_t>::max()); ASSERT(
amt.mantissa() < std::numeric_limits<std::int64_t>::max(),
"ripple::toAmount<IOUAmount> : maximum mantissa");
bool const isNeg = amt.negative(); bool const isNeg = amt.negative();
std::int64_t const sMant = std::int64_t const sMant =
isNeg ? -std::int64_t(amt.mantissa()) : amt.mantissa(); isNeg ? -std::int64_t(amt.mantissa()) : amt.mantissa();
assert(!isXRP(amt)); ASSERT(!isXRP(amt), "ripple::toAmount<IOUAmount> : is not XRP");
return IOUAmount(sMant, amt.exponent()); return IOUAmount(sMant, amt.exponent());
} }
@@ -85,12 +89,14 @@ template <>
inline XRPAmount inline XRPAmount
toAmount<XRPAmount>(STAmount const& amt) toAmount<XRPAmount>(STAmount const& amt)
{ {
assert(amt.mantissa() < std::numeric_limits<std::int64_t>::max()); ASSERT(
amt.mantissa() < std::numeric_limits<std::int64_t>::max(),
"ripple::toAmount<XRPAmount> : maximum mantissa");
bool const isNeg = amt.negative(); bool const isNeg = amt.negative();
std::int64_t const sMant = std::int64_t const sMant =
isNeg ? -std::int64_t(amt.mantissa()) : amt.mantissa(); isNeg ? -std::int64_t(amt.mantissa()) : amt.mantissa();
assert(isXRP(amt)); ASSERT(isXRP(amt), "ripple::toAmount<XRPAmount> : is XRP");
return XRPAmount(sMant); return XRPAmount(sMant);
} }

View File

@@ -151,14 +151,19 @@ public:
explicit FeatureBitset(base const& b) : base(b) explicit FeatureBitset(base const& b) : base(b)
{ {
assert(b.count() == count()); ASSERT(
b.count() == count(),
"ripple::FeatureBitset::FeatureBitset(base) : count match");
} }
template <class... Fs> template <class... Fs>
explicit FeatureBitset(uint256 const& f, Fs&&... fs) explicit FeatureBitset(uint256 const& f, Fs&&... fs)
{ {
initFromFeatures(f, std::forward<Fs>(fs)...); initFromFeatures(f, std::forward<Fs>(fs)...);
assert(count() == (sizeof...(fs) + 1)); ASSERT(
count() == (sizeof...(fs) + 1),
"ripple::FeatureBitset::FeatureBitset(uint256) : count and "
"sizeof... do match");
} }
template <class Col> template <class Col>
@@ -166,7 +171,10 @@ public:
{ {
for (auto const& f : fs) for (auto const& f : fs)
set(featureToBitsetIndex(f)); set(featureToBitsetIndex(f));
assert(fs.size() == count()); ASSERT(
fs.size() == count(),
"ripple::FeatureBitset::FeatureBitset(Container auto) : count and "
"size do match");
} }
auto auto

View File

@@ -220,7 +220,7 @@ page(uint256 const& root, std::uint64_t index = 0) noexcept;
inline Keylet inline Keylet
page(Keylet const& root, std::uint64_t index = 0) noexcept page(Keylet const& root, std::uint64_t index = 0) noexcept
{ {
assert(root.type == ltDIR_NODE); ASSERT(root.type == ltDIR_NODE, "ripple::keylet::page : valid root type");
return page(root.key, index); return page(root.key, index);
} }
/** @} */ /** @} */

View File

@@ -20,10 +20,10 @@
#ifndef RIPPLE_PROTOCOL_ISSUE_H_INCLUDED #ifndef RIPPLE_PROTOCOL_ISSUE_H_INCLUDED
#define 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/json/json_value.h>
#include <xrpl/protocol/UintTypes.h> #include <xrpl/protocol/UintTypes.h>
#include <cassert>
#include <functional> #include <functional>
#include <type_traits> #include <type_traits>

View File

@@ -23,8 +23,8 @@
#include <xrpl/json/json_value.h> #include <xrpl/json/json_value.h>
#include <xrpl/protocol/ApiVersion.h> #include <xrpl/protocol/ApiVersion.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <array> #include <array>
#include <cassert>
#include <concepts> #include <concepts>
#include <cstdlib> #include <cstdlib>
#include <functional> #include <functional>
@@ -159,8 +159,10 @@ struct MultiApiJson
-> std:: -> std::
invoke_result_t<Fn, decltype(json.val[0]), Version, Args&&...> invoke_result_t<Fn, decltype(json.val[0]), Version, Args&&...>
{ {
assert( ASSERT(
valid(version) && index(version) >= 0 && index(version) < size); valid(version) && index(version) >= 0 && index(version) < size,
"ripple::detail::MultiApiJson::operator<Args...>() : valid "
"version");
return std::invoke( return std::invoke(
fn, fn,
json.val[index(version)], json.val[index(version)],
@@ -177,8 +179,9 @@ struct MultiApiJson
operator()(Json& json, Version version, Fn fn) const operator()(Json& json, Version version, Fn fn) const
-> std::invoke_result_t<Fn, decltype(json.val[0])> -> std::invoke_result_t<Fn, decltype(json.val[0])>
{ {
assert( ASSERT(
valid(version) && index(version) >= 0 && index(version) < size); valid(version) && index(version) >= 0 && index(version) < size,
"ripple::detail::MultiApiJson::operator() : valid version");
return std::invoke(fn, json.val[index(version)]); return std::invoke(fn, json.val[index(version)]);
} }
} visitor = {}; } visitor = {};

View File

@@ -298,7 +298,9 @@ public:
friend double friend double
relativeDistance(Quality const& q1, Quality const& q2) relativeDistance(Quality const& q1, Quality const& q2)
{ {
assert(q1.m_value > 0 && q2.m_value > 0); 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 if (q1.m_value == q2.m_value) // make expected common case fast
return 0; return 0;

View File

@@ -20,9 +20,9 @@
#ifndef RIPPLE_PROTOCOL_RATE_H_INCLUDED #ifndef RIPPLE_PROTOCOL_RATE_H_INCLUDED
#define RIPPLE_PROTOCOL_RATE_H_INCLUDED #define RIPPLE_PROTOCOL_RATE_H_INCLUDED
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/protocol/STAmount.h> #include <xrpl/protocol/STAmount.h>
#include <boost/operators.hpp> #include <boost/operators.hpp>
#include <cassert>
#include <cstdint> #include <cstdint>
#include <ostream> #include <ostream>

View File

@@ -26,6 +26,7 @@
#include <xrpl/basics/MPTAmount.h> #include <xrpl/basics/MPTAmount.h>
#include <xrpl/basics/Number.h> #include <xrpl/basics/Number.h>
#include <xrpl/basics/XRPAmount.h> #include <xrpl/basics/XRPAmount.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/protocol/Asset.h> #include <xrpl/protocol/Asset.h>
#include <xrpl/protocol/SField.h> #include <xrpl/protocol/SField.h>
#include <xrpl/protocol/STBase.h> #include <xrpl/protocol/STBase.h>
@@ -353,7 +354,10 @@ STAmount::STAmount(
, mIsNegative(negative) , mIsNegative(negative)
{ {
// mValue is uint64, but needs to fit in the range of int64 // mValue is uint64, but needs to fit in the range of int64
assert(mValue <= std::numeric_limits<std::int64_t>::max()); ASSERT(
mValue <= std::numeric_limits<std::int64_t>::max(),
"ripple::STAmount::STAmount(SField, A, std::uint64_t, int, bool) : "
"maximum mantissa input");
canonicalize(); canonicalize();
} }

View File

@@ -170,8 +170,10 @@ template <int Bits>
void void
STBitString<Bits>::add(Serializer& s) const STBitString<Bits>::add(Serializer& s) const
{ {
assert(getFName().isBinary()); ASSERT(getFName().isBinary(), "ripple::STBitString::add : field is binary");
assert(getFName().fieldType == getSType()); ASSERT(
getFName().fieldType == getSType(),
"ripple::STBitString::add : field type match");
s.addBitString<Bits>(value_); s.addBitString<Bits>(value_);
} }

View File

@@ -23,9 +23,9 @@
#include <xrpl/basics/Buffer.h> #include <xrpl/basics/Buffer.h>
#include <xrpl/basics/CountedObject.h> #include <xrpl/basics/CountedObject.h>
#include <xrpl/basics/Slice.h> #include <xrpl/basics/Slice.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/protocol/STBase.h> #include <xrpl/protocol/STBase.h>
#include <cassert>
#include <cstring> #include <cstring>
#include <memory> #include <memory>

View File

@@ -110,8 +110,10 @@ template <typename Integer>
inline void inline void
STInteger<Integer>::add(Serializer& s) const STInteger<Integer>::add(Serializer& s) const
{ {
assert(getFName().isBinary()); ASSERT(getFName().isBinary(), "ripple::STInteger::add : field is binary");
assert(getFName().fieldType == getSType()); ASSERT(
getFName().fieldType == getSType(),
"ripple::STInteger::add : field type match");
s.addInteger(value_); s.addInteger(value_);
} }

View File

@@ -25,6 +25,7 @@
#include <xrpl/basics/Slice.h> #include <xrpl/basics/Slice.h>
#include <xrpl/basics/chrono.h> #include <xrpl/basics/chrono.h>
#include <xrpl/basics/contract.h> #include <xrpl/basics/contract.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/protocol/HashPrefix.h> #include <xrpl/protocol/HashPrefix.h>
#include <xrpl/protocol/SOTemplate.h> #include <xrpl/protocol/SOTemplate.h>
#include <xrpl/protocol/STAmount.h> #include <xrpl/protocol/STAmount.h>
@@ -35,7 +36,6 @@
#include <xrpl/protocol/STVector256.h> #include <xrpl/protocol/STVector256.h>
#include <xrpl/protocol/detail/STVar.h> #include <xrpl/protocol/detail/STVar.h>
#include <boost/iterator/transform_iterator.hpp> #include <boost/iterator/transform_iterator.hpp>
#include <cassert>
#include <optional> #include <optional>
#include <stdexcept> #include <stdexcept>
#include <type_traits> #include <type_traits>
@@ -737,7 +737,8 @@ STObject::Proxy<T>::assign(U&& u)
t = dynamic_cast<T*>(st_->getPField(*f_, true)); t = dynamic_cast<T*>(st_->getPField(*f_, true));
else else
t = dynamic_cast<T*>(st_->makeFieldPresent(*f_)); t = dynamic_cast<T*>(st_->makeFieldPresent(*f_));
assert(t); ASSERT(
t != nullptr, "ripple::STObject::Proxy::assign : type cast succeeded");
*t = std::forward<U>(u); *t = std::forward<U>(u);
} }
@@ -1033,13 +1034,19 @@ STObject::at(TypedField<T> const& f) const
if (auto const u = dynamic_cast<T const*>(b)) if (auto const u = dynamic_cast<T const*>(b))
return u->value(); return u->value();
assert(mType); ASSERT(
assert(b->getSType() == STI_NOTPRESENT); mType != nullptr,
"ripple::STObject::at(TypedField auto) : field template non-null");
ASSERT(
b->getSType() == STI_NOTPRESENT,
"ripple::STObject::at(TypedField auto) : type not present");
if (mType->style(f) == soeOPTIONAL) if (mType->style(f) == soeOPTIONAL)
Throw<STObject::FieldErr>("Missing optional field: " + f.getName()); Throw<STObject::FieldErr>("Missing optional field: " + f.getName());
assert(mType->style(f) == soeDEFAULT); 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, // Used to help handle the case where value_type is a const reference,
// otherwise we would return the address of a temporary. // otherwise we would return the address of a temporary.
@@ -1057,11 +1064,19 @@ STObject::at(OptionaledField<T> const& of) const
auto const u = dynamic_cast<T const*>(b); auto const u = dynamic_cast<T const*>(b);
if (!u) if (!u)
{ {
assert(mType); ASSERT(
assert(b->getSType() == STI_NOTPRESENT); mType != nullptr,
"ripple::STObject::at(OptionaledField auto) : field template "
"non-null");
ASSERT(
b->getSType() == STI_NOTPRESENT,
"ripple::STObject::at(OptionaledField auto) : type not present");
if (mType->style(*of.f) == soeOPTIONAL) if (mType->style(*of.f) == soeOPTIONAL)
return std::nullopt; return std::nullopt;
assert(mType->style(*of.f) == soeDEFAULT); ASSERT(
mType->style(*of.f) == soeDEFAULT,
"ripple::STObject::at(OptionaledField auto) : template style is "
"default");
return typename T::value_type{}; return typename T::value_type{};
} }
return u->value(); return u->value();

View File

@@ -21,11 +21,11 @@
#define RIPPLE_PROTOCOL_STPATHSET_H_INCLUDED #define RIPPLE_PROTOCOL_STPATHSET_H_INCLUDED
#include <xrpl/basics/CountedObject.h> #include <xrpl/basics/CountedObject.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/json/json_value.h> #include <xrpl/json/json_value.h>
#include <xrpl/protocol/SField.h> #include <xrpl/protocol/SField.h>
#include <xrpl/protocol/STBase.h> #include <xrpl/protocol/STBase.h>
#include <xrpl/protocol/UintTypes.h> #include <xrpl/protocol/UintTypes.h>
#include <cassert>
#include <cstddef> #include <cstddef>
#include <optional> #include <optional>
@@ -257,7 +257,9 @@ inline STPathElement::STPathElement(
is_offer_ = false; is_offer_ = false;
mAccountID = *account; mAccountID = *account;
mType |= typeAccount; mType |= typeAccount;
assert(mAccountID != noAccount()); ASSERT(
mAccountID != noAccount(),
"ripple::STPathElement::STPathElement : account is set");
} }
if (currency) if (currency)
@@ -270,7 +272,9 @@ inline STPathElement::STPathElement(
{ {
mIssuerID = *issuer; mIssuerID = *issuer;
mType |= typeIssuer; mType |= typeIssuer;
assert(mIssuerID != noAccount()); ASSERT(
mIssuerID != noAccount(),
"ripple::STPathElement::STPathElement : issuer is set");
} }
hash_value_ = get_hash(*this); hash_value_ = get_hash(*this);

View File

@@ -22,10 +22,10 @@
#include <xrpl/basics/FeeUnits.h> #include <xrpl/basics/FeeUnits.h>
#include <xrpl/basics/Log.h> #include <xrpl/basics/Log.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/protocol/PublicKey.h> #include <xrpl/protocol/PublicKey.h>
#include <xrpl/protocol/STObject.h> #include <xrpl/protocol/STObject.h>
#include <xrpl/protocol/SecretKey.h> #include <xrpl/protocol/SecretKey.h>
#include <cassert>
#include <cstdint> #include <cstdint>
#include <functional> #include <functional>
#include <memory> #include <memory>
@@ -176,7 +176,9 @@ STValidation::STValidation(
Throw<std::runtime_error>("Invalid signature in validation"); Throw<std::runtime_error>("Invalid signature in validation");
} }
assert(nodeID_.isNonZero()); ASSERT(
nodeID_.isNonZero(),
"ripple::STValidation::STValidation(SerialIter) : nonzero node");
} }
/** Construct, sign and trust a new STValidation issued by this node. /** Construct, sign and trust a new STValidation issued by this node.
@@ -199,7 +201,10 @@ STValidation::STValidation(
, nodeID_(nodeID) , nodeID_(nodeID)
, seenTime_(signTime) , seenTime_(signTime)
{ {
assert(nodeID_.isNonZero()); ASSERT(
nodeID_.isNonZero(),
"ripple::STValidation::STValidation(PublicKey, SecretKey) : nonzero "
"node");
// First, set our own public key: // First, set our own public key:
if (publicKeyType(pk) != KeyType::secp256k1) if (publicKeyType(pk) != KeyType::secp256k1)

View File

@@ -27,9 +27,9 @@
#include <xrpl/basics/contract.h> #include <xrpl/basics/contract.h>
#include <xrpl/basics/safe_cast.h> #include <xrpl/basics/safe_cast.h>
#include <xrpl/basics/strHex.h> #include <xrpl/basics/strHex.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/protocol/HashPrefix.h> #include <xrpl/protocol/HashPrefix.h>
#include <xrpl/protocol/SField.h> #include <xrpl/protocol/SField.h>
#include <cassert>
#include <cstdint> #include <cstdint>
#include <cstring> #include <cstring>
#include <iomanip> #include <iomanip>
@@ -55,7 +55,9 @@ public:
if (size) if (size)
{ {
assert(data != nullptr); ASSERT(
data != nullptr,
"ripple::Serializer::Serializer(void const*) : non-null input");
std::memcpy(mData.data(), data, size); std::memcpy(mData.data(), data, size);
} }
} }
@@ -331,7 +333,7 @@ Serializer::addVL(Iter begin, Iter end, int len)
len -= begin->size(); len -= begin->size();
#endif #endif
} }
assert(len == 0); ASSERT(len == 0, "ripple::Serializer::addVL : length matches distance");
return ret; return ret;
} }

View File

@@ -116,7 +116,9 @@ public:
STAmount STAmount
getDeliveredAmount() const getDeliveredAmount() const
{ {
assert(hasDeliveredAmount()); ASSERT(
hasDeliveredAmount(),
"ripple::TxMeta::getDeliveredAmount : non-null delivered amount");
return *mDelivered; return *mDelivered;
} }

View File

@@ -21,12 +21,12 @@
#define RIPPLE_PROTOCOL_B58_UTILS_H_INCLUDED #define RIPPLE_PROTOCOL_B58_UTILS_H_INCLUDED
#include <xrpl/basics/contract.h> #include <xrpl/basics/contract.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/protocol/detail/token_errors.h> #include <xrpl/protocol/detail/token_errors.h>
#include <boost/outcome.hpp> #include <boost/outcome.hpp>
#include <boost/outcome/result.hpp> #include <boost/outcome/result.hpp>
#include <cassert>
#include <cinttypes> #include <cinttypes>
#include <span> #include <span>
#include <system_error> #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 // 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. // 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; 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 denom128 = denom;
unsigned __int128 const d = num / denom128; unsigned __int128 const d = num / denom128;
unsigned __int128 const r = num - (denom128 * d); unsigned __int128 const r = num - (denom128 * d);
assert(d >> 64 == 0); ASSERT(
assert(r >> 64 == 0); d >> 64 == 0,
"ripple::b58_fast::detail::inplace_bigint_div_rem::div_rem_64 : "
"valid division result");
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)}; return {static_cast<std::uint64_t>(d), static_cast<std::uint64_t>(r)};
}; };
@@ -170,7 +178,9 @@ inplace_bigint_div_rem(std::span<uint64_t> numerator, std::uint64_t divisor)
b58_10_to_b58_be(std::uint64_t input) b58_10_to_b58_be(std::uint64_t input)
{ {
constexpr std::uint64_t B_58_10 = 430804206899405824; // 58^10; constexpr std::uint64_t B_58_10 = 430804206899405824; // 58^10;
assert(input < B_58_10); ASSERT(
input < B_58_10,
"ripple::b58_fast::detail::b58_10_to_b58_be : valid input");
constexpr std::size_t resultSize = 10; constexpr std::size_t resultSize = 10;
std::array<std::uint8_t, resultSize> result{}; std::array<std::uint8_t, resultSize> result{};
int i = 0; int i = 0;

View File

@@ -23,9 +23,9 @@
#include <xrpl/basics/DecayingSample.h> #include <xrpl/basics/DecayingSample.h>
#include <xrpl/beast/clock/abstract_clock.h> #include <xrpl/beast/clock/abstract_clock.h>
#include <xrpl/beast/core/List.h> #include <xrpl/beast/core/List.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/resource/detail/Key.h> #include <xrpl/resource/detail/Key.h>
#include <xrpl/resource/detail/Tuning.h> #include <xrpl/resource/detail/Tuning.h>
#include <cassert>
namespace ripple { namespace ripple {
namespace Resource { namespace Resource {

View File

@@ -21,8 +21,8 @@
#define RIPPLE_RESOURCE_KEY_H_INCLUDED #define RIPPLE_RESOURCE_KEY_H_INCLUDED
#include <xrpl/beast/net/IPEndpoint.h> #include <xrpl/beast/net/IPEndpoint.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/resource/detail/Kind.h> #include <xrpl/resource/detail/Kind.h>
#include <cassert>
namespace ripple { namespace ripple {
namespace Resource { namespace Resource {

View File

@@ -26,12 +26,12 @@
#include <xrpl/beast/clock/abstract_clock.h> #include <xrpl/beast/clock/abstract_clock.h>
#include <xrpl/beast/insight/Insight.h> #include <xrpl/beast/insight/Insight.h>
#include <xrpl/beast/utility/PropertyStream.h> #include <xrpl/beast/utility/PropertyStream.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/json/json_value.h> #include <xrpl/json/json_value.h>
#include <xrpl/protocol/jss.h> #include <xrpl/protocol/jss.h>
#include <xrpl/resource/Fees.h> #include <xrpl/resource/Fees.h>
#include <xrpl/resource/Gossip.h> #include <xrpl/resource/Gossip.h>
#include <xrpl/resource/detail/Import.h> #include <xrpl/resource/detail/Import.h>
#include <cassert>
#include <mutex> #include <mutex>
namespace ripple { namespace ripple {
@@ -401,7 +401,9 @@ public:
{ {
std::lock_guard _(lock_); std::lock_guard _(lock_);
Entry& entry(iter->second); Entry& entry(iter->second);
assert(entry.refcount == 0); ASSERT(
entry.refcount == 0,
"ripple::Resource::Logic::erase : entry not used");
inactive_.erase(inactive_.iterator_to(entry)); inactive_.erase(inactive_.iterator_to(entry));
table_.erase(iter); table_.erase(iter);
} }
@@ -433,7 +435,9 @@ public:
admin_.erase(admin_.iterator_to(entry)); admin_.erase(admin_.iterator_to(entry));
break; break;
default: default:
assert(false); UNREACHABLE(
"ripple::Resource::Logic::release : invalid entry "
"kind");
break; break;
} }
inactive_.push_back(entry); inactive_.push_back(entry);

View File

@@ -22,6 +22,7 @@
#include <xrpl/basics/Log.h> #include <xrpl/basics/Log.h>
#include <xrpl/beast/net/IPAddressConversion.h> #include <xrpl/beast/net/IPAddressConversion.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/server/Session.h> #include <xrpl/server/Session.h>
#include <xrpl/server/detail/io_list.h> #include <xrpl/server/detail/io_list.h>
#include <boost/asio/ip/tcp.hpp> #include <boost/asio/ip/tcp.hpp>
@@ -34,7 +35,6 @@
#include <boost/beast/http/parser.hpp> #include <boost/beast/http/parser.hpp>
#include <boost/beast/http/read.hpp> #include <boost/beast/http/read.hpp>
#include <atomic> #include <atomic>
#include <cassert>
#include <chrono> #include <chrono>
#include <functional> #include <functional>
#include <memory> #include <memory>

View File

@@ -21,12 +21,12 @@
#define RIPPLE_SERVER_BASEPEER_H_INCLUDED #define RIPPLE_SERVER_BASEPEER_H_INCLUDED
#include <xrpl/beast/utility/WrappedSink.h> #include <xrpl/beast/utility/WrappedSink.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/server/Port.h> #include <xrpl/server/Port.h>
#include <xrpl/server/detail/LowestLayer.h> #include <xrpl/server/detail/LowestLayer.h>
#include <xrpl/server/detail/io_list.h> #include <xrpl/server/detail/io_list.h>
#include <boost/asio.hpp> #include <boost/asio.hpp>
#include <atomic> #include <atomic>
#include <cassert>
#include <functional> #include <functional>
#include <string> #include <string>

View File

@@ -21,17 +21,21 @@
#define RIPPLE_SERVER_BASEWSPEER_H_INCLUDED #define RIPPLE_SERVER_BASEWSPEER_H_INCLUDED
#include <xrpl/basics/safe_cast.h> #include <xrpl/basics/safe_cast.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/beast/utility/rngfill.h> #include <xrpl/beast/utility/rngfill.h>
#include <xrpl/crypto/csprng.h> #include <xrpl/crypto/csprng.h>
#include <xrpl/protocol/BuildInfo.h> #include <xrpl/protocol/BuildInfo.h>
#include <xrpl/server/WSSession.h>
#include <xrpl/server/detail/BasePeer.h> #include <xrpl/server/detail/BasePeer.h>
#include <xrpl/server/detail/LowestLayer.h> #include <xrpl/server/detail/LowestLayer.h>
#include <boost/beast/core/multi_buffer.hpp> #include <boost/beast/core/multi_buffer.hpp>
#include <boost/beast/http/message.hpp> #include <boost/beast/http/message.hpp>
#include <boost/beast/websocket.hpp> #include <boost/beast/websocket.hpp>
#include <boost/logic/tribool.hpp>
#include <cassert>
#include <functional> #include <functional>
#include <list>
namespace ripple { namespace ripple {
@@ -508,7 +512,9 @@ template <class String>
void void
BaseWSPeer<Handler, Impl>::fail(error_code ec, String const& what) BaseWSPeer<Handler, Impl>::fail(error_code ec, String const& what)
{ {
assert(strand_.running_in_this_thread()); ASSERT(
strand_.running_in_this_thread(),
"ripple::BaseWSPeer::fail : strand in this thread");
cancel_timer(); cancel_timer();
if (!ec_ && ec != boost::asio::error::operation_aborted) if (!ec_ && ec != boost::asio::error::operation_aborted)

View File

@@ -20,8 +20,8 @@
#include <xrpl/basics/Log.h> #include <xrpl/basics/Log.h>
#include <xrpl/basics/chrono.h> #include <xrpl/basics/chrono.h>
#include <xrpl/basics/contract.h> #include <xrpl/basics/contract.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <cassert>
#include <fstream> #include <fstream>
#include <functional> #include <functional>
#include <iostream> #include <iostream>
@@ -224,7 +224,7 @@ Logs::fromSeverity(beast::severities::Severity level)
return lsERROR; return lsERROR;
default: default:
assert(false); UNREACHABLE("ripple::Logs::fromSeverity : invalid severity");
[[fallthrough]]; [[fallthrough]];
case kFatal: case kFatal:
break; break;
@@ -250,7 +250,7 @@ Logs::toSeverity(LogSeverity level)
case lsERROR: case lsERROR:
return kError; return kError;
default: default:
assert(false); UNREACHABLE("ripple::Logs::toSeverity : invalid severity");
[[fallthrough]]; [[fallthrough]];
case lsFATAL: case lsFATAL:
break; break;
@@ -277,7 +277,7 @@ Logs::toString(LogSeverity s)
case lsFATAL: case lsFATAL:
return "Fatal"; return "Fatal";
default: default:
assert(false); UNREACHABLE("ripple::Logs::toString : invalid severity");
return "Unknown"; return "Unknown";
} }
} }
@@ -341,7 +341,7 @@ Logs::format(
output += "ERR "; output += "ERR ";
break; break;
default: default:
assert(false); UNREACHABLE("ripple::Logs::format : invalid severity");
[[fallthrough]]; [[fallthrough]];
case kFatal: case kFatal:
output += "FTL "; output += "FTL ";

View File

@@ -18,9 +18,9 @@
//============================================================================== //==============================================================================
#include <xrpl/basics/Number.h> #include <xrpl/basics/Number.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <boost/predef.h> #include <boost/predef.h>
#include <algorithm> #include <algorithm>
#include <cassert>
#include <numeric> #include <numeric>
#include <stdexcept> #include <stdexcept>
#include <type_traits> #include <type_traits>
@@ -235,7 +235,9 @@ Number::operator+=(Number const& y)
*this = Number{}; *this = Number{};
return *this; return *this;
} }
assert(isnormal() && y.isnormal()); ASSERT(
isnormal() && y.isnormal(),
"ripple::Number::operator+=(Number) : is normal");
auto xm = mantissa(); auto xm = mantissa();
auto xe = exponent(); auto xe = exponent();
int xn = 1; int xn = 1;
@@ -374,7 +376,9 @@ Number::operator*=(Number const& y)
*this = y; *this = y;
return *this; return *this;
} }
assert(isnormal() && y.isnormal()); ASSERT(
isnormal() && y.isnormal(),
"ripple::Number::operator*=(Number) : is normal");
auto xm = mantissa(); auto xm = mantissa();
auto xe = exponent(); auto xe = exponent();
int xn = 1; int xn = 1;
@@ -428,7 +432,9 @@ Number::operator*=(Number const& y)
std::to_string(xe)); std::to_string(xe));
mantissa_ = xm * zn; mantissa_ = xm * zn;
exponent_ = xe; exponent_ = xe;
assert(isnormal() || *this == Number{}); ASSERT(
isnormal() || *this == Number{},
"ripple::Number::operator*=(Number) : result is normal");
return *this; return *this;
} }
@@ -536,7 +542,7 @@ to_string(Number const& amount)
negative = true; negative = true;
} }
assert(exponent + 43 > 0); ASSERT(exponent + 43 > 0, "ripple::to_string(Number) : minimum exponent");
ptrdiff_t const pad_prefix = 27; ptrdiff_t const pad_prefix = 27;
ptrdiff_t const pad_suffix = 23; ptrdiff_t const pad_suffix = 23;
@@ -562,7 +568,9 @@ to_string(Number const& amount)
if (std::distance(pre_from, pre_to) > pad_prefix) if (std::distance(pre_from, pre_to) > pad_prefix)
pre_from += pad_prefix; pre_from += pad_prefix;
assert(post_to >= post_from); ASSERT(
post_to >= post_from,
"ripple::to_string(Number) : first distance check");
pre_from = std::find_if(pre_from, pre_to, [](char c) { return c != '0'; }); pre_from = std::find_if(pre_from, pre_to, [](char c) { return c != '0'; });
@@ -571,7 +579,9 @@ to_string(Number const& amount)
if (std::distance(post_from, post_to) > pad_suffix) if (std::distance(post_from, post_to) > pad_suffix)
post_to -= pad_suffix; post_to -= pad_suffix;
assert(post_to >= post_from); ASSERT(
post_to >= post_from,
"ripple::to_string(Number) : second distance check");
post_to = std::find_if( post_to = std::find_if(
std::make_reverse_iterator(post_to), std::make_reverse_iterator(post_to),

View File

@@ -21,9 +21,9 @@
#include <xrpl/basics/ResolverAsio.h> #include <xrpl/basics/ResolverAsio.h>
#include <xrpl/beast/net/IPAddressConversion.h> #include <xrpl/beast/net/IPAddressConversion.h>
#include <xrpl/beast/net/IPEndpoint.h> #include <xrpl/beast/net/IPEndpoint.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <boost/asio.hpp> #include <boost/asio.hpp>
#include <atomic> #include <atomic>
#include <cassert>
#include <condition_variable> #include <condition_variable>
#include <deque> #include <deque>
#include <locale> #include <locale>
@@ -48,7 +48,9 @@ public:
~AsyncObject() ~AsyncObject()
{ {
// Destroying the object with I/O pending? Not a clean exit! // Destroying the object with I/O pending? Not a clean exit!
assert(m_pending.load() == 0); ASSERT(
m_pending.load() == 0,
"ripple::AsyncObject::~AsyncObject : nothing pending");
} }
/** RAII container that maintains the count of pending I/O. /** RAII container that maintains the count of pending I/O.
@@ -153,8 +155,11 @@ public:
~ResolverAsioImpl() override ~ResolverAsioImpl() override
{ {
assert(m_work.empty()); ASSERT(
assert(m_stopped); m_work.empty(),
"ripple::ResolverAsioImpl::~ResolverAsioImpl : no pending work");
ASSERT(
m_stopped, "ripple::ResolverAsioImpl::~ResolverAsioImpl : stopped");
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@@ -176,8 +181,10 @@ public:
void void
start() override start() override
{ {
assert(m_stopped == true); ASSERT(m_stopped == true, "ripple::ResolverAsioImpl::start : stopped");
assert(m_stop_called == false); ASSERT(
m_stop_called == false,
"ripple::ResolverAsioImpl::start : not stopping");
if (m_stopped.exchange(false) == true) if (m_stopped.exchange(false) == true)
{ {
@@ -217,8 +224,12 @@ public:
resolve(std::vector<std::string> const& names, HandlerType const& handler) resolve(std::vector<std::string> const& names, HandlerType const& handler)
override override
{ {
assert(m_stop_called == false); ASSERT(
assert(!names.empty()); m_stop_called == false,
"ripple::ResolverAsioImpl::resolve : not stopping");
ASSERT(
!names.empty(),
"ripple::ResolverAsioImpl::resolve : names non-empty");
// TODO NIKB use rvalue references to construct and move // TODO NIKB use rvalue references to construct and move
// reducing cost. // reducing cost.
@@ -235,7 +246,9 @@ public:
void void
do_stop(CompletionCounter) do_stop(CompletionCounter)
{ {
assert(m_stop_called == true); ASSERT(
m_stop_called == true,
"ripple::ResolverAsioImpl::do_stop : stopping");
if (m_stopped.exchange(true) == false) if (m_stopped.exchange(true) == false)
{ {
@@ -381,7 +394,9 @@ public:
HandlerType const& handler, HandlerType const& handler,
CompletionCounter) CompletionCounter)
{ {
assert(!names.empty()); ASSERT(
!names.empty(),
"ripple::ResolverAsioImpl::do_resolve : names non-empty");
if (m_stop_called == false) if (m_stop_called == false)
{ {

View File

@@ -19,6 +19,7 @@
#include <xrpl/basics/Log.h> #include <xrpl/basics/Log.h>
#include <xrpl/basics/contract.h> #include <xrpl/basics/contract.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <cstdlib> #include <cstdlib>
#include <iostream> #include <iostream>
@@ -48,6 +49,12 @@ LogicError(std::string const& s) noexcept
{ {
JLOG(debugLog().fatal()) << s; JLOG(debugLog().fatal()) << s;
std::cerr << "Logic error: " << s << std::endl; std::cerr << "Logic error: " << s << std::endl;
// Use a non-standard contract naming here (without namespace) because
// it's the only location where various unrelated execution paths may
// register an error; this is also why the "message" parameter is passed
// here.
// For the above reasons, we want this contract to stand out.
UNREACHABLE("LogicError", {{"message", s}});
detail::accessViolation(); detail::accessViolation();
} }

View File

@@ -18,9 +18,9 @@
//============================================================================== //==============================================================================
#include <xrpl/beast/clock/basic_seconds_clock.h> #include <xrpl/beast/clock/basic_seconds_clock.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <atomic> #include <atomic>
#include <cassert>
#include <chrono> #include <chrono>
#include <condition_variable> #include <condition_variable>
#include <mutex> #include <mutex>
@@ -57,7 +57,9 @@ static_assert(std::atomic<std::chrono::steady_clock::rep>::is_always_lock_free);
seconds_clock_thread::~seconds_clock_thread() seconds_clock_thread::~seconds_clock_thread()
{ {
assert(thread_.joinable()); ASSERT(
thread_.joinable(),
"beast::seconds_clock_thread::~seconds_clock_thread : thread joinable");
{ {
std::lock_guard lock(mut_); std::lock_guard lock(mut_);
stop_ = true; stop_ = true;

View File

@@ -19,9 +19,9 @@
#include <xrpl/beast/core/LexicalCast.h> #include <xrpl/beast/core/LexicalCast.h>
#include <xrpl/beast/core/SemanticVersion.h> #include <xrpl/beast/core/SemanticVersion.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <algorithm> #include <algorithm>
#include <cassert>
#include <locale> #include <locale>
namespace beast { namespace beast {
@@ -304,7 +304,8 @@ compare(SemanticVersion const& lhs, SemanticVersion const& rhs)
if (isNumeric(left)) if (isNumeric(left))
{ {
assert(isNumeric(right)); ASSERT(
isNumeric(right), "beast::compare : both inputs numeric");
int const iLeft(lexicalCastThrow<int>(left)); int const iLeft(lexicalCastThrow<int>(left));
int const iRight(lexicalCastThrow<int>(right)); int const iRight(lexicalCastThrow<int>(right));
@@ -316,7 +317,9 @@ compare(SemanticVersion const& lhs, SemanticVersion const& rhs)
} }
else else
{ {
assert(!isNumeric(right)); ASSERT(
!isNumeric(right),
"beast::compare : both inputs non-numeric");
int result = left.compare(right); int result = left.compare(right);

View File

@@ -25,8 +25,8 @@
#include <xrpl/beast/insight/MeterImpl.h> #include <xrpl/beast/insight/MeterImpl.h>
#include <xrpl/beast/insight/StatsDCollector.h> #include <xrpl/beast/insight/StatsDCollector.h>
#include <xrpl/beast/net/IPAddressConversion.h> #include <xrpl/beast/net/IPAddressConversion.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <boost/asio/ip/tcp.hpp> #include <boost/asio/ip/tcp.hpp>
#include <cassert>
#include <climits> #include <climits>
#include <deque> #include <deque>
#include <functional> #include <functional>
@@ -400,7 +400,10 @@ public:
for (auto const& s : *keepAlive) for (auto const& s : *keepAlive)
{ {
std::size_t const length(s.size()); std::size_t const length(s.size());
assert(!s.empty()); ASSERT(
!s.empty(),
"beast::insight::detail::StatsDCollectorImp::send_buffers : "
"non-empty payload");
if (!buffers.empty() && (size + length) > max_packet_size) if (!buffers.empty() && (size + length) > max_packet_size)
{ {
log(buffers); log(buffers);

View File

@@ -18,7 +18,7 @@
//============================================================================== //==============================================================================
#include <xrpl/beast/utility/Journal.h> #include <xrpl/beast/utility/Journal.h>
#include <cassert> #include <xrpl/beast/utility/instrumentation.h>
namespace beast { namespace beast {

View File

@@ -18,8 +18,8 @@
//============================================================================== //==============================================================================
#include <xrpl/beast/utility/PropertyStream.h> #include <xrpl/beast/utility/PropertyStream.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <algorithm> #include <algorithm>
#include <cassert>
#include <iostream> #include <iostream>
#include <limits> #include <limits>
@@ -199,7 +199,9 @@ PropertyStream::Source::add(Source& source)
std::lock_guard lk1(lock_, std::adopt_lock); std::lock_guard lk1(lock_, std::adopt_lock);
std::lock_guard lk2(source.lock_, std::adopt_lock); std::lock_guard lk2(source.lock_, std::adopt_lock);
assert(source.parent_ == nullptr); ASSERT(
source.parent_ == nullptr,
"beast::PropertyStream::Source::add : null source parent");
children_.push_back(source.item_); children_.push_back(source.item_);
source.parent_ = this; source.parent_ = this;
} }
@@ -211,7 +213,9 @@ PropertyStream::Source::remove(Source& child)
std::lock_guard lk1(lock_, std::adopt_lock); std::lock_guard lk1(lock_, std::adopt_lock);
std::lock_guard lk2(child.lock_, std::adopt_lock); std::lock_guard lk2(child.lock_, std::adopt_lock);
assert(child.parent_ == this); ASSERT(
child.parent_ == this,
"beast::PropertyStream::Source::remove : child parent match");
children_.erase(children_.iterator_to(child.item_)); children_.erase(children_.iterator_to(child.item_));
child.parent_ = nullptr; child.parent_ = nullptr;
} }

View File

@@ -17,10 +17,10 @@
*/ */
//============================================================================== //==============================================================================
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/crypto/RFC1751.h> #include <xrpl/crypto/RFC1751.h>
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <boost/range/adaptor/copied.hpp> #include <boost/range/adaptor/copied.hpp>
#include <cassert>
#include <cstdint> #include <cstdint>
#include <string> #include <string>
@@ -270,10 +270,12 @@ RFC1751::extract(char const* s, int start, int length)
unsigned char cr; unsigned char cr;
unsigned long x; unsigned long x;
assert(length <= 11); ASSERT(length <= 11, "ripple::RFC1751::extract : maximum length");
assert(start >= 0); ASSERT(start >= 0, "ripple::RFC1751::extract : minimum start");
assert(length >= 0); ASSERT(length >= 0, "ripple::RFC1751::extract : minimum length");
assert(start + length <= 66); ASSERT(
start + length <= 66,
"ripple::RFC1751::extract : maximum start + length");
int const shiftR = 24 - (length + (start % 8)); int const shiftR = 24 - (length + (start % 8));
cl = s[start / 8]; // get components cl = s[start / 8]; // get components
@@ -320,10 +322,12 @@ RFC1751::insert(char* s, int x, int start, int length)
unsigned long y; unsigned long y;
int shift; int shift;
assert(length <= 11); ASSERT(length <= 11, "ripple::RFC1751::insert : maximum length");
assert(start >= 0); ASSERT(start >= 0, "ripple::RFC1751::insert : minimum start");
assert(length >= 0); ASSERT(length >= 0, "ripple::RFC1751::insert : minimum length");
assert(start + length <= 66); ASSERT(
start + length <= 66,
"ripple::RFC1751::insert : maximum start + length");
shift = ((8 - ((start + length) % 8)) % 8); shift = ((8 - ((start + length) % 8)) % 8);
y = (long)x << shift; y = (long)x << shift;

View File

@@ -18,9 +18,9 @@
//============================================================================== //==============================================================================
#include <xrpl/basics/contract.h> #include <xrpl/basics/contract.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/crypto/csprng.h> #include <xrpl/crypto/csprng.h>
#include <array> #include <array>
#include <cassert>
#include <openssl/rand.h> #include <openssl/rand.h>
#include <random> #include <random>
#include <stdexcept> #include <stdexcept>

View File

@@ -18,8 +18,8 @@
//============================================================================== //==============================================================================
#include <xrpl/basics/contract.h> #include <xrpl/basics/contract.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/json/Object.h> #include <xrpl/json/Object.h>
#include <cassert>
namespace Json { namespace Json {
@@ -168,7 +168,7 @@ Array::append(Json::Value const& v)
return; return;
} }
} }
assert(false); // Can't get here. UNREACHABLE("Json::Array::append : invalid type");
} }
void void
@@ -203,7 +203,7 @@ Object::set(std::string const& k, Json::Value const& v)
return; return;
} }
} }
assert(false); // Can't get here. UNREACHABLE("Json::Object::set : invalid type");
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -214,7 +214,7 @@ template <class Object>
void void
doCopyFrom(Object& to, Json::Value const& from) doCopyFrom(Object& to, Json::Value const& from)
{ {
assert(from.isObjectOrNull()); ASSERT(from.isObjectOrNull(), "Json::doCopyFrom : valid input type");
auto members = from.getMemberNames(); auto members = from.getMemberNames();
for (auto& m : members) for (auto& m : members)
to[m] = from[m]; to[m] = from[m];

View File

@@ -953,7 +953,7 @@ operator>>(std::istream& sin, Value& root)
Json::Reader reader; Json::Reader reader;
bool ok = reader.parse(sin, root); bool ok = reader.parse(sin, root);
// JSON_ASSERT( ok ); // ASSERT(ok, "Json::operator>>() : parse succeeded");
if (!ok) if (!ok)
ripple::Throw<std::runtime_error>(reader.getFormatedErrorMessages()); ripple::Throw<std::runtime_error>(reader.getFormatedErrorMessages());

View File

@@ -207,7 +207,7 @@ Value::Value(ValueType type) : type_(type), allocated_(0)
break; break;
default: default:
JSON_ASSERT_UNREACHABLE; UNREACHABLE("Json::Value::Value(ValueType) : invalid type");
} }
} }
@@ -277,7 +277,7 @@ Value::Value(const Value& other) : type_(other.type_)
break; break;
default: default:
JSON_ASSERT_UNREACHABLE; UNREACHABLE("Json::Value::Value(Value const&) : invalid type");
} }
} }
@@ -305,7 +305,7 @@ Value::~Value()
break; break;
default: default:
JSON_ASSERT_UNREACHABLE; UNREACHABLE("Json::Value::~Value : invalid type");
} }
} }
@@ -406,7 +406,7 @@ operator<(const Value& x, const Value& y)
} }
default: default:
JSON_ASSERT_UNREACHABLE; UNREACHABLE("Json::operator<(Value, Value) : invalid type");
} }
return 0; // unreachable return 0; // unreachable
@@ -452,7 +452,7 @@ operator==(const Value& x, const Value& y)
*x.value_.map_ == *y.value_.map_; *x.value_.map_ == *y.value_.map_;
default: default:
JSON_ASSERT_UNREACHABLE; UNREACHABLE("Json::operator==(Value, Value) : invalid type");
} }
return 0; // unreachable return 0; // unreachable
@@ -461,7 +461,7 @@ operator==(const Value& x, const Value& y)
const char* const char*
Value::asCString() const Value::asCString() const
{ {
JSON_ASSERT(type_ == stringValue); ASSERT(type_ == stringValue, "Json::Value::asCString : valid type");
return value_.string_; return value_.string_;
} }
@@ -493,7 +493,7 @@ Value::asString() const
JSON_ASSERT_MESSAGE(false, "Type is not convertible to string"); JSON_ASSERT_MESSAGE(false, "Type is not convertible to string");
default: default:
JSON_ASSERT_UNREACHABLE; UNREACHABLE("Json::Value::asString : invalid type");
} }
return ""; // unreachable return ""; // unreachable
@@ -535,7 +535,7 @@ Value::asInt() const
JSON_ASSERT_MESSAGE(false, "Type is not convertible to int"); JSON_ASSERT_MESSAGE(false, "Type is not convertible to int");
default: default:
JSON_ASSERT_UNREACHABLE; UNREACHABLE("Json::Value::asInt : invalid type");
} }
return 0; // unreachable; return 0; // unreachable;
@@ -577,7 +577,7 @@ Value::asUInt() const
JSON_ASSERT_MESSAGE(false, "Type is not convertible to uint"); JSON_ASSERT_MESSAGE(false, "Type is not convertible to uint");
default: default:
JSON_ASSERT_UNREACHABLE; UNREACHABLE("Json::Value::asUInt : invalid type");
} }
return 0; // unreachable; return 0; // unreachable;
@@ -609,7 +609,7 @@ Value::asDouble() const
JSON_ASSERT_MESSAGE(false, "Type is not convertible to double"); JSON_ASSERT_MESSAGE(false, "Type is not convertible to double");
default: default:
JSON_ASSERT_UNREACHABLE; UNREACHABLE("Json::Value::asDouble : invalid type");
} }
return 0; // unreachable; return 0; // unreachable;
@@ -641,7 +641,7 @@ Value::asBool() const
return value_.map_->size() != 0; return value_.map_->size() != 0;
default: default:
JSON_ASSERT_UNREACHABLE; UNREACHABLE("Json::Value::asBool : invalid type");
} }
return false; // unreachable; return false; // unreachable;
@@ -695,7 +695,7 @@ Value::isConvertibleTo(ValueType other) const
(other == nullValue && value_.map_->size() == 0); (other == nullValue && value_.map_->size() == 0);
default: default:
JSON_ASSERT_UNREACHABLE; UNREACHABLE("Json::Value::isConvertible : invalid type");
} }
return false; // unreachable; return false; // unreachable;
@@ -729,7 +729,7 @@ Value::size() const
return Int(value_.map_->size()); return Int(value_.map_->size());
default: default:
JSON_ASSERT_UNREACHABLE; UNREACHABLE("Json::Value::size : invalid type");
} }
return 0; // unreachable; return 0; // unreachable;
@@ -752,8 +752,9 @@ Value::operator bool() const
void void
Value::clear() Value::clear()
{ {
JSON_ASSERT( ASSERT(
type_ == nullValue || type_ == arrayValue || type_ == objectValue); type_ == nullValue || type_ == arrayValue || type_ == objectValue,
"Json::Value::clear : valid type");
switch (type_) switch (type_)
{ {
@@ -770,7 +771,9 @@ Value::clear()
Value& Value&
Value::operator[](UInt index) Value::operator[](UInt index)
{ {
JSON_ASSERT(type_ == nullValue || type_ == arrayValue); ASSERT(
type_ == nullValue || type_ == arrayValue,
"Json::Value::operator[](UInt) : valid type");
if (type_ == nullValue) if (type_ == nullValue)
*this = Value(arrayValue); *this = Value(arrayValue);
@@ -789,7 +792,9 @@ Value::operator[](UInt index)
const Value& const Value&
Value::operator[](UInt index) const Value::operator[](UInt index) const
{ {
JSON_ASSERT(type_ == nullValue || type_ == arrayValue); ASSERT(
type_ == nullValue || type_ == arrayValue,
"Json::Value::operator[](UInt) const : valid type");
if (type_ == nullValue) if (type_ == nullValue)
return null; return null;
@@ -812,7 +817,9 @@ Value::operator[](const char* key)
Value& Value&
Value::resolveReference(const char* key, bool isStatic) Value::resolveReference(const char* key, bool isStatic)
{ {
JSON_ASSERT(type_ == nullValue || type_ == objectValue); ASSERT(
type_ == nullValue || type_ == objectValue,
"Json::Value::resolveReference : valid type");
if (type_ == nullValue) if (type_ == nullValue)
*this = Value(objectValue); *this = Value(objectValue);
@@ -846,7 +853,9 @@ Value::isValidIndex(UInt index) const
const Value& const Value&
Value::operator[](const char* key) const Value::operator[](const char* key) const
{ {
JSON_ASSERT(type_ == nullValue || type_ == objectValue); ASSERT(
type_ == nullValue || type_ == objectValue,
"Json::Value::operator[](const char*) const : valid type");
if (type_ == nullValue) if (type_ == nullValue)
return null; return null;
@@ -906,7 +915,9 @@ Value::get(std::string const& key, const Value& defaultValue) const
Value Value
Value::removeMember(const char* key) Value::removeMember(const char* key)
{ {
JSON_ASSERT(type_ == nullValue || type_ == objectValue); ASSERT(
type_ == nullValue || type_ == objectValue,
"Json::Value::removeMember : valid type");
if (type_ == nullValue) if (type_ == nullValue)
return null; return null;
@@ -947,7 +958,9 @@ Value::isMember(std::string const& key) const
Value::Members Value::Members
Value::getMemberNames() const Value::getMemberNames() const
{ {
JSON_ASSERT(type_ == nullValue || type_ == objectValue); ASSERT(
type_ == nullValue || type_ == objectValue,
"Json::Value::getMemberNames : valid type");
if (type_ == nullValue) if (type_ == nullValue)
return Value::Members(); return Value::Members();

View File

@@ -17,8 +17,8 @@
*/ */
//============================================================================== //==============================================================================
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/json/json_writer.h> #include <xrpl/json/json_writer.h>
#include <cassert>
#include <iomanip> #include <iomanip>
#include <sstream> #include <sstream>
#include <string> #include <string>
@@ -70,7 +70,7 @@ valueToString(Int value)
if (isNegative) if (isNegative)
*--current = '-'; *--current = '-';
assert(current >= buffer); ASSERT(current >= buffer, "Json::valueToString(Int) : buffer check");
return current; return current;
} }
@@ -80,7 +80,7 @@ valueToString(UInt value)
char buffer[32]; char buffer[32];
char* current = buffer + sizeof(buffer); char* current = buffer + sizeof(buffer);
uintToString(value, current); uintToString(value, current);
assert(current >= buffer); ASSERT(current >= buffer, "Json::valueToString(UInt) : buffer check");
return current; return current;
} }
@@ -391,7 +391,9 @@ StyledWriter::writeArrayValue(const Value& value)
} }
else // output on a single line else // output on a single line
{ {
assert(childValues_.size() == size); ASSERT(
childValues_.size() == size,
"Json::StyledWriter::writeArrayValue : child size match");
document_ += "[ "; document_ += "[ ";
for (unsigned index = 0; index < size; ++index) for (unsigned index = 0; index < size; ++index)
@@ -483,7 +485,9 @@ StyledWriter::indent()
void void
StyledWriter::unindent() StyledWriter::unindent()
{ {
assert(int(indentString_.size()) >= indentSize_); ASSERT(
int(indentString_.size()) >= indentSize_,
"Json::StyledWriter::unindent : maximum indent size");
indentString_.resize(indentString_.size() - indentSize_); indentString_.resize(indentString_.size() - indentSize_);
} }
@@ -613,7 +617,9 @@ StyledStreamWriter::writeArrayValue(const Value& value)
} }
else // output on a single line else // output on a single line
{ {
assert(childValues_.size() == size); ASSERT(
childValues_.size() == size,
"Json::StyledStreamWriter::writeArrayValue : child size match");
*document_ << "[ "; *document_ << "[ ";
for (unsigned index = 0; index < size; ++index) for (unsigned index = 0; index < size; ++index)
@@ -706,7 +712,9 @@ StyledStreamWriter::indent()
void void
StyledStreamWriter::unindent() StyledStreamWriter::unindent()
{ {
assert(indentString_.size() >= indentation_.size()); ASSERT(
indentString_.size() >= indentation_.size(),
"Json::StyledStreamWriter::unindent : maximum indent size");
indentString_.resize(indentString_.size() - indentation_.size()); indentString_.resize(indentString_.size() - indentation_.size());
} }

View File

@@ -109,7 +109,9 @@ ammAuctionTimeSlot(std::uint64_t current, STObject const& auctionSlot)
// It should be impossible for expiration to be < TOTAL_TIME_SLOT_SECS, // It should be impossible for expiration to be < TOTAL_TIME_SLOT_SECS,
// but check just to be safe // but check just to be safe
auto const expiration = auctionSlot[sfExpiration]; auto const expiration = auctionSlot[sfExpiration];
assert(expiration >= TOTAL_TIME_SLOT_SECS); ASSERT(
expiration >= TOTAL_TIME_SLOT_SECS,
"ripple::ammAuctionTimeSlot : minimum expiration");
if (expiration >= TOTAL_TIME_SLOT_SECS) if (expiration >= TOTAL_TIME_SLOT_SECS)
{ {
if (auto const start = expiration - TOTAL_TIME_SLOT_SECS; if (auto const start = expiration - TOTAL_TIME_SLOT_SECS;

View File

@@ -77,7 +77,9 @@ public:
auto ret = auto ret =
encodeBase58Token(TokenType::AccountID, id.data(), id.size()); encodeBase58Token(TokenType::AccountID, id.data(), id.size());
assert(ret.size() <= 38); ASSERT(
ret.size() <= 38,
"ripple::detail::AccountIdCache : maximum result size");
{ {
std::lock_guard lock(sl); std::lock_guard lock(sl);

View File

@@ -17,9 +17,9 @@
*/ */
//============================================================================== //==============================================================================
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/protocol/ErrorCodes.h> #include <xrpl/protocol/ErrorCodes.h>
#include <array> #include <array>
#include <cassert>
#include <stdexcept> #include <stdexcept>
namespace ripple { namespace ripple {
@@ -211,7 +211,9 @@ error_code_http_status(error_code_i code)
std::string std::string
rpcErrorString(Json::Value const& jv) rpcErrorString(Json::Value const& jv)
{ {
assert(RPC::contains_error(jv)); ASSERT(
RPC::contains_error(jv),
"ripple::RPC::rpcErrorString : input contains an error");
return jv[jss::error].asString() + jv[jss::error_message].asString(); return jv[jss::error].asString() + jv[jss::error_message].asString();
} }

View File

@@ -221,7 +221,9 @@ FeatureCollections::FeatureCollections()
std::optional<uint256> std::optional<uint256>
FeatureCollections::getRegisteredFeature(std::string const& name) const FeatureCollections::getRegisteredFeature(std::string const& name) const
{ {
assert(readOnly); ASSERT(
readOnly.load(),
"ripple::FeatureCollections::getRegisteredFeature : startup completed");
Feature const* feature = getByName(name); Feature const* feature = getByName(name);
if (feature) if (feature)
return feature->feature; return feature->feature;
@@ -303,7 +305,9 @@ FeatureCollections::registrationIsDone()
size_t size_t
FeatureCollections::featureToBitsetIndex(uint256 const& f) const FeatureCollections::featureToBitsetIndex(uint256 const& f) const
{ {
assert(readOnly); ASSERT(
readOnly.load(),
"ripple::FeatureCollections::featureToBitsetIndex : startup completed");
Feature const* feature = getByFeature(f); Feature const* feature = getByFeature(f);
if (!feature) if (!feature)
@@ -315,7 +319,9 @@ FeatureCollections::featureToBitsetIndex(uint256 const& f) const
uint256 const& uint256 const&
FeatureCollections::bitsetIndexToFeature(size_t i) const FeatureCollections::bitsetIndexToFeature(size_t i) const
{ {
assert(readOnly); ASSERT(
readOnly.load(),
"ripple::FeatureCollections::bitsetIndexToFeature : startup completed");
Feature const& feature = getByIndex(i); Feature const& feature = getByIndex(i);
return feature.feature; return feature.feature;
} }
@@ -323,7 +329,9 @@ FeatureCollections::bitsetIndexToFeature(size_t i) const
std::string std::string
FeatureCollections::featureToName(uint256 const& f) const FeatureCollections::featureToName(uint256 const& f) const
{ {
assert(readOnly); ASSERT(
readOnly.load(),
"ripple::FeatureCollections::featureToName : startup completed");
Feature const* feature = getByFeature(f); Feature const* feature = getByFeature(f);
return feature ? feature->name : to_string(f); return feature ? feature->name : to_string(f);
} }

View File

@@ -17,6 +17,7 @@
*/ */
//============================================================================== //==============================================================================
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/protocol/Indexes.h> #include <xrpl/protocol/Indexes.h>
#include <xrpl/protocol/LedgerFormats.h> #include <xrpl/protocol/LedgerFormats.h>
#include <xrpl/protocol/SField.h> #include <xrpl/protocol/SField.h>
@@ -26,7 +27,6 @@
#include <xrpl/protocol/nftPageMask.h> #include <xrpl/protocol/nftPageMask.h>
#include <algorithm> #include <algorithm>
#include <cassert>
namespace ripple { namespace ripple {
@@ -95,7 +95,7 @@ indexHash(LedgerNameSpace space, Args const&... args)
uint256 uint256
getBookBase(Book const& book) getBookBase(Book const& book)
{ {
assert(isConsistent(book)); ASSERT(isConsistent(book), "ripple::getBookBase : input is consistent");
auto const index = indexHash( auto const index = indexHash(
LedgerNameSpace::BOOK_DIR, LedgerNameSpace::BOOK_DIR,
@@ -135,7 +135,7 @@ getTicketIndex(AccountID const& account, std::uint32_t ticketSeq)
uint256 uint256
getTicketIndex(AccountID const& account, SeqProxy ticketSeq) getTicketIndex(AccountID const& account, SeqProxy ticketSeq)
{ {
assert(ticketSeq.isTicket()); ASSERT(ticketSeq.isTicket(), "ripple::getTicketIndex : valid input");
return getTicketIndex(account, ticketSeq.value()); return getTicketIndex(account, ticketSeq.value());
} }
@@ -222,7 +222,7 @@ line(
// There is code in SetTrust that calls us with id0 == id1, to allow users // There is code in SetTrust that calls us with id0 == id1, to allow users
// to locate and delete such "weird" trustlines. If we remove that code, we // to locate and delete such "weird" trustlines. If we remove that code, we
// could enable this assert: // could enable this assert:
// assert(id0 != id1); // ASSERT(id0 != id1, "ripple::keylet::line : accounts must be different");
// A trust line is shared between two accounts; while we typically think // A trust line is shared between two accounts; while we typically think
// of this as an "issuer" and a "holder" the relationship is actually fully // of this as an "issuer" and a "holder" the relationship is actually fully
@@ -251,7 +251,7 @@ offer(AccountID const& id, std::uint32_t seq) noexcept
Keylet Keylet
quality(Keylet const& k, std::uint64_t q) noexcept quality(Keylet const& k, std::uint64_t q) noexcept
{ {
assert(k.type == ltDIR_NODE); ASSERT(k.type == ltDIR_NODE, "ripple::keylet::quality : valid input type");
// Indexes are stored in big endian format: they print as hex as stored. // Indexes are stored in big endian format: they print as hex as stored.
// Most significant bytes are first and the least significant bytes // Most significant bytes are first and the least significant bytes
@@ -269,7 +269,9 @@ quality(Keylet const& k, std::uint64_t q) noexcept
Keylet Keylet
next_t::operator()(Keylet const& k) const next_t::operator()(Keylet const& k) const
{ {
assert(k.type == ltDIR_NODE); ASSERT(
k.type == ltDIR_NODE,
"ripple::keylet::next_t::operator() : valid input type");
return {ltDIR_NODE, getQualityNext(k.key)}; return {ltDIR_NODE, getQualityNext(k.key)};
} }
@@ -387,7 +389,8 @@ nftpage_max(AccountID const& owner)
Keylet Keylet
nftpage(Keylet const& k, uint256 const& token) nftpage(Keylet const& k, uint256 const& token)
{ {
assert(k.type == ltNFTOKEN_PAGE); ASSERT(
k.type == ltNFTOKEN_PAGE, "ripple::keylet::nftpage : valid input type");
return {ltNFTOKEN_PAGE, (k.key & ~nft::pageMask) + (token & nft::pageMask)}; return {ltNFTOKEN_PAGE, (k.key & ~nft::pageMask) + (token & nft::pageMask)};
} }

View File

@@ -25,7 +25,9 @@ namespace ripple {
bool bool
Keylet::check(STLedgerEntry const& sle) const Keylet::check(STLedgerEntry const& sle) const
{ {
assert(sle.getType() != ltANY || sle.getType() != ltCHILD); ASSERT(
sle.getType() != ltANY || sle.getType() != ltCHILD,
"ripple::Keylet::check : valid input type");
if (type == ltANY) if (type == ltANY)
return true; return true;

View File

@@ -17,8 +17,8 @@
*/ */
//============================================================================== //==============================================================================
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/protocol/Quality.h> #include <xrpl/protocol/Quality.h>
#include <cassert>
#include <limits> #include <limits>
namespace ripple { namespace ripple {
@@ -35,7 +35,7 @@ Quality::Quality(Amounts const& amount)
Quality& Quality&
Quality::operator++() Quality::operator++()
{ {
assert(m_value > 0); ASSERT(m_value > 0, "ripple::Quality::operator++() : minimum value");
--m_value; --m_value;
return *this; return *this;
} }
@@ -51,7 +51,9 @@ Quality::operator++(int)
Quality& Quality&
Quality::operator--() Quality::operator--()
{ {
assert(m_value < std::numeric_limits<value_type>::max()); ASSERT(
m_value < std::numeric_limits<value_type>::max(),
"ripple::Quality::operator--() : maximum value");
++m_value; ++m_value;
return *this; return *this;
} }
@@ -81,10 +83,11 @@ ceil_in_impl(
// Clamp out // Clamp out
if (result.out > amount.out) if (result.out > amount.out)
result.out = amount.out; result.out = amount.out;
assert(result.in == limit); ASSERT(
result.in == limit, "ripple::ceil_in_impl : result matches limit");
return result; return result;
} }
assert(amount.in <= limit); ASSERT(amount.in <= limit, "ripple::ceil_in_impl : result inside limit");
return amount; return amount;
} }
@@ -120,10 +123,12 @@ ceil_out_impl(
// Clamp in // Clamp in
if (result.in > amount.in) if (result.in > amount.in)
result.in = amount.in; result.in = amount.in;
assert(result.out == limit); ASSERT(
result.out == limit,
"ripple::ceil_out_impl : result matches limit");
return result; return result;
} }
assert(amount.out <= limit); ASSERT(amount.out <= limit, "ripple::ceil_out_impl : result inside limit");
return amount; return amount;
} }
@@ -146,17 +151,23 @@ Quality
composed_quality(Quality const& lhs, Quality const& rhs) composed_quality(Quality const& lhs, Quality const& rhs)
{ {
STAmount const lhs_rate(lhs.rate()); STAmount const lhs_rate(lhs.rate());
assert(lhs_rate != beast::zero); ASSERT(
lhs_rate != beast::zero,
"ripple::composed_quality : nonzero left input");
STAmount const rhs_rate(rhs.rate()); STAmount const rhs_rate(rhs.rate());
assert(rhs_rate != beast::zero); ASSERT(
rhs_rate != beast::zero,
"ripple::composed_quality : nonzero right input");
STAmount const rate(mulRound(lhs_rate, rhs_rate, lhs_rate.asset(), true)); STAmount const rate(mulRound(lhs_rate, rhs_rate, lhs_rate.asset(), true));
std::uint64_t const stored_exponent(rate.exponent() + 100); std::uint64_t const stored_exponent(rate.exponent() + 100);
std::uint64_t const stored_mantissa(rate.mantissa()); std::uint64_t const stored_mantissa(rate.mantissa());
assert((stored_exponent > 0) && (stored_exponent <= 255)); ASSERT(
(stored_exponent > 0) && (stored_exponent <= 255),
"ripple::composed_quality : valid exponent");
return Quality((stored_exponent << (64 - 8)) | stored_mantissa); return Quality((stored_exponent << (64 - 8)) | stored_mantissa);
} }

View File

@@ -46,7 +46,7 @@ transferFeeAsRate(std::uint16_t fee)
STAmount STAmount
multiply(STAmount const& amount, Rate const& rate) multiply(STAmount const& amount, Rate const& rate)
{ {
assert(rate.value != 0); ASSERT(rate.value != 0, "ripple::nft::multiply : nonzero rate input");
if (rate == parityRate) if (rate == parityRate)
return amount; return amount;
@@ -57,7 +57,7 @@ multiply(STAmount const& amount, Rate const& rate)
STAmount STAmount
multiplyRound(STAmount const& amount, Rate const& rate, bool roundUp) multiplyRound(STAmount const& amount, Rate const& rate, bool roundUp)
{ {
assert(rate.value != 0); ASSERT(rate.value != 0, "ripple::nft::multiplyRound : nonzero rate input");
if (rate == parityRate) if (rate == parityRate)
return amount; return amount;
@@ -72,7 +72,9 @@ multiplyRound(
Asset const& asset, Asset const& asset,
bool roundUp) bool roundUp)
{ {
assert(rate.value != 0); ASSERT(
rate.value != 0,
"ripple::nft::multiplyRound(Issue) : nonzero rate input");
if (rate == parityRate) if (rate == parityRate)
{ {
@@ -85,7 +87,7 @@ multiplyRound(
STAmount STAmount
divide(STAmount const& amount, Rate const& rate) divide(STAmount const& amount, Rate const& rate)
{ {
assert(rate.value != 0); ASSERT(rate.value != 0, "ripple::nft::divide : nonzero rate input");
if (rate == parityRate) if (rate == parityRate)
return amount; return amount;
@@ -96,7 +98,7 @@ divide(STAmount const& amount, Rate const& rate)
STAmount STAmount
divideRound(STAmount const& amount, Rate const& rate, bool roundUp) divideRound(STAmount const& amount, Rate const& rate, bool roundUp)
{ {
assert(rate.value != 0); ASSERT(rate.value != 0, "ripple::nft::divideRound : nonzero rate input");
if (rate == parityRate) if (rate == parityRate)
return amount; return amount;
@@ -111,7 +113,9 @@ divideRound(
Asset const& asset, Asset const& asset,
bool roundUp) bool roundUp)
{ {
assert(rate.value != 0); ASSERT(
rate.value != 0,
"ripple::nft::divideRound(Issue) : nonzero rate input");
if (rate == parityRate) if (rate == parityRate)
return amount; return amount;

View File

@@ -91,7 +91,10 @@ public:
return true; return true;
if (!digest_ || !other.digest_) if (!digest_ || !other.digest_)
return false; return false;
assert(presets_ == other.presets_); ASSERT(
presets_ == other.presets_,
"ripple::Rules::Impl::operator==(Impl) const : input presets do "
"match");
return *digest_ == *other.digest_; return *digest_ == *other.digest_;
} }
}; };
@@ -118,7 +121,7 @@ Rules::presets() const
bool bool
Rules::enabled(uint256 const& feature) const Rules::enabled(uint256 const& feature) const
{ {
assert(impl_); ASSERT(impl_ != nullptr, "ripple::Rules::enabled : initialized");
// The functionality of the "NonFungibleTokensV1_1" amendment is // The functionality of the "NonFungibleTokensV1_1" amendment is
// precisely the functionality of the following three amendments // precisely the functionality of the following three amendments
@@ -137,7 +140,9 @@ Rules::enabled(uint256 const& feature) const
bool bool
Rules::operator==(Rules const& other) const Rules::operator==(Rules const& other) const
{ {
assert(impl_ && other.impl_); ASSERT(
impl_ && other.impl_,
"ripple::Rules::operator==(Rules) const : both initialized");
if (impl_.get() == other.impl_.get()) if (impl_.get() == other.impl_.get())
return true; return true;
return *impl_ == *other.impl_; return *impl_ == *other.impl_;

View File

@@ -17,8 +17,8 @@
*/ */
//============================================================================== //==============================================================================
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/protocol/SField.h> #include <xrpl/protocol/SField.h>
#include <cassert>
#include <string> #include <string>
#include <string_view> #include <string_view>
#include <utility> #include <utility>

View File

@@ -80,8 +80,10 @@ STAccount::getSType() const
void void
STAccount::add(Serializer& s) const STAccount::add(Serializer& s) const
{ {
assert(getFName().isBinary()); ASSERT(getFName().isBinary(), "ripple::STAccount::add : field is binary");
assert(getFName().fieldType == STI_ACCOUNT); ASSERT(
getFName().fieldType == STI_ACCOUNT,
"ripple::STAccount::add : valid field type");
// Preserve the serialization behavior of an STBlob: // Preserve the serialization behavior of an STBlob:
// o If we are default (all zeros) serialize as an empty blob. // o If we are default (all zeros) serialize as an empty blob.

View File

@@ -29,7 +29,7 @@
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <boost/multiprecision/cpp_int.hpp> #include <boost/multiprecision/cpp_int.hpp>
#include <boost/regex.hpp> #include <boost/regex.hpp>
#include <iostream>
#include <iterator> #include <iterator>
#include <memory> #include <memory>
@@ -68,11 +68,13 @@ getInt64Value(STAmount const& amount, bool valid, const char* error)
{ {
if (!valid) if (!valid)
Throw<std::runtime_error>(error); Throw<std::runtime_error>(error);
assert(amount.exponent() == 0); ASSERT(amount.exponent() == 0, "ripple::getInt64Value : exponent is zero");
auto ret = static_cast<std::int64_t>(amount.mantissa()); auto ret = static_cast<std::int64_t>(amount.mantissa());
assert(static_cast<std::uint64_t>(ret) == amount.mantissa()); ASSERT(
static_cast<std::uint64_t>(ret) == amount.mantissa(),
"ripple::getInt64Value : mantissa must roundtrip");
if (amount.negative()) if (amount.negative())
ret = -ret; ret = -ret;
@@ -199,7 +201,10 @@ STAmount::STAmount(SField const& name, std::uint64_t mantissa, bool negative)
, mOffset(0) , mOffset(0)
, mIsNegative(negative) , mIsNegative(negative)
{ {
assert(mValue <= std::numeric_limits<std::int64_t>::max()); ASSERT(
mValue <= std::numeric_limits<std::int64_t>::max(),
"ripple::STAmount::STAmount(SField, std::uint64_t, bool) : maximum "
"mantissa input");
} }
STAmount::STAmount(SField const& name, STAmount const& from) STAmount::STAmount(SField const& name, STAmount const& from)
@@ -209,7 +214,9 @@ STAmount::STAmount(SField const& name, STAmount const& from)
, mOffset(from.mOffset) , mOffset(from.mOffset)
, mIsNegative(from.mIsNegative) , mIsNegative(from.mIsNegative)
{ {
assert(mValue <= std::numeric_limits<std::int64_t>::max()); ASSERT(
mValue <= std::numeric_limits<std::int64_t>::max(),
"ripple::STAmount::STAmount(SField, STAmount) : maximum input");
canonicalize(); canonicalize();
} }
@@ -221,7 +228,10 @@ STAmount::STAmount(std::uint64_t mantissa, bool negative)
, mOffset(0) , mOffset(0)
, mIsNegative(mantissa != 0 && negative) , mIsNegative(mantissa != 0 && negative)
{ {
assert(mValue <= std::numeric_limits<std::int64_t>::max()); ASSERT(
mValue <= std::numeric_limits<std::int64_t>::max(),
"ripple::STAmount::STAmount(std::uint64_t, bool) : maximum mantissa "
"input");
} }
STAmount::STAmount(XRPAmount const& amount) STAmount::STAmount(XRPAmount const& amount)
@@ -305,7 +315,9 @@ STAmount::mpt() const
STAmount& STAmount&
STAmount::operator=(IOUAmount const& iou) STAmount::operator=(IOUAmount const& iou)
{ {
assert(native() == false); ASSERT(
native() == false,
"ripple::STAmount::operator=(IOUAmount) : is not XRP");
mOffset = iou.exponent(); mOffset = iou.exponent();
mIsNegative = iou < beast::zero; mIsNegative = iou < beast::zero;
if (mIsNegative) if (mIsNegative)
@@ -444,7 +456,9 @@ getRate(STAmount const& offerOut, STAmount const& offerIn)
STAmount r = divide(offerIn, offerOut, noIssue()); STAmount r = divide(offerIn, offerOut, noIssue());
if (r == beast::zero) // offer is too good if (r == beast::zero) // offer is too good
return 0; return 0;
assert((r.exponent() >= -100) && (r.exponent() <= 155)); ASSERT(
(r.exponent() >= -100) && (r.exponent() <= 155),
"ripple::getRate : exponent inside range");
std::uint64_t ret = r.exponent() + 100; std::uint64_t ret = r.exponent() + 100;
return (ret << (64 - 8)) | r.mantissa(); return (ret << (64 - 8)) | r.mantissa();
} }
@@ -525,7 +539,7 @@ STAmount::getText() const
return ret; return ret;
} }
assert(mOffset + 43 > 0); ASSERT(mOffset + 43 > 0, "ripple::STAmount::getText : minimum offset");
size_t const pad_prefix = 27; size_t const pad_prefix = 27;
size_t const pad_suffix = 23; size_t const pad_suffix = 23;
@@ -549,7 +563,9 @@ STAmount::getText() const
if (std::distance(pre_from, pre_to) > pad_prefix) if (std::distance(pre_from, pre_to) > pad_prefix)
pre_from += pad_prefix; pre_from += pad_prefix;
assert(post_to >= post_from); ASSERT(
post_to >= post_from,
"ripple::STAmount::getText : first distance check");
pre_from = std::find_if(pre_from, pre_to, [](char c) { return c != '0'; }); pre_from = std::find_if(pre_from, pre_to, [](char c) { return c != '0'; });
@@ -558,7 +574,9 @@ STAmount::getText() const
if (std::distance(post_from, post_to) > pad_suffix) if (std::distance(post_from, post_to) > pad_suffix)
post_to -= pad_suffix; post_to -= pad_suffix;
assert(post_to >= post_from); ASSERT(
post_to >= post_from,
"ripple::STAmount::getText : second distance check");
post_to = std::find_if( post_to = std::find_if(
std::make_reverse_iterator(post_to), std::make_reverse_iterator(post_to),
@@ -594,7 +612,7 @@ STAmount::add(Serializer& s) const
{ {
if (native()) if (native())
{ {
assert(mOffset == 0); ASSERT(mOffset == 0, "ripple::STAmount::add : zero offset");
if (!mIsNegative) if (!mIsNegative)
s.add64(mValue | cPositive); s.add64(mValue | cPositive);
@@ -771,10 +789,15 @@ STAmount::canonicalize()
if (mOffset > cMaxOffset) if (mOffset > cMaxOffset)
Throw<std::runtime_error>("value overflow"); Throw<std::runtime_error>("value overflow");
assert((mValue == 0) || ((mValue >= cMinValue) && (mValue <= cMaxValue))); ASSERT(
assert( (mValue == 0) || ((mValue >= cMinValue) && (mValue <= cMaxValue)),
(mValue == 0) || ((mOffset >= cMinOffset) && (mOffset <= cMaxOffset))); "ripple::STAmount::canonicalize : value inside range");
assert((mValue != 0) || (mOffset != -100)); ASSERT(
(mValue == 0) || ((mOffset >= cMinOffset) && (mOffset <= cMaxOffset)),
"ripple::STAmount::canonicalize : offset inside range");
ASSERT(
(mValue != 0) || (mOffset != -100),
"ripple::STAmount::canonicalize : value or offset set");
} }
void void

View File

@@ -17,10 +17,9 @@
*/ */
//============================================================================== //==============================================================================
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/protocol/STBase.h> #include <xrpl/protocol/STBase.h>
#include <boost/checked_delete.hpp> #include <boost/checked_delete.hpp>
#include <cassert>
#include <memory>
namespace ripple { namespace ripple {
@@ -30,7 +29,7 @@ STBase::STBase() : fName(&sfGeneric)
STBase::STBase(SField const& n) : fName(&n) STBase::STBase(SField const& n) : fName(&n)
{ {
assert(fName); ASSERT(fName != nullptr, "ripple::STBase::STBase : field is set");
} }
STBase& STBase&
@@ -106,13 +105,15 @@ void
STBase::add(Serializer& s) const STBase::add(Serializer& s) const
{ {
// Should never be called // Should never be called
assert(false); UNREACHABLE("ripple::STBase::add : not implemented");
} }
bool bool
STBase::isEquivalent(const STBase& t) const STBase::isEquivalent(const STBase& t) const
{ {
assert(getSType() == STI_NOTPRESENT); ASSERT(
getSType() == STI_NOTPRESENT,
"ripple::STBase::isEquivalent : type not present");
return t.getSType() == STI_NOTPRESENT; return t.getSType() == STI_NOTPRESENT;
} }
@@ -126,7 +127,7 @@ void
STBase::setFName(SField const& n) STBase::setFName(SField const& n)
{ {
fName = &n; fName = &n;
assert(fName); ASSERT(fName != nullptr, "ripple::STBase::setFName : field is set");
} }
SField const& SField const&
@@ -138,7 +139,7 @@ STBase::getFName() const
void void
STBase::addFieldID(Serializer& s) const STBase::addFieldID(Serializer& s) const
{ {
assert(fName->isBinary()); ASSERT(fName->isBinary(), "ripple::STBase::addFieldID : field is binary");
s.addFieldID(fName->fieldType, fName->fieldValue); s.addFieldID(fName->fieldType, fName->fieldValue);
} }

View File

@@ -54,10 +54,11 @@ STBlob::getText() const
void void
STBlob::add(Serializer& s) const STBlob::add(Serializer& s) const
{ {
assert(getFName().isBinary()); ASSERT(getFName().isBinary(), "ripple::STBlob::add : field is binary");
assert( ASSERT(
(getFName().fieldType == STI_VL) || (getFName().fieldType == STI_VL) ||
(getFName().fieldType == STI_ACCOUNT)); (getFName().fieldType == STI_ACCOUNT),
"ripple::STBlob::add : valid field type");
s.addVL(value_.data(), value_.size()); s.addVL(value_.data(), value_.size());
} }

View File

@@ -199,12 +199,16 @@ Json::Value
STUInt64::getJson(JsonOptions) const STUInt64::getJson(JsonOptions) const
{ {
auto convertToString = [](uint64_t const value, int const base) { auto convertToString = [](uint64_t const value, int const base) {
assert(base == 10 || base == 16); ASSERT(
base == 10 || base == 16,
"ripple::STUInt64::getJson : base 10 or 16");
std::string str( std::string str(
base == 10 ? 20 : 16, 0); // Allocate space depending on base base == 10 ? 20 : 16, 0); // Allocate space depending on base
auto ret = auto ret =
std::to_chars(str.data(), str.data() + str.size(), value, base); std::to_chars(str.data(), str.data() + str.size(), value, base);
assert(ret.ec == std::errc()); ASSERT(
ret.ec == std::errc(),
"ripple::STUInt64::getJson : to_chars succeeded");
str.resize(std::distance(str.data(), ret.ptr)); str.resize(std::distance(str.data(), ret.ptr));
return str; return str;
}; };

View File

@@ -161,7 +161,9 @@ STLedgerEntry::thread(
if (oldPrevTxID == txID) if (oldPrevTxID == txID)
{ {
// this transaction is already threaded // this transaction is already threaded
assert(getFieldU32(sfPreviousTxnLgrSeq) == ledgerSeq); ASSERT(
getFieldU32(sfPreviousTxnLgrSeq) == ledgerSeq,
"ripple::STLedgerEntry::thread : ledger sequence match");
return false; return false;
} }

View File

@@ -19,6 +19,7 @@
#include <xrpl/protocol/STNumber.h> #include <xrpl/protocol/STNumber.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/protocol/SField.h> #include <xrpl/protocol/SField.h>
namespace ripple { namespace ripple {
@@ -52,8 +53,10 @@ STNumber::getText() const
void void
STNumber::add(Serializer& s) const STNumber::add(Serializer& s) const
{ {
assert(getFName().isBinary()); ASSERT(getFName().isBinary(), "ripple::STNumber::add : field is binary");
assert(getFName().fieldType == getSType()); ASSERT(
getFName().fieldType == getSType(),
"ripple::STNumber::add : field type match");
s.add64(value_.mantissa()); s.add64(value_.mantissa());
s.add32(value_.exponent()); s.add32(value_.exponent());
} }
@@ -85,7 +88,9 @@ STNumber::move(std::size_t n, void* buf)
bool bool
STNumber::isEquivalent(STBase const& t) const STNumber::isEquivalent(STBase const& t) const
{ {
assert(t.getSType() == this->getSType()); ASSERT(
t.getSType() == this->getSType(),
"ripple::STNumber::isEquivalent : field type match");
STNumber const& v = dynamic_cast<STNumber const&>(t); STNumber const& v = dynamic_cast<STNumber const&>(t);
return value_ == v; return value_ == v;
} }

View File

@@ -862,9 +862,10 @@ STObject::add(Serializer& s, WhichFields whichFields) const
// the type associated by rule with this field name // the type associated by rule with this field name
// must be OBJECT, or the object cannot be deserialized // must be OBJECT, or the object cannot be deserialized
SerializedTypeID const sType{field->getSType()}; SerializedTypeID const sType{field->getSType()};
assert( ASSERT(
(sType != STI_OBJECT) || (sType != STI_OBJECT) ||
(field->getFName().fieldType == STI_OBJECT)); (field->getFName().fieldType == STI_OBJECT),
"ripple::STObject::add : valid field type");
field->addFieldID(s); field->addFieldID(s);
field->add(s); field->add(s);
if (sType == STI_ARRAY || sType == STI_OBJECT) if (sType == STI_ARRAY || sType == STI_OBJECT)

View File

@@ -21,6 +21,7 @@
#include <xrpl/basics/contract.h> #include <xrpl/basics/contract.h>
#include <xrpl/basics/safe_cast.h> #include <xrpl/basics/safe_cast.h>
#include <xrpl/beast/core/LexicalCast.h> #include <xrpl/beast/core/LexicalCast.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/protocol/ErrorCodes.h> #include <xrpl/protocol/ErrorCodes.h>
#include <xrpl/protocol/LedgerFormats.h> #include <xrpl/protocol/LedgerFormats.h>
#include <xrpl/protocol/SField.h> #include <xrpl/protocol/SField.h>
@@ -41,7 +42,6 @@
#include <xrpl/protocol/XChainAttestations.h> #include <xrpl/protocol/XChainAttestations.h>
#include <xrpl/protocol/detail/STVar.h> #include <xrpl/protocol/detail/STVar.h>
#include <cassert>
#include <charconv> #include <charconv>
#include <memory> #include <memory>

View File

@@ -209,8 +209,10 @@ STPathSet::getSType() const
void void
STPathSet::add(Serializer& s) const STPathSet::add(Serializer& s) const
{ {
assert(getFName().isBinary()); ASSERT(getFName().isBinary(), "ripple::STPathSet::add : field is binary");
assert(getFName().fieldType == STI_PATHSET); ASSERT(
getFName().fieldType == STI_PATHSET,
"ripple::STPathSet::add : valid field type");
bool first = true; bool first = true;
for (auto const& spPath : value) for (auto const& spPath : value)

View File

@@ -137,7 +137,9 @@ STTx::getMentionedAccounts() const
{ {
if (auto sacc = dynamic_cast<STAccount const*>(&it)) if (auto sacc = dynamic_cast<STAccount const*>(&it))
{ {
assert(!sacc->isDefault()); ASSERT(
!sacc->isDefault(),
"ripple::STTx::getMentionedAccounts : account is set");
if (!sacc->isDefault()) if (!sacc->isDefault())
list.insert(sacc->value()); list.insert(sacc->value());
} }
@@ -298,7 +300,8 @@ STTx::getMetaSQL(
std::string rTxn = sqlBlobLiteral(rawTxn.peekData()); std::string rTxn = sqlBlobLiteral(rawTxn.peekData());
auto format = TxFormats::getInstance().findByType(tx_type_); auto format = TxFormats::getInstance().findByType(tx_type_);
assert(format != nullptr); ASSERT(
format != nullptr, "ripple::STTx::getMetaSQL : non-null type format");
return str( return str(
boost::format(bfTrans) % to_string(getTransactionID()) % boost::format(bfTrans) % to_string(getTransactionID()) %

View File

@@ -107,7 +107,9 @@ STValidation::isValid() const noexcept
{ {
if (!valid_) if (!valid_)
{ {
assert(publicKeyType(getSignerPublic()) == KeyType::secp256k1); ASSERT(
publicKeyType(getSignerPublic()) == KeyType::secp256k1,
"ripple::STValidation::isValid : valid key type");
valid_ = verifyDigest( valid_ = verifyDigest(
getSignerPublic(), getSignerPublic(),

View File

@@ -121,7 +121,9 @@ STVar::STVar(SerialIter& sit, SField const& name, int depth)
STVar::STVar(SerializedTypeID id, SField const& name) STVar::STVar(SerializedTypeID id, SField const& name)
{ {
assert((id == STI_NOTPRESENT) || (id == name.fieldType)); ASSERT(
(id == STI_NOTPRESENT) || (id == name.fieldType),
"ripple::detail::STVar::STVar(SerializedTypeID) : valid type input");
constructST(id, 0, name); constructST(id, 0, name);
} }

View File

@@ -68,8 +68,10 @@ STVector256::isDefault() const
void void
STVector256::add(Serializer& s) const STVector256::add(Serializer& s) const
{ {
assert(getFName().isBinary()); ASSERT(getFName().isBinary(), "ripple::STVector256::add : field is binary");
assert(getFName().fieldType == STI_VECTOR256); ASSERT(
getFName().fieldType == STI_VECTOR256,
"ripple::STVector256::add : valid field type");
s.addVL(mValue.begin(), mValue.end(), mValue.size() * (256 / 8)); s.addVL(mValue.begin(), mValue.end(), mValue.size() * (256 / 8));
} }

View File

@@ -107,7 +107,9 @@ int
Serializer::addFieldID(int type, int name) Serializer::addFieldID(int type, int name)
{ {
int ret = mData.size(); int ret = mData.size();
assert((type > 0) && (type < 256) && (name > 0) && (name < 256)); ASSERT(
(type > 0) && (type < 256) && (name > 0) && (name < 256),
"ripple::Serializer::addFieldID : inputs inside range");
if (type < 16) if (type < 16)
{ {
@@ -176,9 +178,10 @@ Serializer::addVL(Blob const& vector)
{ {
int ret = addEncoded(vector.size()); int ret = addEncoded(vector.size());
addRaw(vector); addRaw(vector);
assert( ASSERT(
mData.size() == mData.size() ==
(ret + vector.size() + encodeLengthLength(vector.size()))); (ret + vector.size() + encodeLengthLength(vector.size())),
"ripple::Serializer::addVL : size matches expected");
return ret; return ret;
} }
@@ -482,7 +485,8 @@ SerialIter::getVLDataLength()
} }
else else
{ {
assert(lenLen == 3); ASSERT(
lenLen == 3, "ripple::SerialIter::getVLDataLength : lenLen is 3");
int b2 = get8(); int b2 = get8();
int b3 = get8(); int b3 = get8();
datLen = Serializer::decodeVLLength(b1, b2, b3); datLen = Serializer::decodeVLLength(b1, b2, b3);

View File

@@ -55,7 +55,9 @@ TxMeta::TxMeta(uint256 const& txid, std::uint32_t ledger, STObject const& obj)
auto affectedNodes = auto affectedNodes =
dynamic_cast<STArray const*>(obj.peekAtPField(sfAffectedNodes)); dynamic_cast<STArray const*>(obj.peekAtPField(sfAffectedNodes));
assert(affectedNodes); ASSERT(
affectedNodes != nullptr,
"ripple::TxMeta::TxMeta(STObject) : type cast succeeded");
if (affectedNodes) if (affectedNodes)
mNodes = *affectedNodes; mNodes = *affectedNodes;
@@ -106,7 +108,9 @@ TxMeta::setAffectedNode(
mNodes.push_back(STObject(type)); mNodes.push_back(STObject(type));
STObject& obj = mNodes.back(); STObject& obj = mNodes.back();
assert(obj.getFName() == type); ASSERT(
obj.getFName() == type,
"ripple::TxMeta::setAffectedNode : field type match");
obj.setFieldH256(sfLedgerIndex, node); obj.setFieldH256(sfLedgerIndex, node);
obj.setFieldU16(sfLedgerEntryType, nodeType); obj.setFieldU16(sfLedgerEntryType, nodeType);
} }
@@ -127,14 +131,18 @@ TxMeta::getAffectedAccounts() const
if (index != -1) if (index != -1)
{ {
auto inner = dynamic_cast<STObject const*>(&it.peekAtIndex(index)); auto inner = dynamic_cast<STObject const*>(&it.peekAtIndex(index));
assert(inner); ASSERT(
inner != nullptr,
"ripple::getAffectedAccounts : STObject type cast succeeded");
if (inner) if (inner)
{ {
for (auto const& field : *inner) for (auto const& field : *inner)
{ {
if (auto sa = dynamic_cast<STAccount const*>(&field)) if (auto sa = dynamic_cast<STAccount const*>(&field))
{ {
assert(!sa->isDefault()); ASSERT(
!sa->isDefault(),
"ripple::getAffectedAccounts : account is set");
if (!sa->isDefault()) if (!sa->isDefault())
list.insert(sa->value()); list.insert(sa->value());
} }
@@ -145,7 +153,10 @@ TxMeta::getAffectedAccounts() const
(field.getFName() == sfTakerGets)) (field.getFName() == sfTakerGets))
{ {
auto lim = dynamic_cast<STAmount const*>(&field); auto lim = dynamic_cast<STAmount const*>(&field);
assert(lim); ASSERT(
lim != nullptr,
"ripple::getAffectedAccounts : STAmount type cast "
"succeeded");
if (lim != nullptr) if (lim != nullptr)
{ {
@@ -175,7 +186,9 @@ TxMeta::getAffectedNode(SLE::ref node, SField const& type)
mNodes.push_back(STObject(type)); mNodes.push_back(STObject(type));
STObject& obj = mNodes.back(); STObject& obj = mNodes.back();
assert(obj.getFName() == type); ASSERT(
obj.getFName() == type,
"ripple::TxMeta::getAffectedNode(SLE::ref) : field type match");
obj.setFieldH256(sfLedgerIndex, index); obj.setFieldH256(sfLedgerIndex, index);
obj.setFieldU16(sfLedgerEntryType, node->getFieldU16(sfLedgerEntryType)); obj.setFieldU16(sfLedgerEntryType, node->getFieldU16(sfLedgerEntryType));
@@ -190,7 +203,7 @@ TxMeta::getAffectedNode(uint256 const& node)
if (n.getFieldH256(sfLedgerIndex) == node) if (n.getFieldH256(sfLedgerIndex) == node)
return n; return n;
} }
assert(false); UNREACHABLE("ripple::TxMeta::getAffectedNode(uint256) : node not found");
Throw<std::runtime_error>("Affected node not found"); Throw<std::runtime_error>("Affected node not found");
return *(mNodes.begin()); // Silence compiler warning. return *(mNodes.begin()); // Silence compiler warning.
} }
@@ -199,7 +212,7 @@ STObject
TxMeta::getAsObject() const TxMeta::getAsObject() const
{ {
STObject metaData(sfTransactionMetaData); STObject metaData(sfTransactionMetaData);
assert(mResult != 255); ASSERT(mResult != 255, "ripple::TxMeta::getAsObject : result is set");
metaData.setFieldU8(sfTransactionResult, mResult); metaData.setFieldU8(sfTransactionResult, mResult);
metaData.setFieldU32(sfTransactionIndex, mIndex); metaData.setFieldU32(sfTransactionIndex, mIndex);
metaData.emplace_back(mNodes); metaData.emplace_back(mNodes);
@@ -213,7 +226,9 @@ TxMeta::addRaw(Serializer& s, TER result, std::uint32_t index)
{ {
mResult = TERtoInt(result); mResult = TERtoInt(result);
mIndex = index; mIndex = index;
assert((mResult == 0) || ((mResult > 100) && (mResult <= 255))); ASSERT(
(mResult == 0) || ((mResult > 100) && (mResult <= 255)),
"ripple::TxMeta::addRaw : valid TER input");
mNodes.sort([](STObject const& o1, STObject const& o2) { mNodes.sort([](STObject const& o1, STObject const& o2) {
return o1.getFieldH256(sfLedgerIndex) < o2.getFieldH256(sfLedgerIndex); return o1.getFieldH256(sfLedgerIndex) < o2.getFieldH256(sfLedgerIndex);

View File

@@ -28,6 +28,7 @@
#include <xrpl/protocol/tokens.h> #include <xrpl/protocol/tokens.h>
#include <xrpl/basics/safe_cast.h> #include <xrpl/basics/safe_cast.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/protocol/detail/b58_utils.h> #include <xrpl/protocol/detail/b58_utils.h>
#include <xrpl/protocol/digest.h> #include <xrpl/protocol/digest.h>
@@ -35,7 +36,6 @@
#include <boost/endian.hpp> #include <boost/endian.hpp>
#include <boost/endian/conversion.hpp> #include <boost/endian/conversion.hpp>
#include <cassert>
#include <cstring> #include <cstring>
#include <memory> #include <memory>
#include <type_traits> #include <type_traits>
@@ -248,7 +248,8 @@ encodeBase58(
iter[-1] = carry % 58; iter[-1] = carry % 58;
carry /= 58; carry /= 58;
} }
assert(carry == 0); ASSERT(
carry == 0, "ripple::b58_ref::detail::encodeBase58 : zero carry");
pbegin++; pbegin++;
} }
@@ -298,7 +299,8 @@ decodeBase58(std::string const& s)
*iter = carry % 256; *iter = carry % 256;
carry /= 256; carry /= 256;
} }
assert(carry == 0); ASSERT(
carry == 0, "ripple::b58_ref::detail::decodeBase58 : zero carry");
++psz; ++psz;
--remain; --remain;
} }
@@ -535,7 +537,9 @@ b58_to_b256_be(std::string_view input, std::span<std::uint8_t> out)
ripple::b58_fast::detail::div_rem(input.size(), 10); ripple::b58_fast::detail::div_rem(input.size(), 10);
auto const num_partial_coeffs = partial_coeff_len ? 1 : 0; auto const num_partial_coeffs = partial_coeff_len ? 1 : 0;
auto const num_b_58_10_coeffs = num_full_coeffs + num_partial_coeffs; auto const num_b_58_10_coeffs = num_full_coeffs + num_partial_coeffs;
assert(num_b_58_10_coeffs <= b_58_10_coeff.size()); ASSERT(
num_b_58_10_coeffs <= b_58_10_coeff.size(),
"ripple::b58_fast::detail::b58_to_b256_be : maximum coeff");
for (auto c : input.substr(0, partial_coeff_len)) for (auto c : input.substr(0, partial_coeff_len))
{ {
auto cur_val = ::ripple::alphabetReverse[c]; auto cur_val = ::ripple::alphabetReverse[c];

View File

@@ -17,10 +17,10 @@
*/ */
//============================================================================== //==============================================================================
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/resource/Consumer.h> #include <xrpl/resource/Consumer.h>
#include <xrpl/resource/detail/Entry.h> #include <xrpl/resource/detail/Entry.h>
#include <xrpl/resource/detail/Logic.h> #include <xrpl/resource/detail/Logic.h>
#include <cassert>
namespace ripple { namespace ripple {
namespace Resource { namespace Resource {
@@ -109,14 +109,18 @@ Consumer::charge(Charge const& what)
bool bool
Consumer::warn() Consumer::warn()
{ {
assert(m_entry != nullptr); ASSERT(
m_entry != nullptr,
"ripple::Resource::Consumer::warn : non-null entry");
return m_logic->warn(*m_entry); return m_logic->warn(*m_entry);
} }
bool bool
Consumer::disconnect(beast::Journal const& j) Consumer::disconnect(beast::Journal const& j)
{ {
assert(m_entry != nullptr); ASSERT(
m_entry != nullptr,
"ripple::Resource::Consumer::disconnect : non-null entry");
bool const d = m_logic->disconnect(*m_entry); bool const d = m_logic->disconnect(*m_entry);
if (d) if (d)
{ {
@@ -128,14 +132,18 @@ Consumer::disconnect(beast::Journal const& j)
int int
Consumer::balance() Consumer::balance()
{ {
assert(m_entry != nullptr); ASSERT(
m_entry != nullptr,
"ripple::Resource::Consumer::balance : non-null entry");
return m_logic->balance(*m_entry); return m_logic->balance(*m_entry);
} }
Entry& Entry&
Consumer::entry() Consumer::entry()
{ {
assert(m_entry != nullptr); ASSERT(
m_entry != nullptr,
"ripple::Resource::Consumer::entry : non-null entry");
return *m_entry; return *m_entry;
} }

View File

@@ -20,7 +20,6 @@
#include <test/jtx/Account.h> #include <test/jtx/Account.h>
#include <test/jtx/amount.h> #include <test/jtx/amount.h>
#include <xrpl/basics/safe_cast.h> #include <xrpl/basics/safe_cast.h>
#include <cassert>
#include <cmath> #include <cmath>
#include <iomanip> #include <iomanip>

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