Compare commits

...

4 Commits
2.3.0 ... 2.3.1

Author SHA1 Message Date
Ed Hennis
8458233a31 Set version to 2.3.1 2025-01-29 09:40:31 -05:00
Ed Hennis
cb0ddbf863 Update conan in the "nix" CI jobs 2025-01-29 09:40:30 -05:00
Valentin Balaschenko
f3e201f983 Set version to 2.3.1-rc1 2025-01-27 19:43:14 -05:00
Valentin Balaschenko
b14c24960b Reduce the peer charges for well-behaved peers:
- Fix an erroneous high fee penalty that peers could incur for sending
  older transactions.
- Update to the fees charged for imposing a load on the server.
- Prevent the relaying of internal pseudo-transactions.
  - Before: Pseudo-transactions received from a peer will fail the signature
    check, even if they were requested (using TMGetObjectByHash), because
    they have no signature. This causes the peer to be charge for an
    invalid signature.
  - After: Pseudo-transactions, are put into the global cache
    (TransactionMaster) only. If the transaction is not part of
    a TMTransactions batch, the peer is charged an unwanted data fee.
    These fees will not be a problem in the normal course of operations,
    but should dissuade peers from behaving badly by sending a bunch of
    junk.
- Improve logging: include the reason for fees charged to a peer.

Co-authored-by: Ed Hennis <ed@ripple.com>
2025-01-27 19:41:22 -05:00
33 changed files with 398 additions and 163 deletions

View File

@@ -64,6 +64,9 @@ jobs:
env:
build_dir: .build
steps:
- name: upgrade conan
run: |
pip install --upgrade "conan<2"
- name: checkout
uses: actions/checkout@v4
- name: check environment
@@ -122,6 +125,9 @@ jobs:
env:
build_dir: .build
steps:
- name: upgrade conan
run: |
pip install --upgrade "conan<2"
- name: download cache
uses: actions/download-artifact@v3
with:
@@ -171,6 +177,9 @@ jobs:
env:
build_dir: .build
steps:
- name: upgrade conan
run: |
pip install --upgrade "conan<2"
- name: download cache
uses: actions/download-artifact@v3
with:
@@ -241,6 +250,9 @@ jobs:
build_dir: .build
configuration: Release
steps:
- name: upgrade conan
run: |
pip install --upgrade "conan<2"
- name: download cache
uses: actions/download-artifact@v3
with:

View File

@@ -82,6 +82,7 @@ test.nodestore > xrpld.core
test.nodestore > xrpld.nodestore
test.nodestore > xrpld.unity
test.overlay > test.jtx
test.overlay > test.toplevel
test.overlay > test.unit_test
test.overlay > xrpl.basics
test.overlay > xrpld.app

View File

@@ -6,6 +6,62 @@ This document contains the release notes for `rippled`, the reference server imp
Have new ideas? Need help with setting up your node? [Please open an issue here](https://github.com/xrplf/rippled/issues/new/choose).
# Version 2.3.1
Version 2.3.1 of `rippled`, the reference server implementation of the XRP Ledger protocol, is now available.
This is a hotfix release that includes the following updates:
- Fix an erroneous high fee penalty that peers could incur for sending older transactions.
- Update to the fees charged for imposing a load on the server.
- Prevent the relaying of internal pseudo-transactions.
- Before: Pseudo-transactions received from a peer will fail the signature check, even if they were requested (using TMGetObjectByHash) because they have no signature. This causes the peer to be charged for an invalid signature.
- After: Pseudo-transactions, are put into the global cache (TransactionMaster) only. If the transaction is not part of a TMTransactions batch, the peer is charged an unwanted data fee. These fees will not be a problem in the normal course of operations but should dissuade peers from behaving badly by sending a bunch of junk.
- Improved logging now specifies the reason for the fee charged to the peer.
[Sign Up for Future Release Announcements](https://groups.google.com/g/ripple-server)
<!-- BREAK -->
## Action Required
If you run an XRP Ledger validator, upgrade to version 2.3.1 as soon as possible to ensure stable and uninterrupted network behavior.
## Changelog
### Amendments and New Features
- None
### Bug Fixes and Performance Improvements
- Change the charged fee for sending older transactions from feeInvalidSignature to feeUnwantedData. [#5243](https://github.com/XRPLF/rippled/pull/5243)
### Docs and Build System
- None
### GitHub
The public source code repository for `rippled` is hosted on GitHub at <https://github.com/XRPLF/rippled>.
We welcome all contributions and invite everyone to join the community of XRP Ledger developers to help build the Internet of Value.
## Credits
The following people contributed directly to this release:
Ed Hennis <ed@ripple.com>
JoelKatz <DavidJoelSchwartz@GMail.com>
Sophia Xie <106177003+sophiax851@users.noreply.github.com>
Valentin Balaschenko <13349202+vlntb@users.noreply.github.com>
Bug Bounties and Responsible Disclosures:
We welcome reviews of the `rippled` code and urge researchers to responsibly disclose any issues they may find.
To report a bug, please send a detailed report to: <bugs@xrpl.org>
# Version 2.3.0
Version 2.3.0 of `rippled`, the reference server implementation of the XRP Ledger protocol, is now available. This release includes 8 new amendments, including Multi-Purpose Tokens, Credentials, Clawback support for AMMs, and the ability to make offers as part of minting NFTs. Additionally, this release includes important fixes for stability, so server operators are encouraged to upgrade as soon as possible.

View File

@@ -53,8 +53,9 @@ public:
bool
operator==(Charge const&) const;
bool
operator!=(Charge const&) const;
std::strong_ordering
operator<=>(Charge const&) const;
private:
value_type m_cost;

View File

@@ -67,7 +67,7 @@ public:
/** Apply a load charge to the consumer. */
Disposition
charge(Charge const& fee);
charge(Charge const& fee, std::string const& context = {});
/** Returns `true` if the consumer should be warned.
This consumes the warning.

View File

@@ -28,28 +28,28 @@ namespace Resource {
// clang-format off
/** Schedule of fees charged for imposing load on the server. */
/** @{ */
extern Charge const feeInvalidRequest; // A request that we can immediately
extern Charge const feeMalformedRequest; // A request that we can immediately
// tell is invalid
extern Charge const feeRequestNoReply; // A request that we cannot satisfy
extern Charge const feeInvalidSignature; // An object whose signature we had
// to check and it failed
extern Charge const feeUnwantedData; // Data we have no use for
extern Charge const feeBadData; // Data we have to verify before
extern Charge const feeUselessData; // Data we have no use for
extern Charge const feeInvalidData; // Data we have to verify before
// rejecting
// RPC loads
extern Charge const feeInvalidRPC; // An RPC request that we can
extern Charge const feeMalformedRPC; // An RPC request that we can
// immediately tell is invalid.
extern Charge const feeReferenceRPC; // A default "reference" unspecified
// load
extern Charge const feeExceptionRPC; // RPC load that causes an exception
extern Charge const feeMediumBurdenRPC; // A somewhat burdensome RPC load
extern Charge const feeHighBurdenRPC; // A very burdensome RPC load
extern Charge const feeHeavyBurdenRPC; // A very burdensome RPC load
// Peer loads
extern Charge const feeLightPeer; // Requires no reply
extern Charge const feeMediumBurdenPeer; // Requires some work
extern Charge const feeHighBurdenPeer; // Extensive work
extern Charge const feeTrivialPeer; // Requires no reply
extern Charge const feeModerateBurdenPeer; // Requires some work
extern Charge const feeHeavyBurdenPeer; // Extensive work
// Administrative
extern Charge const feeWarning; // The cost of receiving a warning

View File

@@ -442,12 +442,34 @@ public:
}
Disposition
charge(Entry& entry, Charge const& fee)
charge(Entry& entry, Charge const& fee, std::string context = {})
{
static constexpr Charge::value_type feeLogAsWarn = 3000;
static constexpr Charge::value_type feeLogAsInfo = 1000;
static constexpr Charge::value_type feeLogAsDebug = 100;
static_assert(
feeLogAsWarn > feeLogAsInfo && feeLogAsInfo > feeLogAsDebug &&
feeLogAsDebug > 10);
static auto getStream = [](Resource::Charge::value_type cost,
beast::Journal& journal) {
if (cost >= feeLogAsWarn)
return journal.warn();
if (cost >= feeLogAsInfo)
return journal.info();
if (cost >= feeLogAsDebug)
return journal.debug();
return journal.trace();
};
if (!context.empty())
context = " (" + context + ")";
std::lock_guard _(lock_);
clock_type::time_point const now(m_clock.now());
int const balance(entry.add(fee.cost(), now));
JLOG(m_journal.trace()) << "Charging " << entry << " for " << fee;
JLOG(getStream(fee.cost(), m_journal))
<< "Charging " << entry << " for " << fee << context;
return disposition(balance);
}

View File

@@ -32,7 +32,7 @@ enum {
// Balance at which the consumer is disconnected
,
dropThreshold = 15000
dropThreshold = 25000
// The number of seconds in the exponential decay window
// (This should be a power of two)

View File

@@ -33,7 +33,7 @@ namespace BuildInfo {
// and follow the format described at http://semver.org/
//------------------------------------------------------------------------------
// clang-format off
char const* const versionString = "2.3.0"
char const* const versionString = "2.3.1"
// clang-format on
#if defined(DEBUG) || defined(SANITIZER)

View File

@@ -61,10 +61,10 @@ Charge::operator==(Charge const& c) const
return c.m_cost == m_cost;
}
bool
Charge::operator!=(Charge const& c) const
std::strong_ordering
Charge::operator<=>(Charge const& c) const
{
return c.m_cost != m_cost;
return m_cost <=> c.m_cost;
}
} // namespace Resource

View File

@@ -96,12 +96,12 @@ Consumer::disposition() const
}
Disposition
Consumer::charge(Charge const& what)
Consumer::charge(Charge const& what, std::string const& context)
{
Disposition d = ok;
if (m_logic && m_entry && !m_entry->isUnlimited())
d = m_logic->charge(*m_entry, what);
d = m_logic->charge(*m_entry, what, context);
return d;
}

View File

@@ -22,24 +22,26 @@
namespace ripple {
namespace Resource {
Charge const feeInvalidRequest(100, "malformed request");
Charge const feeMalformedRequest(200, "malformed request");
Charge const feeRequestNoReply(10, "unsatisfiable request");
Charge const feeInvalidSignature(1000, "invalid signature");
Charge const feeUnwantedData(150, "useless data");
Charge const feeBadData(200, "invalid data");
Charge const feeInvalidSignature(2000, "invalid signature");
Charge const feeUselessData(150, "useless data");
Charge const feeInvalidData(400, "invalid data");
Charge const feeInvalidRPC(100, "malformed RPC");
Charge const feeMalformedRPC(100, "malformed RPC");
Charge const feeReferenceRPC(20, "reference RPC");
Charge const feeExceptionRPC(100, "exceptioned RPC");
Charge const feeMediumBurdenRPC(400, "medium RPC");
Charge const feeHighBurdenRPC(3000, "heavy RPC");
Charge const feeHeavyBurdenRPC(3000, "heavy RPC");
Charge const feeLightPeer(1, "trivial peer request");
Charge const feeMediumBurdenPeer(250, "moderate peer request");
Charge const feeHighBurdenPeer(2000, "heavy peer request");
Charge const feeTrivialPeer(1, "trivial peer request");
Charge const feeModerateBurdenPeer(250, "moderate peer request");
Charge const feeHeavyBurdenPeer(2000, "heavy peer request");
Charge const feeWarning(2000, "received warning");
Charge const feeDrop(3000, "dropped");
Charge const feeWarning(4000, "received warning");
Charge const feeDrop(6000, "dropped");
// See also Resource::Logic::charge for log level cutoff values
} // namespace Resource
} // namespace ripple

View File

@@ -221,7 +221,8 @@ public:
return {};
}
void
charge(Resource::Charge const& fee) override
charge(Resource::Charge const& fee, std::string const& context = {})
override
{
}
id_t

View File

@@ -88,7 +88,8 @@ public:
return {};
}
void
charge(Resource::Charge const& fee) override
charge(Resource::Charge const& fee, std::string const& context = {})
override
{
}
bool

View File

@@ -16,6 +16,7 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================
#include <test/jtx.h>
#include <test/jtx/Env.h>
#include <xrpld/overlay/detail/OverlayImpl.h>
#include <xrpld/overlay/detail/PeerImp.h>
@@ -222,14 +223,21 @@ private:
rid_ = 0;
for (int i = 0; i < nPeers; i++)
addPeer(env, peers, nDisabled);
protocol::TMTransaction m;
m.set_rawtransaction("transaction");
m.set_deferred(false);
m.set_status(protocol::TransactionStatus::tsNEW);
env.app().overlay().relay(uint256{0}, m, toSkip);
BEAST_EXPECT(
PeerTest::sendTx_ == expectRelay &&
PeerTest::queueTx_ == expectQueue);
auto const jtx = env.jt(noop(env.master));
if (BEAST_EXPECT(jtx.stx))
{
protocol::TMTransaction m;
Serializer s;
jtx.stx->add(s);
m.set_rawtransaction(s.data(), s.size());
m.set_deferred(false);
m.set_status(protocol::TransactionStatus::tsNEW);
env.app().overlay().relay(uint256{0}, m, toSkip);
BEAST_EXPECT(
PeerTest::sendTx_ == expectRelay &&
PeerTest::queueTx_ == expectQueue);
}
}
void

View File

@@ -1063,7 +1063,8 @@ InboundLedger::processData(
if (packet.nodes().empty())
{
JLOG(journal_.warn()) << peer->id() << ": empty header data";
peer->charge(Resource::feeInvalidRequest);
peer->charge(
Resource::feeMalformedRequest, "ledger_data empty header");
return -1;
}
@@ -1078,7 +1079,9 @@ InboundLedger::processData(
if (!takeHeader(packet.nodes(0).nodedata()))
{
JLOG(journal_.warn()) << "Got invalid header data";
peer->charge(Resource::feeInvalidRequest);
peer->charge(
Resource::feeMalformedRequest,
"ledger_data invalid header");
return -1;
}
@@ -1101,7 +1104,8 @@ InboundLedger::processData(
{
JLOG(journal_.warn())
<< "Included AS/TX root invalid: " << ex.what();
peer->charge(Resource::feeBadData);
using namespace std::string_literals;
peer->charge(Resource::feeInvalidData, "ledger_data "s + ex.what());
return -1;
}
@@ -1121,7 +1125,7 @@ InboundLedger::processData(
if (packet.nodes().empty())
{
JLOG(journal_.info()) << peer->id() << ": response with no nodes";
peer->charge(Resource::feeInvalidRequest);
peer->charge(Resource::feeMalformedRequest, "ledger_data no nodes");
return -1;
}
@@ -1133,7 +1137,8 @@ InboundLedger::processData(
if (!node.has_nodeid() || !node.has_nodedata())
{
JLOG(journal_.warn()) << "Got bad node";
peer->charge(Resource::feeInvalidRequest);
peer->charge(
Resource::feeMalformedRequest, "ledger_data bad node");
return -1;
}
}

View File

@@ -146,7 +146,7 @@ public:
if (ta == nullptr)
{
peer->charge(Resource::feeUnwantedData);
peer->charge(Resource::feeUselessData, "ledger_data");
return;
}
@@ -157,7 +157,7 @@ public:
{
if (!node.has_nodeid() || !node.has_nodedata())
{
peer->charge(Resource::feeInvalidRequest);
peer->charge(Resource::feeMalformedRequest, "ledger_data");
return;
}
@@ -165,7 +165,7 @@ public:
if (!id)
{
peer->charge(Resource::feeBadData);
peer->charge(Resource::feeInvalidData, "ledger_data");
return;
}
@@ -173,7 +173,7 @@ public:
}
if (!ta->takeNodes(data, peer).isUseful())
peer->charge(Resource::feeUnwantedData);
peer->charge(Resource::feeUselessData, "ledger_data not useful");
}
void

View File

@@ -2116,7 +2116,7 @@ LedgerMaster::makeFetchPack(
{
JLOG(m_journal.info())
<< "Peer requests fetch pack for ledger we don't have: " << have;
peer->charge(Resource::feeRequestNoReply);
peer->charge(Resource::feeRequestNoReply, "get_object ledger");
return;
}
@@ -2124,14 +2124,14 @@ LedgerMaster::makeFetchPack(
{
JLOG(m_journal.warn())
<< "Peer requests fetch pack from open ledger: " << have;
peer->charge(Resource::feeInvalidRequest);
peer->charge(Resource::feeMalformedRequest, "get_object ledger open");
return;
}
if (have->info().seq < getEarliestFetch())
{
JLOG(m_journal.debug()) << "Peer requests fetch pack that is too early";
peer->charge(Resource::feeInvalidRequest);
peer->charge(Resource::feeMalformedRequest, "get_object ledger early");
return;
}
@@ -2142,7 +2142,8 @@ LedgerMaster::makeFetchPack(
JLOG(m_journal.info())
<< "Peer requests fetch pack for ledger whose predecessor we "
<< "don't have: " << have;
peer->charge(Resource::feeRequestNoReply);
peer->charge(
Resource::feeRequestNoReply, "get_object ledger no parent");
return;
}

View File

@@ -183,7 +183,7 @@ public:
virtual void
relay(
uint256 const& hash,
protocol::TMTransaction& m,
std::optional<std::reference_wrapper<protocol::TMTransaction>> m,
std::set<Peer::id_t> const& toSkip) = 0;
/** Visit every active peer.

View File

@@ -77,7 +77,7 @@ public:
/** Adjust this peer's load balance based on the type of load imposed. */
virtual void
charge(Resource::Charge const& fee) = 0;
charge(Resource::Charge const& fee, std::string const& context) = 0;
//
// Identity

View File

@@ -35,6 +35,7 @@
#include <xrpl/basics/make_SSLContext.h>
#include <xrpl/basics/random.h>
#include <xrpl/beast/core/LexicalCast.h>
#include <xrpl/protocol/STTx.h>
#include <xrpl/server/SimpleWriter.h>
#include <boost/algorithm/string/predicate.hpp>
@@ -1199,17 +1200,39 @@ OverlayImpl::getManifestsMessage()
void
OverlayImpl::relay(
uint256 const& hash,
protocol::TMTransaction& m,
std::optional<std::reference_wrapper<protocol::TMTransaction>> tx,
std::set<Peer::id_t> const& toSkip)
{
auto const sm = std::make_shared<Message>(m, protocol::mtTRANSACTION);
bool relay = tx.has_value();
if (relay)
{
auto& txn = tx->get();
SerialIter sit(makeSlice(txn.rawtransaction()));
relay = !isPseudoTx(STTx{sit});
}
Overlay::PeerSequence peers = {};
std::size_t total = 0;
std::size_t disabled = 0;
std::size_t enabledInSkip = 0;
// total peers excluding peers in toSkip
auto peers = getActivePeers(toSkip, total, disabled, enabledInSkip);
auto minRelay = app_.config().TX_REDUCE_RELAY_MIN_PEERS + disabled;
if (!relay)
{
if (!app_.config().TX_REDUCE_RELAY_ENABLE)
return;
peers = getActivePeers(toSkip, total, disabled, enabledInSkip);
JLOG(journal_.trace())
<< "not relaying tx, total peers " << peers.size();
for (auto const& p : peers)
p->addTxQueue(hash);
return;
}
auto& txn = tx->get();
auto const sm = std::make_shared<Message>(txn, protocol::mtTRANSACTION);
peers = getActivePeers(toSkip, total, disabled, enabledInSkip);
auto const minRelay = app_.config().TX_REDUCE_RELAY_MIN_PEERS + disabled;
if (!app_.config().TX_REDUCE_RELAY_ENABLE || total <= minRelay)
{
@@ -1224,7 +1247,7 @@ OverlayImpl::relay(
// We have more peers than the minimum (disabled + minimum enabled),
// relay to all disabled and some randomly selected enabled that
// do not have the transaction.
auto enabledTarget = app_.config().TX_REDUCE_RELAY_MIN_PEERS +
auto const enabledTarget = app_.config().TX_REDUCE_RELAY_MIN_PEERS +
(total - minRelay) * app_.config().TX_RELAY_PERCENTAGE / 100;
txMetrics_.addMetrics(enabledTarget, toSkip.size(), disabled);

View File

@@ -238,7 +238,7 @@ public:
void
relay(
uint256 const&,
protocol::TMTransaction& m,
std::optional<std::reference_wrapper<protocol::TMTransaction>> m,
std::set<Peer::id_t> const& skip) override;
std::shared_ptr<Message>

View File

@@ -62,6 +62,9 @@ std::chrono::milliseconds constexpr peerHighLatency{300};
std::chrono::seconds constexpr peerTimerInterval{60};
} // namespace
// TODO: Remove this exclusion once unit tests are added after the hotfix
// release.
PeerImp::PeerImp(
Application& app,
id_t id,
@@ -95,7 +98,7 @@ PeerImp::PeerImp(
, creationTime_(clock_type::now())
, squelch_(app_.journal("Squelch"))
, usage_(consumer)
, fee_(Resource::feeLightPeer)
, fee_{Resource::feeTrivialPeer, ""}
, slot_(slot)
, request_(std::move(request))
, headers_(request_)
@@ -339,9 +342,9 @@ PeerImp::removeTxQueue(uint256 const& hash)
}
void
PeerImp::charge(Resource::Charge const& fee)
PeerImp::charge(Resource::Charge const& fee, std::string const& context)
{
if ((usage_.charge(fee) == Resource::drop) &&
if ((usage_.charge(fee, context) == Resource::drop) &&
usage_.disconnect(p_journal_) && strand_.running_in_this_thread())
{
// Sever the connection
@@ -997,9 +1000,9 @@ PeerImp::onMessageBegin(
std::size_t uncompressed_size,
bool isCompressed)
{
load_event_ =
app_.getJobQueue().makeLoadEvent(jtPEER, protocolMessageName(type));
fee_ = Resource::feeLightPeer;
auto const name = protocolMessageName(type);
load_event_ = app_.getJobQueue().makeLoadEvent(jtPEER, name);
fee_ = {Resource::feeTrivialPeer, name};
auto const category = TrafficCount::categorize(*m, type, true);
overlay_.reportTraffic(category, true, static_cast<int>(size));
using namespace protocol;
@@ -1029,7 +1032,7 @@ PeerImp::onMessageEnd(
std::shared_ptr<::google::protobuf::Message> const&)
{
load_event_.reset();
charge(fee_);
charge(fee_.fee, fee_.context);
}
void
@@ -1039,12 +1042,12 @@ PeerImp::onMessage(std::shared_ptr<protocol::TMManifests> const& m)
if (s == 0)
{
fee_ = Resource::feeUnwantedData;
fee_.update(Resource::feeUselessData, "empty");
return;
}
if (s > 100)
fee_ = Resource::feeMediumBurdenPeer;
fee_.update(Resource::feeModerateBurdenPeer, "oversize");
app_.getJobQueue().addJob(
jtMANIFEST, "receiveManifests", [this, that = shared_from_this(), m]() {
@@ -1058,7 +1061,7 @@ PeerImp::onMessage(std::shared_ptr<protocol::TMPing> const& m)
if (m->type() == protocol::TMPing::ptPING)
{
// We have received a ping request, reply with a pong
fee_ = Resource::feeMediumBurdenPeer;
fee_.update(Resource::feeModerateBurdenPeer, "ping request");
m->set_type(protocol::TMPing::ptPONG);
send(std::make_shared<Message>(*m, protocol::mtPING));
return;
@@ -1095,7 +1098,7 @@ PeerImp::onMessage(std::shared_ptr<protocol::TMCluster> const& m)
// VFALCO NOTE I think we should drop the peer immediately
if (!cluster())
{
fee_ = Resource::feeUnwantedData;
fee_.fee = Resource::feeUselessData;
return;
}
@@ -1173,7 +1176,7 @@ PeerImp::onMessage(std::shared_ptr<protocol::TMEndpoints> const& m)
// implication for the protocol.
if (m->endpoints_v2().size() >= 1024)
{
charge(Resource::feeBadData);
charge(Resource::feeInvalidData, "endpoints too large");
return;
}
@@ -1188,7 +1191,7 @@ PeerImp::onMessage(std::shared_ptr<protocol::TMEndpoints> const& m)
{
JLOG(p_journal_.error()) << "failed to parse incoming endpoint: {"
<< tm.endpoint() << "}";
charge(Resource::feeBadData);
charge(Resource::feeInvalidData, "endpoints malformed");
continue;
}
@@ -1211,14 +1214,19 @@ PeerImp::onMessage(std::shared_ptr<protocol::TMEndpoints> const& m)
void
PeerImp::onMessage(std::shared_ptr<protocol::TMTransaction> const& m)
{
handleTransaction(m, true);
handleTransaction(m, true, false);
}
void
PeerImp::handleTransaction(
std::shared_ptr<protocol::TMTransaction> const& m,
bool eraseTxQueue)
bool eraseTxQueue,
bool batch)
{
assert(
(eraseTxQueue != batch) &&
// Include a message to make this easier to convert to XRPL_ASSERT
("ripple::PeerImp::handleTransaction correct function params"));
if (tracking_.load() == Tracking::diverged)
return;
@@ -1246,7 +1254,7 @@ PeerImp::handleTransaction(
// we have seen this transaction recently
if (flags & SF_BAD)
{
fee_ = Resource::feeInvalidSignature;
fee_.update(Resource::feeUselessData, "known bad");
JLOG(p_journal_.debug()) << "Ignoring known bad tx " << txID;
}
@@ -1300,9 +1308,11 @@ PeerImp::handleTransaction(
[weak = std::weak_ptr<PeerImp>(shared_from_this()),
flags,
checkSignature,
batch,
stx]() {
if (auto peer = weak.lock())
peer->checkTransaction(flags, checkSignature, stx);
peer->checkTransaction(
flags, checkSignature, stx, batch);
});
}
}
@@ -1318,7 +1328,7 @@ void
PeerImp::onMessage(std::shared_ptr<protocol::TMGetLedger> const& m)
{
auto badData = [&](std::string const& msg) {
charge(Resource::feeBadData);
charge(Resource::feeInvalidData, "get_ledger " + msg);
JLOG(p_journal_.warn()) << "TMGetLedger: " << msg;
};
auto const itype{m->itype()};
@@ -1409,11 +1419,12 @@ PeerImp::onMessage(std::shared_ptr<protocol::TMProofPathRequest> const& m)
JLOG(p_journal_.trace()) << "onMessage, TMProofPathRequest";
if (!ledgerReplayEnabled_)
{
charge(Resource::feeInvalidRequest);
charge(Resource::feeMalformedRequest, "proof_path_request disabled");
return;
}
fee_ = Resource::feeMediumBurdenPeer;
fee_.update(
Resource::feeModerateBurdenPeer, "received a proof path request");
std::weak_ptr<PeerImp> weak = shared_from_this();
app_.getJobQueue().addJob(
jtREPLAY_REQ, "recvProofPathRequest", [weak, m]() {
@@ -1424,9 +1435,12 @@ PeerImp::onMessage(std::shared_ptr<protocol::TMProofPathRequest> const& m)
if (reply.has_error())
{
if (reply.error() == protocol::TMReplyError::reBAD_REQUEST)
peer->charge(Resource::feeInvalidRequest);
peer->charge(
Resource::feeMalformedRequest,
"proof_path_request");
else
peer->charge(Resource::feeRequestNoReply);
peer->charge(
Resource::feeRequestNoReply, "proof_path_request");
}
else
{
@@ -1442,13 +1456,13 @@ PeerImp::onMessage(std::shared_ptr<protocol::TMProofPathResponse> const& m)
{
if (!ledgerReplayEnabled_)
{
charge(Resource::feeInvalidRequest);
charge(Resource::feeMalformedRequest, "proof_path_response disabled");
return;
}
if (!ledgerReplayMsgHandler_.processProofPathResponse(m))
{
charge(Resource::feeBadData);
charge(Resource::feeInvalidData, "proof_path_response");
}
}
@@ -1458,11 +1472,11 @@ PeerImp::onMessage(std::shared_ptr<protocol::TMReplayDeltaRequest> const& m)
JLOG(p_journal_.trace()) << "onMessage, TMReplayDeltaRequest";
if (!ledgerReplayEnabled_)
{
charge(Resource::feeInvalidRequest);
charge(Resource::feeMalformedRequest, "replay_delta_request disabled");
return;
}
fee_ = Resource::feeMediumBurdenPeer;
fee_.fee = Resource::feeModerateBurdenPeer;
std::weak_ptr<PeerImp> weak = shared_from_this();
app_.getJobQueue().addJob(
jtREPLAY_REQ, "recvReplayDeltaRequest", [weak, m]() {
@@ -1473,9 +1487,13 @@ PeerImp::onMessage(std::shared_ptr<protocol::TMReplayDeltaRequest> const& m)
if (reply.has_error())
{
if (reply.error() == protocol::TMReplyError::reBAD_REQUEST)
peer->charge(Resource::feeInvalidRequest);
peer->charge(
Resource::feeMalformedRequest,
"replay_delta_request");
else
peer->charge(Resource::feeRequestNoReply);
peer->charge(
Resource::feeRequestNoReply,
"replay_delta_request");
}
else
{
@@ -1491,13 +1509,13 @@ PeerImp::onMessage(std::shared_ptr<protocol::TMReplayDeltaResponse> const& m)
{
if (!ledgerReplayEnabled_)
{
charge(Resource::feeInvalidRequest);
charge(Resource::feeMalformedRequest, "replay_delta_response disabled");
return;
}
if (!ledgerReplayMsgHandler_.processReplayDeltaResponse(m))
{
charge(Resource::feeBadData);
charge(Resource::feeInvalidData, "replay_delta_response");
}
}
@@ -1505,7 +1523,7 @@ void
PeerImp::onMessage(std::shared_ptr<protocol::TMLedgerData> const& m)
{
auto badData = [&](std::string const& msg) {
fee_ = Resource::feeBadData;
fee_.update(Resource::feeInvalidData, msg);
JLOG(p_journal_.warn()) << "TMLedgerData: " << msg;
};
@@ -1605,7 +1623,9 @@ PeerImp::onMessage(std::shared_ptr<protocol::TMProposeSet> const& m)
(publicKeyType(makeSlice(set.nodepubkey())) != KeyType::secp256k1))
{
JLOG(p_journal_.warn()) << "Proposal: malformed";
fee_ = Resource::feeInvalidSignature;
fee_.update(
Resource::feeInvalidSignature,
" signature can't be longer than 72 bytes");
return;
}
@@ -1613,7 +1633,7 @@ PeerImp::onMessage(std::shared_ptr<protocol::TMProposeSet> const& m)
!stringIsUint256Sized(set.previousledger()))
{
JLOG(p_journal_.warn()) << "Proposal: malformed";
fee_ = Resource::feeInvalidRequest;
fee_.update(Resource::feeMalformedRequest, "bad hashes");
return;
}
@@ -1918,7 +1938,7 @@ PeerImp::onMessage(std::shared_ptr<protocol::TMHaveTransactionSet> const& m)
{
if (!stringIsUint256Sized(m->hash()))
{
fee_ = Resource::feeInvalidRequest;
fee_.update(Resource::feeMalformedRequest, "bad hash");
return;
}
@@ -1931,7 +1951,7 @@ PeerImp::onMessage(std::shared_ptr<protocol::TMHaveTransactionSet> const& m)
if (std::find(recentTxSets_.begin(), recentTxSets_.end(), hash) !=
recentTxSets_.end())
{
fee_ = Resource::feeUnwantedData;
fee_.update(Resource::feeUselessData, "duplicate (tsHAVE)");
return;
}
@@ -1953,7 +1973,7 @@ PeerImp::onValidatorListMessage(
JLOG(p_journal_.warn()) << "Ignored malformed " << messageType
<< " from peer " << remote_address_;
// This shouldn't ever happen with a well-behaved peer
fee_ = Resource::feeHighBurdenPeer;
fee_.update(Resource::feeHeavyBurdenPeer, "no blobs");
return;
}
@@ -1970,7 +1990,7 @@ PeerImp::onValidatorListMessage(
// Charging this fee here won't hurt the peer in the normal
// course of operation (ie. refresh every 5 minutes), but
// will add up if the peer is misbehaving.
fee_ = Resource::feeUnwantedData;
fee_.update(Resource::feeUselessData, "duplicate");
return;
}
@@ -2049,27 +2069,30 @@ PeerImp::onValidatorListMessage(
// Charging this fee here won't hurt the peer in the normal
// course of operation (ie. refresh every 5 minutes), but
// will add up if the peer is misbehaving.
fee_ = Resource::feeUnwantedData;
fee_.update(
Resource::feeUselessData,
" duplicate (same_sequence or known_sequence)");
break;
case ListDisposition::stale:
// There are very few good reasons for a peer to send an
// old list, particularly more than once.
fee_ = Resource::feeBadData;
fee_.update(Resource::feeInvalidData, "expired");
break;
case ListDisposition::untrusted:
// Charging this fee here won't hurt the peer in the normal
// course of operation (ie. refresh every 5 minutes), but
// will add up if the peer is misbehaving.
fee_ = Resource::feeUnwantedData;
fee_.update(Resource::feeUselessData, "untrusted");
break;
case ListDisposition::invalid:
// This shouldn't ever happen with a well-behaved peer
fee_ = Resource::feeInvalidSignature;
fee_.update(
Resource::feeInvalidSignature, "invalid list disposition");
break;
case ListDisposition::unsupported_version:
// During a version transition, this may be legitimate.
// If it happens frequently, that's probably bad.
fee_ = Resource::feeBadData;
fee_.update(Resource::feeInvalidData, "version");
break;
default:
assert(false);
@@ -2146,7 +2169,7 @@ PeerImp::onMessage(std::shared_ptr<protocol::TMValidatorList> const& m)
<< "ValidatorList: received validator list from peer using "
<< "protocol version " << to_string(protocol_)
<< " which shouldn't support this feature.";
fee_ = Resource::feeUnwantedData;
fee_.update(Resource::feeUselessData, "unsupported peer");
return;
}
onValidatorListMessage(
@@ -2159,7 +2182,8 @@ PeerImp::onMessage(std::shared_ptr<protocol::TMValidatorList> const& m)
{
JLOG(p_journal_.warn()) << "ValidatorList: Exception, " << e.what()
<< " from peer " << remote_address_;
fee_ = Resource::feeBadData;
using namespace std::string_literals;
fee_.update(Resource::feeInvalidData, e.what());
}
}
@@ -2175,7 +2199,7 @@ PeerImp::onMessage(
<< "ValidatorListCollection: received validator list from peer "
<< "using protocol version " << to_string(protocol_)
<< " which shouldn't support this feature.";
fee_ = Resource::feeUnwantedData;
fee_.update(Resource::feeUselessData, "unsupported peer");
return;
}
else if (m->version() < 2)
@@ -2185,7 +2209,7 @@ PeerImp::onMessage(
"version "
<< m->version() << " from peer using protocol version "
<< to_string(protocol_);
fee_ = Resource::feeBadData;
fee_.update(Resource::feeInvalidData, "wrong version");
return;
}
onValidatorListMessage(
@@ -2198,7 +2222,8 @@ PeerImp::onMessage(
{
JLOG(p_journal_.warn()) << "ValidatorListCollection: Exception, "
<< e.what() << " from peer " << remote_address_;
fee_ = Resource::feeBadData;
using namespace std::string_literals;
fee_.update(Resource::feeInvalidData, e.what());
}
}
@@ -2208,7 +2233,7 @@ PeerImp::onMessage(std::shared_ptr<protocol::TMValidation> const& m)
if (m->validation().size() < 50)
{
JLOG(p_journal_.warn()) << "Validation: Too small";
fee_ = Resource::feeInvalidRequest;
fee_.update(Resource::feeMalformedRequest, "too small");
return;
}
@@ -2236,7 +2261,7 @@ PeerImp::onMessage(std::shared_ptr<protocol::TMValidation> const& m)
val->getSeenTime()))
{
JLOG(p_journal_.trace()) << "Validation: Not current";
fee_ = Resource::feeUnwantedData;
fee_.update(Resource::feeUselessData, "not current");
return;
}
@@ -2309,7 +2334,8 @@ PeerImp::onMessage(std::shared_ptr<protocol::TMValidation> const& m)
{
JLOG(p_journal_.warn())
<< "Exception processing validation: " << e.what();
fee_ = Resource::feeInvalidRequest;
using namespace std::string_literals;
fee_.update(Resource::feeMalformedRequest, e.what());
}
}
@@ -2342,7 +2368,7 @@ PeerImp::onMessage(std::shared_ptr<protocol::TMGetObjectByHash> const& m)
{
JLOG(p_journal_.error())
<< "TMGetObjectByHash: tx reduce-relay is disabled";
fee_ = Resource::feeInvalidRequest;
fee_.update(Resource::feeMalformedRequest, "disabled");
return;
}
@@ -2355,7 +2381,9 @@ PeerImp::onMessage(std::shared_ptr<protocol::TMGetObjectByHash> const& m)
return;
}
fee_ = Resource::feeMediumBurdenPeer;
fee_.update(
Resource::feeModerateBurdenPeer,
" received a get object by hash request");
protocol::TMGetObjectByHash reply;
@@ -2370,7 +2398,7 @@ PeerImp::onMessage(std::shared_ptr<protocol::TMGetObjectByHash> const& m)
{
if (!stringIsUint256Sized(packet.ledgerhash()))
{
fee_ = Resource::feeInvalidRequest;
fee_.update(Resource::feeMalformedRequest, "ledger hash");
return;
}
@@ -2474,7 +2502,7 @@ PeerImp::onMessage(std::shared_ptr<protocol::TMHaveTransactions> const& m)
{
JLOG(p_journal_.error())
<< "TMHaveTransactions: tx reduce-relay is disabled";
fee_ = Resource::feeInvalidRequest;
fee_.update(Resource::feeMalformedRequest, "disabled");
return;
}
@@ -2503,7 +2531,7 @@ PeerImp::handleHaveTransactions(
{
JLOG(p_journal_.error())
<< "TMHaveTransactions with invalid hash size";
fee_ = Resource::feeInvalidRequest;
fee_.update(Resource::feeMalformedRequest, "hash size");
return;
}
@@ -2543,7 +2571,7 @@ PeerImp::onMessage(std::shared_ptr<protocol::TMTransactions> const& m)
{
JLOG(p_journal_.error())
<< "TMTransactions: tx reduce-relay is disabled";
fee_ = Resource::feeInvalidRequest;
fee_.update(Resource::feeMalformedRequest, "disabled");
return;
}
@@ -2556,7 +2584,8 @@ PeerImp::onMessage(std::shared_ptr<protocol::TMTransactions> const& m)
handleTransaction(
std::shared_ptr<protocol::TMTransaction>(
m->mutable_transactions(i), [](protocol::TMTransaction*) {}),
false);
false,
true);
}
void
@@ -2572,14 +2601,14 @@ PeerImp::onMessage(std::shared_ptr<protocol::TMSquelch> const& m)
if (!m->has_validatorpubkey())
{
charge(Resource::feeBadData);
charge(Resource::feeInvalidData, "squelch no pubkey");
return;
}
auto validator = m->validatorpubkey();
auto const slice{makeSlice(validator)};
if (!publicKeyType(slice))
{
charge(Resource::feeBadData);
charge(Resource::feeInvalidData, "squelch bad pubkey");
return;
}
PublicKey key(slice);
@@ -2587,7 +2616,7 @@ PeerImp::onMessage(std::shared_ptr<protocol::TMSquelch> const& m)
// Ignore non-validator squelch
if (!app_.validators().listed(key))
{
charge(Resource::feeBadData);
charge(Resource::feeInvalidData, "squelch non-validator");
JLOG(p_journal_.debug())
<< "onMessage: TMSquelch discarding non-validator squelch "
<< slice;
@@ -2607,7 +2636,7 @@ PeerImp::onMessage(std::shared_ptr<protocol::TMSquelch> const& m)
if (!m->squelch())
squelch_.removeSquelch(key);
else if (!squelch_.addSquelch(key, std::chrono::seconds{duration}))
charge(Resource::feeBadData);
charge(Resource::feeInvalidData, "squelch duration");
JLOG(p_journal_.debug())
<< "onMessage: TMSquelch " << slice << " " << id() << " " << duration;
@@ -2648,11 +2677,11 @@ PeerImp::doFetchPack(const std::shared_ptr<protocol::TMGetObjectByHash>& packet)
if (!stringIsUint256Sized(packet->ledgerhash()))
{
JLOG(p_journal_.warn()) << "FetchPack hash size malformed";
fee_ = Resource::feeInvalidRequest;
fee_.update(Resource::feeMalformedRequest, "hash size");
return;
}
fee_ = Resource::feeHighBurdenPeer;
fee_.fee = Resource::feeHeavyBurdenPeer;
uint256 const hash{packet->ledgerhash()};
@@ -2677,7 +2706,7 @@ PeerImp::doTransactions(
if (packet->objects_size() > reduce_relay::MAX_TX_QUEUE_SIZE)
{
JLOG(p_journal_.error()) << "doTransactions, invalid number of hashes";
fee_ = Resource::feeInvalidRequest;
fee_.update(Resource::feeMalformedRequest, "too big");
return;
}
@@ -2687,7 +2716,7 @@ PeerImp::doTransactions(
if (!stringIsUint256Sized(obj.hash()))
{
fee_ = Resource::feeInvalidRequest;
fee_.update(Resource::feeMalformedRequest, "hash size");
return;
}
@@ -2699,7 +2728,7 @@ PeerImp::doTransactions(
{
JLOG(p_journal_.error()) << "doTransactions, transaction not found "
<< Slice(hash.data(), hash.size());
fee_ = Resource::feeInvalidRequest;
fee_.update(Resource::feeMalformedRequest, "tx not found");
return;
}
@@ -2724,7 +2753,8 @@ void
PeerImp::checkTransaction(
int flags,
bool checkSignature,
std::shared_ptr<STTx const> const& stx)
std::shared_ptr<STTx const> const& stx,
bool batch)
{
// VFALCO TODO Rewrite to not use exceptions
try
@@ -2735,10 +2765,45 @@ PeerImp::checkTransaction(
app_.getLedgerMaster().getValidLedgerIndex()))
{
app_.getHashRouter().setFlags(stx->getTransactionID(), SF_BAD);
charge(Resource::feeUnwantedData);
charge(Resource::feeUselessData, "expired tx");
return;
}
if (isPseudoTx(*stx))
{
// Don't do anything with pseudo transactions except put them in the
// TransactionMaster cache
std::string reason;
auto tx = std::make_shared<Transaction>(stx, reason, app_);
assert(tx->getStatus() == NEW);
if (tx->getStatus() == NEW)
{
JLOG(p_journal_.debug())
<< "Processing " << (batch ? "batch" : "unsolicited")
<< " pseudo-transaction tx " << tx->getID();
app_.getMasterTransaction().canonicalize(&tx);
// Tell the overlay about it, but don't relay it.
auto const toSkip =
app_.getHashRouter().shouldRelay(tx->getID());
if (toSkip)
{
JLOG(p_journal_.debug())
<< "Passing skipped pseudo pseudo-transaction tx "
<< tx->getID();
app_.overlay().relay(tx->getID(), {}, *toSkip);
}
if (!batch)
{
JLOG(p_journal_.debug())
<< "Charging for pseudo-transaction tx " << tx->getID();
charge(Resource::feeUselessData, "pseudo tx");
}
return;
}
}
if (checkSignature)
{
// Check the signature before handing off to the job queue.
@@ -2757,7 +2822,9 @@ PeerImp::checkTransaction(
// Probably not necessary to set SF_BAD, but doesn't hurt.
app_.getHashRouter().setFlags(stx->getTransactionID(), SF_BAD);
charge(Resource::feeInvalidSignature);
charge(
Resource::feeInvalidSignature,
"check transaction signature failure");
return;
}
}
@@ -2778,7 +2845,7 @@ PeerImp::checkTransaction(
<< "Exception checking transaction: " << reason;
}
app_.getHashRouter().setFlags(stx->getTransactionID(), SF_BAD);
charge(Resource::feeInvalidSignature);
charge(Resource::feeInvalidSignature, "tx (impossible)");
return;
}
@@ -2791,7 +2858,8 @@ PeerImp::checkTransaction(
JLOG(p_journal_.warn())
<< "Exception in " << __func__ << ": " << ex.what();
app_.getHashRouter().setFlags(stx->getTransactionID(), SF_BAD);
charge(Resource::feeBadData);
using namespace std::string_literals;
charge(Resource::feeInvalidData, "tx "s + ex.what());
}
}
@@ -2809,8 +2877,9 @@ PeerImp::checkPropose(
if (!cluster() && !peerPos.checkSign())
{
JLOG(p_journal_.warn()) << "Proposal fails sig check";
charge(Resource::feeInvalidSignature);
std::string desc{"Proposal fails sig check"};
JLOG(p_journal_.warn()) << desc;
charge(Resource::feeInvalidSignature, desc);
return;
}
@@ -2846,8 +2915,9 @@ PeerImp::checkValidation(
{
if (!val->isValid())
{
JLOG(p_journal_.debug()) << "Validation forwarded by peer is invalid";
charge(Resource::feeInvalidSignature);
std::string desc{"Validation forwarded by peer is invalid"};
JLOG(p_journal_.debug()) << desc;
charge(Resource::feeInvalidSignature, desc);
return;
}
@@ -2877,7 +2947,8 @@ PeerImp::checkValidation(
{
JLOG(p_journal_.trace())
<< "Exception processing validation: " << ex.what();
charge(Resource::feeInvalidRequest);
using namespace std::string_literals;
charge(Resource::feeMalformedRequest, "validation "s + ex.what());
}
}
@@ -3046,7 +3117,8 @@ PeerImp::getLedger(std::shared_ptr<protocol::TMGetLedger> const& m)
{
// Do not resource charge a peer responding to a relay
if (!m->has_requestcookie())
charge(Resource::feeInvalidRequest);
charge(
Resource::feeMalformedRequest, "get_ledger ledgerSeq");
ledger.reset();
JLOG(p_journal_.warn())
@@ -3108,7 +3180,8 @@ PeerImp::processLedgerRequest(std::shared_ptr<protocol::TMGetLedger> const& m)
{
// Do not resource charge a peer responding to a relay
if (!m->has_requestcookie())
charge(Resource::feeMediumBurdenPeer);
charge(
Resource::feeModerateBurdenPeer, "received a get ledger request");
std::shared_ptr<Ledger const> ledger;
std::shared_ptr<SHAMap const> sharedMap;
@@ -3218,6 +3291,9 @@ PeerImp::processLedgerRequest(std::shared_ptr<protocol::TMGetLedger> const& m)
for (auto const& d : data)
{
if (ledgerData.nodes_size() >=
Tuning::hardMaxReplyNodes)
break;
protocol::TMLedgerNode* node{ledgerData.add_nodes()};
node->set_nodeid(d.first.getRawString());
node->set_nodedata(d.second.data(), d.second.size());
@@ -3272,6 +3348,9 @@ PeerImp::processLedgerRequest(std::shared_ptr<protocol::TMGetLedger> const& m)
<< ledgerData.nodes_size() << " nodes";
}
if (ledgerData.nodes_size() == 0)
return;
send(std::make_shared<Message>(ledgerData, protocol::mtLEDGER_DATA));
}

View File

@@ -145,10 +145,28 @@ private:
//
// June 2019
struct ChargeWithContext
{
Resource::Charge fee = Resource::feeTrivialPeer;
std::string context = {};
void
update(Resource::Charge f, std::string const& add)
{
assert(f >= fee);
fee = f;
if (!context.empty())
{
context += " ";
}
context += add;
}
};
std::mutex mutable recentLock_;
protocol::TMStatusChange last_status_;
Resource::Consumer usage_;
Resource::Charge fee_;
ChargeWithContext fee_;
std::shared_ptr<PeerFinder::Slot> const slot_;
boost::beast::multi_buffer read_buffer_;
http_request_type request_;
@@ -304,7 +322,7 @@ public:
}
void
charge(Resource::Charge const& fee) override;
charge(Resource::Charge const& fee, std::string const& context) override;
//
// Identity
@@ -482,11 +500,15 @@ private:
the queue when called from onMessage(TMTransactions) because this
message is a response to the missing transactions request and the queue
would not have any of these transactions.
@param batch is false when called from onMessage(TMTransaction)
and is true when called from onMessage(TMTransactions). If true, then the
transaction is part of a batch, and should not be charged an extra fee.
*/
void
handleTransaction(
std::shared_ptr<protocol::TMTransaction> const& m,
bool eraseTxQueue);
bool eraseTxQueue,
bool batch);
/** Handle protocol message with hashes of transactions that have not
been relayed by an upstream node down to its peers - request
@@ -598,7 +620,8 @@ private:
checkTransaction(
int flags,
bool checkSignature,
std::shared_ptr<STTx const> const& stx);
std::shared_ptr<STTx const> const& stx,
bool batch);
void
checkPropose(
@@ -664,7 +687,7 @@ PeerImp::PeerImp(
, creationTime_(clock_type::now())
, squelch_(app_.journal("Squelch"))
, usage_(usage)
, fee_(Resource::feeLightPeer)
, fee_{Resource::feeTrivialPeer}
, slot_(std::move(slot))
, response_(std::move(response))
, headers_(response_)

View File

@@ -1043,7 +1043,7 @@ getLedgerByContext(RPC::JsonContext& context)
"Exactly one of ledger_hash and ledger_index can be set.");
}
context.loadType = Resource::feeHighBurdenRPC;
context.loadType = Resource::feeHeavyBurdenRPC;
if (hasHash)
{

View File

@@ -444,7 +444,7 @@ ServerHandler::processSession(
if (jv.isMember(jss::api_version))
jr[jss::api_version] = jv[jss::api_version];
is->getConsumer().charge(Resource::feeInvalidRPC);
is->getConsumer().charge(Resource::feeMalformedRPC);
return jr;
}
@@ -461,7 +461,7 @@ ServerHandler::processSession(
is->user());
if (Role::FORBID == role)
{
loadType = Resource::feeInvalidRPC;
loadType = Resource::feeMalformedRPC;
jr[jss::result] = rpcError(rpcFORBIDDEN);
}
else
@@ -729,7 +729,7 @@ ServerHandler::processRequest(
if (role == Role::FORBID)
{
usage.charge(Resource::feeInvalidRPC);
usage.charge(Resource::feeMalformedRPC);
if (!batch)
{
HTTPReply(403, "Forbidden", output, rpcJ);
@@ -743,7 +743,7 @@ ServerHandler::processRequest(
if (!jsonRPC.isMember(jss::method) || jsonRPC[jss::method].isNull())
{
usage.charge(Resource::feeInvalidRPC);
usage.charge(Resource::feeMalformedRPC);
if (!batch)
{
HTTPReply(400, "Null method", output, rpcJ);
@@ -758,7 +758,7 @@ ServerHandler::processRequest(
Json::Value const& method = jsonRPC[jss::method];
if (!method.isString())
{
usage.charge(Resource::feeInvalidRPC);
usage.charge(Resource::feeMalformedRPC);
if (!batch)
{
HTTPReply(400, "method is not string", output, rpcJ);
@@ -774,7 +774,7 @@ ServerHandler::processRequest(
std::string strMethod = method.asString();
if (strMethod.empty())
{
usage.charge(Resource::feeInvalidRPC);
usage.charge(Resource::feeMalformedRPC);
if (!batch)
{
HTTPReply(400, "method is empty", output, rpcJ);
@@ -802,7 +802,7 @@ ServerHandler::processRequest(
else if (!params.isArray() || params.size() != 1)
{
usage.charge(Resource::feeInvalidRPC);
usage.charge(Resource::feeMalformedRPC);
HTTPReply(400, "params unparseable", output, rpcJ);
return;
}
@@ -811,7 +811,7 @@ ServerHandler::processRequest(
params = std::move(params[0u]);
if (!params.isObjectOrNull())
{
usage.charge(Resource::feeInvalidRPC);
usage.charge(Resource::feeMalformedRPC);
HTTPReply(400, "params unparseable", output, rpcJ);
return;
}
@@ -827,7 +827,7 @@ ServerHandler::processRequest(
{
if (!params[jss::ripplerpc].isString())
{
usage.charge(Resource::feeInvalidRPC);
usage.charge(Resource::feeMalformedRPC);
if (!batch)
{
HTTPReply(400, "ripplerpc is not a string", output, rpcJ);

View File

@@ -74,7 +74,7 @@ doGatewayBalances(RPC::JsonContext& context)
if (!id)
return rpcError(rpcACT_MALFORMED);
auto const accountID{std::move(id.value())};
context.loadType = Resource::feeHighBurdenRPC;
context.loadType = Resource::feeHeavyBurdenRPC;
result[jss::account] = toBase58(accountID);

View File

@@ -80,7 +80,7 @@ LedgerHandler::check()
return rpcTOO_BUSY;
}
context_.loadType =
binary ? Resource::feeMediumBurdenRPC : Resource::feeHighBurdenRPC;
binary ? Resource::feeMediumBurdenRPC : Resource::feeHeavyBurdenRPC;
}
if (queue)
{

View File

@@ -52,7 +52,7 @@ doPathFind(RPC::JsonContext& context)
if (sSubCommand == "create")
{
context.loadType = Resource::feeHighBurdenRPC;
context.loadType = Resource::feeHeavyBurdenRPC;
context.infoSub->clearRequest();
return context.app.getPathRequests().makePathRequest(
context.infoSub, lpLedger, context.params);

View File

@@ -34,7 +34,7 @@ doRipplePathFind(RPC::JsonContext& context)
if (context.app.config().PATH_SEARCH_MAX == 0)
return rpcError(rpcNOT_SUPPORTED);
context.loadType = Resource::feeHighBurdenRPC;
context.loadType = Resource::feeHeavyBurdenRPC;
std::shared_ptr<ReadView const> lpLedger;
Json::Value jvResult;

View File

@@ -40,7 +40,7 @@ doSignFor(RPC::JsonContext& context)
rpcNOT_SUPPORTED, "Signing is not supported by this server.");
}
context.loadType = Resource::feeHighBurdenRPC;
context.loadType = Resource::feeHeavyBurdenRPC;
auto const failHard = context.params[jss::fail_hard].asBool();
auto const failType = NetworkOPs::doFailHard(failHard);

View File

@@ -38,7 +38,7 @@ doSign(RPC::JsonContext& context)
rpcNOT_SUPPORTED, "Signing is not supported by this server.");
}
context.loadType = Resource::feeHighBurdenRPC;
context.loadType = Resource::feeHeavyBurdenRPC;
NetworkOPs::FailHard const failType = NetworkOPs::doFailHard(
context.params.isMember(jss::fail_hard) &&
context.params[jss::fail_hard].asBool());

View File

@@ -33,7 +33,7 @@ namespace ripple {
Json::Value
doSubmitMultiSigned(RPC::JsonContext& context)
{
context.loadType = Resource::feeHighBurdenRPC;
context.loadType = Resource::feeHeavyBurdenRPC;
auto const failHard = context.params[jss::fail_hard].asBool();
auto const failType = NetworkOPs::doFailHard(failHard);