xrpld
Toggle main menu visibility
Loading...
Searching...
No Matches
xrpld
rpc
detail
DeliveredAmount.cpp
1
#include <xrpld/rpc/DeliveredAmount.h>
2
3
#include <xrpld/app/ledger/LedgerMaster.h>
4
#include <xrpld/app/misc/Transaction.h>
5
#include <xrpld/rpc/Context.h>
6
7
#include <xrpl/basics/chrono.h>
8
#include <xrpl/protocol/Protocol.h>
9
#include <xrpl/protocol/SField.h>
10
#include <xrpl/protocol/STAmount.h>
11
#include <xrpl/protocol/TER.h>
12
#include <xrpl/protocol/TxFormats.h>
13
#include <xrpl/protocol/jss.h>
14
15
#include <
chrono
>
16
#include <
memory
>
17
#include <
optional
>
18
19
namespace
xrpl::rpc
{
20
21
/*
22
GetLedgerIndex and GetCloseTime are lambdas that allow the close time and
23
ledger index to be lazily calculated. Without these lambdas, these values
24
would be calculated even when not needed, and in some circumstances they are
25
not trivial to compute.
26
27
GetLedgerIndex is a callable that returns a LedgerIndex
28
GetCloseTime is a callable that returns a
29
std::optional<NetClock::time_point>
30
*/
31
template
<
class
GetLedgerIndex,
class
GetCloseTime>
32
std::optional<STAmount>
33
getDeliveredAmount
(
34
GetLedgerIndex
const
& getLedgerIndex,
35
GetCloseTime
const
& getCloseTime,
36
std::shared_ptr<STTx const>
const
& serializedTx,
37
TxMeta
const
& transactionMeta)
38
{
39
if
(!serializedTx)
40
return
{};
41
42
if
(
auto
const
& deliveredAmount = transactionMeta.
getDeliveredAmount
();
43
deliveredAmount.has_value())
44
{
45
return
deliveredAmount;
46
}
47
48
if
(serializedTx->isFieldPresent(sfAmount))
49
{
50
using namespace
std::chrono_literals;
51
52
// Ledger 4594095 is the first ledger in which the DeliveredAmount field
53
// was present when a partial payment was made and its absence indicates
54
// that the amount delivered is listed in the Amount field.
55
//
56
// If the ledger closed long after the DeliveredAmount code was deployed
57
// then its absence indicates that the amount delivered is listed in the
58
// Amount field. DeliveredAmount went live January 24, 2014.
59
// 446000000 is in Feb 2014, well after DeliveredAmount went live
60
if
(getLedgerIndex() >= 4594095 || getCloseTime() >
NetClock::time_point
{446000000s})
61
{
62
return
serializedTx->getFieldAmount(sfAmount);
63
}
64
}
65
66
return
{};
67
}
68
69
// Returns true if transaction meta could contain a delivered amount field,
70
// based on transaction type and transaction result
71
bool
72
canHaveDeliveredAmount
(
73
std::shared_ptr<STTx const>
const
& serializedTx,
74
TxMeta
const
& transactionMeta)
75
{
76
if
(!serializedTx)
77
return
false
;
78
79
TxType
const
tt{serializedTx->getTxnType()};
80
// Transaction type should be ttPAYMENT, ttACCOUNT_DELETE or ttCHECK_CASH
81
// and if the transaction failed nothing could have been delivered.
82
return
(tt == ttPAYMENT || tt == ttCHECK_CASH || tt == ttACCOUNT_DELETE) &&
83
transactionMeta.
getResultTER
() ==
tesSUCCESS
;
84
}
85
86
void
87
insertDeliveredAmount
(
88
json::Value
& meta,
89
ReadView
const
& ledger,
90
std::shared_ptr<STTx const>
const
& serializedTx,
91
TxMeta
const
& transactionMeta)
92
{
93
auto
const
info = ledger.
header
();
94
95
if
(
canHaveDeliveredAmount
(serializedTx, transactionMeta))
96
{
97
auto
const
getLedgerIndex = [&info] {
return
info.seq; };
98
auto
const
getCloseTime = [&info] {
return
info.closeTime; };
99
100
auto
amt =
getDeliveredAmount
(getLedgerIndex, getCloseTime, serializedTx, transactionMeta);
101
if
(amt)
102
{
103
meta[jss::delivered_amount] = amt->getJson(
JsonOptions::Values::IncludeDate
);
104
}
105
else
106
{
107
// report "unavailable" which cannot be parsed into a sensible
108
// amount.
109
meta[jss::delivered_amount] =
json::Value
(
"unavailable"
);
110
}
111
}
112
}
113
114
template
<
class
GetLedgerIndex>
115
static
std::optional<STAmount>
116
getDeliveredAmount
(
117
rpc::Context
const
& context,
118
std::shared_ptr<STTx const>
const
& serializedTx,
119
TxMeta
const
& transactionMeta,
120
GetLedgerIndex
const
& getLedgerIndex)
121
{
122
if
(
canHaveDeliveredAmount
(serializedTx, transactionMeta))
123
{
124
auto
const
getCloseTime = [&context,
125
&getLedgerIndex]() ->
std::optional<NetClock::time_point>
{
126
return
context.
ledgerMaster
.
getCloseTimeBySeq
(getLedgerIndex());
127
};
128
return
getDeliveredAmount
(getLedgerIndex, getCloseTime, serializedTx, transactionMeta);
129
}
130
131
return
{};
132
}
133
134
std::optional<STAmount>
135
getDeliveredAmount
(
136
rpc::Context
const
& context,
137
std::shared_ptr<STTx const>
const
& serializedTx,
138
TxMeta
const
& transactionMeta,
139
LedgerIndex
const
& ledgerIndex)
140
{
141
return
getDeliveredAmount
(
142
context, serializedTx, transactionMeta, [&ledgerIndex]() {
return
ledgerIndex; });
143
}
144
145
void
146
insertDeliveredAmount
(
147
json::Value
& meta,
148
rpc::JsonContext
const
& context,
149
std::shared_ptr<Transaction>
const
& transaction,
150
TxMeta
const
& transactionMeta)
151
{
152
insertDeliveredAmount
(meta, context, transaction->getSTransaction(), transactionMeta);
153
}
154
155
void
156
insertDeliveredAmount
(
157
json::Value
& meta,
158
rpc::JsonContext
const
& context,
159
std::shared_ptr<STTx const>
const
& transaction,
160
TxMeta
const
& transactionMeta)
161
{
162
if
(
canHaveDeliveredAmount
(transaction, transactionMeta))
163
{
164
auto
amt =
getDeliveredAmount
(context, transaction, transactionMeta, [&transactionMeta]() {
165
return
transactionMeta.
getLgrSeq
();
166
});
167
168
if
(amt)
169
{
170
meta[jss::delivered_amount] = amt->getJson(
JsonOptions::Values::IncludeDate
);
171
}
172
else
173
{
174
// report "unavailable" which cannot be parsed into a sensible
175
// amount.
176
meta[jss::delivered_amount] =
json::Value
(
"unavailable"
);
177
}
178
}
179
}
180
181
}
// namespace xrpl::rpc
chrono
json::Value
Represents a JSON value.
Definition
json_value.h:117
xrpl::LedgerMaster::getCloseTimeBySeq
std::optional< NetClock::time_point > getCloseTimeBySeq(LedgerIndex ledgerIndex)
Definition
LedgerMaster.cpp:1659
xrpl::NetClock::time_point
std::chrono::time_point< NetClock > time_point
Definition
chrono.h:48
xrpl::ReadView
A view into a ledger.
Definition
ReadView.h:41
xrpl::ReadView::header
virtual LedgerHeader const & header() const =0
Returns information about the ledger.
xrpl::TxMeta
Definition
TxMeta.h:26
xrpl::TxMeta::getResultTER
TER getResultTER() const
Definition
TxMeta.h:48
xrpl::TxMeta::getDeliveredAmount
std::optional< STAmount > const & getDeliveredAmount() const
Definition
TxMeta.h:103
xrpl::TxMeta::getLgrSeq
std::uint32_t getLgrSeq() const
Definition
TxMeta.h:38
memory
xrpl::rpc
API version numbers used in later API versions.
Definition
ApiVersion.h:36
xrpl::rpc::insertDeliveredAmount
void insertDeliveredAmount(json::Value &meta, ReadView const &, std::shared_ptr< STTx const > const &serializedTx, TxMeta const &)
Add a delivered_amount field to the meta input/output parameter.
Definition
DeliveredAmount.cpp:87
xrpl::rpc::canHaveDeliveredAmount
bool canHaveDeliveredAmount(std::shared_ptr< STTx const > const &serializedTx, TxMeta const &transactionMeta)
Definition
DeliveredAmount.cpp:72
xrpl::rpc::getDeliveredAmount
std::optional< STAmount > getDeliveredAmount(rpc::Context const &context, std::shared_ptr< STTx const > const &serializedTx, TxMeta const &transactionMeta, LedgerIndex const &ledgerIndex)
Definition
DeliveredAmount.cpp:135
xrpl::TxType
TxType
Transaction type identifiers.
Definition
TxFormats.h:45
xrpl::LedgerIndex
std::uint32_t LedgerIndex
A ledger index.
Definition
Protocol.h:382
xrpl::tesSUCCESS
@ tesSUCCESS
Definition
TER.h:250
optional
std::shared_ptr
xrpl::JsonOptions::Values::IncludeDate
@ IncludeDate
Definition
STBase.h:28
xrpl::rpc::Context
The context of information needed to call an RPC.
Definition
Context.h:27
xrpl::rpc::Context::ledgerMaster
LedgerMaster & ledgerMaster
Definition
Context.h:32
xrpl::rpc::JsonContext
Definition
Context.h:41
Generated by
1.17.0