rippled
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 <ripple/app/main/Application.h>
21 #include <ripple/app/misc/LoadFeeTrack.h>
22 #include <ripple/app/paths/TrustLine.h>
23 #include <ripple/ledger/ReadView.h>
24 #include <ripple/net/RPCErr.h>
25 #include <ripple/protocol/ErrorCodes.h>
26 #include <ripple/protocol/TxFlags.h>
27 #include <ripple/protocol/jss.h>
28 #include <ripple/rpc/Context.h>
29 #include <ripple/rpc/impl/RPCHelpers.h>
30 #include <ripple/rpc/impl/Tuning.h>
31 
32 namespace ripple {
33 
34 static 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  bool roleGateway = false;
70  {
71  std::string const role = params["role"].asString();
72  if (role == "gateway")
73  roleGateway = true;
74  else if (role != "user")
75  return RPC::invalid_field_error("role");
76  }
77 
78  unsigned int limit;
79  if (auto err = readLimitField(limit, RPC::Tuning::noRippleCheck, context))
80  return *err;
81 
82  bool transactions = false;
83  if (params.isMember(jss::transactions))
84  transactions = params["transactions"].asBool();
85 
86  // The document[https://xrpl.org/noripple_check.html#noripple_check] states
87  // that transactions params is a boolean value, however, assigning any
88  // string value works. Do not allow this. This check is for api Version 2
89  // onwards only
90  if (context.apiVersion > 1u && params.isMember(jss::transactions) &&
91  !params[jss::transactions].isBool())
92  {
94  }
95 
97  auto result = RPC::lookupLedger(ledger, context);
98  if (!ledger)
99  return result;
100 
101  Json::Value dummy;
102  Json::Value& jvTransactions =
103  transactions ? (result[jss::transactions] = Json::arrayValue) : dummy;
104 
105  auto id = parseBase58<AccountID>(params[jss::account].asString());
106  if (!id)
107  {
109  return result;
110  }
111  auto const accountID{std::move(id.value())};
112  auto const sle = ledger->read(keylet::account(accountID));
113  if (!sle)
114  return rpcError(rpcACT_NOT_FOUND);
115 
116  std::uint32_t seq = sle->getFieldU32(sfSequence);
117 
118  Json::Value& problems = (result["problems"] = Json::arrayValue);
119 
120  bool bDefaultRipple = sle->getFieldU32(sfFlags) & lsfDefaultRipple;
121 
122  if (bDefaultRipple & !roleGateway)
123  {
124  problems.append(
125  "You appear to have set your default ripple flag even though you "
126  "are not a gateway. This is not recommended unless you are "
127  "experimenting");
128  }
129  else if (roleGateway & !bDefaultRipple)
130  {
131  problems.append("You should immediately set your default ripple flag");
132  if (transactions)
133  {
134  Json::Value& tx = jvTransactions.append(Json::objectValue);
135  tx["TransactionType"] = jss::AccountSet;
136  tx["SetFlag"] = 8;
137  fillTransaction(context, tx, accountID, seq, *ledger);
138  }
139  }
140 
142  *ledger,
143  accountID,
144  uint256(),
145  0,
146  limit,
147  [&](std::shared_ptr<SLE const> const& ownedItem) {
148  if (ownedItem->getType() == ltRIPPLE_STATE)
149  {
150  bool const bLow = accountID ==
151  ownedItem->getFieldAmount(sfLowLimit).getIssuer();
152 
153  bool const bNoRipple = ownedItem->getFieldU32(sfFlags) &
154  (bLow ? lsfLowNoRipple : lsfHighNoRipple);
155 
156  std::string problem;
157  bool needFix = false;
158  if (bNoRipple & roleGateway)
159  {
160  problem = "You should clear the no ripple flag on your ";
161  needFix = true;
162  }
163  else if (!roleGateway & !bNoRipple)
164  {
165  problem =
166  "You should probably set the no ripple flag on your ";
167  needFix = true;
168  }
169  if (needFix)
170  {
171  AccountID peer =
172  ownedItem
174  .getIssuer();
175  STAmount peerLimit = ownedItem->getFieldAmount(
176  bLow ? sfHighLimit : sfLowLimit);
177  problem += to_string(peerLimit.getCurrency());
178  problem += " line to ";
179  problem += to_string(peerLimit.getIssuer());
180  problems.append(problem);
181 
182  STAmount limitAmount(ownedItem->getFieldAmount(
183  bLow ? sfLowLimit : sfHighLimit));
184  limitAmount.setIssuer(peer);
185 
186  Json::Value& tx = jvTransactions.append(Json::objectValue);
187  tx["TransactionType"] = jss::TrustSet;
188  tx["LimitAmount"] = limitAmount.getJson(JsonOptions::none);
189  tx["Flags"] = bNoRipple ? tfClearNoRipple : tfSetNoRipple;
190  fillTransaction(context, tx, accountID, seq, *ledger);
191 
192  return true;
193  }
194  }
195  return false;
196  });
197 
198  return result;
199 }
200 
201 } // namespace ripple
ripple::RPC::Tuning::noRippleCheck
static constexpr LimitRange noRippleCheck
Limits for the no_ripple_check command.
Definition: rpc/impl/Tuning.h:52
ripple::RPC::JsonContext
Definition: Context.h:53
std::string
STL class.
std::shared_ptr
STL class.
ripple::rpcINVALID_PARAMS
@ rpcINVALID_PARAMS
Definition: ErrorCodes.h:84
ripple::rpcError
Json::Value rpcError(int iError)
Definition: RPCErr.cpp:29
ripple::forEachItemAfter
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:411
Json::arrayValue
@ arrayValue
array value (ordered list)
Definition: json_value.h:42
ripple::sfSequence
const SF_UINT32 sfSequence
Json::UInt
unsigned int UInt
Definition: json_forwards.h:27
ripple::tfSetNoRipple
constexpr std::uint32_t tfSetNoRipple
Definition: TxFlags.h:110
ripple::ReadView::fees
virtual Fees const & fees() const =0
Returns the fees for the base ledger.
ripple::STAmount::getJson
Json::Value getJson(JsonOptions) const override
Definition: STAmount.cpp:653
ripple::toBase58
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
Definition: AccountID.cpp:104
ripple::STAmount::setIssuer
void setIssuer(AccountID const &uIssuer)
Definition: STAmount.h:436
ripple::RPC::lookupLedger
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
ripple::Application::getFeeTrack
virtual LoadFeeTrack & getFeeTrack()=0
ripple::STAmount::getIssuer
AccountID const & getIssuer() const
Definition: STAmount.h:362
ripple::uint256
base_uint< 256 > uint256
Definition: base_uint.h:550
ripple::RPC::missing_field_error
Json::Value missing_field_error(std::string const &name)
Definition: ErrorCodes.h:264
ripple::fillTransaction
static void fillTransaction(RPC::JsonContext &context, Json::Value &txArray, AccountID const &accountID, std::uint32_t &sequence, ReadView const &ledger)
Definition: NoRippleCheck.cpp:35
ripple::base_uint
Integers of any length that is a multiple of 32-bits.
Definition: base_uint.h:82
ripple::sfLowLimit
const SF_AMOUNT sfLowLimit
ripple::lsfDefaultRipple
@ lsfDefaultRipple
Definition: LedgerFormats.h:263
Json::Value::append
Value & append(const Value &value)
Append value to array at the end.
Definition: json_value.cpp:882
Json::objectValue
@ objectValue
object value (collection of name/value pairs).
Definition: json_value.h:43
ripple::keylet::account
Keylet account(AccountID const &id) noexcept
AccountID root.
Definition: Indexes.cpp:142
ripple::rpcACT_NOT_FOUND
@ rpcACT_NOT_FOUND
Definition: ErrorCodes.h:70
ripple::STAmount
Definition: STAmount.h:46
ripple::RPC::Context::app
Application & app
Definition: Context.h:42
ripple::tfClearNoRipple
constexpr std::uint32_t tfClearNoRipple
Definition: TxFlags.h:111
ripple::doNoRippleCheck
Json::Value doNoRippleCheck(RPC::JsonContext &)
Definition: NoRippleCheck.cpp:61
std::uint32_t
ripple::sfHighLimit
const SF_AMOUNT sfHighLimit
ripple::STLedgerEntry::getType
LedgerEntryType getType() const
Definition: STLedgerEntry.h:119
ripple::ReadView::read
virtual std::shared_ptr< SLE const > read(Keylet const &k) const =0
Return the state item associated with a key.
ripple::ReadView
A view into a ledger.
Definition: ReadView.h:54
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::JsonOptions::none
@ none
Definition: STBase.h:42
ripple::rpcACT_MALFORMED
@ rpcACT_MALFORMED
Definition: ErrorCodes.h:90
ripple::sfFlags
const SF_UINT32 sfFlags
ripple::RPC::Context::apiVersion
unsigned int apiVersion
Definition: Context.h:50
ripple::to_string
std::string to_string(Manifest const &m)
Format the specified manifest to a string for debugging purposes.
Definition: app/misc/impl/Manifest.cpp:41
ripple::scaleFeeLoad
XRPAmount scaleFeeLoad(XRPAmount fee, LoadFeeTrack const &feeTrack, Fees const &fees, bool bUnlimited)
Definition: LoadFeeTrack.cpp:89
ripple::ltRIPPLE_STATE
@ ltRIPPLE_STATE
A ledger object which describes a bidirectional trust line.
Definition: LedgerFormats.h:74
ripple::RPC::JsonContext::params
Json::Value params
Definition: Context.h:64
ripple::STAmount::getCurrency
Currency const & getCurrency() const
Definition: STAmount.h:356
ripple::RPC::inject_error
void inject_error(error_code_i code, JsonValue &json)
Add or update the json update to reflect the error code.
Definition: ErrorCodes.h:214
ripple::RPC::invalid_field_error
Json::Value invalid_field_error(std::string const &name)
Definition: ErrorCodes.h:306
ripple::STObject::getFieldAmount
STAmount const & getFieldAmount(SField const &field) const
Definition: STObject.cpp:603
ripple::XRPAmount::jsonClipped
Json::Value jsonClipped() const
Definition: XRPAmount.h:209
Json::Value
Represents a JSON value.
Definition: json_value.h:145