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 Qi Zhao
parent 8458233a31
commit 6704194941
261 changed files with 3827 additions and 1034 deletions

View File

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

View File

@@ -343,6 +343,68 @@ pip3 install pre-commit
pre-commit install
```
## Contracts and instrumentation
We are using [Antithesis](https://antithesis.com/) for continuous fuzzing,
and keep a copy of [Antithesis C++ SDK](https://github.com/antithesishq/antithesis-sdk-cpp/)
in `external/antithesis-sdk`. One of the aims of fuzzing is to identify bugs
by finding external conditions which cause contracts violations inside `rippled`.
The contracts are expressed as `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
To execute all unit tests:

View File

@@ -120,7 +120,7 @@ else ()
target_link_libraries (common
INTERFACE
-rdynamic
$<$<BOOL:${is_linux}>:-Wl,-z,relro,-z,now>
$<$<BOOL:${is_linux}>:-Wl,-z,relro,-z,now,--build-id>
# link to static libc/c++ iff:
# * static option set and
# * NOT APPLE (AppleClang does not support static libc/c++) and
@@ -131,6 +131,17 @@ else ()
>)
endif ()
# Antithesis instrumentation will only be built and deployed using machines running Linux.
if (voidstar)
if (NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
message(FATAL_ERROR "Antithesis instrumentation requires Debug build type, aborting...")
elseif (NOT is_linux)
message(FATAL_ERROR "Antithesis instrumentation requires Linux, aborting...")
elseif (NOT (is_clang AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 16.0))
message(FATAL_ERROR "Antithesis instrumentation requires Clang version 16 or later, aborting...")
endif ()
endif ()
if (use_mold)
# use mold linker if available
execute_process (

View File

@@ -74,6 +74,7 @@ target_compile_definitions(xrpl.libxrpl
target_compile_options(xrpl.libxrpl
PUBLIC
$<$<BOOL:${is_gcc}>:-Wno-maybe-uninitialized>
$<$<BOOL:${voidstar}>:-DENABLE_VOIDSTAR>
)
target_link_libraries(xrpl.libxrpl
@@ -89,6 +90,7 @@ target_link_libraries(xrpl.libxrpl
secp256k1::secp256k1
xrpl.libpb
xxHash::xxhash
$<$<BOOL:${voidstar}>:antithesis-sdk-cpp>
)
if(xrpld)
@@ -129,6 +131,19 @@ if(xrpld)
target_compile_definitions(rippled PRIVATE RIPPLED_RUNNING_IN_CI)
endif ()
if(voidstar)
target_compile_options(rippled
PRIVATE
-fsanitize-coverage=trace-pc-guard
)
# rippled requires access to antithesis-sdk-cpp implementation file
# antithesis_instrumentation.h, which is not exported as INTERFACE
target_include_directories(rippled
PRIVATE
${CMAKE_SOURCE_DIR}/external/antithesis-sdk
)
endif()
# any files that don't play well with unity should be added here
if(tests)
set_source_files_properties(

View File

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

View File

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

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 |
|:----------------|:---------------------------------------------|:------------|
| `antithesis-sdk`| [Project](https://github.com/antithesishq/antithesis-sdk-cpp/) | [Antithesis](https://antithesis.com/docs/using_antithesis/sdk/cpp/overview.html) SDK for C++ |
| `ed25519-donna` | [Project](https://github.com/floodyberry/ed25519-donna) | [Ed25519](http://ed25519.cr.yp.to/) digital signatures |
| `rocksdb` | [Recipe](https://github.com/conan-io/conan-center-index/tree/master/recipes/rocksdb) | Fast key/value database. (Supports rotational disks better than NuDB.) |
| `secp256k1` | [Project](https://github.com/bitcoin-core/secp256k1) | ECDSA digital signatures using the **secp256k1** curve |

3
external/antithesis-sdk/.clang-format vendored Normal file
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
#include <xrpl/basics/Slice.h>
#include <cassert>
#include <xrpl/beast/utility/instrumentation.h>
#include <cstdint>
#include <cstring>
#include <memory>
@@ -112,9 +112,10 @@ public:
operator=(Slice s)
{
// Ensure the slice isn't a subset of the buffer.
assert(
ASSERT(
s.size() == 0 || size_ == 0 || s.data() < p_.get() ||
s.data() >= p_.get() + size_);
s.data() >= p_.get() + size_,
"ripple::Buffer::operator=(Slice) : input not a subset");
if (auto p = alloc(s.size()))
std::memcpy(p, s.data(), s.size());

View File

@@ -20,16 +20,16 @@
#define BASICS_FEES_H_INCLUDED
#include <xrpl/basics/XRPAmount.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <boost/multiprecision/cpp_int.hpp>
#include <limits>
#include <utility>
#include <cassert>
#include <cmath>
#include <ios>
#include <iosfwd>
#include <limits>
#include <sstream>
#include <string>
#include <utility>
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
// without a debugger.
assert(value.value() >= 0);
assert(mul.value() >= 0);
assert(div.value() >= 0);
ASSERT(
value.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;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1330,7 +1330,10 @@ public:
size_type
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()));
}
@@ -1471,7 +1474,10 @@ private:
{
if (would_exceed(additional))
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

View File

@@ -20,9 +20,10 @@
#ifndef BEAST_MODULE_CORE_TEXT_LEXICALCAST_H_INCLUDED
#define BEAST_MODULE_CORE_TEXT_LEXICALCAST_H_INCLUDED
#include <xrpl/beast/utility/instrumentation.h>
#include <boost/core/detail/string_view.hpp>
#include <algorithm>
#include <cassert>
#include <cerrno>
#include <charconv>
#include <cstdlib>
@@ -159,7 +160,9 @@ struct LexicalCast<Out, char const*>
bool
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);
}
};
@@ -174,7 +177,9 @@ struct LexicalCast<Out, char*>
bool
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);
}
};

View File

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

View File

@@ -20,8 +20,8 @@
#ifndef BEAST_NET_IPADDRESSV6_H_INCLUDED
#define BEAST_NET_IPADDRESSV6_H_INCLUDED
#include <xrpl/beast/utility/instrumentation.h>
#include <boost/asio/ip/address_v6.hpp>
#include <cassert>
#include <cstdint>
#include <functional>
#include <ios>

View File

@@ -20,7 +20,7 @@
#ifndef BEAST_UTILITY_JOURNAL_H_INCLUDED
#define BEAST_UTILITY_JOURNAL_H_INCLUDED
#include <cassert>
#include <xrpl/beast/utility/instrumentation.h>
#include <sstream>
namespace beast {
@@ -205,7 +205,9 @@ public:
*/
Stream(Sink& sink, Severity level) : m_sink(sink), m_level(level)
{
assert(m_level < severities::kDisabled);
ASSERT(
m_level < severities::kDisabled,
"beast::Journal::Stream::Stream : maximum level");
}
/** 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
#define BEAST_RANDOM_RNGFILL_H_INCLUDED
#include <xrpl/beast/utility/instrumentation.h>
#include <array>
#include <cassert>
#include <cstdint>
#include <cstring>
#include <type_traits>
@@ -42,7 +42,8 @@ rngfill(void* buffer, std::size_t bytes, Generator& g)
bytes -= sizeof(v);
}
assert(bytes < sizeof(result_type));
ASSERT(
bytes < sizeof(result_type), "beast::rngfill(void*) : maximum bytes");
#ifdef __GNUC__
// gcc 11.1 (falsely) warns about an array-bounds overflow in release mode.

View File

@@ -22,9 +22,6 @@
#include <xrpl/json/json_errors.h>
#define JSON_ASSERT_UNREACHABLE assert(false)
#define JSON_ASSERT(condition) \
assert(condition); // @todo <= change this into an exception throw
#define JSON_ASSERT_MESSAGE(condition, message) \
if (!(condition)) \
ripple::Throw<Json::error>(message);

View File

@@ -53,7 +53,9 @@ toSTAmount(XRPAmount const& xrp)
inline STAmount
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);
}
@@ -72,12 +74,14 @@ template <>
inline IOUAmount
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();
std::int64_t const sMant =
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());
}
@@ -85,12 +89,14 @@ template <>
inline XRPAmount
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();
std::int64_t const sMant =
isNeg ? -std::int64_t(amt.mantissa()) : amt.mantissa();
assert(isXRP(amt));
ASSERT(isXRP(amt), "ripple::toAmount<XRPAmount> : is XRP");
return XRPAmount(sMant);
}

View File

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

View File

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

View File

@@ -20,10 +20,10 @@
#ifndef RIPPLE_PROTOCOL_ISSUE_H_INCLUDED
#define RIPPLE_PROTOCOL_ISSUE_H_INCLUDED
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/json/json_value.h>
#include <xrpl/protocol/UintTypes.h>
#include <cassert>
#include <functional>
#include <type_traits>

View File

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

View File

@@ -298,7 +298,9 @@ public:
friend double
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
return 0;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -25,6 +25,7 @@
#include <xrpl/basics/Slice.h>
#include <xrpl/basics/chrono.h>
#include <xrpl/basics/contract.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/protocol/HashPrefix.h>
#include <xrpl/protocol/SOTemplate.h>
#include <xrpl/protocol/STAmount.h>
@@ -35,7 +36,6 @@
#include <xrpl/protocol/STVector256.h>
#include <xrpl/protocol/detail/STVar.h>
#include <boost/iterator/transform_iterator.hpp>
#include <cassert>
#include <optional>
#include <stdexcept>
#include <type_traits>
@@ -737,7 +737,8 @@ STObject::Proxy<T>::assign(U&& u)
t = dynamic_cast<T*>(st_->getPField(*f_, true));
else
t = dynamic_cast<T*>(st_->makeFieldPresent(*f_));
assert(t);
ASSERT(
t != nullptr, "ripple::STObject::Proxy::assign : type cast succeeded");
*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))
return u->value();
assert(mType);
assert(b->getSType() == STI_NOTPRESENT);
ASSERT(
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)
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,
// 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);
if (!u)
{
assert(mType);
assert(b->getSType() == STI_NOTPRESENT);
ASSERT(
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)
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 u->value();

View File

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

View File

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

View File

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

View File

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

View File

@@ -21,12 +21,12 @@
#define RIPPLE_PROTOCOL_B58_UTILS_H_INCLUDED
#include <xrpl/basics/contract.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/protocol/detail/token_errors.h>
#include <boost/outcome.hpp>
#include <boost/outcome/result.hpp>
#include <cassert>
#include <cinttypes>
#include <span>
#include <system_error>
@@ -130,7 +130,9 @@ inplace_bigint_div_rem(std::span<uint64_t> numerator, std::uint64_t divisor)
{
// should never happen, but if it does then it seems natural to define
// the a null set of numbers to be zero, so the remainder is also zero.
assert(0);
UNREACHABLE(
"ripple::b58_fast::detail::inplace_bigint_div_rem : empty "
"numerator");
return 0;
}
@@ -146,8 +148,14 @@ inplace_bigint_div_rem(std::span<uint64_t> numerator, std::uint64_t divisor)
unsigned __int128 const denom128 = denom;
unsigned __int128 const d = num / denom128;
unsigned __int128 const r = num - (denom128 * d);
assert(d >> 64 == 0);
assert(r >> 64 == 0);
ASSERT(
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)};
};
@@ -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)
{
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;
std::array<std::uint8_t, resultSize> result{};
int i = 0;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -21,17 +21,21 @@
#define RIPPLE_SERVER_BASEWSPEER_H_INCLUDED
#include <xrpl/basics/safe_cast.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/beast/utility/rngfill.h>
#include <xrpl/crypto/csprng.h>
#include <xrpl/protocol/BuildInfo.h>
#include <xrpl/server/WSSession.h>
#include <xrpl/server/detail/BasePeer.h>
#include <xrpl/server/detail/LowestLayer.h>
#include <boost/beast/core/multi_buffer.hpp>
#include <boost/beast/http/message.hpp>
#include <boost/beast/websocket.hpp>
#include <boost/logic/tribool.hpp>
#include <cassert>
#include <functional>
#include <list>
namespace ripple {
@@ -508,7 +512,9 @@ template <class String>
void
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();
if (!ec_ && ec != boost::asio::error::operation_aborted)

View File

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

View File

@@ -18,9 +18,9 @@
//==============================================================================
#include <xrpl/basics/Number.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <boost/predef.h>
#include <algorithm>
#include <cassert>
#include <numeric>
#include <stdexcept>
#include <type_traits>
@@ -235,7 +235,9 @@ Number::operator+=(Number const& y)
*this = Number{};
return *this;
}
assert(isnormal() && y.isnormal());
ASSERT(
isnormal() && y.isnormal(),
"ripple::Number::operator+=(Number) : is normal");
auto xm = mantissa();
auto xe = exponent();
int xn = 1;
@@ -374,7 +376,9 @@ Number::operator*=(Number const& y)
*this = y;
return *this;
}
assert(isnormal() && y.isnormal());
ASSERT(
isnormal() && y.isnormal(),
"ripple::Number::operator*=(Number) : is normal");
auto xm = mantissa();
auto xe = exponent();
int xn = 1;
@@ -428,7 +432,9 @@ Number::operator*=(Number const& y)
std::to_string(xe));
mantissa_ = xm * zn;
exponent_ = xe;
assert(isnormal() || *this == Number{});
ASSERT(
isnormal() || *this == Number{},
"ripple::Number::operator*=(Number) : result is normal");
return *this;
}
@@ -536,7 +542,7 @@ to_string(Number const& amount)
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_suffix = 23;
@@ -562,7 +568,9 @@ to_string(Number const& amount)
if (std::distance(pre_from, pre_to) > 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'; });
@@ -571,7 +579,9 @@ to_string(Number const& amount)
if (std::distance(post_from, 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(
std::make_reverse_iterator(post_to),

View File

@@ -21,9 +21,9 @@
#include <xrpl/basics/ResolverAsio.h>
#include <xrpl/beast/net/IPAddressConversion.h>
#include <xrpl/beast/net/IPEndpoint.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <boost/asio.hpp>
#include <atomic>
#include <cassert>
#include <condition_variable>
#include <deque>
#include <locale>
@@ -48,7 +48,9 @@ public:
~AsyncObject()
{
// 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.
@@ -153,8 +155,11 @@ public:
~ResolverAsioImpl() override
{
assert(m_work.empty());
assert(m_stopped);
ASSERT(
m_work.empty(),
"ripple::ResolverAsioImpl::~ResolverAsioImpl : no pending work");
ASSERT(
m_stopped, "ripple::ResolverAsioImpl::~ResolverAsioImpl : stopped");
}
//-------------------------------------------------------------------------
@@ -176,8 +181,10 @@ public:
void
start() override
{
assert(m_stopped == true);
assert(m_stop_called == false);
ASSERT(m_stopped == true, "ripple::ResolverAsioImpl::start : stopped");
ASSERT(
m_stop_called == false,
"ripple::ResolverAsioImpl::start : not stopping");
if (m_stopped.exchange(false) == true)
{
@@ -217,8 +224,12 @@ public:
resolve(std::vector<std::string> const& names, HandlerType const& handler)
override
{
assert(m_stop_called == false);
assert(!names.empty());
ASSERT(
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
// reducing cost.
@@ -235,7 +246,9 @@ public:
void
do_stop(CompletionCounter)
{
assert(m_stop_called == true);
ASSERT(
m_stop_called == true,
"ripple::ResolverAsioImpl::do_stop : stopping");
if (m_stopped.exchange(true) == false)
{
@@ -381,7 +394,9 @@ public:
HandlerType const& handler,
CompletionCounter)
{
assert(!names.empty());
ASSERT(
!names.empty(),
"ripple::ResolverAsioImpl::do_resolve : names non-empty");
if (m_stop_called == false)
{

View File

@@ -19,6 +19,7 @@
#include <xrpl/basics/Log.h>
#include <xrpl/basics/contract.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <cstdlib>
#include <iostream>
@@ -48,6 +49,12 @@ LogicError(std::string const& s) noexcept
{
JLOG(debugLog().fatal()) << s;
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();
}

View File

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

View File

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

View File

@@ -25,8 +25,8 @@
#include <xrpl/beast/insight/MeterImpl.h>
#include <xrpl/beast/insight/StatsDCollector.h>
#include <xrpl/beast/net/IPAddressConversion.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <boost/asio/ip/tcp.hpp>
#include <cassert>
#include <climits>
#include <deque>
#include <functional>
@@ -400,7 +400,10 @@ public:
for (auto const& s : *keepAlive)
{
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)
{
log(buffers);

View File

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

View File

@@ -18,8 +18,8 @@
//==============================================================================
#include <xrpl/beast/utility/PropertyStream.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <algorithm>
#include <cassert>
#include <iostream>
#include <limits>
@@ -199,7 +199,9 @@ PropertyStream::Source::add(Source& source)
std::lock_guard lk1(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_);
source.parent_ = this;
}
@@ -211,7 +213,9 @@ PropertyStream::Source::remove(Source& child)
std::lock_guard lk1(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_));
child.parent_ = nullptr;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -77,7 +77,9 @@ public:
auto ret =
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);

View File

@@ -17,9 +17,9 @@
*/
//==============================================================================
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/protocol/ErrorCodes.h>
#include <array>
#include <cassert>
#include <stdexcept>
namespace ripple {
@@ -211,7 +211,9 @@ error_code_http_status(error_code_i code)
std::string
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();
}

View File

@@ -221,7 +221,9 @@ FeatureCollections::FeatureCollections()
std::optional<uint256>
FeatureCollections::getRegisteredFeature(std::string const& name) const
{
assert(readOnly);
ASSERT(
readOnly.load(),
"ripple::FeatureCollections::getRegisteredFeature : startup completed");
Feature const* feature = getByName(name);
if (feature)
return feature->feature;
@@ -303,7 +305,9 @@ FeatureCollections::registrationIsDone()
size_t
FeatureCollections::featureToBitsetIndex(uint256 const& f) const
{
assert(readOnly);
ASSERT(
readOnly.load(),
"ripple::FeatureCollections::featureToBitsetIndex : startup completed");
Feature const* feature = getByFeature(f);
if (!feature)
@@ -315,7 +319,9 @@ FeatureCollections::featureToBitsetIndex(uint256 const& f) const
uint256 const&
FeatureCollections::bitsetIndexToFeature(size_t i) const
{
assert(readOnly);
ASSERT(
readOnly.load(),
"ripple::FeatureCollections::bitsetIndexToFeature : startup completed");
Feature const& feature = getByIndex(i);
return feature.feature;
}
@@ -323,7 +329,9 @@ FeatureCollections::bitsetIndexToFeature(size_t i) const
std::string
FeatureCollections::featureToName(uint256 const& f) const
{
assert(readOnly);
ASSERT(
readOnly.load(),
"ripple::FeatureCollections::featureToName : startup completed");
Feature const* feature = getByFeature(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/LedgerFormats.h>
#include <xrpl/protocol/SField.h>
@@ -26,7 +27,6 @@
#include <xrpl/protocol/nftPageMask.h>
#include <algorithm>
#include <cassert>
namespace ripple {
@@ -95,7 +95,7 @@ indexHash(LedgerNameSpace space, Args const&... args)
uint256
getBookBase(Book const& book)
{
assert(isConsistent(book));
ASSERT(isConsistent(book), "ripple::getBookBase : input is consistent");
auto const index = indexHash(
LedgerNameSpace::BOOK_DIR,
@@ -135,7 +135,7 @@ getTicketIndex(AccountID const& account, std::uint32_t ticketSeq)
uint256
getTicketIndex(AccountID const& account, SeqProxy ticketSeq)
{
assert(ticketSeq.isTicket());
ASSERT(ticketSeq.isTicket(), "ripple::getTicketIndex : valid input");
return getTicketIndex(account, ticketSeq.value());
}
@@ -222,7 +222,7 @@ line(
// 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
// 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
// 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
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.
// Most significant bytes are first and the least significant bytes
@@ -269,7 +269,9 @@ quality(Keylet const& k, std::uint64_t q) noexcept
Keylet
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)};
}
@@ -387,7 +389,8 @@ nftpage_max(AccountID const& owner)
Keylet
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)};
}

View File

@@ -25,7 +25,9 @@ namespace ripple {
bool
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)
return true;

View File

@@ -17,8 +17,8 @@
*/
//==============================================================================
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/protocol/Quality.h>
#include <cassert>
#include <limits>
namespace ripple {
@@ -35,7 +35,7 @@ Quality::Quality(Amounts const& amount)
Quality&
Quality::operator++()
{
assert(m_value > 0);
ASSERT(m_value > 0, "ripple::Quality::operator++() : minimum value");
--m_value;
return *this;
}
@@ -51,7 +51,9 @@ Quality::operator++(int)
Quality&
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;
return *this;
}
@@ -81,10 +83,11 @@ ceil_in_impl(
// Clamp out
if (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;
}
assert(amount.in <= limit);
ASSERT(amount.in <= limit, "ripple::ceil_in_impl : result inside limit");
return amount;
}
@@ -120,10 +123,12 @@ ceil_out_impl(
// Clamp in
if (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;
}
assert(amount.out <= limit);
ASSERT(amount.out <= limit, "ripple::ceil_out_impl : result inside limit");
return amount;
}
@@ -146,17 +151,23 @@ Quality
composed_quality(Quality const& lhs, Quality const& rhs)
{
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());
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));
std::uint64_t const stored_exponent(rate.exponent() + 100);
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);
}

View File

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

View File

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

View File

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

View File

@@ -80,8 +80,10 @@ STAccount::getSType() const
void
STAccount::add(Serializer& s) const
{
assert(getFName().isBinary());
assert(getFName().fieldType == STI_ACCOUNT);
ASSERT(getFName().isBinary(), "ripple::STAccount::add : field is binary");
ASSERT(
getFName().fieldType == STI_ACCOUNT,
"ripple::STAccount::add : valid field type");
// Preserve the serialization behavior of an STBlob:
// 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/multiprecision/cpp_int.hpp>
#include <boost/regex.hpp>
#include <iostream>
#include <iterator>
#include <memory>
@@ -68,11 +68,13 @@ getInt64Value(STAmount const& amount, bool valid, const char* error)
{
if (!valid)
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());
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())
ret = -ret;
@@ -199,7 +201,10 @@ STAmount::STAmount(SField const& name, std::uint64_t mantissa, bool negative)
, mOffset(0)
, 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)
@@ -209,7 +214,9 @@ STAmount::STAmount(SField const& name, STAmount const& from)
, mOffset(from.mOffset)
, 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();
}
@@ -221,7 +228,10 @@ STAmount::STAmount(std::uint64_t mantissa, bool negative)
, mOffset(0)
, 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)
@@ -305,7 +315,9 @@ STAmount::mpt() const
STAmount&
STAmount::operator=(IOUAmount const& iou)
{
assert(native() == false);
ASSERT(
native() == false,
"ripple::STAmount::operator=(IOUAmount) : is not XRP");
mOffset = iou.exponent();
mIsNegative = iou < beast::zero;
if (mIsNegative)
@@ -444,7 +456,9 @@ getRate(STAmount const& offerOut, STAmount const& offerIn)
STAmount r = divide(offerIn, offerOut, noIssue());
if (r == beast::zero) // offer is too good
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;
return (ret << (64 - 8)) | r.mantissa();
}
@@ -525,7 +539,7 @@ STAmount::getText() const
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_suffix = 23;
@@ -549,7 +563,9 @@ STAmount::getText() const
if (std::distance(pre_from, pre_to) > 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'; });
@@ -558,7 +574,9 @@ STAmount::getText() const
if (std::distance(post_from, 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(
std::make_reverse_iterator(post_to),
@@ -594,7 +612,7 @@ STAmount::add(Serializer& s) const
{
if (native())
{
assert(mOffset == 0);
ASSERT(mOffset == 0, "ripple::STAmount::add : zero offset");
if (!mIsNegative)
s.add64(mValue | cPositive);
@@ -771,10 +789,15 @@ STAmount::canonicalize()
if (mOffset > cMaxOffset)
Throw<std::runtime_error>("value overflow");
assert((mValue == 0) || ((mValue >= cMinValue) && (mValue <= cMaxValue)));
assert(
(mValue == 0) || ((mOffset >= cMinOffset) && (mOffset <= cMaxOffset)));
assert((mValue != 0) || (mOffset != -100));
ASSERT(
(mValue == 0) || ((mValue >= cMinValue) && (mValue <= cMaxValue)),
"ripple::STAmount::canonicalize : value inside range");
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

View File

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

View File

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

View File

@@ -199,12 +199,16 @@ Json::Value
STUInt64::getJson(JsonOptions) const
{
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(
base == 10 ? 20 : 16, 0); // Allocate space depending on base
auto ret =
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));
return str;
};

View File

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

View File

@@ -19,6 +19,7 @@
#include <xrpl/protocol/STNumber.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/protocol/SField.h>
namespace ripple {
@@ -52,8 +53,10 @@ STNumber::getText() const
void
STNumber::add(Serializer& s) const
{
assert(getFName().isBinary());
assert(getFName().fieldType == getSType());
ASSERT(getFName().isBinary(), "ripple::STNumber::add : field is binary");
ASSERT(
getFName().fieldType == getSType(),
"ripple::STNumber::add : field type match");
s.add64(value_.mantissa());
s.add32(value_.exponent());
}
@@ -85,7 +88,9 @@ STNumber::move(std::size_t n, void* buf)
bool
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);
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
// must be OBJECT, or the object cannot be deserialized
SerializedTypeID const sType{field->getSType()};
assert(
ASSERT(
(sType != STI_OBJECT) ||
(field->getFName().fieldType == STI_OBJECT));
(field->getFName().fieldType == STI_OBJECT),
"ripple::STObject::add : valid field type");
field->addFieldID(s);
field->add(s);
if (sType == STI_ARRAY || sType == STI_OBJECT)

View File

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

View File

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

View File

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

View File

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

View File

@@ -121,7 +121,9 @@ STVar::STVar(SerialIter& sit, SField const& name, int depth)
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);
}

View File

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

View File

@@ -107,7 +107,9 @@ int
Serializer::addFieldID(int type, int name)
{
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)
{
@@ -176,9 +178,10 @@ Serializer::addVL(Blob const& vector)
{
int ret = addEncoded(vector.size());
addRaw(vector);
assert(
ASSERT(
mData.size() ==
(ret + vector.size() + encodeLengthLength(vector.size())));
(ret + vector.size() + encodeLengthLength(vector.size())),
"ripple::Serializer::addVL : size matches expected");
return ret;
}
@@ -482,7 +485,8 @@ SerialIter::getVLDataLength()
}
else
{
assert(lenLen == 3);
ASSERT(
lenLen == 3, "ripple::SerialIter::getVLDataLength : lenLen is 3");
int b2 = get8();
int b3 = get8();
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 =
dynamic_cast<STArray const*>(obj.peekAtPField(sfAffectedNodes));
assert(affectedNodes);
ASSERT(
affectedNodes != nullptr,
"ripple::TxMeta::TxMeta(STObject) : type cast succeeded");
if (affectedNodes)
mNodes = *affectedNodes;
@@ -106,7 +108,9 @@ TxMeta::setAffectedNode(
mNodes.push_back(STObject(type));
STObject& obj = mNodes.back();
assert(obj.getFName() == type);
ASSERT(
obj.getFName() == type,
"ripple::TxMeta::setAffectedNode : field type match");
obj.setFieldH256(sfLedgerIndex, node);
obj.setFieldU16(sfLedgerEntryType, nodeType);
}
@@ -127,14 +131,18 @@ TxMeta::getAffectedAccounts() const
if (index != -1)
{
auto inner = dynamic_cast<STObject const*>(&it.peekAtIndex(index));
assert(inner);
ASSERT(
inner != nullptr,
"ripple::getAffectedAccounts : STObject type cast succeeded");
if (inner)
{
for (auto const& field : *inner)
{
if (auto sa = dynamic_cast<STAccount const*>(&field))
{
assert(!sa->isDefault());
ASSERT(
!sa->isDefault(),
"ripple::getAffectedAccounts : account is set");
if (!sa->isDefault())
list.insert(sa->value());
}
@@ -145,7 +153,10 @@ TxMeta::getAffectedAccounts() const
(field.getFName() == sfTakerGets))
{
auto lim = dynamic_cast<STAmount const*>(&field);
assert(lim);
ASSERT(
lim != nullptr,
"ripple::getAffectedAccounts : STAmount type cast "
"succeeded");
if (lim != nullptr)
{
@@ -175,7 +186,9 @@ TxMeta::getAffectedNode(SLE::ref node, SField const& type)
mNodes.push_back(STObject(type));
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.setFieldU16(sfLedgerEntryType, node->getFieldU16(sfLedgerEntryType));
@@ -190,7 +203,7 @@ TxMeta::getAffectedNode(uint256 const& node)
if (n.getFieldH256(sfLedgerIndex) == node)
return n;
}
assert(false);
UNREACHABLE("ripple::TxMeta::getAffectedNode(uint256) : node not found");
Throw<std::runtime_error>("Affected node not found");
return *(mNodes.begin()); // Silence compiler warning.
}
@@ -199,7 +212,7 @@ STObject
TxMeta::getAsObject() const
{
STObject metaData(sfTransactionMetaData);
assert(mResult != 255);
ASSERT(mResult != 255, "ripple::TxMeta::getAsObject : result is set");
metaData.setFieldU8(sfTransactionResult, mResult);
metaData.setFieldU32(sfTransactionIndex, mIndex);
metaData.emplace_back(mNodes);
@@ -213,7 +226,9 @@ TxMeta::addRaw(Serializer& s, TER result, std::uint32_t index)
{
mResult = TERtoInt(result);
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) {
return o1.getFieldH256(sfLedgerIndex) < o2.getFieldH256(sfLedgerIndex);

View File

@@ -28,6 +28,7 @@
#include <xrpl/protocol/tokens.h>
#include <xrpl/basics/safe_cast.h>
#include <xrpl/beast/utility/instrumentation.h>
#include <xrpl/protocol/detail/b58_utils.h>
#include <xrpl/protocol/digest.h>
@@ -35,7 +36,6 @@
#include <boost/endian.hpp>
#include <boost/endian/conversion.hpp>
#include <cassert>
#include <cstring>
#include <memory>
#include <type_traits>
@@ -248,7 +248,8 @@ encodeBase58(
iter[-1] = carry % 58;
carry /= 58;
}
assert(carry == 0);
ASSERT(
carry == 0, "ripple::b58_ref::detail::encodeBase58 : zero carry");
pbegin++;
}
@@ -298,7 +299,8 @@ decodeBase58(std::string const& s)
*iter = carry % 256;
carry /= 256;
}
assert(carry == 0);
ASSERT(
carry == 0, "ripple::b58_ref::detail::decodeBase58 : zero carry");
++psz;
--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);
auto const num_partial_coeffs = partial_coeff_len ? 1 : 0;
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))
{
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/detail/Entry.h>
#include <xrpl/resource/detail/Logic.h>
#include <cassert>
namespace ripple {
namespace Resource {
@@ -109,14 +109,18 @@ Consumer::charge(Charge const& what, std::string const& context)
bool
Consumer::warn()
{
assert(m_entry != nullptr);
ASSERT(
m_entry != nullptr,
"ripple::Resource::Consumer::warn : non-null entry");
return m_logic->warn(*m_entry);
}
bool
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);
if (d)
{
@@ -128,14 +132,18 @@ Consumer::disconnect(beast::Journal const& j)
int
Consumer::balance()
{
assert(m_entry != nullptr);
ASSERT(
m_entry != nullptr,
"ripple::Resource::Consumer::balance : non-null entry");
return m_logic->balance(*m_entry);
}
Entry&
Consumer::entry()
{
assert(m_entry != nullptr);
ASSERT(
m_entry != nullptr,
"ripple::Resource::Consumer::entry : non-null entry");
return *m_entry;
}

View File

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

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