xrpld
Loading...
Searching...
No Matches
LedgerDiff.cpp
1#include <xrpld/rpc/Context.h>
2#include <xrpld/rpc/GRPCHandlers.h>
3#include <xrpld/rpc/detail/RPCLedgerHelpers.h>
4
5#include <xrpl/beast/utility/instrumentation.h>
6#include <xrpl/ledger/Ledger.h>
7#include <xrpl/shamap/SHAMap.h>
8
9#include <grpcpp/support/status.h>
10#include <org/xrpl/rpc/v1/get_ledger_diff.pb.h>
11
12#include <limits>
13#include <memory>
14#include <utility>
15
16namespace xrpl {
17std::pair<org::xrpl::rpc::v1::GetLedgerDiffResponse, grpc::Status>
19{
20 org::xrpl::rpc::v1::GetLedgerDiffRequest const& request = context.params;
21 org::xrpl::rpc::v1::GetLedgerDiffResponse response;
22 grpc::Status const status = grpc::Status::OK;
23
25 std::shared_ptr<ReadView const> desiredLedgerRv;
26
27 if (RPC::ledgerFromSpecifier(baseLedgerRv, request.base_ledger(), context))
28 {
29 grpc::Status const errorStatus{grpc::StatusCode::NOT_FOUND, "base ledger not found"};
30 return {response, errorStatus};
31 }
32
33 if (RPC::ledgerFromSpecifier(desiredLedgerRv, request.desired_ledger(), context))
34 {
35 grpc::Status const errorStatus{grpc::StatusCode::NOT_FOUND, "desired ledger not found"};
36 return {response, errorStatus};
37 }
38
39 std::shared_ptr<Ledger const> const baseLedger =
41 if (!baseLedger)
42 {
43 grpc::Status const errorStatus{grpc::StatusCode::NOT_FOUND, "base ledger not validated"};
44 return {response, errorStatus};
45 }
46
47 std::shared_ptr<Ledger const> const desiredLedger =
49 if (!desiredLedger)
50 {
51 grpc::Status const errorStatus{grpc::StatusCode::NOT_FOUND, "desired ledger not validated"};
52 return {response, errorStatus};
53 }
54
55 SHAMap::Delta differences;
56
57 int const maxDifferences = std::numeric_limits<int>::max();
58
59 bool const res =
60 baseLedger->stateMap().compare(desiredLedger->stateMap(), differences, maxDifferences);
61 if (!res)
62 {
63 grpc::Status const errorStatus{
64 grpc::StatusCode::RESOURCE_EXHAUSTED, "too many differences between specified ledgers"};
65 return {response, errorStatus};
66 }
67
68 for (auto& [k, v] : differences)
69 {
70 auto diff = response.mutable_ledger_objects()->add_objects();
71 auto inBase = v.first;
72 auto inDesired = v.second;
73
74 // key does not exist in desired
75 if (!inDesired)
76 {
77 diff->set_key(k.data(), k.size());
78 }
79 else
80 {
81 XRPL_ASSERT(inDesired->size() > 0, "xrpl::doLedgerDiffGrpc : non-empty desired");
82 diff->set_key(k.data(), k.size());
83 if (request.include_blobs())
84 {
85 diff->set_data(inDesired->data(), inDesired->size());
86 }
87 }
88 }
89 return {response, status};
90}
91
92} // namespace xrpl
std::map< uint256, DeltaItem > Delta
Definition SHAMap.h:104
T max(T... args)
Status ledgerFromSpecifier(T &ledger, org::xrpl::rpc::v1::LedgerSpecifier const &specifier, Context const &context)
Retrieves a ledger based on a LedgerSpecifier.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
std::pair< org::xrpl::rpc::v1::GetLedgerDiffResponse, grpc::Status > doLedgerDiffGrpc(RPC::GRPCContext< org::xrpl::rpc::v1::GetLedgerDiffRequest > &context)
T dynamic_pointer_cast(T... args)
RequestType params
Definition Context.h:51