rippled
Loading...
Searching...
No Matches
NoRippleCheck.cpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2012-2014 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#include <xrpld/app/main/Application.h>
21#include <xrpld/app/misc/LoadFeeTrack.h>
22#include <xrpld/app/paths/TrustLine.h>
23#include <xrpld/ledger/ReadView.h>
24#include <xrpld/rpc/Context.h>
25#include <xrpld/rpc/detail/RPCHelpers.h>
26#include <xrpld/rpc/detail/Tuning.h>
27#include <xrpl/protocol/ErrorCodes.h>
28#include <xrpl/protocol/RPCErr.h>
29#include <xrpl/protocol/TxFlags.h>
30#include <xrpl/protocol/jss.h>
31
32namespace ripple {
33
34static void
36 RPC::JsonContext& context,
37 Json::Value& txArray,
38 AccountID const& accountID,
39 std::uint32_t& sequence,
40 ReadView const& ledger)
41{
42 txArray["Sequence"] = Json::UInt(sequence++);
43 txArray["Account"] = toBase58(accountID);
44 auto& fees = ledger.fees();
45 // Convert the reference transaction cost in fee units to drops
46 // scaled to represent the current fee load.
47 txArray["Fee"] =
48 scaleFeeLoad(fees.base, context.app.getFeeTrack(), fees, false)
49 .jsonClipped();
50}
51
52// {
53// account: <account>
54// ledger_hash : <ledger>
55// ledger_index : <ledger_index>
56// limit: integer // optional, number of problems
57// role: gateway|user // account role to assume
58// transactions: true // optional, reccommend transactions
59// }
62{
63 auto const& params(context.params);
64 if (!params.isMember(jss::account))
65 return RPC::missing_field_error("account");
66
67 if (!params.isMember("role"))
68 return RPC::missing_field_error("role");
69
70 if (!params[jss::account].isString())
71 return RPC::invalid_field_error(jss::account);
72
73 bool roleGateway = false;
74 {
75 std::string const role = params["role"].asString();
76 if (role == "gateway")
77 roleGateway = true;
78 else if (role != "user")
79 return RPC::invalid_field_error("role");
80 }
81
82 unsigned int limit;
83 if (auto err = readLimitField(limit, RPC::Tuning::noRippleCheck, context))
84 return *err;
85
86 bool transactions = false;
87 if (params.isMember(jss::transactions))
88 transactions = params["transactions"].asBool();
89
90 // The document[https://xrpl.org/noripple_check.html#noripple_check] states
91 // that transactions params is a boolean value, however, assigning any
92 // string value works. Do not allow this. This check is for api Version 2
93 // onwards only
94 if (context.apiVersion > 1u && params.isMember(jss::transactions) &&
95 !params[jss::transactions].isBool())
96 {
97 return RPC::invalid_field_error(jss::transactions);
98 }
99
101 auto result = RPC::lookupLedger(ledger, context);
102 if (!ledger)
103 return result;
104
105 Json::Value dummy;
106 Json::Value& jvTransactions =
107 transactions ? (result[jss::transactions] = Json::arrayValue) : dummy;
108
109 auto id = parseBase58<AccountID>(params[jss::account].asString());
110 if (!id)
111 {
113 return result;
114 }
115 auto const accountID{std::move(id.value())};
116 auto const sle = ledger->read(keylet::account(accountID));
117 if (!sle)
119
120 std::uint32_t seq = sle->getFieldU32(sfSequence);
121
122 Json::Value& problems = (result["problems"] = Json::arrayValue);
123
124 bool bDefaultRipple = sle->getFieldU32(sfFlags) & lsfDefaultRipple;
125
126 if (bDefaultRipple & !roleGateway)
127 {
128 problems.append(
129 "You appear to have set your default ripple flag even though you "
130 "are not a gateway. This is not recommended unless you are "
131 "experimenting");
132 }
133 else if (roleGateway & !bDefaultRipple)
134 {
135 problems.append("You should immediately set your default ripple flag");
136 if (transactions)
137 {
138 Json::Value& tx = jvTransactions.append(Json::objectValue);
139 tx["TransactionType"] = jss::AccountSet;
140 tx["SetFlag"] = 8;
141 fillTransaction(context, tx, accountID, seq, *ledger);
142 }
143 }
144
146 *ledger,
147 accountID,
148 uint256(),
149 0,
150 limit,
151 [&](std::shared_ptr<SLE const> const& ownedItem) {
152 if (ownedItem->getType() == ltRIPPLE_STATE)
153 {
154 bool const bLow = accountID ==
155 ownedItem->getFieldAmount(sfLowLimit).getIssuer();
156
157 bool const bNoRipple = ownedItem->getFieldU32(sfFlags) &
158 (bLow ? lsfLowNoRipple : lsfHighNoRipple);
159
160 std::string problem;
161 bool needFix = false;
162 if (bNoRipple & roleGateway)
163 {
164 problem = "You should clear the no ripple flag on your ";
165 needFix = true;
166 }
167 else if (!roleGateway & !bNoRipple)
168 {
169 problem =
170 "You should probably set the no ripple flag on your ";
171 needFix = true;
172 }
173 if (needFix)
174 {
175 AccountID peer =
176 ownedItem
177 ->getFieldAmount(bLow ? sfHighLimit : sfLowLimit)
178 .getIssuer();
179 STAmount peerLimit = ownedItem->getFieldAmount(
180 bLow ? sfHighLimit : sfLowLimit);
181 problem += to_string(peerLimit.getCurrency());
182 problem += " line to ";
183 problem += to_string(peerLimit.getIssuer());
184 problems.append(problem);
185
186 STAmount limitAmount(ownedItem->getFieldAmount(
187 bLow ? sfLowLimit : sfHighLimit));
188 limitAmount.setIssuer(peer);
189
190 Json::Value& tx = jvTransactions.append(Json::objectValue);
191 tx["TransactionType"] = jss::TrustSet;
192 tx["LimitAmount"] = limitAmount.getJson(JsonOptions::none);
193 tx["Flags"] = bNoRipple ? tfClearNoRipple : tfSetNoRipple;
194 fillTransaction(context, tx, accountID, seq, *ledger);
195
196 return true;
197 }
198 }
199 return false;
200 });
201
202 return result;
203}
204
205} // namespace ripple
Represents a JSON value.
Definition: json_value.h:147
Value & append(const Value &value)
Append value to array at the end.
Definition: json_value.cpp:891
virtual LoadFeeTrack & getFeeTrack()=0
A view into a ledger.
Definition: ReadView.h:55
virtual Fees const & fees() const =0
Returns the fees for the base ledger.
Json::Value getJson(JsonOptions) const override
Definition: STAmount.cpp:604
void setIssuer(AccountID const &uIssuer)
Definition: STAmount.h:569
Currency const & getCurrency() const
Definition: STAmount.h:493
AccountID const & getIssuer() const
Definition: STAmount.h:499
Json::Value jsonClipped() const
Definition: XRPAmount.h:218
@ arrayValue
array value (ordered list)
Definition: json_value.h:42
@ objectValue
object value (collection of name/value pairs).
Definition: json_value.h:43
unsigned int UInt
Definition: json_forwards.h:27
static LimitRange constexpr noRippleCheck
Limits for the no_ripple_check command.
Json::Value invalid_field_error(std::string const &name)
Definition: ErrorCodes.h:315
void inject_error(error_code_i code, JsonValue &json)
Add or update the json update to reflect the error code.
Definition: ErrorCodes.h:223
Status lookupLedger(std::shared_ptr< ReadView const > &ledger, JsonContext &context, Json::Value &result)
Look up a ledger from a request and fill a Json::Result with the data representing a ledger.
Definition: RPCHelpers.cpp:623
Json::Value missing_field_error(std::string const &name)
Definition: ErrorCodes.h:273
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition: Indexes.cpp:160
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
Definition: AccountID.cpp:106
Json::Value doNoRippleCheck(RPC::JsonContext &)
@ rpcACT_NOT_FOUND
Definition: ErrorCodes.h:70
@ rpcACT_MALFORMED
Definition: ErrorCodes.h:90
base_uint< 256 > uint256
Definition: base_uint.h:557
@ lsfDefaultRipple
Json::Value rpcError(int iError)
Definition: RPCErr.cpp:29
constexpr std::uint32_t tfClearNoRipple
Definition: TxFlags.h:114
std::string to_string(base_uint< Bits, Tag > const &a)
Definition: base_uint.h:629
bool forEachItemAfter(ReadView const &view, Keylet const &root, uint256 const &after, std::uint64_t const hint, unsigned int limit, std::function< bool(std::shared_ptr< SLE const > const &)> const &f)
Iterate all items after an item in the given directory.
Definition: View.cpp:572
XRPAmount scaleFeeLoad(XRPAmount fee, LoadFeeTrack const &feeTrack, Fees const &fees, bool bUnlimited)
constexpr std::uint32_t tfSetNoRipple
Definition: TxFlags.h:113
static void fillTransaction(RPC::JsonContext &context, Json::Value &txArray, AccountID const &accountID, std::uint32_t &sequence, ReadView const &ledger)
unsigned int apiVersion
Definition: Context.h:50
Application & app
Definition: Context.h:42
Json::Value params
Definition: Context.h:64