Skip to content

Commit

Permalink
Merge branch 'develop' into price-oracle
Browse files Browse the repository at this point in the history
  • Loading branch information
gregtatcam committed Oct 25, 2023
2 parents 9e59e30 + 1eac4d2 commit 5e2edff
Show file tree
Hide file tree
Showing 16 changed files with 389 additions and 66 deletions.
7 changes: 7 additions & 0 deletions API-CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,13 @@ Currently (prior to the release of 2.0), it is available as a "beta" version, me

Since `api_version` 2 is in "beta", breaking changes to V2 can currently be made at any time.

#### Removed methods

In API version 2, the following methods are no longer available:

- `tx_history` - Instead, use other methods such as `account_tx` or `ledger` with the `transactions` field set to `true`.
- `ledger_header` - Instead, use the `ledger` method.

#### Modifications to account_info response in V2

- `signer_lists` is returned in the root of the response. Previously, in API version 1, it was nested under `account_data`. (https://github.com/XRPLF/rippled/pull/3770)
Expand Down
2 changes: 2 additions & 0 deletions Builds/CMake/RippledCore.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -1069,6 +1069,7 @@ if (tests)
src/test/rpc/KeyGeneration_test.cpp
src/test/rpc/LedgerClosed_test.cpp
src/test/rpc/LedgerData_test.cpp
src/test/rpc/LedgerHeader_test.cpp
src/test/rpc/LedgerRPC_test.cpp
src/test/rpc/LedgerRequestRPC_test.cpp
src/test/rpc/ManifestRPC_test.cpp
Expand All @@ -1092,6 +1093,7 @@ if (tests)
src/test/rpc/ValidatorInfo_test.cpp
src/test/rpc/ValidatorRPC_test.cpp
src/test/rpc/Version_test.cpp
src/test/rpc/Handler_test.cpp
#[===============================[
test sources:
subdir: server
Expand Down
26 changes: 21 additions & 5 deletions src/ripple/app/misc/FeeEscalation.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,11 +190,27 @@ lower) fee to get into the same position as a reference transaction.

### Consensus Health

For consensus to be considered healthy, the consensus process must take
less than 5 seconds. This time limit was chosen based on observed past
behavior of the network. Note that this is not necessarily the time between
ledger closings, as consensus usually starts some amount of time after
a ledger opens.
For consensus to be considered healthy, the peers on the network
should largely remain in sync with one another. It is particularly
important for the validators to remain in sync, because that is required
for participation in consensus. However, the network tolerates some
validators being out of sync. Fundamentally, network health is a
function of validators reaching consensus on sets of recently submitted
transactions.

Another factor to consider is
the duration of the consensus process itself. This generally takes
under 5 seconds on the main network under low volume. This is based on
historical observations. However factors such as transaction volume
can increase consensus duration. This is because rippled performs
more work as transaction volume increases. Under sufficient load this
tends to increase consensus duration. It's possible that relatively high
consensus duration indicates a problem, but it is not appropriate to
conclude so without investigation. The upper limit for consensus
duration should be roughly 20 seconds. That is far above the normal.
If the network takes this long to close ledgers, then it is almost
certain that there is a problem with the network. This circumstance
often coincides with new ledgers with zero transactions.

### Other Constants

Expand Down
2 changes: 1 addition & 1 deletion src/ripple/perflog/impl/PerfLogImp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ namespace ripple {
namespace perf {

PerfLogImp::Counters::Counters(
std::vector<char const*> const& labels,
std::set<char const*> const& labels,
JobTypes const& jobTypes)
{
{
Expand Down
4 changes: 1 addition & 3 deletions src/ripple/perflog/impl/PerfLogImp.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,7 @@ class PerfLogImp : public PerfLog
std::unordered_map<std::uint64_t, MethodStart> methods_;
mutable std::mutex methodsMutex_;

Counters(
std::vector<char const*> const& labels,
JobTypes const& jobTypes);
Counters(std::set<char const*> const& labels, JobTypes const& jobTypes);
Json::Value
countersJson() const;
Json::Value
Expand Down
2 changes: 1 addition & 1 deletion src/ripple/protocol/impl/BuildInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ namespace BuildInfo {
// and follow the format described at http://semver.org/
//------------------------------------------------------------------------------
// clang-format off
char const* const versionString = "2.0.0-b3"
char const* const versionString = "2.0.0-b4"
// clang-format on

#if defined(DEBUG) || defined(SANITIZER)
Expand Down
23 changes: 8 additions & 15 deletions src/ripple/rpc/handlers/LedgerHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <ripple/rpc/Role.h>
#include <ripple/rpc/Status.h>
#include <ripple/rpc/impl/Handler.h>
#include <ripple/rpc/impl/RPCHelpers.h>

namespace Json {
class Object;
Expand Down Expand Up @@ -58,23 +59,15 @@ class LedgerHandler
void
writeResult(Object&);

static char const*
name()
{
return "ledger";
}
static constexpr char name[] = "ledger";

static Role
role()
{
return Role::USER;
}
static constexpr unsigned minApiVer = RPC::apiMinimumSupportedVersion;

static Condition
condition()
{
return NO_CONDITION;
}
static constexpr unsigned maxApiVer = RPC::apiMaximumValidVersion;

static constexpr Role role = Role::USER;

static constexpr Condition condition = NO_CONDITION;

private:
JsonContext& context_;
Expand Down
22 changes: 7 additions & 15 deletions src/ripple/rpc/handlers/Version.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,23 +46,15 @@ class VersionHandler
setVersion(obj, apiVersion_, betaEnabled_);
}

static char const*
name()
{
return "version";
}
static constexpr char const* name = "version";

static Role
role()
{
return Role::USER;
}
static constexpr unsigned minApiVer = RPC::apiMinimumSupportedVersion;

static Condition
condition()
{
return NO_CONDITION;
}
static constexpr unsigned maxApiVer = RPC::apiMaximumValidVersion;

static constexpr Role role = Role::USER;

static constexpr Condition condition = NO_CONDITION;

private:
unsigned int apiVersion_;
Expand Down
107 changes: 83 additions & 24 deletions src/ripple/rpc/impl/Handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,14 @@
*/
//==============================================================================

#include <ripple/basics/contract.h>
#include <ripple/rpc/handlers/Handlers.h>
#include <ripple/rpc/handlers/Version.h>
#include <ripple/rpc/impl/Handler.h>
#include <ripple/rpc/impl/RPCHelpers.h>

#include <map>

namespace ripple {
namespace RPC {
namespace {
Expand All @@ -47,6 +50,9 @@ template <class Object, class HandlerImpl>
Status
handle(JsonContext& context, Object& object)
{
assert(
context.apiVersion >= HandlerImpl::minApiVer &&
context.apiVersion <= HandlerImpl::maxApiVer);
HandlerImpl handler(context);

auto status = handler.check();
Expand All @@ -55,7 +61,20 @@ handle(JsonContext& context, Object& object)
else
handler.writeResult(object);
return status;
};
}

template <typename HandlerImpl>
Handler
handlerFrom()
{
return {
HandlerImpl::name,
&handle<Json::Value, HandlerImpl>,
HandlerImpl::role,
HandlerImpl::condition,
HandlerImpl::minApiVer,
HandlerImpl::maxApiVer};
}

Handler const handlerArray[]{
// Some handlers not specified here are added to the table via addHandler()
Expand Down Expand Up @@ -114,7 +133,7 @@ Handler const handlerArray[]{
NEEDS_CURRENT_LEDGER},
{"ledger_data", byRef(&doLedgerData), Role::USER, NO_CONDITION},
{"ledger_entry", byRef(&doLedgerEntry), Role::USER, NO_CONDITION},
{"ledger_header", byRef(&doLedgerHeader), Role::USER, NO_CONDITION},
{"ledger_header", byRef(&doLedgerHeader), Role::USER, NO_CONDITION, 1, 1},
{"ledger_request", byRef(&doLedgerRequest), Role::ADMIN, NO_CONDITION},
{"log_level", byRef(&doLogLevel), Role::ADMIN, NO_CONDITION},
{"logrotate", byRef(&doLogRotate), Role::ADMIN, NO_CONDITION},
Expand Down Expand Up @@ -160,7 +179,7 @@ Handler const handlerArray[]{
NEEDS_CURRENT_LEDGER},
{"transaction_entry", byRef(&doTransactionEntry), Role::USER, NO_CONDITION},
{"tx", byRef(&doTxJson), Role::USER, NEEDS_NETWORK_CONNECTION},
{"tx_history", byRef(&doTxHistory), Role::USER, NO_CONDITION},
{"tx_history", byRef(&doTxHistory), Role::USER, NO_CONDITION, 1, 1},
{"tx_reduce_relay", byRef(&doTxReduceRelay), Role::USER, NO_CONDITION},
{"unl_list", byRef(&doUnlList), Role::ADMIN, NO_CONDITION},
{"validation_create",
Expand All @@ -182,14 +201,42 @@ Handler const handlerArray[]{
class HandlerTable
{
private:
using handler_table_t = std::multimap<std::string, Handler>;

// Use with equal_range to enforce that API range of a newly added handler
// does not overlap with API range of an existing handler with same name
[[nodiscard]] bool
overlappingApiVersion(
std::pair<handler_table_t::iterator, handler_table_t::iterator> range,
unsigned minVer,
unsigned maxVer)
{
assert(minVer <= maxVer);
assert(maxVer <= RPC::apiMaximumValidVersion);

return std::any_of(
range.first,
range.second, //
[minVer, maxVer](auto const& item) {
return item.second.minApiVer_ <= maxVer &&
item.second.maxApiVer_ >= minVer;
});
}

template <std::size_t N>
explicit HandlerTable(const Handler (&entries)[N])
{
for (std::size_t i = 0; i < N; ++i)
for (auto const& entry : entries)
{
auto const& entry = entries[i];
assert(table_.find(entry.name_) == table_.end());
table_[entry.name_] = entry;
if (overlappingApiVersion(
table_.equal_range(entry.name_),
entry.minApiVer_,
entry.maxApiVer_))
LogicError(
std::string("Handler for ") + entry.name_ +
" overlaps with an existing handler");

table_.insert({entry.name_, entry});
}

// This is where the new-style handlers are added.
Expand All @@ -205,44 +252,56 @@ class HandlerTable
return handlerTable;
}

Handler const*
[[nodiscard]] Handler const*
getHandler(unsigned version, bool betaEnabled, std::string const& name)
const
{
if (version < RPC::apiMinimumSupportedVersion ||
version > (betaEnabled ? RPC::apiBetaVersion
: RPC::apiMaximumSupportedVersion))
return nullptr;
auto i = table_.find(name);
return i == table_.end() ? nullptr : &i->second;

auto const range = table_.equal_range(name);
auto const i = std::find_if(
range.first, range.second, [version](auto const& entry) {
return entry.second.minApiVer_ <= version &&
version <= entry.second.maxApiVer_;
});

return i == range.second ? nullptr : &i->second;
}

std::vector<char const*>
[[nodiscard]] std::set<char const*>
getHandlerNames() const
{
std::vector<char const*> ret;
ret.reserve(table_.size());
std::set<char const*> ret;
for (auto const& i : table_)
ret.push_back(i.second.name_);
ret.insert(i.second.name_);

return ret;
}

private:
std::map<std::string, Handler> table_;
handler_table_t table_;

template <class HandlerImpl>
void
addHandler()
{
assert(table_.find(HandlerImpl::name()) == table_.end());
static_assert(HandlerImpl::minApiVer <= HandlerImpl::maxApiVer);
static_assert(HandlerImpl::maxApiVer <= RPC::apiMaximumValidVersion);
static_assert(
RPC::apiMinimumSupportedVersion <= HandlerImpl::minApiVer);

Handler h;
h.name_ = HandlerImpl::name();
h.valueMethod_ = &handle<Json::Value, HandlerImpl>;
h.role_ = HandlerImpl::role();
h.condition_ = HandlerImpl::condition();
if (overlappingApiVersion(
table_.equal_range(HandlerImpl::name),
HandlerImpl::minApiVer,
HandlerImpl::maxApiVer))
LogicError(
std::string("Handler for ") + HandlerImpl::name +
" overlaps with an existing handler");

table_[HandlerImpl::name()] = h;
table_.insert({HandlerImpl::name, handlerFrom<HandlerImpl>()});
}
};

Expand All @@ -254,11 +313,11 @@ getHandler(unsigned version, bool betaEnabled, std::string const& name)
return HandlerTable::instance().getHandler(version, betaEnabled, name);
}

std::vector<char const*>
std::set<char const*>
getHandlerNames()
{
return HandlerTable::instance().getHandlerNames();
};
}

} // namespace RPC
} // namespace ripple
6 changes: 5 additions & 1 deletion src/ripple/rpc/impl/Handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <ripple/core/Config.h>
#include <ripple/rpc/RPCHandler.h>
#include <ripple/rpc/Status.h>
#include <ripple/rpc/impl/RPCHelpers.h>
#include <ripple/rpc/impl/Tuning.h>
#include <vector>

Expand Down Expand Up @@ -52,6 +53,9 @@ struct Handler
Method<Json::Value> valueMethod_;
Role role_;
RPC::Condition condition_;

unsigned minApiVer_ = apiMinimumSupportedVersion;
unsigned maxApiVer_ = apiMaximumValidVersion;
};

Handler const*
Expand All @@ -70,7 +74,7 @@ makeObjectValue(
}

/** Return names of all methods. */
std::vector<char const*>
std::set<char const*>
getHandlerNames();

template <class T>
Expand Down
2 changes: 2 additions & 0 deletions src/ripple/rpc/impl/RPCHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -242,10 +242,12 @@ constexpr unsigned int apiVersionIfUnspecified = 1;
constexpr unsigned int apiMinimumSupportedVersion = 1;
constexpr unsigned int apiMaximumSupportedVersion = 1;
constexpr unsigned int apiBetaVersion = 2;
constexpr unsigned int apiMaximumValidVersion = apiBetaVersion;

static_assert(apiMinimumSupportedVersion >= apiVersionIfUnspecified);
static_assert(apiMaximumSupportedVersion >= apiMinimumSupportedVersion);
static_assert(apiBetaVersion >= apiMaximumSupportedVersion);
static_assert(apiMaximumValidVersion >= apiMaximumSupportedVersion);

template <class Object>
void
Expand Down
Loading

0 comments on commit 5e2edff

Please sign in to comment.