3#include <xrpl/basics/Log.h>
4#include <xrpl/basics/UnorderedContainers.h>
5#include <xrpl/basics/chrono.h>
6#include <xrpl/beast/clock/abstract_clock.h>
7#include <xrpl/beast/insight/Insight.h>
8#include <xrpl/beast/utility/PropertyStream.h>
9#include <xrpl/beast/utility/instrumentation.h>
10#include <xrpl/json/json_value.h>
11#include <xrpl/protocol/jss.h>
12#include <xrpl/resource/Fees.h>
13#include <xrpl/resource/Gossip.h>
14#include <xrpl/resource/detail/Import.h>
33 warn = collector->make_meter(
"warn");
34 drop = collector->make_meter(
"drop");
93 Entry* entry(
nullptr);
102 entry = &resultIt->second;
103 entry->key = &resultIt->first;
105 if (entry->refcount == 1)
123 Entry* entry(
nullptr);
132 entry = &resultIt->second;
133 entry->key = &resultIt->first;
135 if (entry->refcount == 1)
156 Entry* entry(
nullptr);
165 entry = &resultIt->second;
166 entry->key = &resultIt->first;
168 if (entry->refcount == 1)
198 int const localBalance = inboundEntry.local_balance.value(now);
199 if ((localBalance + inboundEntry.remote_balance) >= threshold)
202 entry[jss::local] = localBalance;
203 entry[jss::remote] = inboundEntry.remote_balance;
204 entry[jss::type] =
"inbound";
209 int const localBalance = outboundEntry.local_balance.value(now);
210 if ((localBalance + outboundEntry.remote_balance) >= threshold)
213 entry[jss::local] = localBalance;
214 entry[jss::remote] = outboundEntry.remote_balance;
215 entry[jss::type] =
"outbound";
218 for (
auto& adminEntry :
admin_)
220 int const localBalance = adminEntry.local_balance.value(now);
221 if ((localBalance + adminEntry.remote_balance) >= threshold)
224 entry[jss::local] = localBalance;
225 entry[jss::remote] = adminEntry.remote_balance;
226 entry[jss::type] =
"admin";
246 item.
balance = inboundEntry.local_balance.value(now);
250 gossip.
items.push_back(item);
273 Import& next(resultIt->second);
275 next.items.reserve(gossip.
items.size());
277 for (
auto const& gossipItem : gossip.
items)
280 item.
balance = gossipItem.balance;
283 next.items.push_back(item);
293 next.items.reserve(gossip.
items.size());
294 for (
auto const& gossipItem : gossip.
items)
297 item.
balance = gossipItem.balance;
300 next.items.push_back(item);
303 Import& prev(resultIt->second);
304 for (
auto& item : prev.items)
306 item.consumer.entry().remote_balance -= item.balance;
327 if (iter->whenExpires <= elapsed)
343 Import&
import(iter->second);
344 if (iter->second.whenExpires <= elapsed)
346 for (
auto item_iter(
import.items.begin()); item_iter !=
import.items.end();
349 item_iter->consumer.entry().remote_balance -= item_iter->balance;
378 Entry& entry(iter->second);
379 XRPL_ASSERT(entry.refcount == 0,
"xrpl::Resource::Logic::erase : entry not used");
395 if (--entry.refcount == 0)
399 switch (entry.key->kind)
413 "xrpl::Resource::Logic::release : invalid entry "
430 feeLogAsWarn > feeLogAsInfo && feeLogAsInfo > feeLogAsDebug && feeLogAsDebug > 10);
433 if (cost >= feeLogAsWarn)
434 return journal.warn();
435 if (cost >= feeLogAsInfo)
436 return journal.info();
437 if (cost >= feeLogAsDebug)
438 return journal.debug();
439 return journal.trace();
442 if (!context.empty())
443 context =
" (" + context +
")";
448 JLOG(getStream(fee.
cost(),
m_journal)) <<
"Charging " << entry <<
" for " << fee << context;
455 if (entry.isUnlimited())
465 entry.lastWarningTime = elapsed;
478 if (entry.isUnlimited())
484 int const balance(entry.balance(now));
487 JLOG(
m_journal.
warn()) <<
"Consumer entry " << entry <<
" dropped with balance "
515 for (
auto& entry : list)
518 if (entry.refcount != 0)
519 item[
"count"] = entry.refcount;
520 item[
"name"] = entry.to_string();
521 item[
"balance"] = entry.balance(now);
522 if (entry.remote_balance != 0)
523 item[
"remote_balance"] = entry.remote_balance;
A version-independent IP address and port combination.
Address const & address() const
Returns the address portion of this endpoint.
Endpoint at_port(Port port) const
Returns a new Endpoint with a different port.
A generic endpoint for log messages.
iterator iterator_to(T &element) const noexcept
Obtain an iterator from an element.
iterator push_back(T &element) noexcept
Append an element at the end of the list.
iterator begin() noexcept
Obtain an iterator to the beginning of the list.
iterator end() noexcept
Obtain a iterator to the end of the list.
size_type size() const noexcept
Returns the number of elements in the list.
iterator erase(iterator pos) noexcept
Remove an element.
typename Clock::time_point time_point
virtual time_point now() const =0
Returns the current time.
A metric for measuring an integral value.
value_type cost() const
Return the cost of the charge in Resource::Manager units.
int value_type
The type used to hold a consumption charge.
An endpoint that consumes resources.
Consumer newInboundEndpoint(beast::IP::Endpoint const &address)
Consumer newOutboundEndpoint(beast::IP::Endpoint const &address)
void acquire(Entry &entry)
std::recursive_mutex lock_
int balance(Entry &entry)
EntryIntrusiveList inbound_
void release(Entry &entry)
void erase(Table::iterator iter)
Consumer newUnlimitedEndpoint(beast::IP::Endpoint const &address)
Create endpoint that should not have resource limits applied.
EntryIntrusiveList admin_
void writeList(clock_type::time_point const now, beast::PropertyStream::Set &items, EntryIntrusiveList &list)
Disposition charge(Entry &entry, Charge const &fee, std::string context={})
void importConsumers(std::string const &origin, Gossip const &gossip)
static Disposition disposition(int balance)
EntryIntrusiveList outbound_
void onWrite(beast::PropertyStream::Map &map)
EntryIntrusiveList inactive_
bool disconnect(Entry &entry)
Json::Value getJson(int threshold)
Returns a Json::objectValue.
Logic(beast::insight::Collector::ptr const &collector, clock_type &clock, beast::Journal journal)
@ objectValue
object value (collection of name/value pairs).
Disposition
The disposition of a consumer after applying a load charge.
@ warn
Consumer should be disconnected for excess consumption.
std::chrono::seconds constexpr gossipExpirationSeconds
std::chrono::seconds constexpr secondsUntilExpiration
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
beast::abstract_clock< std::chrono::steady_clock > Stopwatch
A clock for measuring elapsed time.
Describes a single consumer.
beast::IP::Endpoint address
Data format for exchanging consumption information across peers.
std::vector< Item > items
A set of imported consumer data from a gossip origin.
Stats(beast::insight::Collector::ptr const &collector)
beast::insight::Meter warn
beast::insight::Meter drop