mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-04 19:25:51 +00:00
Compare commits
13 Commits
ripple/se/
...
a1q123456/
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bf4dc342c6 | ||
|
|
a71cd5d271 | ||
|
|
45baf7339c | ||
|
|
f4f7618173 | ||
|
|
66f16469f9 | ||
|
|
1845b1c656 | ||
|
|
e192ffe964 | ||
|
|
2bc2930a28 | ||
|
|
e837171f7c | ||
|
|
6f05bd035c | ||
|
|
b98b42bbec | ||
|
|
6e6ea4311b | ||
|
|
f2271305e5 |
2
.github/workflows/pre-commit.yml
vendored
2
.github/workflows/pre-commit.yml
vendored
@@ -9,7 +9,7 @@ on:
|
||||
jobs:
|
||||
# Call the workflow in the XRPLF/actions repo that runs the pre-commit hooks.
|
||||
run-hooks:
|
||||
uses: XRPLF/actions/.github/workflows/pre-commit.yml@a8d7472b450eb53a1e5228f64552e5974457a21a
|
||||
uses: XRPLF/actions/.github/workflows/pre-commit.yml@34790936fae4c6c751f62ec8c06696f9c1a5753a
|
||||
with:
|
||||
runs_on: ubuntu-latest
|
||||
container: '{ "image": "ghcr.io/xrplf/ci/tools-rippled-pre-commit:sha-a8c7be1" }'
|
||||
|
||||
18
.github/workflows/reusable-build.yml
vendored
18
.github/workflows/reusable-build.yml
vendored
@@ -101,11 +101,27 @@ jobs:
|
||||
--parallel $(nproc) \
|
||||
--target "${CMAKE_TARGET}"
|
||||
|
||||
- name: Put built binaries in one location
|
||||
shell: bash
|
||||
working-directory: ${{ inputs.build_dir }}
|
||||
env:
|
||||
BUILD_TYPE_DIR: ${{ runner.os == 'Windows' && inputs.build_type || '' }}
|
||||
CMAKE_TARGET: ${{ inputs.cmake_target }}
|
||||
run: |
|
||||
mkdir -p ./binaries/doctest/
|
||||
|
||||
cp ./${BUILD_TYPE_DIR}/rippled* ./binaries/
|
||||
if [ "${CMAKE_TARGET}" != 'coverage' ]; then
|
||||
cp ./src/tests/libxrpl/${BUILD_TYPE_DIR}/xrpl.test.* ./binaries/doctest/
|
||||
fi
|
||||
|
||||
- name: Upload rippled artifact
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
env:
|
||||
BUILD_DIR: ${{ inputs.build_dir }}
|
||||
with:
|
||||
name: rippled-${{ inputs.config_name }}
|
||||
path: ${{ inputs.build_dir }}/${{ runner.os == 'Windows' && inputs.build_type || '' }}/rippled${{ runner.os == 'Windows' && '.exe' || '' }}
|
||||
path: ${{ env.BUILD_DIR }}/binaries/
|
||||
retention-days: 3
|
||||
if-no-files-found: error
|
||||
|
||||
|
||||
21
.github/workflows/reusable-test.yml
vendored
21
.github/workflows/reusable-test.yml
vendored
@@ -33,6 +33,10 @@ jobs:
|
||||
container: ${{ inputs.image != '' && inputs.image || null }}
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- name: Cleanup workspace
|
||||
if: ${{ runner.os == 'macOS' }}
|
||||
uses: XRPLF/actions/.github/actions/cleanup-workspace@3f044c7478548e3c32ff68980eeb36ece02b364e
|
||||
|
||||
- name: Download rippled artifact
|
||||
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
|
||||
with:
|
||||
@@ -62,9 +66,22 @@ jobs:
|
||||
run: |
|
||||
./rippled --version | grep libvoidstar
|
||||
|
||||
- name: Test the binary
|
||||
- name: Run the embedded tests
|
||||
if: ${{ inputs.run_tests }}
|
||||
shell: bash
|
||||
run: |
|
||||
./rippled --unittest --unittest-jobs $(nproc)
|
||||
ctest -j $(nproc) --output-on-failure
|
||||
|
||||
- name: Run the separate tests
|
||||
if: ${{ inputs.run_tests }}
|
||||
shell: bash
|
||||
run: |
|
||||
for test_file in ./doctest/*; do
|
||||
echo "Executing $test_file"
|
||||
chmod +x "$test_file"
|
||||
if [[ "${{ runner.os }}" == "Windows" && "$test_file" == "./doctest/xrpl.test.net.exe" ]]; then
|
||||
echo "Skipping $test_file on Windows"
|
||||
else
|
||||
"$test_file"
|
||||
fi
|
||||
done
|
||||
|
||||
@@ -7,7 +7,7 @@ function(xrpl_add_test name)
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/${name}/*.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/${name}.cpp"
|
||||
)
|
||||
add_executable(${target} EXCLUDE_FROM_ALL ${ARGN} ${sources})
|
||||
add_executable(${target} ${ARGN} ${sources})
|
||||
|
||||
isolate_headers(
|
||||
${target}
|
||||
|
||||
@@ -21,11 +21,11 @@ compiler.libcxx={{detect_api.detect_libcxx(compiler, version, compiler_exe)}}
|
||||
|
||||
[conf]
|
||||
{% if compiler == "clang" and compiler_version >= 19 %}
|
||||
tools.build:cxxflags=['-Wno-missing-template-arg-list-after-template-kw']
|
||||
grpc/1.50.1:tools.build:cxxflags+=['-Wno-missing-template-arg-list-after-template-kw']
|
||||
{% endif %}
|
||||
{% if compiler == "apple-clang" and compiler_version >= 17 %}
|
||||
tools.build:cxxflags=['-Wno-missing-template-arg-list-after-template-kw']
|
||||
grpc/1.50.1:tools.build:cxxflags+=['-Wno-missing-template-arg-list-after-template-kw']
|
||||
{% endif %}
|
||||
{% if compiler == "gcc" and compiler_version < 13 %}
|
||||
tools.build:cxxflags=['-Wno-restrict']
|
||||
tools.build:cxxflags+=['-Wno-restrict']
|
||||
{% endif %}
|
||||
|
||||
@@ -127,15 +127,16 @@ public:
|
||||
|
||||
@param key The key corresponding to the object
|
||||
@param data A shared pointer to the data corresponding to the object.
|
||||
@param replace Function that decides if cache should be replaced
|
||||
@param replaceCallback Function that decides if cache should be replaced
|
||||
|
||||
@return `true` If the key already existed.
|
||||
@return First item: `true` If the key already existed; Second item: The
|
||||
canonicalized item.
|
||||
*/
|
||||
template <class R>
|
||||
bool
|
||||
std::pair<bool, SharedPointerType>
|
||||
canonicalize(
|
||||
key_type const& key,
|
||||
SharedPointerType& data,
|
||||
SharedPointerType const& data,
|
||||
R&& replaceCallback);
|
||||
|
||||
bool
|
||||
|
||||
@@ -403,7 +403,7 @@ template <
|
||||
class KeyEqual,
|
||||
class Mutex>
|
||||
template <class R>
|
||||
inline bool
|
||||
inline std::pair<bool, SharedPointerType>
|
||||
TaggedCache<
|
||||
Key,
|
||||
T,
|
||||
@@ -415,11 +415,9 @@ TaggedCache<
|
||||
Mutex>::
|
||||
canonicalize(
|
||||
key_type const& key,
|
||||
SharedPointerType& data,
|
||||
SharedPointerType const& data,
|
||||
R&& replaceCallback)
|
||||
{
|
||||
// Return canonical value, store if needed, refresh in cache
|
||||
// Return values: true=we had the data already
|
||||
std::lock_guard lock(m_mutex);
|
||||
|
||||
auto cit = m_cache.find(key);
|
||||
@@ -431,62 +429,49 @@ TaggedCache<
|
||||
std::forward_as_tuple(key),
|
||||
std::forward_as_tuple(m_clock.now(), data));
|
||||
++m_cache_count;
|
||||
return false;
|
||||
return std::make_pair(false, data);
|
||||
}
|
||||
|
||||
Entry& entry = cit->second;
|
||||
entry.touch(m_clock.now());
|
||||
|
||||
auto shouldReplace = [&] {
|
||||
auto replaceEntryIfNecessary = [&] {
|
||||
bool shouldReplace = false;
|
||||
if constexpr (std::is_invocable_r_v<bool, R>)
|
||||
{
|
||||
// The reason for this extra complexity is for intrusive
|
||||
// strong/weak combo getting a strong is relatively expensive
|
||||
// and not needed for many cases.
|
||||
return replaceCallback();
|
||||
shouldReplace = replaceCallback();
|
||||
}
|
||||
else
|
||||
{
|
||||
return replaceCallback(entry.ptr.getStrong());
|
||||
shouldReplace = replaceCallback(entry.ptr.getStrong());
|
||||
}
|
||||
|
||||
if (shouldReplace)
|
||||
entry.ptr = data;
|
||||
};
|
||||
|
||||
if (entry.isCached())
|
||||
{
|
||||
if (shouldReplace())
|
||||
{
|
||||
entry.ptr = data;
|
||||
}
|
||||
else
|
||||
{
|
||||
data = entry.ptr.getStrong();
|
||||
}
|
||||
|
||||
return true;
|
||||
replaceEntryIfNecessary();
|
||||
return std::make_pair(true, entry.ptr.getStrong());
|
||||
}
|
||||
|
||||
auto cachedData = entry.lock();
|
||||
|
||||
if (cachedData)
|
||||
{
|
||||
if (shouldReplace())
|
||||
{
|
||||
entry.ptr = data;
|
||||
}
|
||||
else
|
||||
{
|
||||
entry.ptr.convertToStrong();
|
||||
data = cachedData;
|
||||
}
|
||||
|
||||
replaceEntryIfNecessary();
|
||||
entry.ptr.convertToStrong();
|
||||
++m_cache_count;
|
||||
return true;
|
||||
return std::make_pair(true, entry.ptr.getStrong());
|
||||
}
|
||||
|
||||
entry.ptr = data;
|
||||
++m_cache_count;
|
||||
|
||||
return false;
|
||||
return std::make_pair(false, data);
|
||||
}
|
||||
|
||||
template <
|
||||
@@ -512,8 +497,8 @@ TaggedCache<
|
||||
key_type const& key,
|
||||
SharedPointerType const& data)
|
||||
{
|
||||
return canonicalize(
|
||||
key, const_cast<SharedPointerType&>(data), []() { return true; });
|
||||
auto [alreadyExists, _] = canonicalize(key, data, []() { return true; });
|
||||
return alreadyExists;
|
||||
}
|
||||
|
||||
template <
|
||||
@@ -537,7 +522,10 @@ TaggedCache<
|
||||
Mutex>::
|
||||
canonicalize_replace_client(key_type const& key, SharedPointerType& data)
|
||||
{
|
||||
return canonicalize(key, data, []() { return false; });
|
||||
auto [alreadyExists, itemInCache] =
|
||||
canonicalize(key, data, []() { return false; });
|
||||
data = itemInCache;
|
||||
return alreadyExists;
|
||||
}
|
||||
|
||||
template <
|
||||
|
||||
@@ -37,7 +37,7 @@ XRPL_FEATURE(DynamicMPT, Supported::no, VoteBehavior::DefaultNo
|
||||
XRPL_FIX (TokenEscrowV1, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (DelegateV1_1, Supported::no, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (PriceOracleOrder, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (MPTDeliveredAmount, Supported::no, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (MPTDeliveredAmount, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (AMMClawbackRounding, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FEATURE(TokenEscrow, Supported::yes, VoteBehavior::DefaultNo)
|
||||
XRPL_FIX (EnforceNFTokenTrustlineV2, Supported::yes, VoteBehavior::DefaultNo)
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
#include <xrpl/basics/chrono.h>
|
||||
#include <xrpl/protocol/Protocol.h>
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
/*
|
||||
@@ -148,6 +150,131 @@ public:
|
||||
BEAST_EXPECT(c.getCacheSize() == 0);
|
||||
BEAST_EXPECT(c.getTrackSize() == 0);
|
||||
}
|
||||
{
|
||||
BEAST_EXPECT(!c.insert(5, "five"));
|
||||
BEAST_EXPECT(c.getCacheSize() == 1);
|
||||
BEAST_EXPECT(c.size() == 1);
|
||||
|
||||
{
|
||||
auto const p1 = c.fetch(5);
|
||||
BEAST_EXPECT(p1 != nullptr);
|
||||
BEAST_EXPECT(c.getCacheSize() == 1);
|
||||
BEAST_EXPECT(c.size() == 1);
|
||||
|
||||
// Advance the clock a lot
|
||||
++clock;
|
||||
c.sweep();
|
||||
BEAST_EXPECT(c.getCacheSize() == 0);
|
||||
BEAST_EXPECT(c.size() == 1);
|
||||
|
||||
auto p2 = std::make_shared<std::string>("five_2");
|
||||
BEAST_EXPECT(c.canonicalize_replace_cache(5, p2));
|
||||
BEAST_EXPECT(c.getCacheSize() == 1);
|
||||
BEAST_EXPECT(c.size() == 1);
|
||||
// Make sure we get the original object
|
||||
BEAST_EXPECT(p1.get() != p2.get());
|
||||
BEAST_EXPECT(*p2 == "five_2");
|
||||
}
|
||||
|
||||
++clock;
|
||||
c.sweep();
|
||||
BEAST_EXPECT(c.getCacheSize() == 0);
|
||||
BEAST_EXPECT(c.size() == 0);
|
||||
}
|
||||
|
||||
{
|
||||
testcase("intrptr");
|
||||
|
||||
struct MyRefCountObject : IntrusiveRefCounts
|
||||
{
|
||||
std::string _data;
|
||||
|
||||
// Needed to support weak intrusive pointers
|
||||
virtual void
|
||||
partialDestructor() {};
|
||||
|
||||
MyRefCountObject() = default;
|
||||
explicit MyRefCountObject(std::string data)
|
||||
: _data(std::move(data))
|
||||
{
|
||||
}
|
||||
explicit MyRefCountObject(char const* data) : _data(data)
|
||||
{
|
||||
}
|
||||
|
||||
MyRefCountObject&
|
||||
operator=(MyRefCountObject const& other)
|
||||
{
|
||||
_data = other._data;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool
|
||||
operator==(MyRefCountObject const& other) const
|
||||
{
|
||||
return _data == other._data;
|
||||
}
|
||||
|
||||
bool
|
||||
operator==(std::string const& other) const
|
||||
{
|
||||
return _data == other;
|
||||
}
|
||||
};
|
||||
|
||||
using IntrPtrCache = TaggedCache<
|
||||
Key,
|
||||
MyRefCountObject,
|
||||
/*IsKeyCache*/ false,
|
||||
intr_ptr::SharedWeakUnionPtr<MyRefCountObject>,
|
||||
intr_ptr::SharedPtr<MyRefCountObject>>;
|
||||
|
||||
IntrPtrCache intrPtrCache("IntrPtrTest", 1, 1s, clock, journal);
|
||||
|
||||
intrPtrCache.canonicalize_replace_cache(
|
||||
1, intr_ptr::make_shared<MyRefCountObject>("one"));
|
||||
BEAST_EXPECT(intrPtrCache.getCacheSize() == 1);
|
||||
BEAST_EXPECT(intrPtrCache.size() == 1);
|
||||
|
||||
{
|
||||
{
|
||||
intrPtrCache.canonicalize_replace_cache(
|
||||
1,
|
||||
intr_ptr::make_shared<MyRefCountObject>(
|
||||
"one_replaced"));
|
||||
|
||||
auto p = intrPtrCache.fetch(1);
|
||||
BEAST_EXPECT(*p == "one_replaced");
|
||||
|
||||
// Advance the clock a lot
|
||||
++clock;
|
||||
intrPtrCache.sweep();
|
||||
BEAST_EXPECT(intrPtrCache.getCacheSize() == 0);
|
||||
BEAST_EXPECT(intrPtrCache.size() == 1);
|
||||
|
||||
intrPtrCache.canonicalize_replace_cache(
|
||||
1,
|
||||
intr_ptr::make_shared<MyRefCountObject>(
|
||||
"one_replaced_2"));
|
||||
|
||||
auto p2 = intrPtrCache.fetch(1);
|
||||
BEAST_EXPECT(*p2 == "one_replaced_2");
|
||||
|
||||
intrPtrCache.del(1, true);
|
||||
}
|
||||
|
||||
intrPtrCache.canonicalize_replace_cache(
|
||||
1,
|
||||
intr_ptr::make_shared<MyRefCountObject>("one_replaced_3"));
|
||||
auto p3 = intrPtrCache.fetch(1);
|
||||
BEAST_EXPECT(*p3 == "one_replaced_3");
|
||||
}
|
||||
|
||||
++clock;
|
||||
intrPtrCache.sweep();
|
||||
BEAST_EXPECT(intrPtrCache.getCacheSize() == 0);
|
||||
BEAST_EXPECT(intrPtrCache.size() == 0);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user