xrpld
Loading...
Searching...
No Matches
InfoSub.cpp
1#include <xrpl/server/InfoSub.h>
2
3#include <xrpl/basics/Log.h>
4#include <xrpl/beast/utility/Journal.h>
5#include <xrpl/beast/utility/instrumentation.h>
6#include <xrpl/protocol/AccountID.h>
7#include <xrpl/protocol/Book.h>
8#include <xrpl/resource/Consumer.h>
9
10#include <cstdint>
11#include <exception>
12#include <memory>
13#include <mutex>
14
15namespace xrpl {
16
17namespace {
18
19// Wraps a Source teardown call so that an exception from one cleanup
20// step does not prevent the subsequent steps from running. Source methods
21// acquire a lock and can throw std::system_error; a throw out of ~InfoSub
22// during stack unwinding would terminate the process. Failures are
23// reported through the Source's Journal so they reach the configured log
24// sinks; JLOG itself cannot throw, so the noexcept guarantee holds.
25template <typename F>
26void
27safeUnsub(std::uint64_t seq, F&& f, beast::Journal j) noexcept
28{
29 try
30 {
31 f();
32 }
33 catch (std::exception const& e)
34 {
35 JLOG(j.warn()) << "~InfoSub[seq=" << seq << "]: cleanup step failed: " << e.what();
36 }
37 catch (...)
38 {
39 JLOG(j.warn()) << "~InfoSub[seq=" << seq << "]: cleanup step failed: unknown exception";
40 }
41}
42
43} // namespace
44
45// This is the primary interface into the "client" portion of the program.
46// Code that wants to do normal operations on the network such as
47// creating and monitoring accounts, creating transactions, and so on
48// should use this interface. The RPC code will primarily be a light wrapper
49// over this code.
50
51// Eventually, it will check the node's operating mode (synced, unsynced,
52// etcetera) and defer to the correct means of processing. The current
53// code assumes this node is synced (and will continue to do so until
54// there's a functional network.
55
57{
58}
59
61 : consumer_(consumer), source_(source), seq_(assignId())
62{
63}
64
66{
67 // Each Source teardown call below acquires a server-side lock and
68 // can throw. Wrap each independent call so partial failure does not
69 // skip the remaining teardown steps.
70
71 auto const& j = source_.journal();
72
73 safeUnsub(seq_, [&] { source_.unsubTransactions(seq_); }, j);
74 safeUnsub(seq_, [&] { source_.unsubRTTransactions(seq_); }, j);
75 safeUnsub(seq_, [&] { source_.unsubLedger(seq_); }, j);
76 safeUnsub(seq_, [&] { source_.unsubManifests(seq_); }, j);
77 safeUnsub(seq_, [&] { source_.unsubServer(seq_); }, j);
78 safeUnsub(seq_, [&] { source_.unsubValidations(seq_); }, j);
79 safeUnsub(seq_, [&] { source_.unsubPeerStatus(seq_); }, j);
80 safeUnsub(seq_, [&] { source_.unsubConsensus(seq_); }, j);
81
82 // Use the internal unsubscribe so that it won't call
83 // back to us and modify its own parameter
84 if (!realTimeSubscriptions_.empty())
85 {
86 safeUnsub(
87 seq_, [&] { source_.unsubAccountInternal(seq_, realTimeSubscriptions_, true); }, j);
88 }
89
90 if (!normalSubscriptions_.empty())
91 {
92 safeUnsub(
93 seq_, [&] { source_.unsubAccountInternal(seq_, normalSubscriptions_, false); }, j);
94 }
95
96 for (auto const& account : accountHistorySubscriptions_)
97 {
98 safeUnsub(seq_, [&] { source_.unsubAccountHistoryInternal(seq_, account, false); }, j);
99 }
100
101 for (auto const& book : bookSubscriptions_)
102 {
103 safeUnsub(seq_, [&] { source_.unsubBookInternal(seq_, book); }, j);
104 }
105}
106
109{
110 return consumer_;
111}
112
115{
116 return seq_;
117}
118
119void
123
124void
126{
127 std::scoped_lock const sl(lock_);
128
129 if (rt)
130 {
131 realTimeSubscriptions_.insert(account);
132 }
133 else
134 {
135 normalSubscriptions_.insert(account);
136 }
137}
138
139void
141{
142 std::scoped_lock const sl(lock_);
143
144 if (rt)
145 {
146 realTimeSubscriptions_.erase(account);
147 }
148 else
149 {
150 normalSubscriptions_.erase(account);
151 }
152}
153
154bool
156{
157 std::scoped_lock const sl(lock_);
158 return accountHistorySubscriptions_.insert(account).second;
159}
160
161void
163{
164 std::scoped_lock const sl(lock_);
165 accountHistorySubscriptions_.erase(account);
166}
167
168void
170{
171 std::scoped_lock const sl(lock_);
172 bookSubscriptions_.insert(book);
173}
174
175void
177{
178 std::scoped_lock const sl(lock_);
179 bookSubscriptions_.erase(book);
180}
181
182void
184{
185 request_.reset();
186}
187
188void
193
196{
197 return request_;
198}
199
200void
201InfoSub::setApiVersion(unsigned int apiVersion)
202{
203 apiVersion_ = apiVersion;
204}
205
206unsigned int
208{
209 XRPL_ASSERT(apiVersion_ > 0, "xrpl::InfoSub::getApiVersion : valid API version");
210 return apiVersion_;
211}
212
213} // namespace xrpl
Specifies an order book.
Definition Book.h:16
Abstracts the source of subscription data.
Definition InfoSub.h:61
void setRequest(std::shared_ptr< InfoSubRequest > const &req)
Definition InfoSub.cpp:189
void insertBookSubscription(Book const &book)
Record that this subscriber is following book.
Definition InfoSub.cpp:169
InfoSub(Source &source)
Definition InfoSub.cpp:56
Resource::Consumer Consumer
Definition InfoSub.h:55
void clearRequest()
Definition InfoSub.cpp:183
Consumer consumer_
Definition InfoSub.h:294
bool insertSubAccountHistory(AccountID const &account)
Definition InfoSub.cpp:155
Consumer & getConsumer()
Definition InfoSub.cpp:108
void setApiVersion(unsigned int apiVersion)
Definition InfoSub.cpp:201
static int assignId()
Definition InfoSub.h:305
virtual ~InfoSub()
Definition InfoSub.cpp:65
std::uint64_t getSeq() const
Definition InfoSub.cpp:114
void insertSubAccountInfo(AccountID const &account, bool rt)
Definition InfoSub.cpp:125
void deleteBookSubscription(Book const &book)
Stop tracking book for this subscriber.
Definition InfoSub.cpp:176
Source & source_
Definition InfoSub.h:295
hash_set< AccountID > accountHistorySubscriptions_
Definition InfoSub.h:300
hash_set< AccountID > normalSubscriptions_
Definition InfoSub.h:297
hash_set< Book > bookSubscriptions_
Definition InfoSub.h:301
hash_set< AccountID > realTimeSubscriptions_
Definition InfoSub.h:296
void deleteSubAccountInfo(AccountID const &account, bool rt)
Definition InfoSub.cpp:140
void deleteSubAccountHistory(AccountID const &account)
Definition InfoSub.cpp:162
unsigned int getApiVersion() const noexcept
Definition InfoSub.cpp:207
std::uint64_t seq_
Definition InfoSub.h:299
std::mutex lock_
Definition InfoSub.h:291
unsigned int apiVersion_
Definition InfoSub.h:302
void onSendEmpty()
Definition InfoSub.cpp:120
std::shared_ptr< InfoSubRequest > const & getRequest()
Definition InfoSub.cpp:195
std::shared_ptr< InfoSubRequest > request_
Definition InfoSub.h:298
An endpoint that consumes resources.
Definition Consumer.h:15
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
BaseUInt< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
Definition AccountID.h:28
T what(T... args)