mirror of
https://github.com/XRPLF/rippled.git
synced 2026-04-29 15:37:57 +00:00
Merge branch 'develop' into vlntb/refactore-barrier-semaphore
This commit is contained in:
5
.github/workflows/macos.yml
vendored
5
.github/workflows/macos.yml
vendored
@@ -96,4 +96,7 @@ jobs:
|
||||
run: |
|
||||
n=$(nproc)
|
||||
echo "Using $n test jobs"
|
||||
${build_dir}/rippled --unittest --unittest-jobs $n
|
||||
|
||||
cd ${build_dir}
|
||||
./rippled --unittest --unittest-jobs $n
|
||||
ctest -j $n --output-on-failure
|
||||
|
||||
10
.github/workflows/nix.yml
vendored
10
.github/workflows/nix.yml
vendored
@@ -163,7 +163,9 @@ jobs:
|
||||
cmake-args: "-Dassert=TRUE -Dwerr=TRUE ${{ matrix.cmake-args }}"
|
||||
- name: test
|
||||
run: |
|
||||
${build_dir}/rippled --unittest --unittest-jobs $(nproc)
|
||||
cd ${build_dir}
|
||||
./rippled --unittest --unittest-jobs $(nproc)
|
||||
ctest -j $(nproc) --output-on-failure
|
||||
|
||||
reference-fee-test:
|
||||
strategy:
|
||||
@@ -217,8 +219,9 @@ jobs:
|
||||
cmake-args: "-Dassert=TRUE -Dwerr=TRUE ${{ matrix.cmake-args }}"
|
||||
- name: test
|
||||
run: |
|
||||
${build_dir}/rippled --unittest --unittest-jobs $(nproc)
|
||||
|
||||
cd ${build_dir}
|
||||
./rippled --unittest --unittest-jobs $(nproc)
|
||||
ctest -j $(nproc) --output-on-failure
|
||||
coverage:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
@@ -441,3 +444,4 @@ jobs:
|
||||
run: |
|
||||
cd ${BUILD_DIR}
|
||||
./rippled -u --unittest-jobs $(( $(nproc)/4 ))
|
||||
ctest -j $(nproc) --output-on-failure
|
||||
|
||||
5
.github/workflows/windows.yml
vendored
5
.github/workflows/windows.yml
vendored
@@ -95,5 +95,6 @@ jobs:
|
||||
shell: bash
|
||||
if: ${{ matrix.configuration.tests }}
|
||||
run: |
|
||||
${build_dir}/${{ matrix.configuration.type }}/rippled --unittest \
|
||||
--unittest-jobs $(nproc)
|
||||
cd ${build_dir}/${{ matrix.configuration.type }}
|
||||
./rippled --unittest --unittest-jobs $(nproc)
|
||||
ctest -j $(nproc) --output-on-failure
|
||||
|
||||
@@ -132,6 +132,7 @@ test.shamap > xrpl.protocol
|
||||
test.toplevel > test.csf
|
||||
test.toplevel > xrpl.json
|
||||
test.unit_test > xrpl.basics
|
||||
tests.libxrpl > xrpl.basics
|
||||
xrpl.json > xrpl.basics
|
||||
xrpl.protocol > xrpl.basics
|
||||
xrpl.protocol > xrpl.json
|
||||
|
||||
@@ -90,6 +90,11 @@ set_target_properties(OpenSSL::SSL PROPERTIES
|
||||
INTERFACE_COMPILE_DEFINITIONS OPENSSL_NO_SSL2
|
||||
)
|
||||
set(SECP256K1_INSTALL TRUE)
|
||||
set(SECP256K1_BUILD_BENCHMARK FALSE)
|
||||
set(SECP256K1_BUILD_TESTS FALSE)
|
||||
set(SECP256K1_BUILD_EXHAUSTIVE_TESTS FALSE)
|
||||
set(SECP256K1_BUILD_CTIME_TESTS FALSE)
|
||||
set(SECP256K1_BUILD_EXAMPLES FALSE)
|
||||
add_subdirectory(external/secp256k1)
|
||||
add_library(secp256k1::secp256k1 ALIAS secp256k1)
|
||||
add_subdirectory(external/ed25519-donna)
|
||||
@@ -144,3 +149,8 @@ set(PROJECT_EXPORT_SET RippleExports)
|
||||
include(RippledCore)
|
||||
include(RippledInstall)
|
||||
include(RippledValidatorKeys)
|
||||
|
||||
if(tests)
|
||||
include(CTest)
|
||||
add_subdirectory(src/tests/libxrpl)
|
||||
endif()
|
||||
|
||||
41
cmake/xrpl_add_test.cmake
Normal file
41
cmake/xrpl_add_test.cmake
Normal file
@@ -0,0 +1,41 @@
|
||||
include(isolate_headers)
|
||||
|
||||
function(xrpl_add_test name)
|
||||
set(target ${PROJECT_NAME}.test.${name})
|
||||
|
||||
file(GLOB_RECURSE sources CONFIGURE_DEPENDS
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/${name}/*.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/${name}.cpp"
|
||||
)
|
||||
add_executable(${target} EXCLUDE_FROM_ALL ${ARGN} ${sources})
|
||||
|
||||
isolate_headers(
|
||||
${target}
|
||||
"${CMAKE_SOURCE_DIR}"
|
||||
"${CMAKE_SOURCE_DIR}/tests/${name}"
|
||||
PRIVATE
|
||||
)
|
||||
|
||||
# Make sure the test isn't optimized away in unity builds
|
||||
set_target_properties(${target} PROPERTIES
|
||||
UNITY_BUILD_MODE GROUP
|
||||
UNITY_BUILD_BATCH_SIZE 0) # Adjust as needed
|
||||
|
||||
add_test(NAME ${target} COMMAND ${target})
|
||||
set_tests_properties(
|
||||
${target} PROPERTIES
|
||||
FIXTURES_REQUIRED ${target}_fixture
|
||||
)
|
||||
|
||||
add_test(
|
||||
NAME ${target}.build
|
||||
COMMAND
|
||||
${CMAKE_COMMAND}
|
||||
--build ${CMAKE_BINARY_DIR}
|
||||
--config $<CONFIG>
|
||||
--target ${target}
|
||||
)
|
||||
set_tests_properties(${target}.build PROPERTIES
|
||||
FIXTURES_SETUP ${target}_fixture
|
||||
)
|
||||
endfunction()
|
||||
@@ -24,6 +24,7 @@ class Xrpl(ConanFile):
|
||||
}
|
||||
|
||||
requires = [
|
||||
'doctest/2.4.11',
|
||||
'grpc/1.50.1',
|
||||
'libarchive/3.7.6',
|
||||
'nudb/2.0.8',
|
||||
|
||||
@@ -61,6 +61,13 @@
|
||||
* 2) The feature is not in the ledger (has always been marked as
|
||||
* Supported::no) and the code to support it has been removed
|
||||
*
|
||||
* If we want to discontinue a feature that we've never fully supported and
|
||||
* the feature has never been enabled, we should remove all the related
|
||||
* code, and mark the feature as "abandoned". To do this:
|
||||
*
|
||||
* 1) Open features.macro, move the feature to the abandoned section and
|
||||
* change the macro to XRPL_ABANDON
|
||||
*
|
||||
* When a feature has been enabled for several years, the conditional code
|
||||
* may be removed, and the feature "retired". To retire a feature:
|
||||
*
|
||||
@@ -93,10 +100,13 @@ namespace detail {
|
||||
#undef XRPL_FIX
|
||||
#pragma push_macro("XRPL_RETIRE")
|
||||
#undef XRPL_RETIRE
|
||||
#pragma push_macro("XRPL_ABANDON")
|
||||
#undef XRPL_ABANDON
|
||||
|
||||
#define XRPL_FEATURE(name, supported, vote) +1
|
||||
#define XRPL_FIX(name, supported, vote) +1
|
||||
#define XRPL_RETIRE(name) +1
|
||||
#define XRPL_ABANDON(name) +1
|
||||
|
||||
// This value SHOULD be equal to the number of amendments registered in
|
||||
// Feature.cpp. Because it's only used to reserve storage, and determine how
|
||||
@@ -113,6 +123,8 @@ static constexpr std::size_t numFeatures =
|
||||
#pragma pop_macro("XRPL_FIX")
|
||||
#undef XRPL_FEATURE
|
||||
#pragma pop_macro("XRPL_FEATURE")
|
||||
#undef XRPL_ABANDON
|
||||
#pragma pop_macro("XRPL_ABANDON")
|
||||
|
||||
/** Amendments that this server supports and the default voting behavior.
|
||||
Whether they are enabled depends on the Rules defined in the validated
|
||||
@@ -354,10 +366,13 @@ foreachFeature(FeatureBitset bs, F&& f)
|
||||
#undef XRPL_FIX
|
||||
#pragma push_macro("XRPL_RETIRE")
|
||||
#undef XRPL_RETIRE
|
||||
#pragma push_macro("XRPL_ABANDON")
|
||||
#undef XRPL_ABANDON
|
||||
|
||||
#define XRPL_FEATURE(name, supported, vote) extern uint256 const feature##name;
|
||||
#define XRPL_FIX(name, supported, vote) extern uint256 const fix##name;
|
||||
#define XRPL_RETIRE(name)
|
||||
#define XRPL_ABANDON(name)
|
||||
|
||||
#include <xrpl/protocol/detail/features.macro>
|
||||
|
||||
@@ -367,6 +382,8 @@ foreachFeature(FeatureBitset bs, F&& f)
|
||||
#pragma pop_macro("XRPL_FIX")
|
||||
#undef XRPL_FEATURE
|
||||
#pragma pop_macro("XRPL_FEATURE")
|
||||
#undef XRPL_ABANDON
|
||||
#pragma pop_macro("XRPL_ABANDON")
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
|
||||
@@ -26,6 +26,9 @@
|
||||
#if !defined(XRPL_RETIRE)
|
||||
#error "undefined macro: XRPL_RETIRE"
|
||||
#endif
|
||||
#if !defined(XRPL_ABANDON)
|
||||
#error "undefined macro: XRPL_ABANDON"
|
||||
#endif
|
||||
|
||||
// Add new amendments to the top of this list.
|
||||
// Keep it sorted in reverse chronological order.
|
||||
@@ -130,8 +133,11 @@ XRPL_FIX (NFTokenNegOffer, Supported::yes, VoteBehavior::Obsolete)
|
||||
XRPL_FIX (NFTokenDirV1, Supported::yes, VoteBehavior::Obsolete)
|
||||
XRPL_FEATURE(NonFungibleTokensV1, Supported::yes, VoteBehavior::Obsolete)
|
||||
XRPL_FEATURE(CryptoConditionsSuite, Supported::yes, VoteBehavior::Obsolete)
|
||||
// This sits here temporarily and will be moved to another section soon
|
||||
XRPL_FEATURE(OwnerPaysFee, Supported::no, VoteBehavior::Obsolete)
|
||||
|
||||
// The following amendments were never supported, never enabled, and
|
||||
// we've abanded them. These features should never be in the ledger,
|
||||
// and we've removed all the related code.
|
||||
XRPL_ABANDON(OwnerPaysFee)
|
||||
|
||||
// The following amendments have been active for at least two years. Their
|
||||
// pre-amendment code has been removed and the identifiers are deprecated.
|
||||
|
||||
@@ -398,6 +398,14 @@ retireFeature(std::string const& name)
|
||||
return registerFeature(name, Supported::yes, VoteBehavior::Obsolete);
|
||||
}
|
||||
|
||||
// Abandoned features are not in the ledger and have no code controlled by the
|
||||
// feature. They were never supported, and cannot be voted on.
|
||||
uint256
|
||||
abandonFeature(std::string const& name)
|
||||
{
|
||||
return registerFeature(name, Supported::no, VoteBehavior::Obsolete);
|
||||
}
|
||||
|
||||
/** Tell FeatureCollections when registration is complete. */
|
||||
bool
|
||||
registrationIsDone()
|
||||
@@ -432,6 +440,8 @@ featureToName(uint256 const& f)
|
||||
#undef XRPL_FIX
|
||||
#pragma push_macro("XRPL_RETIRE")
|
||||
#undef XRPL_RETIRE
|
||||
#pragma push_macro("XRPL_ABANDON")
|
||||
#undef XRPL_ABANDON
|
||||
|
||||
#define XRPL_FEATURE(name, supported, vote) \
|
||||
uint256 const feature##name = registerFeature(#name, supported, vote);
|
||||
@@ -443,6 +453,11 @@ featureToName(uint256 const& f)
|
||||
[[deprecated("The referenced amendment has been retired")]] \
|
||||
[[maybe_unused]] \
|
||||
uint256 const retired##name = retireFeature(#name);
|
||||
|
||||
#define XRPL_ABANDON(name) \
|
||||
[[deprecated("The referenced amendment has been abandoned")]] \
|
||||
[[maybe_unused]] \
|
||||
uint256 const abandoned##name = abandonFeature(#name);
|
||||
// clang-format on
|
||||
|
||||
#include <xrpl/protocol/detail/features.macro>
|
||||
@@ -453,6 +468,8 @@ featureToName(uint256 const& f)
|
||||
#pragma pop_macro("XRPL_FIX")
|
||||
#undef XRPL_FEATURE
|
||||
#pragma pop_macro("XRPL_FEATURE")
|
||||
#undef XRPL_ABANDON
|
||||
#pragma pop_macro("XRPL_ABANDON")
|
||||
|
||||
// All of the features should now be registered, since variables in a cpp file
|
||||
// are initialized from top to bottom.
|
||||
|
||||
@@ -1,144 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <xrpl/basics/RangeSet.h>
|
||||
#include <xrpl/beast/unit_test.h>
|
||||
|
||||
namespace ripple {
|
||||
class RangeSet_test : public beast::unit_test::suite
|
||||
{
|
||||
public:
|
||||
void
|
||||
testPrevMissing()
|
||||
{
|
||||
testcase("prevMissing");
|
||||
|
||||
// Set will include:
|
||||
// [ 0, 5]
|
||||
// [10,15]
|
||||
// [20,25]
|
||||
// etc...
|
||||
|
||||
RangeSet<std::uint32_t> set;
|
||||
for (std::uint32_t i = 0; i < 10; ++i)
|
||||
set.insert(range(10 * i, 10 * i + 5));
|
||||
|
||||
for (std::uint32_t i = 1; i < 100; ++i)
|
||||
{
|
||||
std::optional<std::uint32_t> expected;
|
||||
// no prev missing in domain for i <= 6
|
||||
if (i > 6)
|
||||
{
|
||||
std::uint32_t const oneBelowRange = (10 * (i / 10)) - 1;
|
||||
|
||||
expected = ((i % 10) > 6) ? (i - 1) : oneBelowRange;
|
||||
}
|
||||
BEAST_EXPECT(prevMissing(set, i) == expected);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
testToString()
|
||||
{
|
||||
testcase("toString");
|
||||
|
||||
RangeSet<std::uint32_t> set;
|
||||
BEAST_EXPECT(to_string(set) == "empty");
|
||||
|
||||
set.insert(1);
|
||||
BEAST_EXPECT(to_string(set) == "1");
|
||||
|
||||
set.insert(range(4u, 6u));
|
||||
BEAST_EXPECT(to_string(set) == "1,4-6");
|
||||
|
||||
set.insert(2);
|
||||
BEAST_EXPECT(to_string(set) == "1-2,4-6");
|
||||
|
||||
set.erase(range(4u, 5u));
|
||||
BEAST_EXPECT(to_string(set) == "1-2,6");
|
||||
}
|
||||
|
||||
void
|
||||
testFromString()
|
||||
{
|
||||
testcase("fromString");
|
||||
|
||||
RangeSet<std::uint32_t> set;
|
||||
|
||||
BEAST_EXPECT(!from_string(set, ""));
|
||||
BEAST_EXPECT(boost::icl::length(set) == 0);
|
||||
|
||||
BEAST_EXPECT(!from_string(set, "#"));
|
||||
BEAST_EXPECT(boost::icl::length(set) == 0);
|
||||
|
||||
BEAST_EXPECT(!from_string(set, ","));
|
||||
BEAST_EXPECT(boost::icl::length(set) == 0);
|
||||
|
||||
BEAST_EXPECT(!from_string(set, ",-"));
|
||||
BEAST_EXPECT(boost::icl::length(set) == 0);
|
||||
|
||||
BEAST_EXPECT(!from_string(set, "1,,2"));
|
||||
BEAST_EXPECT(boost::icl::length(set) == 0);
|
||||
|
||||
BEAST_EXPECT(from_string(set, "1"));
|
||||
BEAST_EXPECT(boost::icl::length(set) == 1);
|
||||
BEAST_EXPECT(boost::icl::first(set) == 1);
|
||||
|
||||
BEAST_EXPECT(from_string(set, "1,1"));
|
||||
BEAST_EXPECT(boost::icl::length(set) == 1);
|
||||
BEAST_EXPECT(boost::icl::first(set) == 1);
|
||||
|
||||
BEAST_EXPECT(from_string(set, "1-1"));
|
||||
BEAST_EXPECT(boost::icl::length(set) == 1);
|
||||
BEAST_EXPECT(boost::icl::first(set) == 1);
|
||||
|
||||
BEAST_EXPECT(from_string(set, "1,4-6"));
|
||||
BEAST_EXPECT(boost::icl::length(set) == 4);
|
||||
BEAST_EXPECT(boost::icl::first(set) == 1);
|
||||
BEAST_EXPECT(!boost::icl::contains(set, 2));
|
||||
BEAST_EXPECT(!boost::icl::contains(set, 3));
|
||||
BEAST_EXPECT(boost::icl::contains(set, 4));
|
||||
BEAST_EXPECT(boost::icl::contains(set, 5));
|
||||
BEAST_EXPECT(boost::icl::last(set) == 6);
|
||||
|
||||
BEAST_EXPECT(from_string(set, "1-2,4-6"));
|
||||
BEAST_EXPECT(boost::icl::length(set) == 5);
|
||||
BEAST_EXPECT(boost::icl::first(set) == 1);
|
||||
BEAST_EXPECT(boost::icl::contains(set, 2));
|
||||
BEAST_EXPECT(boost::icl::contains(set, 4));
|
||||
BEAST_EXPECT(boost::icl::last(set) == 6);
|
||||
|
||||
BEAST_EXPECT(from_string(set, "1-2,6"));
|
||||
BEAST_EXPECT(boost::icl::length(set) == 3);
|
||||
BEAST_EXPECT(boost::icl::first(set) == 1);
|
||||
BEAST_EXPECT(boost::icl::contains(set, 2));
|
||||
BEAST_EXPECT(boost::icl::last(set) == 6);
|
||||
}
|
||||
void
|
||||
run() override
|
||||
{
|
||||
testPrevMissing();
|
||||
testToString();
|
||||
testFromString();
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(RangeSet, ripple_basics, ripple);
|
||||
|
||||
} // namespace ripple
|
||||
@@ -1,116 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github0.com/ripple/rippled
|
||||
Copyright (c) 2012-2016 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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <xrpl/basics/Slice.h>
|
||||
#include <xrpl/beast/unit_test.h>
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
|
||||
namespace ripple {
|
||||
namespace test {
|
||||
|
||||
struct Slice_test : beast::unit_test::suite
|
||||
{
|
||||
void
|
||||
run() override
|
||||
{
|
||||
std::uint8_t const data[] = {
|
||||
0xa8, 0xa1, 0x38, 0x45, 0x23, 0xec, 0xe4, 0x23, 0x71, 0x6d, 0x2a,
|
||||
0x18, 0xb4, 0x70, 0xcb, 0xf5, 0xac, 0x2d, 0x89, 0x4d, 0x19, 0x9c,
|
||||
0xf0, 0x2c, 0x15, 0xd1, 0xf9, 0x9b, 0x66, 0xd2, 0x30, 0xd3};
|
||||
|
||||
{
|
||||
testcase("Equality & Inequality");
|
||||
|
||||
Slice const s0{};
|
||||
|
||||
BEAST_EXPECT(s0.size() == 0);
|
||||
BEAST_EXPECT(s0.data() == nullptr);
|
||||
BEAST_EXPECT(s0 == s0);
|
||||
|
||||
// Test slices of equal and unequal size pointing to same data:
|
||||
for (std::size_t i = 0; i != sizeof(data); ++i)
|
||||
{
|
||||
Slice const s1{data, i};
|
||||
|
||||
BEAST_EXPECT(s1.size() == i);
|
||||
BEAST_EXPECT(s1.data() != nullptr);
|
||||
|
||||
if (i == 0)
|
||||
BEAST_EXPECT(s1 == s0);
|
||||
else
|
||||
BEAST_EXPECT(s1 != s0);
|
||||
|
||||
for (std::size_t j = 0; j != sizeof(data); ++j)
|
||||
{
|
||||
Slice const s2{data, j};
|
||||
|
||||
if (i == j)
|
||||
BEAST_EXPECT(s1 == s2);
|
||||
else
|
||||
BEAST_EXPECT(s1 != s2);
|
||||
}
|
||||
}
|
||||
|
||||
// Test slices of equal size but pointing to different data:
|
||||
std::array<std::uint8_t, sizeof(data)> a;
|
||||
std::array<std::uint8_t, sizeof(data)> b;
|
||||
|
||||
for (std::size_t i = 0; i != sizeof(data); ++i)
|
||||
a[i] = b[i] = data[i];
|
||||
|
||||
BEAST_EXPECT(makeSlice(a) == makeSlice(b));
|
||||
b[7]++;
|
||||
BEAST_EXPECT(makeSlice(a) != makeSlice(b));
|
||||
a[7]++;
|
||||
BEAST_EXPECT(makeSlice(a) == makeSlice(b));
|
||||
}
|
||||
|
||||
{
|
||||
testcase("Indexing");
|
||||
|
||||
Slice const s{data, sizeof(data)};
|
||||
|
||||
for (std::size_t i = 0; i != sizeof(data); ++i)
|
||||
BEAST_EXPECT(s[i] == data[i]);
|
||||
}
|
||||
|
||||
{
|
||||
testcase("Advancing");
|
||||
|
||||
for (std::size_t i = 0; i < sizeof(data); ++i)
|
||||
{
|
||||
for (std::size_t j = 0; i + j < sizeof(data); ++j)
|
||||
{
|
||||
Slice s(data + i, sizeof(data) - i);
|
||||
s += j;
|
||||
|
||||
BEAST_EXPECT(s.data() == data + i + j);
|
||||
BEAST_EXPECT(s.size() == sizeof(data) - i - j);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(Slice, ripple_basics, ripple);
|
||||
|
||||
} // namespace test
|
||||
} // namespace ripple
|
||||
@@ -1,82 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012-2018 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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
//
|
||||
// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
// Official repository: https://github.com/boostorg/beast
|
||||
//
|
||||
|
||||
#include <xrpl/basics/base64.h>
|
||||
#include <xrpl/beast/unit_test.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
class base64_test : public beast::unit_test::suite
|
||||
{
|
||||
public:
|
||||
void
|
||||
check(std::string const& in, std::string const& out)
|
||||
{
|
||||
auto const encoded = base64_encode(in);
|
||||
BEAST_EXPECT(encoded == out);
|
||||
BEAST_EXPECT(base64_decode(encoded) == in);
|
||||
}
|
||||
|
||||
void
|
||||
run() override
|
||||
{
|
||||
check("", "");
|
||||
check("f", "Zg==");
|
||||
check("fo", "Zm8=");
|
||||
check("foo", "Zm9v");
|
||||
check("foob", "Zm9vYg==");
|
||||
check("fooba", "Zm9vYmE=");
|
||||
check("foobar", "Zm9vYmFy");
|
||||
|
||||
check(
|
||||
"Man is distinguished, not only by his reason, but by this "
|
||||
"singular passion from "
|
||||
"other animals, which is a lust of the mind, that by a "
|
||||
"perseverance of delight "
|
||||
"in the continued and indefatigable generation of knowledge, "
|
||||
"exceeds the short "
|
||||
"vehemence of any carnal pleasure.",
|
||||
"TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dC"
|
||||
"BieSB0aGlz"
|
||||
"IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIG"
|
||||
"x1c3Qgb2Yg"
|
||||
"dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aG"
|
||||
"UgY29udGlu"
|
||||
"dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleG"
|
||||
"NlZWRzIHRo"
|
||||
"ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=");
|
||||
|
||||
std::string const notBase64 = "not_base64!!";
|
||||
std::string const truncated = "not";
|
||||
BEAST_EXPECT(base64_decode(notBase64) == base64_decode(truncated));
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(base64, ripple_basics, ripple);
|
||||
|
||||
} // namespace ripple
|
||||
@@ -1,62 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012-2016 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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <xrpl/basics/mulDiv.h>
|
||||
#include <xrpl/beast/unit_test.h>
|
||||
|
||||
namespace ripple {
|
||||
namespace test {
|
||||
|
||||
struct mulDiv_test : beast::unit_test::suite
|
||||
{
|
||||
void
|
||||
run() override
|
||||
{
|
||||
auto const max = std::numeric_limits<std::uint64_t>::max();
|
||||
std::uint64_t const max32 = std::numeric_limits<std::uint32_t>::max();
|
||||
|
||||
auto result = mulDiv(85, 20, 5);
|
||||
BEAST_EXPECT(result && *result == 340);
|
||||
result = mulDiv(20, 85, 5);
|
||||
BEAST_EXPECT(result && *result == 340);
|
||||
|
||||
result = mulDiv(0, max - 1, max - 3);
|
||||
BEAST_EXPECT(result && *result == 0);
|
||||
result = mulDiv(max - 1, 0, max - 3);
|
||||
BEAST_EXPECT(result && *result == 0);
|
||||
|
||||
result = mulDiv(max, 2, max / 2);
|
||||
BEAST_EXPECT(result && *result == 4);
|
||||
result = mulDiv(max, 1000, max / 1000);
|
||||
BEAST_EXPECT(result && *result == 1000000);
|
||||
result = mulDiv(max, 1000, max / 1001);
|
||||
BEAST_EXPECT(result && *result == 1001000);
|
||||
result = mulDiv(max32 + 1, max32 + 1, 5);
|
||||
BEAST_EXPECT(result && *result == 3689348814741910323);
|
||||
|
||||
// Overflow
|
||||
result = mulDiv(max - 1, max - 2, 5);
|
||||
BEAST_EXPECT(!result);
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(mulDiv, ripple_basics, ripple);
|
||||
|
||||
} // namespace test
|
||||
} // namespace ripple
|
||||
@@ -1,193 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github0.com/ripple/rippled
|
||||
Copyright (c) 2021 Ripple 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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <xrpl/basics/scope.h>
|
||||
#include <xrpl/beast/unit_test.h>
|
||||
|
||||
namespace ripple {
|
||||
namespace test {
|
||||
|
||||
struct scope_test : beast::unit_test::suite
|
||||
{
|
||||
void
|
||||
test_scope_exit()
|
||||
{
|
||||
// scope_exit always executes the functor on destruction,
|
||||
// unless release() is called
|
||||
int i = 0;
|
||||
{
|
||||
scope_exit x{[&i]() { i = 1; }};
|
||||
}
|
||||
BEAST_EXPECT(i == 1);
|
||||
{
|
||||
scope_exit x{[&i]() { i = 2; }};
|
||||
x.release();
|
||||
}
|
||||
BEAST_EXPECT(i == 1);
|
||||
{
|
||||
scope_exit x{[&i]() { i += 2; }};
|
||||
auto x2 = std::move(x);
|
||||
}
|
||||
BEAST_EXPECT(i == 3);
|
||||
{
|
||||
scope_exit x{[&i]() { i = 4; }};
|
||||
x.release();
|
||||
auto x2 = std::move(x);
|
||||
}
|
||||
BEAST_EXPECT(i == 3);
|
||||
{
|
||||
try
|
||||
{
|
||||
scope_exit x{[&i]() { i = 5; }};
|
||||
throw 1;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
BEAST_EXPECT(i == 5);
|
||||
{
|
||||
try
|
||||
{
|
||||
scope_exit x{[&i]() { i = 6; }};
|
||||
x.release();
|
||||
throw 1;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
BEAST_EXPECT(i == 5);
|
||||
}
|
||||
|
||||
void
|
||||
test_scope_fail()
|
||||
{
|
||||
// scope_fail executes the functor on destruction only
|
||||
// if an exception is unwinding, unless release() is called
|
||||
int i = 0;
|
||||
{
|
||||
scope_fail x{[&i]() { i = 1; }};
|
||||
}
|
||||
BEAST_EXPECT(i == 0);
|
||||
{
|
||||
scope_fail x{[&i]() { i = 2; }};
|
||||
x.release();
|
||||
}
|
||||
BEAST_EXPECT(i == 0);
|
||||
{
|
||||
scope_fail x{[&i]() { i = 3; }};
|
||||
auto x2 = std::move(x);
|
||||
}
|
||||
BEAST_EXPECT(i == 0);
|
||||
{
|
||||
scope_fail x{[&i]() { i = 4; }};
|
||||
x.release();
|
||||
auto x2 = std::move(x);
|
||||
}
|
||||
BEAST_EXPECT(i == 0);
|
||||
{
|
||||
try
|
||||
{
|
||||
scope_fail x{[&i]() { i = 5; }};
|
||||
throw 1;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
BEAST_EXPECT(i == 5);
|
||||
{
|
||||
try
|
||||
{
|
||||
scope_fail x{[&i]() { i = 6; }};
|
||||
x.release();
|
||||
throw 1;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
BEAST_EXPECT(i == 5);
|
||||
}
|
||||
|
||||
void
|
||||
test_scope_success()
|
||||
{
|
||||
// scope_success executes the functor on destruction only
|
||||
// if an exception is not unwinding, unless release() is called
|
||||
int i = 0;
|
||||
{
|
||||
scope_success x{[&i]() { i = 1; }};
|
||||
}
|
||||
BEAST_EXPECT(i == 1);
|
||||
{
|
||||
scope_success x{[&i]() { i = 2; }};
|
||||
x.release();
|
||||
}
|
||||
BEAST_EXPECT(i == 1);
|
||||
{
|
||||
scope_success x{[&i]() { i += 2; }};
|
||||
auto x2 = std::move(x);
|
||||
}
|
||||
BEAST_EXPECT(i == 3);
|
||||
{
|
||||
scope_success x{[&i]() { i = 4; }};
|
||||
x.release();
|
||||
auto x2 = std::move(x);
|
||||
}
|
||||
BEAST_EXPECT(i == 3);
|
||||
{
|
||||
try
|
||||
{
|
||||
scope_success x{[&i]() { i = 5; }};
|
||||
throw 1;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
BEAST_EXPECT(i == 3);
|
||||
{
|
||||
try
|
||||
{
|
||||
scope_success x{[&i]() { i = 6; }};
|
||||
x.release();
|
||||
throw 1;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
BEAST_EXPECT(i == 3);
|
||||
}
|
||||
|
||||
void
|
||||
run() override
|
||||
{
|
||||
test_scope_exit();
|
||||
test_scope_fail();
|
||||
test_scope_success();
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(scope, ripple_basics, ripple);
|
||||
|
||||
} // namespace test
|
||||
} // namespace ripple
|
||||
@@ -1,258 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright 2014, Nikolaos D. Bougalis <nikb@bougalis.net>
|
||||
|
||||
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <xrpl/basics/tagged_integer.h>
|
||||
#include <xrpl/beast/unit_test.h>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace ripple {
|
||||
namespace test {
|
||||
|
||||
class tagged_integer_test : public beast::unit_test::suite
|
||||
{
|
||||
private:
|
||||
struct Tag1
|
||||
{
|
||||
};
|
||||
struct Tag2
|
||||
{
|
||||
};
|
||||
|
||||
// Static checks that types are not interoperable
|
||||
|
||||
using TagUInt1 = tagged_integer<std::uint32_t, Tag1>;
|
||||
using TagUInt2 = tagged_integer<std::uint32_t, Tag2>;
|
||||
using TagUInt3 = tagged_integer<std::uint64_t, Tag1>;
|
||||
|
||||
// Check construction of tagged_integers
|
||||
static_assert(
|
||||
std::is_constructible<TagUInt1, std::uint32_t>::value,
|
||||
"TagUInt1 should be constructible using a std::uint32_t");
|
||||
|
||||
static_assert(
|
||||
!std::is_constructible<TagUInt1, std::uint64_t>::value,
|
||||
"TagUInt1 should not be constructible using a std::uint64_t");
|
||||
|
||||
static_assert(
|
||||
std::is_constructible<TagUInt3, std::uint32_t>::value,
|
||||
"TagUInt3 should be constructible using a std::uint32_t");
|
||||
|
||||
static_assert(
|
||||
std::is_constructible<TagUInt3, std::uint64_t>::value,
|
||||
"TagUInt3 should be constructible using a std::uint64_t");
|
||||
|
||||
// Check assignment of tagged_integers
|
||||
static_assert(
|
||||
!std::is_assignable<TagUInt1, std::uint32_t>::value,
|
||||
"TagUInt1 should not be assignable with a std::uint32_t");
|
||||
|
||||
static_assert(
|
||||
!std::is_assignable<TagUInt1, std::uint64_t>::value,
|
||||
"TagUInt1 should not be assignable with a std::uint64_t");
|
||||
|
||||
static_assert(
|
||||
!std::is_assignable<TagUInt3, std::uint32_t>::value,
|
||||
"TagUInt3 should not be assignable with a std::uint32_t");
|
||||
|
||||
static_assert(
|
||||
!std::is_assignable<TagUInt3, std::uint64_t>::value,
|
||||
"TagUInt3 should not be assignable with a std::uint64_t");
|
||||
|
||||
static_assert(
|
||||
std::is_assignable<TagUInt1, TagUInt1>::value,
|
||||
"TagUInt1 should be assignable with a TagUInt1");
|
||||
|
||||
static_assert(
|
||||
!std::is_assignable<TagUInt1, TagUInt2>::value,
|
||||
"TagUInt1 should not be assignable with a TagUInt2");
|
||||
|
||||
static_assert(
|
||||
std::is_assignable<TagUInt3, TagUInt3>::value,
|
||||
"TagUInt3 should be assignable with a TagUInt1");
|
||||
|
||||
static_assert(
|
||||
!std::is_assignable<TagUInt1, TagUInt3>::value,
|
||||
"TagUInt1 should not be assignable with a TagUInt3");
|
||||
|
||||
static_assert(
|
||||
!std::is_assignable<TagUInt3, TagUInt1>::value,
|
||||
"TagUInt3 should not be assignable with a TagUInt1");
|
||||
|
||||
// Check convertibility of tagged_integers
|
||||
static_assert(
|
||||
!std::is_convertible<std::uint32_t, TagUInt1>::value,
|
||||
"std::uint32_t should not be convertible to a TagUInt1");
|
||||
|
||||
static_assert(
|
||||
!std::is_convertible<std::uint32_t, TagUInt3>::value,
|
||||
"std::uint32_t should not be convertible to a TagUInt3");
|
||||
|
||||
static_assert(
|
||||
!std::is_convertible<std::uint64_t, TagUInt3>::value,
|
||||
"std::uint64_t should not be convertible to a TagUInt3");
|
||||
|
||||
static_assert(
|
||||
!std::is_convertible<std::uint64_t, TagUInt2>::value,
|
||||
"std::uint64_t should not be convertible to a TagUInt2");
|
||||
|
||||
static_assert(
|
||||
!std::is_convertible<TagUInt1, TagUInt2>::value,
|
||||
"TagUInt1 should not be convertible to TagUInt2");
|
||||
|
||||
static_assert(
|
||||
!std::is_convertible<TagUInt1, TagUInt3>::value,
|
||||
"TagUInt1 should not be convertible to TagUInt3");
|
||||
|
||||
static_assert(
|
||||
!std::is_convertible<TagUInt2, TagUInt3>::value,
|
||||
"TagUInt2 should not be convertible to a TagUInt3");
|
||||
|
||||
public:
|
||||
void
|
||||
run() override
|
||||
{
|
||||
using TagInt = tagged_integer<std::int32_t, Tag1>;
|
||||
|
||||
{
|
||||
testcase("Comparison Operators");
|
||||
|
||||
TagInt const zero(0);
|
||||
TagInt const one(1);
|
||||
|
||||
BEAST_EXPECT(one == one);
|
||||
BEAST_EXPECT(!(one == zero));
|
||||
|
||||
BEAST_EXPECT(one != zero);
|
||||
BEAST_EXPECT(!(one != one));
|
||||
|
||||
BEAST_EXPECT(zero < one);
|
||||
BEAST_EXPECT(!(one < zero));
|
||||
|
||||
BEAST_EXPECT(one > zero);
|
||||
BEAST_EXPECT(!(zero > one));
|
||||
|
||||
BEAST_EXPECT(one >= one);
|
||||
BEAST_EXPECT(one >= zero);
|
||||
BEAST_EXPECT(!(zero >= one));
|
||||
|
||||
BEAST_EXPECT(zero <= one);
|
||||
BEAST_EXPECT(zero <= zero);
|
||||
BEAST_EXPECT(!(one <= zero));
|
||||
}
|
||||
|
||||
{
|
||||
testcase("Increment/Decrement Operators");
|
||||
TagInt const zero(0);
|
||||
TagInt const one(1);
|
||||
TagInt a{0};
|
||||
++a;
|
||||
BEAST_EXPECT(a == one);
|
||||
--a;
|
||||
BEAST_EXPECT(a == zero);
|
||||
a++;
|
||||
BEAST_EXPECT(a == one);
|
||||
a--;
|
||||
BEAST_EXPECT(a == zero);
|
||||
}
|
||||
|
||||
{
|
||||
testcase("Arithmetic Operators");
|
||||
TagInt a{-2};
|
||||
BEAST_EXPECT(+a == TagInt{-2});
|
||||
BEAST_EXPECT(-a == TagInt{2});
|
||||
BEAST_EXPECT(TagInt{-3} + TagInt{4} == TagInt{1});
|
||||
BEAST_EXPECT(TagInt{-3} - TagInt{4} == TagInt{-7});
|
||||
BEAST_EXPECT(TagInt{-3} * TagInt{4} == TagInt{-12});
|
||||
BEAST_EXPECT(TagInt{8} / TagInt{4} == TagInt{2});
|
||||
BEAST_EXPECT(TagInt{7} % TagInt{4} == TagInt{3});
|
||||
|
||||
BEAST_EXPECT(~TagInt{8} == TagInt{~TagInt::value_type{8}});
|
||||
BEAST_EXPECT((TagInt{6} & TagInt{3}) == TagInt{2});
|
||||
BEAST_EXPECT((TagInt{6} | TagInt{3}) == TagInt{7});
|
||||
BEAST_EXPECT((TagInt{6} ^ TagInt{3}) == TagInt{5});
|
||||
|
||||
BEAST_EXPECT((TagInt{4} << TagInt{2}) == TagInt{16});
|
||||
BEAST_EXPECT((TagInt{16} >> TagInt{2}) == TagInt{4});
|
||||
}
|
||||
{
|
||||
testcase("Assignment Operators");
|
||||
TagInt a{-2};
|
||||
TagInt b{0};
|
||||
b = a;
|
||||
BEAST_EXPECT(b == TagInt{-2});
|
||||
|
||||
// -3 + 4 == 1
|
||||
a = TagInt{-3};
|
||||
a += TagInt{4};
|
||||
BEAST_EXPECT(a == TagInt{1});
|
||||
|
||||
// -3 - 4 == -7
|
||||
a = TagInt{-3};
|
||||
a -= TagInt{4};
|
||||
BEAST_EXPECT(a == TagInt{-7});
|
||||
|
||||
// -3 * 4 == -12
|
||||
a = TagInt{-3};
|
||||
a *= TagInt{4};
|
||||
BEAST_EXPECT(a == TagInt{-12});
|
||||
|
||||
// 8/4 == 2
|
||||
a = TagInt{8};
|
||||
a /= TagInt{4};
|
||||
BEAST_EXPECT(a == TagInt{2});
|
||||
|
||||
// 7 % 4 == 3
|
||||
a = TagInt{7};
|
||||
a %= TagInt{4};
|
||||
BEAST_EXPECT(a == TagInt{3});
|
||||
|
||||
// 6 & 3 == 2
|
||||
a = TagInt{6};
|
||||
a /= TagInt{3};
|
||||
BEAST_EXPECT(a == TagInt{2});
|
||||
|
||||
// 6 | 3 == 7
|
||||
a = TagInt{6};
|
||||
a |= TagInt{3};
|
||||
BEAST_EXPECT(a == TagInt{7});
|
||||
|
||||
// 6 ^ 3 == 5
|
||||
a = TagInt{6};
|
||||
a ^= TagInt{3};
|
||||
BEAST_EXPECT(a == TagInt{5});
|
||||
|
||||
// 4 << 2 == 16
|
||||
a = TagInt{4};
|
||||
a <<= TagInt{2};
|
||||
BEAST_EXPECT(a == TagInt{16});
|
||||
|
||||
// 16 >> 2 == 4
|
||||
a = TagInt{16};
|
||||
a >>= TagInt{2};
|
||||
BEAST_EXPECT(a == TagInt{4});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(tagged_integer, ripple_basics, ripple);
|
||||
|
||||
} // namespace test
|
||||
} // namespace ripple
|
||||
@@ -94,6 +94,8 @@ SuiteJournalSink::writeAlways(
|
||||
return "FTL:";
|
||||
}();
|
||||
|
||||
static std::mutex log_mutex;
|
||||
std::lock_guard lock(log_mutex);
|
||||
suite_.log << s << partition_ << text << std::endl;
|
||||
}
|
||||
|
||||
|
||||
4
src/tests/README.md
Normal file
4
src/tests/README.md
Normal file
@@ -0,0 +1,4 @@
|
||||
# Unit tests
|
||||
This directory contains unit tests for the project. The difference from existing `src/test` folder
|
||||
is that we switch to 3rd party testing framework (doctest). We intend to gradually move existing tests
|
||||
from our own framework to doctest and such tests will be moved to this new folder.
|
||||
14
src/tests/libxrpl/CMakeLists.txt
Normal file
14
src/tests/libxrpl/CMakeLists.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
include(xrpl_add_test)
|
||||
|
||||
# Test requirements.
|
||||
find_package(doctest REQUIRED)
|
||||
|
||||
# Common library dependencies for the rest of the tests.
|
||||
add_library(xrpl.imports.test INTERFACE)
|
||||
target_link_libraries(xrpl.imports.test INTERFACE doctest::doctest xrpl.libxrpl)
|
||||
|
||||
# One test for each module.
|
||||
xrpl_add_test(basics)
|
||||
target_link_libraries(xrpl.test.basics PRIVATE xrpl.imports.test)
|
||||
xrpl_add_test(crypto)
|
||||
target_link_libraries(xrpl.test.crypto PRIVATE xrpl.imports.test)
|
||||
129
src/tests/libxrpl/basics/RangeSet.cpp
Normal file
129
src/tests/libxrpl/basics/RangeSet.cpp
Normal file
@@ -0,0 +1,129 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012 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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <xrpl/basics/RangeSet.h>
|
||||
|
||||
#include <doctest/doctest.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
|
||||
using namespace ripple;
|
||||
|
||||
TEST_SUITE_BEGIN("RangeSet");
|
||||
|
||||
TEST_CASE("prevMissing")
|
||||
{
|
||||
// Set will include:
|
||||
// [ 0, 5]
|
||||
// [10,15]
|
||||
// [20,25]
|
||||
// etc...
|
||||
|
||||
RangeSet<std::uint32_t> set;
|
||||
for (std::uint32_t i = 0; i < 10; ++i)
|
||||
set.insert(range(10 * i, 10 * i + 5));
|
||||
|
||||
for (std::uint32_t i = 1; i < 100; ++i)
|
||||
{
|
||||
std::optional<std::uint32_t> expected;
|
||||
// no prev missing in domain for i <= 6
|
||||
if (i > 6)
|
||||
{
|
||||
std::uint32_t const oneBelowRange = (10 * (i / 10)) - 1;
|
||||
|
||||
expected = ((i % 10) > 6) ? (i - 1) : oneBelowRange;
|
||||
}
|
||||
CHECK(prevMissing(set, i) == expected);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("toString")
|
||||
{
|
||||
RangeSet<std::uint32_t> set;
|
||||
CHECK(to_string(set) == "empty");
|
||||
|
||||
set.insert(1);
|
||||
CHECK(to_string(set) == "1");
|
||||
|
||||
set.insert(range(4u, 6u));
|
||||
CHECK(to_string(set) == "1,4-6");
|
||||
|
||||
set.insert(2);
|
||||
CHECK(to_string(set) == "1-2,4-6");
|
||||
|
||||
set.erase(range(4u, 5u));
|
||||
CHECK(to_string(set) == "1-2,6");
|
||||
}
|
||||
|
||||
TEST_CASE("fromString")
|
||||
{
|
||||
RangeSet<std::uint32_t> set;
|
||||
|
||||
CHECK(!from_string(set, ""));
|
||||
CHECK(boost::icl::length(set) == 0);
|
||||
|
||||
CHECK(!from_string(set, "#"));
|
||||
CHECK(boost::icl::length(set) == 0);
|
||||
|
||||
CHECK(!from_string(set, ","));
|
||||
CHECK(boost::icl::length(set) == 0);
|
||||
|
||||
CHECK(!from_string(set, ",-"));
|
||||
CHECK(boost::icl::length(set) == 0);
|
||||
|
||||
CHECK(!from_string(set, "1,,2"));
|
||||
CHECK(boost::icl::length(set) == 0);
|
||||
|
||||
CHECK(from_string(set, "1"));
|
||||
CHECK(boost::icl::length(set) == 1);
|
||||
CHECK(boost::icl::first(set) == 1);
|
||||
|
||||
CHECK(from_string(set, "1,1"));
|
||||
CHECK(boost::icl::length(set) == 1);
|
||||
CHECK(boost::icl::first(set) == 1);
|
||||
|
||||
CHECK(from_string(set, "1-1"));
|
||||
CHECK(boost::icl::length(set) == 1);
|
||||
CHECK(boost::icl::first(set) == 1);
|
||||
|
||||
CHECK(from_string(set, "1,4-6"));
|
||||
CHECK(boost::icl::length(set) == 4);
|
||||
CHECK(boost::icl::first(set) == 1);
|
||||
CHECK(!boost::icl::contains(set, 2));
|
||||
CHECK(!boost::icl::contains(set, 3));
|
||||
CHECK(boost::icl::contains(set, 4));
|
||||
CHECK(boost::icl::contains(set, 5));
|
||||
CHECK(boost::icl::last(set) == 6);
|
||||
|
||||
CHECK(from_string(set, "1-2,4-6"));
|
||||
CHECK(boost::icl::length(set) == 5);
|
||||
CHECK(boost::icl::first(set) == 1);
|
||||
CHECK(boost::icl::contains(set, 2));
|
||||
CHECK(boost::icl::contains(set, 4));
|
||||
CHECK(boost::icl::last(set) == 6);
|
||||
|
||||
CHECK(from_string(set, "1-2,6"));
|
||||
CHECK(boost::icl::length(set) == 3);
|
||||
CHECK(boost::icl::first(set) == 1);
|
||||
CHECK(boost::icl::contains(set, 2));
|
||||
CHECK(boost::icl::last(set) == 6);
|
||||
}
|
||||
|
||||
TEST_SUITE_END();
|
||||
105
src/tests/libxrpl/basics/Slice.cpp
Normal file
105
src/tests/libxrpl/basics/Slice.cpp
Normal file
@@ -0,0 +1,105 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012 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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <xrpl/basics/Slice.h>
|
||||
|
||||
#include <doctest/doctest.h>
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
|
||||
using namespace ripple;
|
||||
|
||||
static std::uint8_t const data[] = {
|
||||
0xa8, 0xa1, 0x38, 0x45, 0x23, 0xec, 0xe4, 0x23, 0x71, 0x6d, 0x2a,
|
||||
0x18, 0xb4, 0x70, 0xcb, 0xf5, 0xac, 0x2d, 0x89, 0x4d, 0x19, 0x9c,
|
||||
0xf0, 0x2c, 0x15, 0xd1, 0xf9, 0x9b, 0x66, 0xd2, 0x30, 0xd3};
|
||||
|
||||
TEST_SUITE_BEGIN("Slice");
|
||||
|
||||
TEST_CASE("equality & inequality")
|
||||
{
|
||||
Slice const s0{};
|
||||
|
||||
CHECK(s0.size() == 0);
|
||||
CHECK(s0.data() == nullptr);
|
||||
CHECK(s0 == s0);
|
||||
|
||||
// Test slices of equal and unequal size pointing to same data:
|
||||
for (std::size_t i = 0; i != sizeof(data); ++i)
|
||||
{
|
||||
Slice const s1{data, i};
|
||||
|
||||
CHECK(s1.size() == i);
|
||||
CHECK(s1.data() != nullptr);
|
||||
|
||||
if (i == 0)
|
||||
CHECK(s1 == s0);
|
||||
else
|
||||
CHECK(s1 != s0);
|
||||
|
||||
for (std::size_t j = 0; j != sizeof(data); ++j)
|
||||
{
|
||||
Slice const s2{data, j};
|
||||
|
||||
if (i == j)
|
||||
CHECK(s1 == s2);
|
||||
else
|
||||
CHECK(s1 != s2);
|
||||
}
|
||||
}
|
||||
|
||||
// Test slices of equal size but pointing to different data:
|
||||
std::array<std::uint8_t, sizeof(data)> a;
|
||||
std::array<std::uint8_t, sizeof(data)> b;
|
||||
|
||||
for (std::size_t i = 0; i != sizeof(data); ++i)
|
||||
a[i] = b[i] = data[i];
|
||||
|
||||
CHECK(makeSlice(a) == makeSlice(b));
|
||||
b[7]++;
|
||||
CHECK(makeSlice(a) != makeSlice(b));
|
||||
a[7]++;
|
||||
CHECK(makeSlice(a) == makeSlice(b));
|
||||
}
|
||||
|
||||
TEST_CASE("indexing")
|
||||
{
|
||||
Slice const s{data, sizeof(data)};
|
||||
|
||||
for (std::size_t i = 0; i != sizeof(data); ++i)
|
||||
CHECK(s[i] == data[i]);
|
||||
}
|
||||
|
||||
TEST_CASE("advancing")
|
||||
{
|
||||
for (std::size_t i = 0; i < sizeof(data); ++i)
|
||||
{
|
||||
for (std::size_t j = 0; i + j < sizeof(data); ++j)
|
||||
{
|
||||
Slice s(data + i, sizeof(data) - i);
|
||||
s += j;
|
||||
|
||||
CHECK(s.data() == data + i + j);
|
||||
CHECK(s.size() == sizeof(data) - i - j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_SUITE_END();
|
||||
67
src/tests/libxrpl/basics/base64.cpp
Normal file
67
src/tests/libxrpl/basics/base64.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012 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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <xrpl/basics/base64.h>
|
||||
|
||||
#include <doctest/doctest.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
using namespace ripple;
|
||||
|
||||
static void
|
||||
check(std::string const& in, std::string const& out)
|
||||
{
|
||||
auto const encoded = base64_encode(in);
|
||||
CHECK(encoded == out);
|
||||
CHECK(base64_decode(encoded) == in);
|
||||
}
|
||||
|
||||
TEST_CASE("base64")
|
||||
{
|
||||
check("", "");
|
||||
check("f", "Zg==");
|
||||
check("fo", "Zm8=");
|
||||
check("foo", "Zm9v");
|
||||
check("foob", "Zm9vYg==");
|
||||
check("fooba", "Zm9vYmE=");
|
||||
check("foobar", "Zm9vYmFy");
|
||||
|
||||
check(
|
||||
"Man is distinguished, not only by his reason, but by this "
|
||||
"singular passion from "
|
||||
"other animals, which is a lust of the mind, that by a "
|
||||
"perseverance of delight "
|
||||
"in the continued and indefatigable generation of knowledge, "
|
||||
"exceeds the short "
|
||||
"vehemence of any carnal pleasure.",
|
||||
"TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dC"
|
||||
"BieSB0aGlz"
|
||||
"IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIG"
|
||||
"x1c3Qgb2Yg"
|
||||
"dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aG"
|
||||
"UgY29udGlu"
|
||||
"dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleG"
|
||||
"NlZWRzIHRo"
|
||||
"ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=");
|
||||
|
||||
std::string const notBase64 = "not_base64!!";
|
||||
std::string const truncated = "not";
|
||||
CHECK(base64_decode(notBase64) == base64_decode(truncated));
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
Copyright (c) 2012 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
|
||||
@@ -18,46 +18,39 @@
|
||||
//==============================================================================
|
||||
|
||||
#include <xrpl/basics/contract.h>
|
||||
#include <xrpl/beast/unit_test.h>
|
||||
|
||||
#include <doctest/doctest.h>
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
namespace ripple {
|
||||
using namespace ripple;
|
||||
|
||||
class contract_test : public beast::unit_test::suite
|
||||
TEST_CASE("contract")
|
||||
{
|
||||
public:
|
||||
void
|
||||
run() override
|
||||
try
|
||||
{
|
||||
Throw<std::runtime_error>("Throw test");
|
||||
}
|
||||
catch (std::runtime_error const& e1)
|
||||
{
|
||||
CHECK(std::string(e1.what()) == "Throw test");
|
||||
|
||||
try
|
||||
{
|
||||
Throw<std::runtime_error>("Throw test");
|
||||
Rethrow();
|
||||
}
|
||||
catch (std::runtime_error const& e1)
|
||||
catch (std::runtime_error const& e2)
|
||||
{
|
||||
BEAST_EXPECT(std::string(e1.what()) == "Throw test");
|
||||
|
||||
try
|
||||
{
|
||||
Rethrow();
|
||||
}
|
||||
catch (std::runtime_error const& e2)
|
||||
{
|
||||
BEAST_EXPECT(std::string(e2.what()) == "Throw test");
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
BEAST_EXPECT(false);
|
||||
}
|
||||
CHECK(std::string(e2.what()) == "Throw test");
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
BEAST_EXPECT(false);
|
||||
CHECK(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(contract, basics, ripple);
|
||||
|
||||
} // namespace ripple
|
||||
catch (...)
|
||||
{
|
||||
CHECK(false);
|
||||
}
|
||||
}
|
||||
2
src/tests/libxrpl/basics/main.cpp
Normal file
2
src/tests/libxrpl/basics/main.cpp
Normal file
@@ -0,0 +1,2 @@
|
||||
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
|
||||
#include <doctest/doctest.h>
|
||||
64
src/tests/libxrpl/basics/mulDiv.cpp
Normal file
64
src/tests/libxrpl/basics/mulDiv.cpp
Normal file
@@ -0,0 +1,64 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012 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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <xrpl/basics/mulDiv.h>
|
||||
|
||||
#include <doctest/doctest.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
|
||||
using namespace ripple;
|
||||
|
||||
TEST_CASE("mulDiv")
|
||||
{
|
||||
auto const max = std::numeric_limits<std::uint64_t>::max();
|
||||
std::uint64_t const max32 = std::numeric_limits<std::uint32_t>::max();
|
||||
|
||||
auto result = mulDiv(85, 20, 5);
|
||||
REQUIRE(result);
|
||||
CHECK(*result == 340);
|
||||
result = mulDiv(20, 85, 5);
|
||||
REQUIRE(result);
|
||||
CHECK(*result == 340);
|
||||
|
||||
result = mulDiv(0, max - 1, max - 3);
|
||||
REQUIRE(result);
|
||||
CHECK(*result == 0);
|
||||
result = mulDiv(max - 1, 0, max - 3);
|
||||
REQUIRE(result);
|
||||
CHECK(*result == 0);
|
||||
|
||||
result = mulDiv(max, 2, max / 2);
|
||||
REQUIRE(result);
|
||||
CHECK(*result == 4);
|
||||
result = mulDiv(max, 1000, max / 1000);
|
||||
REQUIRE(result);
|
||||
CHECK(*result == 1000000);
|
||||
result = mulDiv(max, 1000, max / 1001);
|
||||
REQUIRE(result);
|
||||
CHECK(*result == 1001000);
|
||||
result = mulDiv(max32 + 1, max32 + 1, 5);
|
||||
REQUIRE(result);
|
||||
CHECK(*result == 3689348814741910323);
|
||||
|
||||
// Overflow
|
||||
result = mulDiv(max - 1, max - 2, 5);
|
||||
CHECK(!result);
|
||||
}
|
||||
174
src/tests/libxrpl/basics/scope.cpp
Normal file
174
src/tests/libxrpl/basics/scope.cpp
Normal file
@@ -0,0 +1,174 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2021 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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <xrpl/basics/scope.h>
|
||||
|
||||
#include <doctest/doctest.h>
|
||||
|
||||
using namespace ripple;
|
||||
|
||||
TEST_CASE("scope_exit")
|
||||
{
|
||||
// scope_exit always executes the functor on destruction,
|
||||
// unless release() is called
|
||||
int i = 0;
|
||||
{
|
||||
scope_exit x{[&i]() { i = 1; }};
|
||||
}
|
||||
CHECK(i == 1);
|
||||
{
|
||||
scope_exit x{[&i]() { i = 2; }};
|
||||
x.release();
|
||||
}
|
||||
CHECK(i == 1);
|
||||
{
|
||||
scope_exit x{[&i]() { i += 2; }};
|
||||
auto x2 = std::move(x);
|
||||
}
|
||||
CHECK(i == 3);
|
||||
{
|
||||
scope_exit x{[&i]() { i = 4; }};
|
||||
x.release();
|
||||
auto x2 = std::move(x);
|
||||
}
|
||||
CHECK(i == 3);
|
||||
{
|
||||
try
|
||||
{
|
||||
scope_exit x{[&i]() { i = 5; }};
|
||||
throw 1;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
CHECK(i == 5);
|
||||
{
|
||||
try
|
||||
{
|
||||
scope_exit x{[&i]() { i = 6; }};
|
||||
x.release();
|
||||
throw 1;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
CHECK(i == 5);
|
||||
}
|
||||
|
||||
TEST_CASE("scope_fail")
|
||||
{
|
||||
// scope_fail executes the functor on destruction only
|
||||
// if an exception is unwinding, unless release() is called
|
||||
int i = 0;
|
||||
{
|
||||
scope_fail x{[&i]() { i = 1; }};
|
||||
}
|
||||
CHECK(i == 0);
|
||||
{
|
||||
scope_fail x{[&i]() { i = 2; }};
|
||||
x.release();
|
||||
}
|
||||
CHECK(i == 0);
|
||||
{
|
||||
scope_fail x{[&i]() { i = 3; }};
|
||||
auto x2 = std::move(x);
|
||||
}
|
||||
CHECK(i == 0);
|
||||
{
|
||||
scope_fail x{[&i]() { i = 4; }};
|
||||
x.release();
|
||||
auto x2 = std::move(x);
|
||||
}
|
||||
CHECK(i == 0);
|
||||
{
|
||||
try
|
||||
{
|
||||
scope_fail x{[&i]() { i = 5; }};
|
||||
throw 1;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
CHECK(i == 5);
|
||||
{
|
||||
try
|
||||
{
|
||||
scope_fail x{[&i]() { i = 6; }};
|
||||
x.release();
|
||||
throw 1;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
CHECK(i == 5);
|
||||
}
|
||||
|
||||
TEST_CASE("scope_success")
|
||||
{
|
||||
// scope_success executes the functor on destruction only
|
||||
// if an exception is not unwinding, unless release() is called
|
||||
int i = 0;
|
||||
{
|
||||
scope_success x{[&i]() { i = 1; }};
|
||||
}
|
||||
CHECK(i == 1);
|
||||
{
|
||||
scope_success x{[&i]() { i = 2; }};
|
||||
x.release();
|
||||
}
|
||||
CHECK(i == 1);
|
||||
{
|
||||
scope_success x{[&i]() { i += 2; }};
|
||||
auto x2 = std::move(x);
|
||||
}
|
||||
CHECK(i == 3);
|
||||
{
|
||||
scope_success x{[&i]() { i = 4; }};
|
||||
x.release();
|
||||
auto x2 = std::move(x);
|
||||
}
|
||||
CHECK(i == 3);
|
||||
{
|
||||
try
|
||||
{
|
||||
scope_success x{[&i]() { i = 5; }};
|
||||
throw 1;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
CHECK(i == 3);
|
||||
{
|
||||
try
|
||||
{
|
||||
scope_success x{[&i]() { i = 6; }};
|
||||
x.release();
|
||||
throw 1;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
CHECK(i == 3);
|
||||
}
|
||||
247
src/tests/libxrpl/basics/tagged_integer.cpp
Normal file
247
src/tests/libxrpl/basics/tagged_integer.cpp
Normal file
@@ -0,0 +1,247 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2014 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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <xrpl/basics/tagged_integer.h>
|
||||
|
||||
#include <doctest/doctest.h>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
using namespace ripple;
|
||||
|
||||
struct Tag1
|
||||
{
|
||||
};
|
||||
struct Tag2
|
||||
{
|
||||
};
|
||||
|
||||
// Static checks that types are not interoperable
|
||||
|
||||
using TagUInt1 = tagged_integer<std::uint32_t, Tag1>;
|
||||
using TagUInt2 = tagged_integer<std::uint32_t, Tag2>;
|
||||
using TagUInt3 = tagged_integer<std::uint64_t, Tag1>;
|
||||
|
||||
// Check construction of tagged_integers
|
||||
static_assert(
|
||||
std::is_constructible<TagUInt1, std::uint32_t>::value,
|
||||
"TagUInt1 should be constructible using a std::uint32_t");
|
||||
|
||||
static_assert(
|
||||
!std::is_constructible<TagUInt1, std::uint64_t>::value,
|
||||
"TagUInt1 should not be constructible using a std::uint64_t");
|
||||
|
||||
static_assert(
|
||||
std::is_constructible<TagUInt3, std::uint32_t>::value,
|
||||
"TagUInt3 should be constructible using a std::uint32_t");
|
||||
|
||||
static_assert(
|
||||
std::is_constructible<TagUInt3, std::uint64_t>::value,
|
||||
"TagUInt3 should be constructible using a std::uint64_t");
|
||||
|
||||
// Check assignment of tagged_integers
|
||||
static_assert(
|
||||
!std::is_assignable<TagUInt1, std::uint32_t>::value,
|
||||
"TagUInt1 should not be assignable with a std::uint32_t");
|
||||
|
||||
static_assert(
|
||||
!std::is_assignable<TagUInt1, std::uint64_t>::value,
|
||||
"TagUInt1 should not be assignable with a std::uint64_t");
|
||||
|
||||
static_assert(
|
||||
!std::is_assignable<TagUInt3, std::uint32_t>::value,
|
||||
"TagUInt3 should not be assignable with a std::uint32_t");
|
||||
|
||||
static_assert(
|
||||
!std::is_assignable<TagUInt3, std::uint64_t>::value,
|
||||
"TagUInt3 should not be assignable with a std::uint64_t");
|
||||
|
||||
static_assert(
|
||||
std::is_assignable<TagUInt1, TagUInt1>::value,
|
||||
"TagUInt1 should be assignable with a TagUInt1");
|
||||
|
||||
static_assert(
|
||||
!std::is_assignable<TagUInt1, TagUInt2>::value,
|
||||
"TagUInt1 should not be assignable with a TagUInt2");
|
||||
|
||||
static_assert(
|
||||
std::is_assignable<TagUInt3, TagUInt3>::value,
|
||||
"TagUInt3 should be assignable with a TagUInt1");
|
||||
|
||||
static_assert(
|
||||
!std::is_assignable<TagUInt1, TagUInt3>::value,
|
||||
"TagUInt1 should not be assignable with a TagUInt3");
|
||||
|
||||
static_assert(
|
||||
!std::is_assignable<TagUInt3, TagUInt1>::value,
|
||||
"TagUInt3 should not be assignable with a TagUInt1");
|
||||
|
||||
// Check convertibility of tagged_integers
|
||||
static_assert(
|
||||
!std::is_convertible<std::uint32_t, TagUInt1>::value,
|
||||
"std::uint32_t should not be convertible to a TagUInt1");
|
||||
|
||||
static_assert(
|
||||
!std::is_convertible<std::uint32_t, TagUInt3>::value,
|
||||
"std::uint32_t should not be convertible to a TagUInt3");
|
||||
|
||||
static_assert(
|
||||
!std::is_convertible<std::uint64_t, TagUInt3>::value,
|
||||
"std::uint64_t should not be convertible to a TagUInt3");
|
||||
|
||||
static_assert(
|
||||
!std::is_convertible<std::uint64_t, TagUInt2>::value,
|
||||
"std::uint64_t should not be convertible to a TagUInt2");
|
||||
|
||||
static_assert(
|
||||
!std::is_convertible<TagUInt1, TagUInt2>::value,
|
||||
"TagUInt1 should not be convertible to TagUInt2");
|
||||
|
||||
static_assert(
|
||||
!std::is_convertible<TagUInt1, TagUInt3>::value,
|
||||
"TagUInt1 should not be convertible to TagUInt3");
|
||||
|
||||
static_assert(
|
||||
!std::is_convertible<TagUInt2, TagUInt3>::value,
|
||||
"TagUInt2 should not be convertible to a TagUInt3");
|
||||
|
||||
TEST_SUITE_BEGIN("tagged_integer");
|
||||
|
||||
using TagInt = tagged_integer<std::int32_t, Tag1>;
|
||||
|
||||
TEST_CASE("comparison operators")
|
||||
{
|
||||
TagInt const zero(0);
|
||||
TagInt const one(1);
|
||||
|
||||
CHECK(one == one);
|
||||
CHECK(!(one == zero));
|
||||
|
||||
CHECK(one != zero);
|
||||
CHECK(!(one != one));
|
||||
|
||||
CHECK(zero < one);
|
||||
CHECK(!(one < zero));
|
||||
|
||||
CHECK(one > zero);
|
||||
CHECK(!(zero > one));
|
||||
|
||||
CHECK(one >= one);
|
||||
CHECK(one >= zero);
|
||||
CHECK(!(zero >= one));
|
||||
|
||||
CHECK(zero <= one);
|
||||
CHECK(zero <= zero);
|
||||
CHECK(!(one <= zero));
|
||||
}
|
||||
|
||||
TEST_CASE("increment / decrement operators")
|
||||
{
|
||||
TagInt const zero(0);
|
||||
TagInt const one(1);
|
||||
TagInt a{0};
|
||||
++a;
|
||||
CHECK(a == one);
|
||||
--a;
|
||||
CHECK(a == zero);
|
||||
a++;
|
||||
CHECK(a == one);
|
||||
a--;
|
||||
CHECK(a == zero);
|
||||
}
|
||||
|
||||
TEST_CASE("arithmetic operators")
|
||||
{
|
||||
TagInt a{-2};
|
||||
CHECK(+a == TagInt{-2});
|
||||
CHECK(-a == TagInt{2});
|
||||
CHECK(TagInt{-3} + TagInt{4} == TagInt{1});
|
||||
CHECK(TagInt{-3} - TagInt{4} == TagInt{-7});
|
||||
CHECK(TagInt{-3} * TagInt{4} == TagInt{-12});
|
||||
CHECK(TagInt{8} / TagInt{4} == TagInt{2});
|
||||
CHECK(TagInt{7} % TagInt{4} == TagInt{3});
|
||||
|
||||
CHECK(~TagInt{8} == TagInt{~TagInt::value_type{8}});
|
||||
CHECK((TagInt{6} & TagInt{3}) == TagInt{2});
|
||||
CHECK((TagInt{6} | TagInt{3}) == TagInt{7});
|
||||
CHECK((TagInt{6} ^ TagInt{3}) == TagInt{5});
|
||||
|
||||
CHECK((TagInt{4} << TagInt{2}) == TagInt{16});
|
||||
CHECK((TagInt{16} >> TagInt{2}) == TagInt{4});
|
||||
}
|
||||
|
||||
TEST_CASE("assignment operators")
|
||||
{
|
||||
TagInt a{-2};
|
||||
TagInt b{0};
|
||||
b = a;
|
||||
CHECK(b == TagInt{-2});
|
||||
|
||||
// -3 + 4 == 1
|
||||
a = TagInt{-3};
|
||||
a += TagInt{4};
|
||||
CHECK(a == TagInt{1});
|
||||
|
||||
// -3 - 4 == -7
|
||||
a = TagInt{-3};
|
||||
a -= TagInt{4};
|
||||
CHECK(a == TagInt{-7});
|
||||
|
||||
// -3 * 4 == -12
|
||||
a = TagInt{-3};
|
||||
a *= TagInt{4};
|
||||
CHECK(a == TagInt{-12});
|
||||
|
||||
// 8/4 == 2
|
||||
a = TagInt{8};
|
||||
a /= TagInt{4};
|
||||
CHECK(a == TagInt{2});
|
||||
|
||||
// 7 % 4 == 3
|
||||
a = TagInt{7};
|
||||
a %= TagInt{4};
|
||||
CHECK(a == TagInt{3});
|
||||
|
||||
// 6 & 3 == 2
|
||||
a = TagInt{6};
|
||||
a /= TagInt{3};
|
||||
CHECK(a == TagInt{2});
|
||||
|
||||
// 6 | 3 == 7
|
||||
a = TagInt{6};
|
||||
a |= TagInt{3};
|
||||
CHECK(a == TagInt{7});
|
||||
|
||||
// 6 ^ 3 == 5
|
||||
a = TagInt{6};
|
||||
a ^= TagInt{3};
|
||||
CHECK(a == TagInt{5});
|
||||
|
||||
// 4 << 2 == 16
|
||||
a = TagInt{4};
|
||||
a <<= TagInt{2};
|
||||
CHECK(a == TagInt{16});
|
||||
|
||||
// 16 >> 2 == 4
|
||||
a = TagInt{16};
|
||||
a >>= TagInt{2};
|
||||
CHECK(a == TagInt{4});
|
||||
}
|
||||
|
||||
TEST_SUITE_END();
|
||||
@@ -17,44 +17,18 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <test/jtx/Env.h>
|
||||
|
||||
#include <xrpl/beast/utility/temp_dir.h>
|
||||
#include <xrpl/crypto/csprng.h>
|
||||
|
||||
namespace ripple {
|
||||
#include <doctest/doctest.h>
|
||||
|
||||
class CryptoPRNG_test : public beast::unit_test::suite
|
||||
using namespace ripple;
|
||||
|
||||
TEST_CASE("get values")
|
||||
{
|
||||
void
|
||||
testGetValues()
|
||||
{
|
||||
testcase("Get Values");
|
||||
try
|
||||
{
|
||||
auto& engine = crypto_prng();
|
||||
auto rand_val = engine();
|
||||
BEAST_EXPECT(rand_val >= engine.min());
|
||||
BEAST_EXPECT(rand_val <= engine.max());
|
||||
|
||||
uint16_t twoByte{0};
|
||||
engine(&twoByte, sizeof(uint16_t));
|
||||
pass();
|
||||
}
|
||||
catch (std::exception&)
|
||||
{
|
||||
fail();
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
void
|
||||
run() override
|
||||
{
|
||||
testGetValues();
|
||||
}
|
||||
};
|
||||
|
||||
BEAST_DEFINE_TESTSUITE(CryptoPRNG, core, ripple);
|
||||
|
||||
} // namespace ripple
|
||||
auto& engine = crypto_prng();
|
||||
auto rand_val = engine();
|
||||
CHECK(rand_val >= engine.min());
|
||||
CHECK(rand_val <= engine.max());
|
||||
uint16_t twoByte{0};
|
||||
engine(&twoByte, sizeof(uint16_t));
|
||||
}
|
||||
2
src/tests/libxrpl/crypto/main.cpp
Normal file
2
src/tests/libxrpl/crypto/main.cpp
Normal file
@@ -0,0 +1,2 @@
|
||||
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
|
||||
#include <doctest/doctest.h>
|
||||
@@ -120,15 +120,15 @@ deleteSLE(
|
||||
}
|
||||
|
||||
NotTEC
|
||||
checkFields(PreflightContext const& ctx)
|
||||
checkFields(STTx const& tx, beast::Journal j)
|
||||
{
|
||||
if (!ctx.tx.isFieldPresent(sfCredentialIDs))
|
||||
if (!tx.isFieldPresent(sfCredentialIDs))
|
||||
return tesSUCCESS;
|
||||
|
||||
auto const& credentials = ctx.tx.getFieldV256(sfCredentialIDs);
|
||||
auto const& credentials = tx.getFieldV256(sfCredentialIDs);
|
||||
if (credentials.empty() || (credentials.size() > maxCredentialsArraySize))
|
||||
{
|
||||
JLOG(ctx.j.trace())
|
||||
JLOG(j.trace())
|
||||
<< "Malformed transaction: Credentials array size is invalid: "
|
||||
<< credentials.size();
|
||||
return temMALFORMED;
|
||||
@@ -140,7 +140,7 @@ checkFields(PreflightContext const& ctx)
|
||||
auto [it, ins] = duplicates.insert(cred);
|
||||
if (!ins)
|
||||
{
|
||||
JLOG(ctx.j.trace())
|
||||
JLOG(j.trace())
|
||||
<< "Malformed transaction: duplicates in credentials.";
|
||||
return temMALFORMED;
|
||||
}
|
||||
@@ -150,24 +150,28 @@ checkFields(PreflightContext const& ctx)
|
||||
}
|
||||
|
||||
TER
|
||||
valid(PreclaimContext const& ctx, AccountID const& src)
|
||||
valid(
|
||||
STTx const& tx,
|
||||
ReadView const& view,
|
||||
AccountID const& src,
|
||||
beast::Journal j)
|
||||
{
|
||||
if (!ctx.tx.isFieldPresent(sfCredentialIDs))
|
||||
if (!tx.isFieldPresent(sfCredentialIDs))
|
||||
return tesSUCCESS;
|
||||
|
||||
auto const& credIDs(ctx.tx.getFieldV256(sfCredentialIDs));
|
||||
auto const& credIDs(tx.getFieldV256(sfCredentialIDs));
|
||||
for (auto const& h : credIDs)
|
||||
{
|
||||
auto const sleCred = ctx.view.read(keylet::credential(h));
|
||||
auto const sleCred = view.read(keylet::credential(h));
|
||||
if (!sleCred)
|
||||
{
|
||||
JLOG(ctx.j.trace()) << "Credential doesn't exist. Cred: " << h;
|
||||
JLOG(j.trace()) << "Credential doesn't exist. Cred: " << h;
|
||||
return tecBAD_CREDENTIALS;
|
||||
}
|
||||
|
||||
if (sleCred->getAccountID(sfSubject) != src)
|
||||
{
|
||||
JLOG(ctx.j.trace())
|
||||
JLOG(j.trace())
|
||||
<< "Credential doesn't belong to the source account. Cred: "
|
||||
<< h;
|
||||
return tecBAD_CREDENTIALS;
|
||||
@@ -175,7 +179,7 @@ valid(PreclaimContext const& ctx, AccountID const& src)
|
||||
|
||||
if (!(sleCred->getFlags() & lsfAccepted))
|
||||
{
|
||||
JLOG(ctx.j.trace()) << "Credential isn't accepted. Cred: " << h;
|
||||
JLOG(j.trace()) << "Credential isn't accepted. Cred: " << h;
|
||||
return tecBAD_CREDENTIALS;
|
||||
}
|
||||
|
||||
@@ -352,10 +356,12 @@ verifyValidDomain(
|
||||
|
||||
TER
|
||||
verifyDepositPreauth(
|
||||
ApplyContext& ctx,
|
||||
STTx const& tx,
|
||||
ApplyView& view,
|
||||
AccountID const& src,
|
||||
AccountID const& dst,
|
||||
std::shared_ptr<SLE> const& sleDst)
|
||||
std::shared_ptr<SLE> const& sleDst,
|
||||
beast::Journal j)
|
||||
{
|
||||
// If depositPreauth is enabled, then an account that requires
|
||||
// authorization has at least two ways to get a payment in:
|
||||
@@ -363,24 +369,21 @@ verifyDepositPreauth(
|
||||
// 2. If src is deposit preauthorized by dst (either by account or by
|
||||
// credentials).
|
||||
|
||||
bool const credentialsPresent = ctx.tx.isFieldPresent(sfCredentialIDs);
|
||||
bool const credentialsPresent = tx.isFieldPresent(sfCredentialIDs);
|
||||
|
||||
if (credentialsPresent &&
|
||||
credentials::removeExpired(
|
||||
ctx.view(), ctx.tx.getFieldV256(sfCredentialIDs), ctx.journal))
|
||||
credentials::removeExpired(view, tx.getFieldV256(sfCredentialIDs), j))
|
||||
return tecEXPIRED;
|
||||
|
||||
if (sleDst && (sleDst->getFlags() & lsfDepositAuth))
|
||||
{
|
||||
if (src != dst)
|
||||
{
|
||||
if (!ctx.view().exists(keylet::depositPreauth(dst, src)))
|
||||
if (!view.exists(keylet::depositPreauth(dst, src)))
|
||||
return !credentialsPresent
|
||||
? tecNO_PERMISSION
|
||||
: credentials::authorizedDepositPreauth(
|
||||
ctx.view(),
|
||||
ctx.tx.getFieldV256(sfCredentialIDs),
|
||||
dst);
|
||||
view, tx.getFieldV256(sfCredentialIDs), dst);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,16 @@
|
||||
#ifndef RIPPLE_APP_MISC_CREDENTIALHELPERS_H_INCLUDED
|
||||
#define RIPPLE_APP_MISC_CREDENTIALHELPERS_H_INCLUDED
|
||||
|
||||
#include <xrpld/app/tx/detail/Transactor.h>
|
||||
#include <xrpld/ledger/ApplyView.h>
|
||||
#include <xrpld/ledger/ReadView.h>
|
||||
|
||||
#include <xrpl/basics/Log.h>
|
||||
#include <xrpl/basics/base_uint.h>
|
||||
#include <xrpl/beast/utility/Journal.h>
|
||||
#include <xrpl/protocol/AccountID.h>
|
||||
#include <xrpl/protocol/STArray.h>
|
||||
#include <xrpl/protocol/STTx.h>
|
||||
#include <xrpl/protocol/TER.h>
|
||||
|
||||
namespace ripple {
|
||||
namespace credentials {
|
||||
@@ -48,13 +57,17 @@ deleteSLE(
|
||||
|
||||
// Amendment and parameters checks for sfCredentialIDs field
|
||||
NotTEC
|
||||
checkFields(PreflightContext const& ctx);
|
||||
checkFields(STTx const& tx, beast::Journal j);
|
||||
|
||||
// Accessing the ledger to check if provided credentials are valid. Do not use
|
||||
// in doApply (only in preclaim) since it does not remove expired credentials.
|
||||
// If you call it in prelaim, you also must call verifyDepositPreauth in doApply
|
||||
TER
|
||||
valid(PreclaimContext const& ctx, AccountID const& src);
|
||||
valid(
|
||||
STTx const& tx,
|
||||
ReadView const& view,
|
||||
AccountID const& src,
|
||||
beast::Journal j);
|
||||
|
||||
// Check if subject has any credential maching the given domain. If you call it
|
||||
// in preclaim and it returns tecEXPIRED, you should call verifyValidDomain in
|
||||
@@ -93,10 +106,12 @@ verifyValidDomain(
|
||||
// Check expired credentials and for existing DepositPreauth ledger object
|
||||
TER
|
||||
verifyDepositPreauth(
|
||||
ApplyContext& ctx,
|
||||
STTx const& tx,
|
||||
ApplyView& view,
|
||||
AccountID const& src,
|
||||
AccountID const& dst,
|
||||
std::shared_ptr<SLE> const& sleDst);
|
||||
std::shared_ptr<SLE> const& sleDst,
|
||||
beast::Journal j);
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
|
||||
@@ -58,7 +58,8 @@ DeleteAccount::preflight(PreflightContext const& ctx)
|
||||
// An account cannot be deleted and give itself the resulting XRP.
|
||||
return temDST_IS_SRC;
|
||||
|
||||
if (auto const err = credentials::checkFields(ctx); !isTesSuccess(err))
|
||||
if (auto const err = credentials::checkFields(ctx.tx, ctx.j);
|
||||
!isTesSuccess(err))
|
||||
return err;
|
||||
|
||||
return preflight2(ctx);
|
||||
@@ -241,7 +242,8 @@ DeleteAccount::preclaim(PreclaimContext const& ctx)
|
||||
return tecDST_TAG_NEEDED;
|
||||
|
||||
// If credentials are provided - check them anyway
|
||||
if (auto const err = credentials::valid(ctx, account); !isTesSuccess(err))
|
||||
if (auto const err = credentials::valid(ctx.tx, ctx.view, account, ctx.j);
|
||||
!isTesSuccess(err))
|
||||
return err;
|
||||
|
||||
// if credentials then postpone auth check to doApply, to check for expired
|
||||
@@ -376,7 +378,8 @@ DeleteAccount::doApply()
|
||||
if (ctx_.view().rules().enabled(featureDepositAuth) &&
|
||||
ctx_.tx.isFieldPresent(sfCredentialIDs))
|
||||
{
|
||||
if (auto err = verifyDepositPreauth(ctx_, account_, dstID, dst);
|
||||
if (auto err = verifyDepositPreauth(
|
||||
ctx_.tx, ctx_.view(), account_, dstID, dst, ctx_.journal);
|
||||
!isTesSuccess(err))
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -672,7 +672,8 @@ EscrowFinish::preflight(PreflightContext const& ctx)
|
||||
}
|
||||
}
|
||||
|
||||
if (auto const err = credentials::checkFields(ctx); !isTesSuccess(err))
|
||||
if (auto const err = credentials::checkFields(ctx.tx, ctx.j);
|
||||
!isTesSuccess(err))
|
||||
return err;
|
||||
|
||||
return tesSUCCESS;
|
||||
@@ -761,7 +762,8 @@ EscrowFinish::preclaim(PreclaimContext const& ctx)
|
||||
{
|
||||
if (ctx.view.rules().enabled(featureCredentials))
|
||||
{
|
||||
if (auto const err = credentials::valid(ctx, ctx.tx[sfAccount]);
|
||||
if (auto const err =
|
||||
credentials::valid(ctx.tx, ctx.view, ctx.tx[sfAccount], ctx.j);
|
||||
!isTesSuccess(err))
|
||||
return err;
|
||||
}
|
||||
@@ -1107,7 +1109,8 @@ EscrowFinish::doApply()
|
||||
|
||||
if (ctx_.view().rules().enabled(featureDepositAuth))
|
||||
{
|
||||
if (auto err = verifyDepositPreauth(ctx_, account_, destID, sled);
|
||||
if (auto err = verifyDepositPreauth(
|
||||
ctx_.tx, ctx_.view(), account_, destID, sled, ctx_.journal);
|
||||
!isTesSuccess(err))
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -473,7 +473,8 @@ PayChanClaim::preflight(PreflightContext const& ctx)
|
||||
return temBAD_SIGNATURE;
|
||||
}
|
||||
|
||||
if (auto const err = credentials::checkFields(ctx); !isTesSuccess(err))
|
||||
if (auto const err = credentials::checkFields(ctx.tx, ctx.j);
|
||||
!isTesSuccess(err))
|
||||
return err;
|
||||
|
||||
return preflight2(ctx);
|
||||
@@ -485,7 +486,8 @@ PayChanClaim::preclaim(PreclaimContext const& ctx)
|
||||
if (!ctx.view.rules().enabled(featureCredentials))
|
||||
return Transactor::preclaim(ctx);
|
||||
|
||||
if (auto const err = credentials::valid(ctx, ctx.tx[sfAccount]);
|
||||
if (auto const err =
|
||||
credentials::valid(ctx.tx, ctx.view, ctx.tx[sfAccount], ctx.j);
|
||||
!isTesSuccess(err))
|
||||
return err;
|
||||
|
||||
@@ -554,7 +556,8 @@ PayChanClaim::doApply()
|
||||
|
||||
if (depositAuth)
|
||||
{
|
||||
if (auto err = verifyDepositPreauth(ctx_, txAccount, dst, sled);
|
||||
if (auto err = verifyDepositPreauth(
|
||||
ctx_.tx, ctx_.view(), txAccount, dst, sled, ctx_.journal);
|
||||
!isTesSuccess(err))
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -238,7 +238,8 @@ Payment::preflight(PreflightContext const& ctx)
|
||||
}
|
||||
}
|
||||
|
||||
if (auto const err = credentials::checkFields(ctx); !isTesSuccess(err))
|
||||
if (auto const err = credentials::checkFields(ctx.tx, ctx.j);
|
||||
!isTesSuccess(err))
|
||||
return err;
|
||||
|
||||
return preflight2(ctx);
|
||||
@@ -358,7 +359,8 @@ Payment::preclaim(PreclaimContext const& ctx)
|
||||
}
|
||||
}
|
||||
|
||||
if (auto const err = credentials::valid(ctx, ctx.tx[sfAccount]);
|
||||
if (auto const err =
|
||||
credentials::valid(ctx.tx, ctx.view, ctx.tx[sfAccount], ctx.j);
|
||||
!isTesSuccess(err))
|
||||
return err;
|
||||
|
||||
@@ -450,8 +452,13 @@ Payment::doApply()
|
||||
// 1. If Account == Destination, or
|
||||
// 2. If Account is deposit preauthorized by destination.
|
||||
|
||||
if (auto err =
|
||||
verifyDepositPreauth(ctx_, account_, dstAccountID, sleDst);
|
||||
if (auto err = verifyDepositPreauth(
|
||||
ctx_.tx,
|
||||
ctx_.view(),
|
||||
account_,
|
||||
dstAccountID,
|
||||
sleDst,
|
||||
ctx_.journal);
|
||||
!isTesSuccess(err))
|
||||
return err;
|
||||
}
|
||||
@@ -521,8 +528,13 @@ Payment::doApply()
|
||||
ter != tesSUCCESS)
|
||||
return ter;
|
||||
|
||||
if (auto err =
|
||||
verifyDepositPreauth(ctx_, account_, dstAccountID, sleDst);
|
||||
if (auto err = verifyDepositPreauth(
|
||||
ctx_.tx,
|
||||
ctx_.view(),
|
||||
account_,
|
||||
dstAccountID,
|
||||
sleDst,
|
||||
ctx_.journal);
|
||||
!isTesSuccess(err))
|
||||
return err;
|
||||
|
||||
@@ -644,8 +656,13 @@ Payment::doApply()
|
||||
if (dstAmount > dstReserve ||
|
||||
sleDst->getFieldAmount(sfBalance) > dstReserve)
|
||||
{
|
||||
if (auto err =
|
||||
verifyDepositPreauth(ctx_, account_, dstAccountID, sleDst);
|
||||
if (auto err = verifyDepositPreauth(
|
||||
ctx_.tx,
|
||||
ctx_.view(),
|
||||
account_,
|
||||
dstAccountID,
|
||||
sleDst,
|
||||
ctx_.journal);
|
||||
!isTesSuccess(err))
|
||||
return err;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user