mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-19 02:25:52 +00:00
Add 'delivered_amount' to Transaction JSON (RIPD-643):
The synthetic field 'delivered_amount' can be used to determine the exact amount delivered by a Payment without having to check the DeliveredAmount field, if present, or the Amount field otherwise. The field is only returned when metadata is available and the data is not returned in binary format.
This commit is contained in:
@@ -3090,6 +3090,9 @@
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\src\ripple\rpc\impl\Tuning.h">
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\rpc\impl\Utilities.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\rpc\impl\WriteJson.cpp">
|
||||
<ExcludedFromBuild>True</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
|
||||
@@ -4194,6 +4194,9 @@
|
||||
<ClInclude Include="..\..\src\ripple\rpc\impl\Tuning.h">
|
||||
<Filter>ripple\rpc\impl</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="..\..\src\ripple\rpc\impl\Utilities.cpp">
|
||||
<Filter>ripple\rpc\impl</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\ripple\rpc\impl\WriteJson.cpp">
|
||||
<Filter>ripple\rpc\impl</Filter>
|
||||
</ClCompile>
|
||||
|
||||
@@ -68,6 +68,7 @@ JSS ( converge_time_s );
|
||||
JSS ( currency );
|
||||
JSS ( data );
|
||||
JSS ( date );
|
||||
JSS ( delivered_amount );
|
||||
JSS ( engine_result );
|
||||
JSS ( engine_result_code );
|
||||
JSS ( engine_result_message );
|
||||
|
||||
@@ -110,15 +110,15 @@ Json::Value doAccountTx (RPC::Context& context)
|
||||
{
|
||||
Json::Value& jvObj = jvTxns.append (Json::objectValue);
|
||||
|
||||
std::uint32_t uLedgerIndex = std::get<2> (it);
|
||||
jvObj["tx_blob"] = std::get<0> (it);
|
||||
jvObj["meta"] = std::get<1> (it);
|
||||
jvObj["ledger_index"] = uLedgerIndex;
|
||||
jvObj[jss::validated]
|
||||
= bValidated
|
||||
&& uValidatedMin <= uLedgerIndex
|
||||
&& uValidatedMax >= uLedgerIndex;
|
||||
|
||||
std::uint32_t uLedgerIndex = std::get<2> (it);
|
||||
|
||||
jvObj["ledger_index"] = uLedgerIndex;
|
||||
jvObj[jss::validated] = bValidated &&
|
||||
uValidatedMin <= uLedgerIndex &&
|
||||
uValidatedMax >= uLedgerIndex;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -136,13 +136,15 @@ Json::Value doAccountTx (RPC::Context& context)
|
||||
|
||||
if (it.second)
|
||||
{
|
||||
auto meta = it.second->getJson (1);
|
||||
addPaymentDeliveredAmount (meta, context, it.first, it.second);
|
||||
jvObj[jss::meta] = meta;
|
||||
|
||||
std::uint32_t uLedgerIndex = it.second->getLgrSeq ();
|
||||
|
||||
jvObj[jss::meta] = it.second->getJson (0);
|
||||
jvObj[jss::validated]
|
||||
= bValidated
|
||||
&& uValidatedMin <= uLedgerIndex
|
||||
&& uValidatedMax >= uLedgerIndex;
|
||||
jvObj[jss::validated] = bValidated &&
|
||||
uValidatedMin <= uLedgerIndex &&
|
||||
uValidatedMax >= uLedgerIndex;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
|
||||
namespace ripple {
|
||||
|
||||
// {
|
||||
@@ -31,60 +30,53 @@ Json::Value doTx (RPC::Context& context)
|
||||
bool binary = context.params.isMember (jss::binary)
|
||||
&& context.params[jss::binary].asBool ();
|
||||
|
||||
std::string strTransaction = context.params[jss::transaction].asString ();
|
||||
auto const txid = context.params[jss::transaction].asString ();
|
||||
|
||||
if (Transaction::isHexTxID (strTransaction))
|
||||
if (!Transaction::isHexTxID (txid))
|
||||
return rpcError (rpcNOT_IMPL);
|
||||
|
||||
auto txn = getApp().getMasterTransaction ().fetch (uint256 (txid), true);
|
||||
|
||||
if (!txn)
|
||||
return rpcError (rpcTXN_NOT_FOUND);
|
||||
|
||||
Json::Value ret = txn->getJson (1, binary);
|
||||
|
||||
if (txn->getLedger () == 0)
|
||||
return ret;
|
||||
|
||||
if (auto lgr = context.netOps.getLedgerBySeq (txn->getLedger ()))
|
||||
{
|
||||
// transaction by ID
|
||||
uint256 txid (strTransaction);
|
||||
bool okay = false;
|
||||
|
||||
auto txn = getApp().getMasterTransaction ().fetch (txid, true);
|
||||
|
||||
if (!txn)
|
||||
return rpcError (rpcTXN_NOT_FOUND);
|
||||
|
||||
#ifdef READY_FOR_NEW_TX_FORMAT
|
||||
// TODO(tom): what new format is this?
|
||||
Json::Value ret;
|
||||
ret[jss::transaction] = txn->getJson (1, binary);
|
||||
#else
|
||||
Json::Value ret = txn->getJson (1, binary);
|
||||
#endif
|
||||
|
||||
if (txn->getLedger () != 0)
|
||||
if (binary)
|
||||
{
|
||||
if (auto lgr = context.netOps.getLedgerBySeq (txn->getLedger ()))
|
||||
std::string meta;
|
||||
|
||||
if (lgr->getMetaHex (txn->getID (), meta))
|
||||
{
|
||||
bool okay = false;
|
||||
if (binary)
|
||||
{
|
||||
std::string meta;
|
||||
ret[jss::meta] = meta;
|
||||
okay = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TransactionMetaSet::pointer txMeta;
|
||||
|
||||
if (lgr->getMetaHex (txid, meta))
|
||||
{
|
||||
ret[jss::meta] = meta;
|
||||
okay = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TransactionMetaSet::pointer set;
|
||||
if (lgr->getTransactionMeta (txid, set))
|
||||
{
|
||||
okay = true;
|
||||
ret[jss::meta] = set->getJson (0);
|
||||
}
|
||||
}
|
||||
|
||||
if (okay)
|
||||
ret[jss::validated] = context.netOps.isValidated (lgr);
|
||||
if (lgr->getTransactionMeta (txn->getID (), txMeta))
|
||||
{
|
||||
okay = true;
|
||||
auto meta = txMeta->getJson (0);
|
||||
addPaymentDeliveredAmount (meta, context, txn, txMeta);
|
||||
ret[jss::meta] = meta;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
if (okay)
|
||||
ret[jss::validated] = context.netOps.isValidated (lgr);
|
||||
}
|
||||
|
||||
return rpcError (rpcNOT_IMPL);
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // ripple
|
||||
|
||||
75
src/ripple/rpc/impl/Utilities.cpp
Normal file
75
src/ripple/rpc/impl/Utilities.cpp
Normal file
@@ -0,0 +1,75 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
This file is part of rippled: https://github.com/ripple/rippled
|
||||
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include "boost/date_time/posix_time/posix_time.hpp"
|
||||
#include <utility>
|
||||
|
||||
namespace ripple {
|
||||
namespace RPC {
|
||||
|
||||
void
|
||||
addPaymentDeliveredAmount (
|
||||
Json::Value& meta,
|
||||
RPC::Context& context,
|
||||
Transaction::pointer transaction,
|
||||
TransactionMetaSet::pointer transactionMeta)
|
||||
{
|
||||
STTx::pointer serializedTx;
|
||||
|
||||
if (transaction)
|
||||
serializedTx = transaction->getSTransaction ();
|
||||
|
||||
if (serializedTx && serializedTx->getTxnType () == ttPAYMENT)
|
||||
{
|
||||
// If the transaction explicitly specifies a DeliveredAmount in the
|
||||
// metadata then we use it.
|
||||
if (transactionMeta && transactionMeta->hasDeliveredAmount ())
|
||||
{
|
||||
meta[jss::delivered_amount] =
|
||||
transactionMeta->getDeliveredAmount ().getJson (1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (auto ledger = context.netOps.getLedgerBySeq (transaction->getLedger ()))
|
||||
{
|
||||
// The first ledger where the DeliveredAmount flag appears is
|
||||
// which closed on 2014-Jan-24 at 04:50:10. If the transaction we
|
||||
// are dealing with is in a ledger that closed after this date then
|
||||
// the absence of DeliveredAmount indicates that the correct amount
|
||||
// is in the Amount field.
|
||||
|
||||
boost::posix_time::ptime const cutoff (
|
||||
boost::posix_time::time_from_string ("2014-01-24 04:50:10"));
|
||||
|
||||
if (ledger->getCloseTime () >= cutoff)
|
||||
{
|
||||
meta[jss::delivered_amount] =
|
||||
serializedTx->getFieldAmount (sfAmount).getJson (1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise we report "unavailable" which cannot be parsed into a
|
||||
// sensible amount.
|
||||
meta[jss::delivered_amount] = Json::Value ("unavailable");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <ripple/rpc/impl/RPCHandler.cpp>
|
||||
#include <ripple/rpc/impl/Status.cpp>
|
||||
#include <ripple/rpc/impl/Yield.cpp>
|
||||
#include <ripple/rpc/impl/Utilities.cpp>
|
||||
|
||||
#include <ripple/rpc/handlers/Handlers.h>
|
||||
#include <ripple/rpc/handlers/AccountCurrencies.cpp>
|
||||
|
||||
Reference in New Issue
Block a user