mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Compare commits
11 Commits
415a412d42
...
bthomee/cm
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3d6cc7dc91 | ||
|
|
3711d40901 | ||
|
|
26acbaed64 | ||
|
|
afb6e0e41b | ||
|
|
5523557226 | ||
|
|
b64707f53b | ||
|
|
0b113f371f | ||
|
|
b4c894c1ba | ||
|
|
92281a4ede | ||
|
|
e80642fc12 | ||
|
|
640ce4988f |
6
.github/actions/build-deps/action.yml
vendored
6
.github/actions/build-deps/action.yml
vendored
@@ -28,6 +28,7 @@ runs:
|
||||
BUILD_DIR: ${{ inputs.build_dir }}
|
||||
BUILD_OPTION: ${{ inputs.force_build == 'true' && '*' || 'missing' }}
|
||||
BUILD_TYPE: ${{ inputs.build_type }}
|
||||
VERBOSITY: ${{ inputs.verbosity }}
|
||||
run: |
|
||||
echo 'Installing dependencies.'
|
||||
mkdir -p '${{ env.BUILD_DIR }}'
|
||||
@@ -38,7 +39,6 @@ runs:
|
||||
--options:host='&:tests=True' \
|
||||
--options:host='&:xrpld=True' \
|
||||
--settings:all build_type='${{ env.BUILD_TYPE }}' \
|
||||
--conf:all tools.build:verbosity='${{ inputs.verbosity }}' \
|
||||
--conf:all tools.compilation:verbosity='${{ inputs.verbosity }}' \
|
||||
--conf:all tools.build:jobs=$(nproc) \
|
||||
--conf:all tools.build:verbosity='${{ env.VERBOSITY }}' \
|
||||
--conf:all tools.compilation:verbosity='${{ env.VERBOSITY }}' \
|
||||
..
|
||||
|
||||
@@ -138,7 +138,6 @@ test.toplevel > test.csf
|
||||
test.toplevel > xrpl.json
|
||||
test.unit_test > xrpl.basics
|
||||
tests.libxrpl > xrpl.basics
|
||||
tests.libxrpl > xrpl.ledger
|
||||
tests.libxrpl > xrpl.net
|
||||
xrpl.json > xrpl.basics
|
||||
xrpl.ledger > xrpl.basics
|
||||
|
||||
26
.github/scripts/strategy-matrix/linux.json
vendored
26
.github/scripts/strategy-matrix/linux.json
vendored
@@ -73,47 +73,61 @@
|
||||
"compiler_version": "20",
|
||||
"image_sha": "6948666"
|
||||
},
|
||||
{
|
||||
"distro_name": "rhel",
|
||||
"distro_version": "8",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "14",
|
||||
"image_sha": "10e69b4"
|
||||
},
|
||||
{
|
||||
"distro_name": "rhel",
|
||||
"distro_version": "8",
|
||||
"compiler_name": "clang",
|
||||
"compiler_version": "any",
|
||||
"image_sha": "10e69b4"
|
||||
},
|
||||
{
|
||||
"distro_name": "rhel",
|
||||
"distro_version": "9",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "12",
|
||||
"image_sha": "6948666"
|
||||
"image_sha": "10e69b4"
|
||||
},
|
||||
{
|
||||
"distro_name": "rhel",
|
||||
"distro_version": "9",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "13",
|
||||
"image_sha": "6948666"
|
||||
"image_sha": "10e69b4"
|
||||
},
|
||||
{
|
||||
"distro_name": "rhel",
|
||||
"distro_version": "9",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "14",
|
||||
"image_sha": "6948666"
|
||||
"image_sha": "10e69b4"
|
||||
},
|
||||
{
|
||||
"distro_name": "rhel",
|
||||
"distro_version": "9",
|
||||
"compiler_name": "clang",
|
||||
"compiler_version": "any",
|
||||
"image_sha": "6948666"
|
||||
"image_sha": "10e69b4"
|
||||
},
|
||||
{
|
||||
"distro_name": "rhel",
|
||||
"distro_version": "10",
|
||||
"compiler_name": "gcc",
|
||||
"compiler_version": "14",
|
||||
"image_sha": "6948666"
|
||||
"image_sha": "10e69b4"
|
||||
},
|
||||
{
|
||||
"distro_name": "rhel",
|
||||
"distro_version": "10",
|
||||
"compiler_name": "clang",
|
||||
"compiler_version": "any",
|
||||
"image_sha": "6948666"
|
||||
"image_sha": "10e69b4"
|
||||
},
|
||||
{
|
||||
"distro_name": "ubuntu",
|
||||
|
||||
1
.github/workflows/on-pr.yml
vendored
1
.github/workflows/on-pr.yml
vendored
@@ -103,6 +103,7 @@ jobs:
|
||||
if: ${{ needs.should-run.outputs.go == 'true' }}
|
||||
uses: ./.github/workflows/reusable-build-test.yml
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [linux, macos, windows]
|
||||
with:
|
||||
|
||||
1
.github/workflows/on-trigger.yml
vendored
1
.github/workflows/on-trigger.yml
vendored
@@ -65,6 +65,7 @@ jobs:
|
||||
build-test:
|
||||
uses: ./.github/workflows/reusable-build-test.yml
|
||||
strategy:
|
||||
fail-fast: ${{ github.event_name == 'merge_group' }}
|
||||
matrix:
|
||||
os: [linux, macos, windows]
|
||||
with:
|
||||
|
||||
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@af1b0f0d764cda2e5435f5ac97b240d4bd4d95d3
|
||||
uses: XRPLF/actions/.github/workflows/pre-commit.yml@a8d7472b450eb53a1e5228f64552e5974457a21a
|
||||
with:
|
||||
runs_on: ubuntu-latest
|
||||
container: '{ "image": "ghcr.io/xrplf/ci/tools-rippled-pre-commit:sha-a8c7be1" }'
|
||||
|
||||
2
.github/workflows/reusable-build-test.yml
vendored
2
.github/workflows/reusable-build-test.yml
vendored
@@ -42,7 +42,7 @@ jobs:
|
||||
- generate-matrix
|
||||
uses: ./.github/workflows/reusable-build-test-config.yml
|
||||
strategy:
|
||||
fail-fast: false
|
||||
fail-fast: ${{ github.event_name == 'merge_group' }}
|
||||
matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix) }}
|
||||
max-parallel: 10
|
||||
with:
|
||||
|
||||
4
.github/workflows/reusable-notify-clio.yml
vendored
4
.github/workflows/reusable-notify-clio.yml
vendored
@@ -64,7 +64,9 @@ jobs:
|
||||
conan_remote_name: ${{ inputs.conan_remote_name }}
|
||||
conan_remote_url: ${{ inputs.conan_remote_url }}
|
||||
- name: Log into Conan remote
|
||||
run: conan remote login ${{ inputs.conan_remote_name }} "${{ secrets.conan_remote_username }}" --password "${{ secrets.conan_remote_password }}"
|
||||
env:
|
||||
CONAN_REMOTE_NAME: ${{ inputs.conan_remote_name }}
|
||||
run: conan remote login ${{ env.CONAN_REMOTE_NAME }} "${{ secrets.conan_remote_username }}" --password "${{ secrets.conan_remote_password }}"
|
||||
- name: Upload package
|
||||
env:
|
||||
CONAN_REMOTE_NAME: ${{ inputs.conan_remote_name }}
|
||||
|
||||
@@ -181,11 +181,6 @@ if(xrpld)
|
||||
xrpl.libxrpl
|
||||
)
|
||||
exclude_if_included(rippled)
|
||||
# define a macro for tests that might need to
|
||||
# be exluded or run differently in CI environment
|
||||
if(is_ci)
|
||||
target_compile_definitions(rippled PRIVATE RIPPLED_RUNNING_IN_CI)
|
||||
endif ()
|
||||
|
||||
if(voidstar)
|
||||
target_compile_options(rippled
|
||||
|
||||
@@ -43,6 +43,7 @@ else ()
|
||||
set (is_linux FALSE)
|
||||
endif ()
|
||||
|
||||
# The CI environment variable is set by GitHub Actions.
|
||||
if ("$ENV{CI}" STREQUAL "true" OR "$ENV{CONTINUOUS_INTEGRATION}" STREQUAL "true")
|
||||
set (is_ci TRUE)
|
||||
else ()
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
core:non_interactive=True
|
||||
core.download:parallel={{ os.cpu_count() }}
|
||||
core.upload:parallel={{ os.cpu_count() }}
|
||||
tools.build:jobs={{ (os.cpu_count() * 4/5) | int }}
|
||||
tools.build:jobs={{ os.cpu_count() - 1 }}
|
||||
|
||||
@@ -170,6 +170,9 @@ public:
|
||||
bool
|
||||
retrieve(key_type const& key, T& data);
|
||||
|
||||
mutex_type&
|
||||
peekMutex();
|
||||
|
||||
std::vector<key_type>
|
||||
getKeys() const;
|
||||
|
||||
|
||||
@@ -668,6 +668,29 @@ TaggedCache<
|
||||
return true;
|
||||
}
|
||||
|
||||
template <
|
||||
class Key,
|
||||
class T,
|
||||
bool IsKeyCache,
|
||||
class SharedWeakUnionPointer,
|
||||
class SharedPointerType,
|
||||
class Hash,
|
||||
class KeyEqual,
|
||||
class Mutex>
|
||||
inline auto
|
||||
TaggedCache<
|
||||
Key,
|
||||
T,
|
||||
IsKeyCache,
|
||||
SharedWeakUnionPointer,
|
||||
SharedPointerType,
|
||||
Hash,
|
||||
KeyEqual,
|
||||
Mutex>::peekMutex() -> mutex_type&
|
||||
{
|
||||
return m_mutex;
|
||||
}
|
||||
|
||||
template <
|
||||
class Key,
|
||||
class T,
|
||||
|
||||
@@ -1,138 +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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#ifndef RIPPLE_APP_LEDGER_INDEX_MAP_H_INCLUDED
|
||||
#define RIPPLE_APP_LEDGER_INDEX_MAP_H_INCLUDED
|
||||
|
||||
#include <algorithm>
|
||||
#include <mutex>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
template <class Key, class Mapped>
|
||||
class LedgerIndexMap
|
||||
{
|
||||
public:
|
||||
LedgerIndexMap() = default;
|
||||
explicit LedgerIndexMap(std::size_t reserve_capacity)
|
||||
{
|
||||
data_.reserve(reserve_capacity);
|
||||
}
|
||||
|
||||
LedgerIndexMap(LedgerIndexMap const&) = delete;
|
||||
LedgerIndexMap&
|
||||
operator=(LedgerIndexMap const&) = delete;
|
||||
LedgerIndexMap(LedgerIndexMap&&) = delete;
|
||||
LedgerIndexMap&
|
||||
operator=(LedgerIndexMap&&) = delete;
|
||||
|
||||
Mapped&
|
||||
operator[](Key const& k)
|
||||
{
|
||||
std::lock_guard lock(mutex_);
|
||||
return data_[k];
|
||||
}
|
||||
|
||||
Mapped&
|
||||
operator[](Key&& k)
|
||||
{
|
||||
std::lock_guard lock(mutex_);
|
||||
return data_[std::move(k)];
|
||||
}
|
||||
|
||||
[[nodiscard]] Mapped*
|
||||
get(Key const& k)
|
||||
{
|
||||
std::lock_guard lock(mutex_);
|
||||
auto it = data_.find(k);
|
||||
return it == data_.end() ? nullptr : &it->second;
|
||||
}
|
||||
|
||||
[[nodiscard]] Mapped const*
|
||||
get(Key const& k) const
|
||||
{
|
||||
std::lock_guard lock(mutex_);
|
||||
auto it = data_.find(k);
|
||||
return it == data_.end() ? nullptr : &it->second;
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
Mapped&
|
||||
put(Key const& k, Args&&... args)
|
||||
{
|
||||
std::lock_guard lock(mutex_);
|
||||
auto [it, inserted] = data_.try_emplace(k, std::forward<Args>(args)...);
|
||||
if (!inserted)
|
||||
it->second = Mapped(std::forward<Args>(args)...);
|
||||
return it->second;
|
||||
}
|
||||
|
||||
bool
|
||||
contains(Key const& k) const
|
||||
{
|
||||
std::lock_guard lock(mutex_);
|
||||
return data_.find(k) != data_.end();
|
||||
}
|
||||
|
||||
std::size_t
|
||||
size() const noexcept
|
||||
{
|
||||
std::lock_guard lock(mutex_);
|
||||
return data_.size();
|
||||
}
|
||||
|
||||
bool
|
||||
empty() const noexcept
|
||||
{
|
||||
std::lock_guard lock(mutex_);
|
||||
return data_.empty();
|
||||
}
|
||||
|
||||
void
|
||||
reserve(std::size_t n)
|
||||
{
|
||||
std::lock_guard lock(mutex_);
|
||||
data_.reserve(n);
|
||||
}
|
||||
|
||||
void
|
||||
rehash(std::size_t n)
|
||||
{
|
||||
std::lock_guard lock(mutex_);
|
||||
data_.rehash(n);
|
||||
}
|
||||
|
||||
std::size_t
|
||||
eraseBefore(Key const& cutoff)
|
||||
{
|
||||
std::lock_guard lock(mutex_);
|
||||
auto const before = data_.size();
|
||||
std::erase_if(data_, [&](auto const& kv) { return kv.first < cutoff; });
|
||||
return before - data_.size();
|
||||
}
|
||||
|
||||
private:
|
||||
std::unordered_map<Key, Mapped> data_;
|
||||
mutable std::mutex mutex_;
|
||||
};
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif // RIPPLE_APP_LEDGER_INDEX_MAP_H_INCLUDED
|
||||
@@ -88,10 +88,8 @@ class NFTokenBurnBaseUtil_test : public beast::unit_test::suite
|
||||
jvParams[jss::ledger_index] = "current";
|
||||
jvParams[jss::binary] = false;
|
||||
{
|
||||
Json::Value jrr = env.rpc(
|
||||
"json",
|
||||
"ledger_data",
|
||||
boost::lexical_cast<std::string>(jvParams));
|
||||
Json::Value jrr =
|
||||
env.rpc("json", "ledger_data", to_string(jvParams));
|
||||
|
||||
// Iterate the state and print all NFTokenPages.
|
||||
if (!jrr.isMember(jss::result) ||
|
||||
@@ -413,10 +411,8 @@ class NFTokenBurnBaseUtil_test : public beast::unit_test::suite
|
||||
jvParams[jss::ledger_index] = "current";
|
||||
jvParams[jss::binary] = false;
|
||||
{
|
||||
Json::Value jrr = env.rpc(
|
||||
"json",
|
||||
"ledger_data",
|
||||
boost::lexical_cast<std::string>(jvParams));
|
||||
Json::Value jrr =
|
||||
env.rpc("json", "ledger_data", to_string(jvParams));
|
||||
|
||||
Json::Value& state = jrr[jss::result][jss::state];
|
||||
|
||||
@@ -460,10 +456,8 @@ class NFTokenBurnBaseUtil_test : public beast::unit_test::suite
|
||||
jvParams[jss::ledger_index] = "current";
|
||||
jvParams[jss::binary] = false;
|
||||
{
|
||||
Json::Value jrr = env.rpc(
|
||||
"json",
|
||||
"ledger_data",
|
||||
boost::lexical_cast<std::string>(jvParams));
|
||||
Json::Value jrr =
|
||||
env.rpc("json", "ledger_data", to_string(jvParams));
|
||||
|
||||
Json::Value& state = jrr[jss::result][jss::state];
|
||||
|
||||
@@ -1235,10 +1229,8 @@ class NFTokenBurnBaseUtil_test : public beast::unit_test::suite
|
||||
jvParams[jss::ledger_index] = "current";
|
||||
jvParams[jss::binary] = false;
|
||||
{
|
||||
Json::Value jrr = env.rpc(
|
||||
"json",
|
||||
"ledger_data",
|
||||
boost::lexical_cast<std::string>(jvParams));
|
||||
Json::Value jrr =
|
||||
env.rpc("json", "ledger_data", to_string(jvParams));
|
||||
|
||||
Json::Value& state = jrr[jss::result][jss::state];
|
||||
|
||||
|
||||
@@ -47,10 +47,8 @@ class NFTokenDir_test : public beast::unit_test::suite
|
||||
jvParams[jss::ledger_index] = "current";
|
||||
jvParams[jss::binary] = false;
|
||||
{
|
||||
Json::Value jrr = env.rpc(
|
||||
"json",
|
||||
"ledger_data",
|
||||
boost::lexical_cast<std::string>(jvParams));
|
||||
Json::Value jrr =
|
||||
env.rpc("json", "ledger_data", to_string(jvParams));
|
||||
|
||||
// Iterate the state and print all NFTokenPages.
|
||||
if (!jrr.isMember(jss::result) ||
|
||||
|
||||
@@ -592,10 +592,8 @@ private:
|
||||
jvParams[field] = value;
|
||||
jvParams[jss::binary] = false;
|
||||
jvParams[jss::type] = jss::oracle;
|
||||
Json::Value jrr = env.rpc(
|
||||
"json",
|
||||
"ledger_data",
|
||||
boost::lexical_cast<std::string>(jvParams));
|
||||
Json::Value jrr =
|
||||
env.rpc("json", "ledger_data", to_string(jvParams));
|
||||
BEAST_EXPECT(jrr[jss::result][jss::state].size() == 2);
|
||||
};
|
||||
verifyLedgerData(jss::ledger_index, index);
|
||||
|
||||
@@ -3081,16 +3081,23 @@ public:
|
||||
env.fund(XRP(1000000), alice);
|
||||
env.close();
|
||||
|
||||
auto const withQueue =
|
||||
R"({ "account": ")" + alice.human() + R"(", "queue": true })";
|
||||
auto const withoutQueue = R"({ "account": ")" + alice.human() + R"("})";
|
||||
auto const prevLedgerWithQueue = R"({ "account": ")" + alice.human() +
|
||||
R"(", "queue": true, "ledger_index": 3 })";
|
||||
Json::Value withQueue;
|
||||
withQueue[jss::account] = alice.human();
|
||||
withQueue[jss::queue] = true;
|
||||
|
||||
Json::Value withoutQueue;
|
||||
withoutQueue[jss::account] = alice.human();
|
||||
|
||||
Json::Value prevLedgerWithQueue;
|
||||
prevLedgerWithQueue[jss::account] = alice.human();
|
||||
prevLedgerWithQueue[jss::queue] = true;
|
||||
prevLedgerWithQueue[jss::ledger_index] = 3;
|
||||
BEAST_EXPECT(env.current()->info().seq > 3);
|
||||
|
||||
{
|
||||
// account_info without the "queue" argument.
|
||||
auto const info = env.rpc("json", "account_info", withoutQueue);
|
||||
auto const info =
|
||||
env.rpc("json", "account_info", to_string(withoutQueue));
|
||||
BEAST_EXPECT(
|
||||
info.isMember(jss::result) &&
|
||||
info[jss::result].isMember(jss::account_data));
|
||||
@@ -3098,7 +3105,8 @@ public:
|
||||
}
|
||||
{
|
||||
// account_info with the "queue" argument.
|
||||
auto const info = env.rpc("json", "account_info", withQueue);
|
||||
auto const info =
|
||||
env.rpc("json", "account_info", to_string(withQueue));
|
||||
BEAST_EXPECT(
|
||||
info.isMember(jss::result) &&
|
||||
info[jss::result].isMember(jss::account_data));
|
||||
@@ -3120,7 +3128,8 @@ public:
|
||||
checkMetrics(*this, env, 0, 6, 4, 3);
|
||||
|
||||
{
|
||||
auto const info = env.rpc("json", "account_info", withQueue);
|
||||
auto const info =
|
||||
env.rpc("json", "account_info", to_string(withQueue));
|
||||
BEAST_EXPECT(
|
||||
info.isMember(jss::result) &&
|
||||
info[jss::result].isMember(jss::account_data));
|
||||
@@ -3149,7 +3158,8 @@ public:
|
||||
checkMetrics(*this, env, 4, 6, 4, 3);
|
||||
|
||||
{
|
||||
auto const info = env.rpc("json", "account_info", withQueue);
|
||||
auto const info =
|
||||
env.rpc("json", "account_info", to_string(withQueue));
|
||||
BEAST_EXPECT(
|
||||
info.isMember(jss::result) &&
|
||||
info[jss::result].isMember(jss::account_data));
|
||||
@@ -3212,7 +3222,8 @@ public:
|
||||
checkMetrics(*this, env, 1, 8, 5, 4);
|
||||
|
||||
{
|
||||
auto const info = env.rpc("json", "account_info", withQueue);
|
||||
auto const info =
|
||||
env.rpc("json", "account_info", to_string(withQueue));
|
||||
BEAST_EXPECT(
|
||||
info.isMember(jss::result) &&
|
||||
info[jss::result].isMember(jss::account_data));
|
||||
@@ -3276,7 +3287,8 @@ public:
|
||||
checkMetrics(*this, env, 1, 8, 5, 4);
|
||||
|
||||
{
|
||||
auto const info = env.rpc("json", "account_info", withQueue);
|
||||
auto const info =
|
||||
env.rpc("json", "account_info", to_string(withQueue));
|
||||
BEAST_EXPECT(
|
||||
info.isMember(jss::result) &&
|
||||
info[jss::result].isMember(jss::account_data));
|
||||
@@ -3344,7 +3356,7 @@ public:
|
||||
|
||||
{
|
||||
auto const info =
|
||||
env.rpc("json", "account_info", prevLedgerWithQueue);
|
||||
env.rpc("json", "account_info", to_string(prevLedgerWithQueue));
|
||||
BEAST_EXPECT(
|
||||
info.isMember(jss::result) &&
|
||||
RPC::contains_error(info[jss::result]));
|
||||
@@ -3356,7 +3368,8 @@ public:
|
||||
checkMetrics(*this, env, 0, 10, 0, 5);
|
||||
|
||||
{
|
||||
auto const info = env.rpc("json", "account_info", withQueue);
|
||||
auto const info =
|
||||
env.rpc("json", "account_info", to_string(withQueue));
|
||||
BEAST_EXPECT(
|
||||
info.isMember(jss::result) &&
|
||||
info[jss::result].isMember(jss::account_data));
|
||||
|
||||
@@ -411,7 +411,7 @@ Env::sign_and_submit(JTx const& jt, Json::Value params)
|
||||
if (params.isNull())
|
||||
{
|
||||
// Use the command line interface
|
||||
auto const jv = boost::lexical_cast<std::string>(jt.jv);
|
||||
auto const jv = to_string(jt.jv);
|
||||
jr = rpc("submit", passphrase, jv);
|
||||
}
|
||||
else
|
||||
|
||||
@@ -43,9 +43,7 @@ class AccountCurrencies_test : public beast::unit_test::suite
|
||||
params[jss::account] = Account{"bob"}.human();
|
||||
params[jss::ledger_hash] = 1;
|
||||
auto const result = env.rpc(
|
||||
"json",
|
||||
"account_currencies",
|
||||
boost::lexical_cast<std::string>(params))[jss::result];
|
||||
"json", "account_currencies", to_string(params))[jss::result];
|
||||
BEAST_EXPECT(result[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(result[jss::error_message] == "ledgerHashNotString");
|
||||
}
|
||||
@@ -107,9 +105,7 @@ class AccountCurrencies_test : public beast::unit_test::suite
|
||||
params[jss::account] =
|
||||
"llIIOO"; // these are invalid in bitcoin alphabet
|
||||
auto const result = env.rpc(
|
||||
"json",
|
||||
"account_currencies",
|
||||
boost::lexical_cast<std::string>(params))[jss::result];
|
||||
"json", "account_currencies", to_string(params))[jss::result];
|
||||
BEAST_EXPECT(result[jss::error] == "actMalformed");
|
||||
BEAST_EXPECT(result[jss::error_message] == "Account malformed.");
|
||||
}
|
||||
@@ -119,9 +115,7 @@ class AccountCurrencies_test : public beast::unit_test::suite
|
||||
Json::Value params;
|
||||
params[jss::account] = "Bob";
|
||||
auto const result = env.rpc(
|
||||
"json",
|
||||
"account_currencies",
|
||||
boost::lexical_cast<std::string>(params))[jss::result];
|
||||
"json", "account_currencies", to_string(params))[jss::result];
|
||||
BEAST_EXPECT(result[jss::error] == "actMalformed");
|
||||
BEAST_EXPECT(result[jss::error_message] == "Account malformed.");
|
||||
}
|
||||
@@ -130,9 +124,7 @@ class AccountCurrencies_test : public beast::unit_test::suite
|
||||
Json::Value params;
|
||||
params[jss::account] = Account{"bob"}.human();
|
||||
auto const result = env.rpc(
|
||||
"json",
|
||||
"account_currencies",
|
||||
boost::lexical_cast<std::string>(params))[jss::result];
|
||||
"json", "account_currencies", to_string(params))[jss::result];
|
||||
BEAST_EXPECT(result[jss::error] == "actNotFound");
|
||||
BEAST_EXPECT(result[jss::error_message] == "Account not found.");
|
||||
}
|
||||
@@ -161,9 +153,7 @@ class AccountCurrencies_test : public beast::unit_test::suite
|
||||
Json::Value params;
|
||||
params[jss::account] = alice.human();
|
||||
auto result = env.rpc(
|
||||
"json",
|
||||
"account_currencies",
|
||||
boost::lexical_cast<std::string>(params))[jss::result];
|
||||
"json", "account_currencies", to_string(params))[jss::result];
|
||||
|
||||
auto arrayCheck =
|
||||
[&result](
|
||||
@@ -189,9 +179,7 @@ class AccountCurrencies_test : public beast::unit_test::suite
|
||||
|
||||
// send_currencies should be populated now
|
||||
result = env.rpc(
|
||||
"json",
|
||||
"account_currencies",
|
||||
boost::lexical_cast<std::string>(params))[jss::result];
|
||||
"json", "account_currencies", to_string(params))[jss::result];
|
||||
BEAST_EXPECT(arrayCheck(jss::receive_currencies, gwCurrencies));
|
||||
BEAST_EXPECT(arrayCheck(jss::send_currencies, gwCurrencies));
|
||||
|
||||
@@ -203,9 +191,7 @@ class AccountCurrencies_test : public beast::unit_test::suite
|
||||
BEAST_EXPECT(
|
||||
l[jss::freeze].asBool() == (l[jss::currency] == "USD"));
|
||||
result = env.rpc(
|
||||
"json",
|
||||
"account_currencies",
|
||||
boost::lexical_cast<std::string>(params))[jss::result];
|
||||
"json", "account_currencies", to_string(params))[jss::result];
|
||||
BEAST_EXPECT(arrayCheck(jss::receive_currencies, gwCurrencies));
|
||||
BEAST_EXPECT(arrayCheck(jss::send_currencies, gwCurrencies));
|
||||
// clear the freeze
|
||||
@@ -215,9 +201,7 @@ class AccountCurrencies_test : public beast::unit_test::suite
|
||||
env(pay(gw, alice, gw["USA"](50)));
|
||||
// USA should now be missing from receive_currencies
|
||||
result = env.rpc(
|
||||
"json",
|
||||
"account_currencies",
|
||||
boost::lexical_cast<std::string>(params))[jss::result];
|
||||
"json", "account_currencies", to_string(params))[jss::result];
|
||||
decltype(gwCurrencies) gwCurrenciesNoUSA(
|
||||
gwCurrencies.begin() + 1, gwCurrencies.end());
|
||||
BEAST_EXPECT(arrayCheck(jss::receive_currencies, gwCurrenciesNoUSA));
|
||||
@@ -228,9 +212,7 @@ class AccountCurrencies_test : public beast::unit_test::suite
|
||||
env(trust(gw, alice["USA"](100)));
|
||||
env(pay(alice, gw, alice["USA"](200)));
|
||||
result = env.rpc(
|
||||
"json",
|
||||
"account_currencies",
|
||||
boost::lexical_cast<std::string>(params))[jss::result];
|
||||
"json", "account_currencies", to_string(params))[jss::result];
|
||||
BEAST_EXPECT(arrayCheck(jss::receive_currencies, gwCurrencies));
|
||||
BEAST_EXPECT(arrayCheck(jss::send_currencies, gwCurrenciesNoUSA));
|
||||
}
|
||||
|
||||
@@ -58,10 +58,10 @@ public:
|
||||
{
|
||||
// account_info with an account that's not in the ledger.
|
||||
Account const bogie{"bogie"};
|
||||
auto const info = env.rpc(
|
||||
"json",
|
||||
"account_info",
|
||||
R"({ "account": ")" + bogie.human() + R"("})");
|
||||
Json::Value params;
|
||||
params[jss::account] = bogie.human();
|
||||
auto const info =
|
||||
env.rpc("json", "account_info", to_string(params));
|
||||
BEAST_EXPECT(
|
||||
info[jss::result][jss::error_code] == rpcACT_NOT_FOUND);
|
||||
BEAST_EXPECT(
|
||||
@@ -128,16 +128,18 @@ public:
|
||||
Account const alice{"alice"};
|
||||
env.fund(XRP(1000), alice);
|
||||
|
||||
auto const withoutSigners =
|
||||
std::string("{ ") + "\"account\": \"" + alice.human() + "\"}";
|
||||
Json::Value withoutSigners;
|
||||
withoutSigners[jss::account] = alice.human();
|
||||
|
||||
auto const withSigners = std::string("{ ") + "\"account\": \"" +
|
||||
alice.human() + "\", " + "\"signer_lists\": true }";
|
||||
Json::Value withSigners;
|
||||
withSigners[jss::account] = alice.human();
|
||||
withSigners[jss::signer_lists] = true;
|
||||
|
||||
// Alice has no SignerList yet.
|
||||
{
|
||||
// account_info without the "signer_lists" argument.
|
||||
auto const info = env.rpc("json", "account_info", withoutSigners);
|
||||
auto const info =
|
||||
env.rpc("json", "account_info", to_string(withoutSigners));
|
||||
BEAST_EXPECT(
|
||||
info.isMember(jss::result) &&
|
||||
info[jss::result].isMember(jss::account_data));
|
||||
@@ -146,7 +148,8 @@ public:
|
||||
}
|
||||
{
|
||||
// account_info with the "signer_lists" argument.
|
||||
auto const info = env.rpc("json", "account_info", withSigners);
|
||||
auto const info =
|
||||
env.rpc("json", "account_info", to_string(withSigners));
|
||||
BEAST_EXPECT(
|
||||
info.isMember(jss::result) &&
|
||||
info[jss::result].isMember(jss::account_data));
|
||||
@@ -164,7 +167,8 @@ public:
|
||||
env(smallSigners);
|
||||
{
|
||||
// account_info without the "signer_lists" argument.
|
||||
auto const info = env.rpc("json", "account_info", withoutSigners);
|
||||
auto const info =
|
||||
env.rpc("json", "account_info", to_string(withoutSigners));
|
||||
BEAST_EXPECT(
|
||||
info.isMember(jss::result) &&
|
||||
info[jss::result].isMember(jss::account_data));
|
||||
@@ -173,7 +177,8 @@ public:
|
||||
}
|
||||
{
|
||||
// account_info with the "signer_lists" argument.
|
||||
auto const info = env.rpc("json", "account_info", withSigners);
|
||||
auto const info =
|
||||
env.rpc("json", "account_info", to_string(withSigners));
|
||||
BEAST_EXPECT(
|
||||
info.isMember(jss::result) &&
|
||||
info[jss::result].isMember(jss::account_data));
|
||||
@@ -216,7 +221,8 @@ public:
|
||||
env(bigSigners);
|
||||
{
|
||||
// account_info with the "signer_lists" argument.
|
||||
auto const info = env.rpc("json", "account_info", withSigners);
|
||||
auto const info =
|
||||
env.rpc("json", "account_info", to_string(withSigners));
|
||||
BEAST_EXPECT(
|
||||
info.isMember(jss::result) &&
|
||||
info[jss::result].isMember(jss::account_data));
|
||||
@@ -250,12 +256,14 @@ public:
|
||||
Account const alice{"alice"};
|
||||
env.fund(XRP(1000), alice);
|
||||
|
||||
auto const withoutSigners = std::string("{ ") +
|
||||
"\"api_version\": 2, \"account\": \"" + alice.human() + "\"}";
|
||||
Json::Value withoutSigners;
|
||||
withoutSigners[jss::api_version] = 2;
|
||||
withoutSigners[jss::account] = alice.human();
|
||||
|
||||
auto const withSigners = std::string("{ ") +
|
||||
"\"api_version\": 2, \"account\": \"" + alice.human() + "\", " +
|
||||
"\"signer_lists\": true }";
|
||||
Json::Value withSigners;
|
||||
withSigners[jss::api_version] = 2;
|
||||
withSigners[jss::account] = alice.human();
|
||||
withSigners[jss::signer_lists] = true;
|
||||
|
||||
auto const withSignersAsString = std::string("{ ") +
|
||||
"\"api_version\": 2, \"account\": \"" + alice.human() + "\", " +
|
||||
@@ -264,13 +272,15 @@ public:
|
||||
// Alice has no SignerList yet.
|
||||
{
|
||||
// account_info without the "signer_lists" argument.
|
||||
auto const info = env.rpc("json", "account_info", withoutSigners);
|
||||
auto const info =
|
||||
env.rpc("json", "account_info", to_string(withoutSigners));
|
||||
BEAST_EXPECT(info.isMember(jss::result));
|
||||
BEAST_EXPECT(!info[jss::result].isMember(jss::signer_lists));
|
||||
}
|
||||
{
|
||||
// account_info with the "signer_lists" argument.
|
||||
auto const info = env.rpc("json", "account_info", withSigners);
|
||||
auto const info =
|
||||
env.rpc("json", "account_info", to_string(withSigners));
|
||||
BEAST_EXPECT(info.isMember(jss::result));
|
||||
auto const& data = info[jss::result];
|
||||
BEAST_EXPECT(data.isMember(jss::signer_lists));
|
||||
@@ -286,13 +296,15 @@ public:
|
||||
env(smallSigners);
|
||||
{
|
||||
// account_info without the "signer_lists" argument.
|
||||
auto const info = env.rpc("json", "account_info", withoutSigners);
|
||||
auto const info =
|
||||
env.rpc("json", "account_info", to_string(withoutSigners));
|
||||
BEAST_EXPECT(info.isMember(jss::result));
|
||||
BEAST_EXPECT(!info[jss::result].isMember(jss::signer_lists));
|
||||
}
|
||||
{
|
||||
// account_info with the "signer_lists" argument.
|
||||
auto const info = env.rpc("json", "account_info", withSigners);
|
||||
auto const info =
|
||||
env.rpc("json", "account_info", to_string(withSigners));
|
||||
BEAST_EXPECT(info.isMember(jss::result));
|
||||
auto const& data = info[jss::result];
|
||||
BEAST_EXPECT(data.isMember(jss::signer_lists));
|
||||
@@ -340,7 +352,8 @@ public:
|
||||
env(bigSigners);
|
||||
{
|
||||
// account_info with the "signer_lists" argument.
|
||||
auto const info = env.rpc("json", "account_info", withSigners);
|
||||
auto const info =
|
||||
env.rpc("json", "account_info", to_string(withSigners));
|
||||
BEAST_EXPECT(info.isMember(jss::result));
|
||||
auto const& data = info[jss::result];
|
||||
BEAST_EXPECT(data.isMember(jss::signer_lists));
|
||||
@@ -567,10 +580,10 @@ public:
|
||||
auto getAccountFlag = [&env](
|
||||
std::string_view fName,
|
||||
Account const& account) {
|
||||
auto const info = env.rpc(
|
||||
"json",
|
||||
"account_info",
|
||||
R"({"account" : ")" + account.human() + R"("})");
|
||||
Json::Value params;
|
||||
params[jss::account] = account.human();
|
||||
auto const info =
|
||||
env.rpc("json", "account_info", to_string(params));
|
||||
|
||||
std::optional<bool> res;
|
||||
if (info[jss::result][jss::status] == "success" &&
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -309,10 +309,8 @@ class Feature_test : public beast::unit_test::suite
|
||||
params[jss::feature] =
|
||||
"1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCD"
|
||||
"EF";
|
||||
auto const result = env.rpc(
|
||||
"json",
|
||||
"feature",
|
||||
boost::lexical_cast<std::string>(params))[jss::result];
|
||||
auto const result =
|
||||
env.rpc("json", "feature", to_string(params))[jss::result];
|
||||
BEAST_EXPECTS(
|
||||
result[jss::error] == "badFeature", result.toStyledString());
|
||||
BEAST_EXPECT(
|
||||
@@ -326,10 +324,8 @@ class Feature_test : public beast::unit_test::suite
|
||||
"A7";
|
||||
// invalid param
|
||||
params[jss::vetoed] = true;
|
||||
auto const result = env.rpc(
|
||||
"json",
|
||||
"feature",
|
||||
boost::lexical_cast<std::string>(params))[jss::result];
|
||||
auto const result =
|
||||
env.rpc("json", "feature", to_string(params))[jss::result];
|
||||
BEAST_EXPECTS(
|
||||
result[jss::error] == "noPermission",
|
||||
result[jss::error].asString());
|
||||
@@ -344,10 +340,8 @@ class Feature_test : public beast::unit_test::suite
|
||||
"37";
|
||||
Json::Value params;
|
||||
params[jss::feature] = feature;
|
||||
auto const result = env.rpc(
|
||||
"json",
|
||||
"feature",
|
||||
boost::lexical_cast<std::string>(params))[jss::result];
|
||||
auto const result =
|
||||
env.rpc("json", "feature", to_string(params))[jss::result];
|
||||
BEAST_EXPECT(result.isMember(feature));
|
||||
auto const amendmentResult = result[feature];
|
||||
BEAST_EXPECT(amendmentResult[jss::enabled].asBool() == false);
|
||||
|
||||
@@ -63,9 +63,7 @@ public:
|
||||
jvParams[jss::binary] = false;
|
||||
{
|
||||
auto const jrr = env.rpc(
|
||||
"json",
|
||||
"ledger_data",
|
||||
boost::lexical_cast<std::string>(jvParams))[jss::result];
|
||||
"json", "ledger_data", to_string(jvParams))[jss::result];
|
||||
BEAST_EXPECT(
|
||||
jrr[jss::ledger_current_index].isIntegral() &&
|
||||
jrr[jss::ledger_current_index].asInt() > 0);
|
||||
@@ -78,9 +76,7 @@ public:
|
||||
{
|
||||
jvParams[jss::limit] = max_limit + delta;
|
||||
auto const jrr = env.rpc(
|
||||
"json",
|
||||
"ledger_data",
|
||||
boost::lexical_cast<std::string>(jvParams))[jss::result];
|
||||
"json", "ledger_data", to_string(jvParams))[jss::result];
|
||||
BEAST_EXPECT(checkArraySize(
|
||||
jrr[jss::state],
|
||||
(delta > 0 && !asAdmin) ? max_limit : max_limit + delta));
|
||||
@@ -109,10 +105,8 @@ public:
|
||||
Json::Value jvParams;
|
||||
jvParams[jss::ledger_index] = "current";
|
||||
jvParams[jss::binary] = true;
|
||||
auto const jrr = env.rpc(
|
||||
"json",
|
||||
"ledger_data",
|
||||
boost::lexical_cast<std::string>(jvParams))[jss::result];
|
||||
auto const jrr =
|
||||
env.rpc("json", "ledger_data", to_string(jvParams))[jss::result];
|
||||
BEAST_EXPECT(
|
||||
jrr[jss::ledger_current_index].isIntegral() &&
|
||||
jrr[jss::ledger_current_index].asInt() > 0);
|
||||
@@ -137,9 +131,7 @@ public:
|
||||
Json::Value jvParams;
|
||||
jvParams[jss::limit] = "0"; // NOT an integer
|
||||
auto const jrr = env.rpc(
|
||||
"json",
|
||||
"ledger_data",
|
||||
boost::lexical_cast<std::string>(jvParams))[jss::result];
|
||||
"json", "ledger_data", to_string(jvParams))[jss::result];
|
||||
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(jrr[jss::status] == "error");
|
||||
BEAST_EXPECT(
|
||||
@@ -152,9 +144,7 @@ public:
|
||||
Json::Value jvParams;
|
||||
jvParams[jss::marker] = "NOT_A_MARKER";
|
||||
auto const jrr = env.rpc(
|
||||
"json",
|
||||
"ledger_data",
|
||||
boost::lexical_cast<std::string>(jvParams))[jss::result];
|
||||
"json", "ledger_data", to_string(jvParams))[jss::result];
|
||||
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(jrr[jss::status] == "error");
|
||||
BEAST_EXPECT(
|
||||
@@ -167,9 +157,7 @@ public:
|
||||
Json::Value jvParams;
|
||||
jvParams[jss::marker] = 1;
|
||||
auto const jrr = env.rpc(
|
||||
"json",
|
||||
"ledger_data",
|
||||
boost::lexical_cast<std::string>(jvParams))[jss::result];
|
||||
"json", "ledger_data", to_string(jvParams))[jss::result];
|
||||
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(jrr[jss::status] == "error");
|
||||
BEAST_EXPECT(
|
||||
@@ -182,9 +170,7 @@ public:
|
||||
Json::Value jvParams;
|
||||
jvParams[jss::ledger_index] = 10u;
|
||||
auto const jrr = env.rpc(
|
||||
"json",
|
||||
"ledger_data",
|
||||
boost::lexical_cast<std::string>(jvParams))[jss::result];
|
||||
"json", "ledger_data", to_string(jvParams))[jss::result];
|
||||
BEAST_EXPECT(jrr[jss::error] == "lgrNotFound");
|
||||
BEAST_EXPECT(jrr[jss::status] == "error");
|
||||
BEAST_EXPECT(jrr[jss::error_message] == "ledgerNotFound");
|
||||
@@ -213,27 +199,20 @@ public:
|
||||
Json::Value jvParams;
|
||||
jvParams[jss::ledger_index] = "current";
|
||||
jvParams[jss::binary] = false;
|
||||
auto jrr = env.rpc(
|
||||
"json",
|
||||
"ledger_data",
|
||||
boost::lexical_cast<std::string>(jvParams))[jss::result];
|
||||
auto jrr =
|
||||
env.rpc("json", "ledger_data", to_string(jvParams))[jss::result];
|
||||
auto const total_count = jrr[jss::state].size();
|
||||
|
||||
// now make request with a limit and loop until we get all
|
||||
jvParams[jss::limit] = 5;
|
||||
jrr = env.rpc(
|
||||
"json",
|
||||
"ledger_data",
|
||||
boost::lexical_cast<std::string>(jvParams))[jss::result];
|
||||
jrr = env.rpc("json", "ledger_data", to_string(jvParams))[jss::result];
|
||||
BEAST_EXPECT(checkMarker(jrr));
|
||||
auto running_total = jrr[jss::state].size();
|
||||
while (jrr.isMember(jss::marker))
|
||||
{
|
||||
jvParams[jss::marker] = jrr[jss::marker];
|
||||
jrr = env.rpc(
|
||||
"json",
|
||||
"ledger_data",
|
||||
boost::lexical_cast<std::string>(jvParams))[jss::result];
|
||||
"json", "ledger_data", to_string(jvParams))[jss::result];
|
||||
running_total += jrr[jss::state].size();
|
||||
}
|
||||
BEAST_EXPECT(running_total == total_count);
|
||||
@@ -253,9 +232,7 @@ public:
|
||||
Json::Value jvParams;
|
||||
jvParams[jss::ledger_index] = "closed";
|
||||
auto jrr = env.rpc(
|
||||
"json",
|
||||
"ledger_data",
|
||||
boost::lexical_cast<std::string>(jvParams))[jss::result];
|
||||
"json", "ledger_data", to_string(jvParams))[jss::result];
|
||||
if (BEAST_EXPECT(jrr.isMember(jss::ledger)))
|
||||
BEAST_EXPECT(
|
||||
jrr[jss::ledger][jss::ledger_hash] ==
|
||||
@@ -267,9 +244,7 @@ public:
|
||||
jvParams[jss::ledger_index] = "closed";
|
||||
jvParams[jss::binary] = true;
|
||||
auto jrr = env.rpc(
|
||||
"json",
|
||||
"ledger_data",
|
||||
boost::lexical_cast<std::string>(jvParams))[jss::result];
|
||||
"json", "ledger_data", to_string(jvParams))[jss::result];
|
||||
if (BEAST_EXPECT(jrr.isMember(jss::ledger)))
|
||||
{
|
||||
auto data =
|
||||
@@ -288,9 +263,7 @@ public:
|
||||
Json::Value jvParams;
|
||||
jvParams[jss::binary] = true;
|
||||
auto jrr = env.rpc(
|
||||
"json",
|
||||
"ledger_data",
|
||||
boost::lexical_cast<std::string>(jvParams))[jss::result];
|
||||
"json", "ledger_data", to_string(jvParams))[jss::result];
|
||||
BEAST_EXPECT(jrr.isMember(jss::ledger));
|
||||
BEAST_EXPECT(!jrr[jss::ledger].isMember(jss::ledger_data));
|
||||
}
|
||||
@@ -319,9 +292,7 @@ public:
|
||||
jvParams[jss::ledger_index] = "current";
|
||||
jvParams[jss::type] = type;
|
||||
return env.rpc(
|
||||
"json",
|
||||
"ledger_data",
|
||||
boost::lexical_cast<std::string>(jvParams))[jss::result];
|
||||
"json", "ledger_data", to_string(jvParams))[jss::result];
|
||||
};
|
||||
|
||||
// Assert that state is an empty array.
|
||||
@@ -500,9 +471,7 @@ public:
|
||||
jvParams[jss::ledger_index] = "current";
|
||||
jvParams[jss::type] = "misspelling";
|
||||
auto const jrr = env.rpc(
|
||||
"json",
|
||||
"ledger_data",
|
||||
boost::lexical_cast<std::string>(jvParams))[jss::result];
|
||||
"json", "ledger_data", to_string(jvParams))[jss::result];
|
||||
BEAST_EXPECT(jrr.isMember("error"));
|
||||
BEAST_EXPECT(jrr["error"] == "invalidParams");
|
||||
BEAST_EXPECT(jrr["error_message"] == "Invalid field 'type'.");
|
||||
|
||||
@@ -287,56 +287,39 @@ class LedgerRPC_test : public beast::unit_test::suite
|
||||
// access via the legacy ledger field, keyword index values
|
||||
Json::Value jvParams;
|
||||
jvParams[jss::ledger] = "closed";
|
||||
auto jrr = env.rpc(
|
||||
"json",
|
||||
"ledger",
|
||||
boost::lexical_cast<std::string>(jvParams))[jss::result];
|
||||
auto jrr =
|
||||
env.rpc("json", "ledger", to_string(jvParams))[jss::result];
|
||||
BEAST_EXPECT(jrr.isMember(jss::ledger));
|
||||
BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
|
||||
BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] == "5");
|
||||
|
||||
jvParams[jss::ledger] = "validated";
|
||||
jrr = env.rpc(
|
||||
"json",
|
||||
"ledger",
|
||||
boost::lexical_cast<std::string>(jvParams))[jss::result];
|
||||
jrr = env.rpc("json", "ledger", to_string(jvParams))[jss::result];
|
||||
BEAST_EXPECT(jrr.isMember(jss::ledger));
|
||||
BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
|
||||
BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] == "5");
|
||||
|
||||
jvParams[jss::ledger] = "current";
|
||||
jrr = env.rpc(
|
||||
"json",
|
||||
"ledger",
|
||||
boost::lexical_cast<std::string>(jvParams))[jss::result];
|
||||
jrr = env.rpc("json", "ledger", to_string(jvParams))[jss::result];
|
||||
BEAST_EXPECT(jrr.isMember(jss::ledger));
|
||||
BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] == "6");
|
||||
|
||||
// ask for a bad ledger keyword
|
||||
jvParams[jss::ledger] = "invalid";
|
||||
jrr = env.rpc(
|
||||
"json",
|
||||
"ledger",
|
||||
boost::lexical_cast<std::string>(jvParams))[jss::result];
|
||||
jrr = env.rpc("json", "ledger", to_string(jvParams))[jss::result];
|
||||
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(jrr[jss::error_message] == "ledgerIndexMalformed");
|
||||
|
||||
// numeric index
|
||||
jvParams[jss::ledger] = 4;
|
||||
jrr = env.rpc(
|
||||
"json",
|
||||
"ledger",
|
||||
boost::lexical_cast<std::string>(jvParams))[jss::result];
|
||||
jrr = env.rpc("json", "ledger", to_string(jvParams))[jss::result];
|
||||
BEAST_EXPECT(jrr.isMember(jss::ledger));
|
||||
BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
|
||||
BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] == "4");
|
||||
|
||||
// numeric index - out of range
|
||||
jvParams[jss::ledger] = 20;
|
||||
jrr = env.rpc(
|
||||
"json",
|
||||
"ledger",
|
||||
boost::lexical_cast<std::string>(jvParams))[jss::result];
|
||||
jrr = env.rpc("json", "ledger", to_string(jvParams))[jss::result];
|
||||
BEAST_EXPECT(jrr[jss::error] == "lgrNotFound");
|
||||
BEAST_EXPECT(jrr[jss::error_message] == "ledgerNotFound");
|
||||
}
|
||||
@@ -348,29 +331,21 @@ class LedgerRPC_test : public beast::unit_test::suite
|
||||
// access via the ledger_hash field
|
||||
Json::Value jvParams;
|
||||
jvParams[jss::ledger_hash] = hash3;
|
||||
auto jrr = env.rpc(
|
||||
"json",
|
||||
"ledger",
|
||||
boost::lexical_cast<std::string>(jvParams))[jss::result];
|
||||
auto jrr =
|
||||
env.rpc("json", "ledger", to_string(jvParams))[jss::result];
|
||||
BEAST_EXPECT(jrr.isMember(jss::ledger));
|
||||
BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
|
||||
BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] == "3");
|
||||
|
||||
// extra leading hex chars in hash are not allowed
|
||||
jvParams[jss::ledger_hash] = "DEADBEEF" + hash3;
|
||||
jrr = env.rpc(
|
||||
"json",
|
||||
"ledger",
|
||||
boost::lexical_cast<std::string>(jvParams))[jss::result];
|
||||
jrr = env.rpc("json", "ledger", to_string(jvParams))[jss::result];
|
||||
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(jrr[jss::error_message] == "ledgerHashMalformed");
|
||||
|
||||
// request with non-string ledger_hash
|
||||
jvParams[jss::ledger_hash] = 2;
|
||||
jrr = env.rpc(
|
||||
"json",
|
||||
"ledger",
|
||||
boost::lexical_cast<std::string>(jvParams))[jss::result];
|
||||
jrr = env.rpc("json", "ledger", to_string(jvParams))[jss::result];
|
||||
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(jrr[jss::error_message] == "ledgerHashNotString");
|
||||
|
||||
@@ -378,10 +353,7 @@ class LedgerRPC_test : public beast::unit_test::suite
|
||||
jvParams[jss::ledger_hash] =
|
||||
"2E81FC6EC0DD943197EGC7E3FBE9AE30"
|
||||
"7F2775F2F7485BB37307984C3C0F2340";
|
||||
jrr = env.rpc(
|
||||
"json",
|
||||
"ledger",
|
||||
boost::lexical_cast<std::string>(jvParams))[jss::result];
|
||||
jrr = env.rpc("json", "ledger", to_string(jvParams))[jss::result];
|
||||
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(jrr[jss::error_message] == "ledgerHashMalformed");
|
||||
|
||||
@@ -389,10 +361,7 @@ class LedgerRPC_test : public beast::unit_test::suite
|
||||
jvParams[jss::ledger_hash] =
|
||||
"8C3EEDB3124D92E49E75D81A8826A2E6"
|
||||
"5A75FD71FC3FD6F36FEB803C5F1D812D";
|
||||
jrr = env.rpc(
|
||||
"json",
|
||||
"ledger",
|
||||
boost::lexical_cast<std::string>(jvParams))[jss::result];
|
||||
jrr = env.rpc("json", "ledger", to_string(jvParams))[jss::result];
|
||||
BEAST_EXPECT(jrr[jss::error] == "lgrNotFound");
|
||||
BEAST_EXPECT(jrr[jss::error_message] == "ledgerNotFound");
|
||||
}
|
||||
@@ -401,39 +370,28 @@ class LedgerRPC_test : public beast::unit_test::suite
|
||||
// access via the ledger_index field, keyword index values
|
||||
Json::Value jvParams;
|
||||
jvParams[jss::ledger_index] = "closed";
|
||||
auto jrr = env.rpc(
|
||||
"json",
|
||||
"ledger",
|
||||
boost::lexical_cast<std::string>(jvParams))[jss::result];
|
||||
auto jrr =
|
||||
env.rpc("json", "ledger", to_string(jvParams))[jss::result];
|
||||
BEAST_EXPECT(jrr.isMember(jss::ledger));
|
||||
BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
|
||||
BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] == "5");
|
||||
BEAST_EXPECT(jrr.isMember(jss::ledger_index));
|
||||
|
||||
jvParams[jss::ledger_index] = "validated";
|
||||
jrr = env.rpc(
|
||||
"json",
|
||||
"ledger",
|
||||
boost::lexical_cast<std::string>(jvParams))[jss::result];
|
||||
jrr = env.rpc("json", "ledger", to_string(jvParams))[jss::result];
|
||||
BEAST_EXPECT(jrr.isMember(jss::ledger));
|
||||
BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
|
||||
BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] == "5");
|
||||
|
||||
jvParams[jss::ledger_index] = "current";
|
||||
jrr = env.rpc(
|
||||
"json",
|
||||
"ledger",
|
||||
boost::lexical_cast<std::string>(jvParams))[jss::result];
|
||||
jrr = env.rpc("json", "ledger", to_string(jvParams))[jss::result];
|
||||
BEAST_EXPECT(jrr.isMember(jss::ledger));
|
||||
BEAST_EXPECT(jrr[jss::ledger][jss::ledger_index] == "6");
|
||||
BEAST_EXPECT(jrr.isMember(jss::ledger_current_index));
|
||||
|
||||
// ask for a bad ledger keyword
|
||||
jvParams[jss::ledger_index] = "invalid";
|
||||
jrr = env.rpc(
|
||||
"json",
|
||||
"ledger",
|
||||
boost::lexical_cast<std::string>(jvParams))[jss::result];
|
||||
jrr = env.rpc("json", "ledger", to_string(jvParams))[jss::result];
|
||||
BEAST_EXPECT(jrr[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(jrr[jss::error_message] == "ledgerIndexMalformed");
|
||||
|
||||
@@ -441,10 +399,8 @@ class LedgerRPC_test : public beast::unit_test::suite
|
||||
for (auto i : {1, 2, 3, 4, 5, 6})
|
||||
{
|
||||
jvParams[jss::ledger_index] = i;
|
||||
jrr = env.rpc(
|
||||
"json",
|
||||
"ledger",
|
||||
boost::lexical_cast<std::string>(jvParams))[jss::result];
|
||||
jrr =
|
||||
env.rpc("json", "ledger", to_string(jvParams))[jss::result];
|
||||
BEAST_EXPECT(jrr.isMember(jss::ledger));
|
||||
if (i < 6)
|
||||
BEAST_EXPECT(jrr.isMember(jss::ledger_hash));
|
||||
@@ -454,10 +410,7 @@ class LedgerRPC_test : public beast::unit_test::suite
|
||||
|
||||
// numeric index - out of range
|
||||
jvParams[jss::ledger_index] = 7;
|
||||
jrr = env.rpc(
|
||||
"json",
|
||||
"ledger",
|
||||
boost::lexical_cast<std::string>(jvParams))[jss::result];
|
||||
jrr = env.rpc("json", "ledger", to_string(jvParams))[jss::result];
|
||||
BEAST_EXPECT(jrr[jss::error] == "lgrNotFound");
|
||||
BEAST_EXPECT(jrr[jss::error_message] == "ledgerNotFound");
|
||||
}
|
||||
|
||||
@@ -59,9 +59,7 @@ class NoRippleCheck_test : public beast::unit_test::suite
|
||||
Json::Value params;
|
||||
params[jss::account] = alice.human();
|
||||
auto const result = env.rpc(
|
||||
"json",
|
||||
"noripple_check",
|
||||
boost::lexical_cast<std::string>(params))[jss::result];
|
||||
"json", "noripple_check", to_string(params))[jss::result];
|
||||
BEAST_EXPECT(result[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(result[jss::error_message] == "Missing field 'role'.");
|
||||
}
|
||||
@@ -92,9 +90,7 @@ class NoRippleCheck_test : public beast::unit_test::suite
|
||||
params[jss::account] = alice.human();
|
||||
params[jss::role] = "not_a_role";
|
||||
auto const result = env.rpc(
|
||||
"json",
|
||||
"noripple_check",
|
||||
boost::lexical_cast<std::string>(params))[jss::result];
|
||||
"json", "noripple_check", to_string(params))[jss::result];
|
||||
BEAST_EXPECT(result[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(result[jss::error_message] == "Invalid field 'role'.");
|
||||
}
|
||||
@@ -105,9 +101,7 @@ class NoRippleCheck_test : public beast::unit_test::suite
|
||||
params[jss::role] = "user";
|
||||
params[jss::limit] = -1;
|
||||
auto const result = env.rpc(
|
||||
"json",
|
||||
"noripple_check",
|
||||
boost::lexical_cast<std::string>(params))[jss::result];
|
||||
"json", "noripple_check", to_string(params))[jss::result];
|
||||
BEAST_EXPECT(result[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(
|
||||
result[jss::error_message] ==
|
||||
@@ -120,9 +114,7 @@ class NoRippleCheck_test : public beast::unit_test::suite
|
||||
params[jss::role] = "user";
|
||||
params[jss::ledger_hash] = 1;
|
||||
auto const result = env.rpc(
|
||||
"json",
|
||||
"noripple_check",
|
||||
boost::lexical_cast<std::string>(params))[jss::result];
|
||||
"json", "noripple_check", to_string(params))[jss::result];
|
||||
BEAST_EXPECT(result[jss::error] == "invalidParams");
|
||||
BEAST_EXPECT(result[jss::error_message] == "ledgerHashNotString");
|
||||
}
|
||||
@@ -133,9 +125,7 @@ class NoRippleCheck_test : public beast::unit_test::suite
|
||||
params[jss::role] = "user";
|
||||
params[jss::ledger] = "current";
|
||||
auto const result = env.rpc(
|
||||
"json",
|
||||
"noripple_check",
|
||||
boost::lexical_cast<std::string>(params))[jss::result];
|
||||
"json", "noripple_check", to_string(params))[jss::result];
|
||||
BEAST_EXPECT(result[jss::error] == "actNotFound");
|
||||
BEAST_EXPECT(result[jss::error_message] == "Account not found.");
|
||||
}
|
||||
@@ -147,9 +137,7 @@ class NoRippleCheck_test : public beast::unit_test::suite
|
||||
params[jss::role] = "user";
|
||||
params[jss::ledger] = "current";
|
||||
auto const result = env.rpc(
|
||||
"json",
|
||||
"noripple_check",
|
||||
boost::lexical_cast<std::string>(params))[jss::result];
|
||||
"json", "noripple_check", to_string(params))[jss::result];
|
||||
BEAST_EXPECT(result[jss::error] == "actMalformed");
|
||||
BEAST_EXPECT(result[jss::error_message] == "Account malformed.");
|
||||
}
|
||||
@@ -184,10 +172,8 @@ class NoRippleCheck_test : public beast::unit_test::suite
|
||||
params[jss::account] = alice.human();
|
||||
params[jss::role] = (user ? "user" : "gateway");
|
||||
params[jss::ledger] = "current";
|
||||
auto result = env.rpc(
|
||||
"json",
|
||||
"noripple_check",
|
||||
boost::lexical_cast<std::string>(params))[jss::result];
|
||||
auto result =
|
||||
env.rpc("json", "noripple_check", to_string(params))[jss::result];
|
||||
|
||||
auto const pa = result["problems"];
|
||||
if (!BEAST_EXPECT(pa.isArray()))
|
||||
@@ -221,10 +207,8 @@ class NoRippleCheck_test : public beast::unit_test::suite
|
||||
// now make a second request asking for the relevant transactions this
|
||||
// time.
|
||||
params[jss::transactions] = true;
|
||||
result = env.rpc(
|
||||
"json",
|
||||
"noripple_check",
|
||||
boost::lexical_cast<std::string>(params))[jss::result];
|
||||
result =
|
||||
env.rpc("json", "noripple_check", to_string(params))[jss::result];
|
||||
if (!BEAST_EXPECT(result[jss::transactions].isArray()))
|
||||
return;
|
||||
|
||||
@@ -343,43 +327,33 @@ class NoRippleCheckLimits_test : public beast::unit_test::suite
|
||||
params[jss::account] = alice.human();
|
||||
params[jss::role] = "user";
|
||||
params[jss::ledger] = "current";
|
||||
auto result = env.rpc(
|
||||
"json",
|
||||
"noripple_check",
|
||||
boost::lexical_cast<std::string>(params))[jss::result];
|
||||
auto result =
|
||||
env.rpc("json", "noripple_check", to_string(params))[jss::result];
|
||||
|
||||
BEAST_EXPECT(result["problems"].size() == 301);
|
||||
|
||||
// one below minimum
|
||||
params[jss::limit] = 9;
|
||||
result = env.rpc(
|
||||
"json",
|
||||
"noripple_check",
|
||||
boost::lexical_cast<std::string>(params))[jss::result];
|
||||
result =
|
||||
env.rpc("json", "noripple_check", to_string(params))[jss::result];
|
||||
BEAST_EXPECT(result["problems"].size() == (admin ? 10 : 11));
|
||||
|
||||
// at minimum
|
||||
params[jss::limit] = 10;
|
||||
result = env.rpc(
|
||||
"json",
|
||||
"noripple_check",
|
||||
boost::lexical_cast<std::string>(params))[jss::result];
|
||||
result =
|
||||
env.rpc("json", "noripple_check", to_string(params))[jss::result];
|
||||
BEAST_EXPECT(result["problems"].size() == 11);
|
||||
|
||||
// at max
|
||||
params[jss::limit] = 400;
|
||||
result = env.rpc(
|
||||
"json",
|
||||
"noripple_check",
|
||||
boost::lexical_cast<std::string>(params))[jss::result];
|
||||
result =
|
||||
env.rpc("json", "noripple_check", to_string(params))[jss::result];
|
||||
BEAST_EXPECT(result["problems"].size() == 401);
|
||||
|
||||
// at max+1
|
||||
params[jss::limit] = 401;
|
||||
result = env.rpc(
|
||||
"json",
|
||||
"noripple_check",
|
||||
boost::lexical_cast<std::string>(params))[jss::result];
|
||||
result =
|
||||
env.rpc("json", "noripple_check", to_string(params))[jss::result];
|
||||
BEAST_EXPECT(result["problems"].size() == (admin ? 402 : 401));
|
||||
}
|
||||
|
||||
|
||||
@@ -258,15 +258,13 @@ class TransactionEntry_test : public beast::unit_test::suite
|
||||
Account A2{"A2"};
|
||||
|
||||
env.fund(XRP(10000), A1);
|
||||
auto fund_1_tx =
|
||||
boost::lexical_cast<std::string>(env.tx()->getTransactionID());
|
||||
auto fund_1_tx = to_string(env.tx()->getTransactionID());
|
||||
BEAST_EXPECT(
|
||||
fund_1_tx ==
|
||||
"F4E9DF90D829A9E8B423FF68C34413E240D8D8BB0EFD080DF08114ED398E2506");
|
||||
|
||||
env.fund(XRP(10000), A2);
|
||||
auto fund_2_tx =
|
||||
boost::lexical_cast<std::string>(env.tx()->getTransactionID());
|
||||
auto fund_2_tx = to_string(env.tx()->getTransactionID());
|
||||
BEAST_EXPECT(
|
||||
fund_2_tx ==
|
||||
"6853CD8226A05068C951CB1F54889FF4E40C5B440DC1C5BA38F114C4E0B1E705");
|
||||
@@ -308,15 +306,13 @@ class TransactionEntry_test : public beast::unit_test::suite
|
||||
// the trust tx is actually a payment since the trust method
|
||||
// refunds fees with a payment after TrustSet..so just ignore the type
|
||||
// in the check below
|
||||
auto trust_tx =
|
||||
boost::lexical_cast<std::string>(env.tx()->getTransactionID());
|
||||
auto trust_tx = to_string(env.tx()->getTransactionID());
|
||||
BEAST_EXPECT(
|
||||
trust_tx ==
|
||||
"C992D97D88FF444A1AB0C06B27557EC54B7F7DA28254778E60238BEA88E0C101");
|
||||
|
||||
env(pay(A2, A1, A2["USD"](5)));
|
||||
auto pay_tx =
|
||||
boost::lexical_cast<std::string>(env.tx()->getTransactionID());
|
||||
auto pay_tx = to_string(env.tx()->getTransactionID());
|
||||
env.close();
|
||||
BEAST_EXPECT(
|
||||
pay_tx ==
|
||||
@@ -362,8 +358,7 @@ class TransactionEntry_test : public beast::unit_test::suite
|
||||
"2000-01-01T00:00:20Z");
|
||||
|
||||
env(offer(A2, XRP(100), A2["USD"](1)));
|
||||
auto offer_tx =
|
||||
boost::lexical_cast<std::string>(env.tx()->getTransactionID());
|
||||
auto offer_tx = to_string(env.tx()->getTransactionID());
|
||||
BEAST_EXPECT(
|
||||
offer_tx ==
|
||||
"5FCC1A27A7664F82A0CC4BE5766FBBB7C560D52B93AA7B550CD33B27AEC7EFFB");
|
||||
|
||||
@@ -14,5 +14,3 @@ xrpl_add_test(crypto)
|
||||
target_link_libraries(xrpl.test.crypto PRIVATE xrpl.imports.test)
|
||||
xrpl_add_test(net)
|
||||
target_link_libraries(xrpl.test.net PRIVATE xrpl.imports.test)
|
||||
xrpl_add_test(ledger)
|
||||
target_link_libraries(xrpl.test.ledger PRIVATE xrpl.imports.test)
|
||||
|
||||
@@ -1,210 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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/ledger/LedgerIndexMap.h>
|
||||
|
||||
#include <doctest/doctest.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using namespace ripple;
|
||||
|
||||
TEST_SUITE_BEGIN("LedgerIndexMap");
|
||||
|
||||
using TestMap = LedgerIndexMap<int, std::string>;
|
||||
|
||||
TEST_CASE("Default empty")
|
||||
{
|
||||
TestMap m;
|
||||
CHECK(m.size() == 0);
|
||||
CHECK(m.empty());
|
||||
CHECK(m.get(42) == nullptr);
|
||||
CHECK_FALSE(m.contains(42));
|
||||
}
|
||||
|
||||
TEST_CASE("Operator bracket inserts default")
|
||||
{
|
||||
TestMap m;
|
||||
auto& v = m[10];
|
||||
CHECK(m.size() == 1);
|
||||
CHECK(m.contains(10));
|
||||
CHECK(v.empty());
|
||||
}
|
||||
|
||||
TEST_CASE("Operator bracket, rvalue key")
|
||||
{
|
||||
TestMap m;
|
||||
int k = 7;
|
||||
auto& v1 = m[std::move(k)];
|
||||
v1 = "seven";
|
||||
CHECK(m.size() == 1);
|
||||
auto* got = m.get(7);
|
||||
REQUIRE(got != nullptr);
|
||||
CHECK(*got == "seven");
|
||||
}
|
||||
|
||||
TEST_CASE("Insert through put")
|
||||
{
|
||||
TestMap m;
|
||||
auto& v = m.put(20, "twenty");
|
||||
CHECK(v == "twenty");
|
||||
auto* got = m.get(20);
|
||||
REQUIRE(got != nullptr);
|
||||
CHECK(*got == "twenty");
|
||||
CHECK(m.size() == 1);
|
||||
}
|
||||
|
||||
TEST_CASE("Overwrite existing key with put")
|
||||
{
|
||||
TestMap m;
|
||||
m.put(5, "five");
|
||||
CHECK(m.size() == 1);
|
||||
m.put(5, "FIVE");
|
||||
CHECK(m.size() == 1);
|
||||
auto* got = m.get(5);
|
||||
REQUIRE(got != nullptr);
|
||||
CHECK(*got == "FIVE");
|
||||
}
|
||||
|
||||
TEST_CASE("Once found, one not found")
|
||||
{
|
||||
TestMap m;
|
||||
m.put(1, "one");
|
||||
CHECK(m.get(1) != nullptr);
|
||||
CHECK(m.get(2) == nullptr);
|
||||
}
|
||||
|
||||
TEST_CASE("Try eraseBefore - nothing to do")
|
||||
{
|
||||
TestMap m;
|
||||
m.put(10, "a");
|
||||
m.put(11, "b");
|
||||
m.put(12, "c");
|
||||
CHECK(m.eraseBefore(10) == 0);
|
||||
CHECK(m.size() == 3);
|
||||
CHECK(m.contains(10));
|
||||
CHECK(m.contains(11));
|
||||
CHECK(m.contains(12));
|
||||
}
|
||||
|
||||
TEST_CASE("eraseBefore - removes several entries")
|
||||
{
|
||||
TestMap m;
|
||||
m.put(10, "a");
|
||||
m.put(11, "b");
|
||||
m.put(12, "c");
|
||||
m.put(13, "d");
|
||||
CHECK(m.eraseBefore(12) == 2);
|
||||
CHECK_FALSE(m.contains(10));
|
||||
CHECK_FALSE(m.contains(11));
|
||||
CHECK(m.contains(12));
|
||||
CHECK(m.contains(13));
|
||||
CHECK(m.size() == 2);
|
||||
}
|
||||
|
||||
TEST_CASE("eraseBefore - removes all entries")
|
||||
{
|
||||
TestMap m;
|
||||
m.put(1, "x");
|
||||
m.put(2, "y");
|
||||
CHECK(m.eraseBefore(1000) == 2);
|
||||
CHECK(m.size() == 0);
|
||||
CHECK(m.empty());
|
||||
}
|
||||
|
||||
TEST_CASE("eraseBefore - same call, second time nothing to do")
|
||||
{
|
||||
TestMap m;
|
||||
m.put(10, "a");
|
||||
m.put(11, "b");
|
||||
m.put(12, "c");
|
||||
CHECK(m.eraseBefore(12) == 2);
|
||||
CHECK(m.contains(12));
|
||||
CHECK(m.eraseBefore(12) == 0);
|
||||
CHECK(m.size() == 1);
|
||||
}
|
||||
|
||||
TEST_CASE("eraseBefore - single entry removed")
|
||||
{
|
||||
TestMap m;
|
||||
m.put(10, "v1");
|
||||
m.put(10, "v2");
|
||||
m.put(10, "v3");
|
||||
CHECK(m.size() == 1);
|
||||
CHECK(m.eraseBefore(11) == 1);
|
||||
CHECK(m.size() == 0);
|
||||
}
|
||||
|
||||
TEST_CASE("eraseBefore - outlier still removed in one call")
|
||||
{
|
||||
TestMap m;
|
||||
m.put(10, "a");
|
||||
m.put(12, "c");
|
||||
m.put(11, "b"); // out-of-order insert
|
||||
|
||||
CHECK(m.eraseBefore(12) == 2); // removes 10 and 11
|
||||
CHECK_FALSE(m.contains(10));
|
||||
CHECK_FALSE(m.contains(11));
|
||||
CHECK(m.contains(12));
|
||||
CHECK(m.size() == 1);
|
||||
}
|
||||
|
||||
TEST_CASE("eraseBefore - erase in two steps (one first, then some more)")
|
||||
{
|
||||
TestMap m;
|
||||
for (int k : {10, 11, 12, 13})
|
||||
m.put(k, std::to_string(k));
|
||||
|
||||
CHECK(m.eraseBefore(11) == 1);
|
||||
CHECK_FALSE(m.contains(10));
|
||||
CHECK(m.size() == 3);
|
||||
|
||||
CHECK(m.eraseBefore(13) == 2);
|
||||
CHECK_FALSE(m.contains(11));
|
||||
CHECK_FALSE(m.contains(12));
|
||||
CHECK(m.contains(13));
|
||||
CHECK(m.size() == 1);
|
||||
}
|
||||
|
||||
TEST_CASE("rehash does not lose entries")
|
||||
{
|
||||
TestMap m;
|
||||
for (int k = 0; k < 16; ++k)
|
||||
m.put(k, "v" + std::to_string(k));
|
||||
|
||||
m.reserve(64);
|
||||
m.rehash(32);
|
||||
|
||||
for (int k = 0; k < 16; ++k)
|
||||
{
|
||||
auto* v = m.get(k);
|
||||
REQUIRE(v != nullptr);
|
||||
CHECK(*v == "v" + std::to_string(k));
|
||||
}
|
||||
|
||||
CHECK(m.eraseBefore(8) == 8);
|
||||
for (int k = 0; k < 8; ++k)
|
||||
CHECK_FALSE(m.contains(k));
|
||||
for (int k = 8; k < 16; ++k)
|
||||
CHECK(m.contains(k));
|
||||
}
|
||||
|
||||
TEST_SUITE_END();
|
||||
@@ -1,2 +0,0 @@
|
||||
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
|
||||
#include <doctest/doctest.h>
|
||||
@@ -27,6 +27,8 @@
|
||||
|
||||
namespace ripple {
|
||||
|
||||
// FIXME: Need to clean up ledgers by index at some point
|
||||
|
||||
LedgerHistory::LedgerHistory(
|
||||
beast::insight::Collector::ptr const& collector,
|
||||
Application& app)
|
||||
@@ -45,7 +47,6 @@ LedgerHistory::LedgerHistory(
|
||||
std::chrono::minutes{5},
|
||||
stopwatch(),
|
||||
app_.journal("TaggedCache"))
|
||||
, mLedgersByIndex(512)
|
||||
, j_(app.journal("LedgerHistory"))
|
||||
{
|
||||
}
|
||||
@@ -62,6 +63,8 @@ LedgerHistory::insert(
|
||||
ledger->stateMap().getHash().isNonZero(),
|
||||
"ripple::LedgerHistory::insert : nonzero hash");
|
||||
|
||||
std::unique_lock sl(m_ledgers_by_hash.peekMutex());
|
||||
|
||||
bool const alreadyHad = m_ledgers_by_hash.canonicalize_replace_cache(
|
||||
ledger->info().hash, ledger);
|
||||
if (validated)
|
||||
@@ -73,18 +76,25 @@ LedgerHistory::insert(
|
||||
LedgerHash
|
||||
LedgerHistory::getLedgerHash(LedgerIndex index)
|
||||
{
|
||||
if (auto p = mLedgersByIndex.get(index))
|
||||
return *p;
|
||||
std::unique_lock sl(m_ledgers_by_hash.peekMutex());
|
||||
if (auto it = mLedgersByIndex.find(index); it != mLedgersByIndex.end())
|
||||
return it->second;
|
||||
return {};
|
||||
}
|
||||
|
||||
std::shared_ptr<Ledger const>
|
||||
LedgerHistory::getLedgerBySeq(LedgerIndex index)
|
||||
{
|
||||
if (auto p = mLedgersByIndex.get(index))
|
||||
{
|
||||
uint256 const hash = *p;
|
||||
return getLedgerByHash(hash);
|
||||
std::unique_lock sl(m_ledgers_by_hash.peekMutex());
|
||||
auto it = mLedgersByIndex.find(index);
|
||||
|
||||
if (it != mLedgersByIndex.end())
|
||||
{
|
||||
uint256 hash = it->second;
|
||||
sl.unlock();
|
||||
return getLedgerByHash(hash);
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<Ledger const> ret = loadByIndex(index, app_);
|
||||
@@ -98,6 +108,8 @@ LedgerHistory::getLedgerBySeq(LedgerIndex index)
|
||||
|
||||
{
|
||||
// Add this ledger to the local tracking by index
|
||||
std::unique_lock sl(m_ledgers_by_hash.peekMutex());
|
||||
|
||||
XRPL_ASSERT(
|
||||
ret->isImmutable(),
|
||||
"ripple::LedgerHistory::getLedgerBySeq : immutable result ledger");
|
||||
@@ -446,6 +458,8 @@ LedgerHistory::builtLedger(
|
||||
XRPL_ASSERT(
|
||||
!hash.isZero(), "ripple::LedgerHistory::builtLedger : nonzero hash");
|
||||
|
||||
std::unique_lock sl(m_consensus_validated.peekMutex());
|
||||
|
||||
auto entry = std::make_shared<cv_entry>();
|
||||
m_consensus_validated.canonicalize_replace_client(index, entry);
|
||||
|
||||
@@ -486,6 +500,8 @@ LedgerHistory::validatedLedger(
|
||||
!hash.isZero(),
|
||||
"ripple::LedgerHistory::validatedLedger : nonzero hash");
|
||||
|
||||
std::unique_lock sl(m_consensus_validated.peekMutex());
|
||||
|
||||
auto entry = std::make_shared<cv_entry>();
|
||||
m_consensus_validated.canonicalize_replace_client(index, entry);
|
||||
|
||||
@@ -519,13 +535,13 @@ LedgerHistory::validatedLedger(
|
||||
bool
|
||||
LedgerHistory::fixIndex(LedgerIndex ledgerIndex, LedgerHash const& ledgerHash)
|
||||
{
|
||||
if (auto cur = mLedgersByIndex.get(ledgerIndex))
|
||||
std::unique_lock sl(m_ledgers_by_hash.peekMutex());
|
||||
auto it = mLedgersByIndex.find(ledgerIndex);
|
||||
|
||||
if ((it != mLedgersByIndex.end()) && (it->second != ledgerHash))
|
||||
{
|
||||
if (*cur != ledgerHash)
|
||||
{
|
||||
mLedgersByIndex.put(ledgerIndex, ledgerHash);
|
||||
return false;
|
||||
}
|
||||
it->second = ledgerHash;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -533,24 +549,12 @@ LedgerHistory::fixIndex(LedgerIndex ledgerIndex, LedgerHash const& ledgerHash)
|
||||
void
|
||||
LedgerHistory::clearLedgerCachePrior(LedgerIndex seq)
|
||||
{
|
||||
std::size_t hashesCleared = 0;
|
||||
for (LedgerHash it : m_ledgers_by_hash.getKeys())
|
||||
{
|
||||
auto const ledger = getLedgerByHash(it);
|
||||
if (!ledger || ledger->info().seq < seq)
|
||||
{
|
||||
m_ledgers_by_hash.del(it, false);
|
||||
++hashesCleared;
|
||||
}
|
||||
}
|
||||
JLOG(j_.debug()) << "LedgersByHash: cleared " << hashesCleared
|
||||
<< " entries before seq " << seq << " (total now "
|
||||
<< m_ledgers_by_hash.size() << ")";
|
||||
|
||||
std::size_t const indexesCleared = mLedgersByIndex.eraseBefore(seq);
|
||||
JLOG(j_.debug()) << "LedgerIndexMap: cleared " << indexesCleared
|
||||
<< " index entries before seq " << seq << " (total now "
|
||||
<< mLedgersByIndex.size() << ")";
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
#include <xrpld/app/main/Application.h>
|
||||
|
||||
#include <xrpl/beast/insight/Collector.h>
|
||||
#include <xrpl/ledger/LedgerIndexMap.h>
|
||||
#include <xrpl/protocol/RippleLedgerHash.h>
|
||||
|
||||
#include <optional>
|
||||
@@ -150,8 +149,7 @@ private:
|
||||
ConsensusValidated m_consensus_validated;
|
||||
|
||||
// Maps ledger indexes to the corresponding hash.
|
||||
ripple::LedgerIndexMap<LedgerIndex, LedgerHash>
|
||||
mLedgersByIndex; // validated ledgers
|
||||
std::map<LedgerIndex, LedgerHash> mLedgersByIndex; // validated ledgers
|
||||
|
||||
beast::Journal j_;
|
||||
};
|
||||
|
||||
@@ -600,8 +600,8 @@ ConnectAttempt::processResponse()
|
||||
JLOG(journal_.info()) << "Cluster name: " << *member;
|
||||
}
|
||||
|
||||
auto const result =
|
||||
overlay_.peerFinder().activate(slot_, publicKey, !member->empty());
|
||||
auto const result = overlay_.peerFinder().activate(
|
||||
slot_, publicKey, member.has_value());
|
||||
if (result != PeerFinder::Result::success)
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
@@ -72,39 +72,23 @@ getAutofillSequence(Json::Value const& tx_json, RPC::JsonContext& context)
|
||||
}
|
||||
|
||||
static std::optional<Json::Value>
|
||||
autofillTx(Json::Value& tx_json, RPC::JsonContext& context)
|
||||
autofillSignature(Json::Value& sigObject)
|
||||
{
|
||||
if (!tx_json.isMember(jss::Fee))
|
||||
{
|
||||
// autofill Fee
|
||||
// Must happen after all the other autofills happen
|
||||
// Error handling/messaging works better that way
|
||||
auto feeOrError = RPC::getCurrentNetworkFee(
|
||||
context.role,
|
||||
context.app.config(),
|
||||
context.app.getFeeTrack(),
|
||||
context.app.getTxQ(),
|
||||
context.app,
|
||||
tx_json);
|
||||
if (feeOrError.isMember(jss::error))
|
||||
return feeOrError;
|
||||
tx_json[jss::Fee] = feeOrError;
|
||||
}
|
||||
|
||||
if (!tx_json.isMember(jss::SigningPubKey))
|
||||
if (!sigObject.isMember(jss::SigningPubKey))
|
||||
{
|
||||
// autofill SigningPubKey
|
||||
tx_json[jss::SigningPubKey] = "";
|
||||
sigObject[jss::SigningPubKey] = "";
|
||||
}
|
||||
|
||||
if (tx_json.isMember(jss::Signers))
|
||||
if (sigObject.isMember(jss::Signers))
|
||||
{
|
||||
if (!tx_json[jss::Signers].isArray())
|
||||
if (!sigObject[jss::Signers].isArray())
|
||||
return RPC::invalid_field_error("tx.Signers");
|
||||
// check multisigned signers
|
||||
for (unsigned index = 0; index < tx_json[jss::Signers].size(); index++)
|
||||
for (unsigned index = 0; index < sigObject[jss::Signers].size();
|
||||
index++)
|
||||
{
|
||||
auto& signer = tx_json[jss::Signers][index];
|
||||
auto& signer = sigObject[jss::Signers][index];
|
||||
if (!signer.isObject() || !signer.isMember(jss::Signer) ||
|
||||
!signer[jss::Signer].isObject())
|
||||
return RPC::invalid_field_error(
|
||||
@@ -129,16 +113,41 @@ autofillTx(Json::Value& tx_json, RPC::JsonContext& context)
|
||||
}
|
||||
}
|
||||
|
||||
if (!tx_json.isMember(jss::TxnSignature))
|
||||
if (!sigObject.isMember(jss::TxnSignature))
|
||||
{
|
||||
// autofill TxnSignature
|
||||
tx_json[jss::TxnSignature] = "";
|
||||
sigObject[jss::TxnSignature] = "";
|
||||
}
|
||||
else if (tx_json[jss::TxnSignature] != "")
|
||||
else if (sigObject[jss::TxnSignature] != "")
|
||||
{
|
||||
// Transaction must not be signed
|
||||
return rpcError(rpcTX_SIGNED);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
static std::optional<Json::Value>
|
||||
autofillTx(Json::Value& tx_json, RPC::JsonContext& context)
|
||||
{
|
||||
if (!tx_json.isMember(jss::Fee))
|
||||
{
|
||||
// autofill Fee
|
||||
// Must happen after all the other autofills happen
|
||||
// Error handling/messaging works better that way
|
||||
auto feeOrError = RPC::getCurrentNetworkFee(
|
||||
context.role,
|
||||
context.app.config(),
|
||||
context.app.getFeeTrack(),
|
||||
context.app.getTxQ(),
|
||||
context.app,
|
||||
tx_json);
|
||||
if (feeOrError.isMember(jss::error))
|
||||
return feeOrError;
|
||||
tx_json[jss::Fee] = feeOrError;
|
||||
}
|
||||
|
||||
if (auto error = autofillSignature(tx_json))
|
||||
return *error;
|
||||
|
||||
if (!tx_json.isMember(jss::Sequence))
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user