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/RippleState.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"] = context.app.accountIDCache().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.units, context.app.getFeeTrack(), fees, false)
49  .jsonClipped();
50 }
51 
52 // {
53 // account: <account>|<account_public_key>
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 
87  auto result = RPC::lookupLedger(ledger, context);
88  if (!ledger)
89  return result;
90 
91  Json::Value dummy;
92  Json::Value& jvTransactions =
93  transactions ? (result[jss::transactions] = Json::arrayValue) : dummy;
94 
95  std::string strIdent(params[jss::account].asString());
96  AccountID accountID;
97 
98  if (auto jv = RPC::accountFromString(accountID, strIdent))
99  {
100  for (auto it(jv.begin()); it != jv.end(); ++it)
101  result[it.memberName()] = *it;
102 
103  return result;
104  }
105 
106  auto const sle = ledger->read(keylet::account(accountID));
107  if (!sle)
108  return rpcError(rpcACT_NOT_FOUND);
109 
110  std::uint32_t seq = sle->getFieldU32(sfSequence);
111 
112  Json::Value& problems = (result["problems"] = Json::arrayValue);
113 
114  bool bDefaultRipple = sle->getFieldU32(sfFlags) & lsfDefaultRipple;
115 
116  if (bDefaultRipple & !roleGateway)
117  {
118  problems.append(
119  "You appear to have set your default ripple flag even though you "
120  "are not a gateway. This is not recommended unless you are "
121  "experimenting");
122  }
123  else if (roleGateway & !bDefaultRipple)
124  {
125  problems.append("You should immediately set your default ripple flag");
126  if (transactions)
127  {
128  Json::Value& tx = jvTransactions.append(Json::objectValue);
129  tx["TransactionType"] = jss::AccountSet;
130  tx["SetFlag"] = 8;
131  fillTransaction(context, tx, accountID, seq, *ledger);
132  }
133  }
134 
136  *ledger,
137  accountID,
138  uint256(),
139  0,
140  limit,
141  [&](std::shared_ptr<SLE const> const& ownedItem) {
142  if (ownedItem->getType() == ltRIPPLE_STATE)
143  {
144  bool const bLow = accountID ==
145  ownedItem->getFieldAmount(sfLowLimit).getIssuer();
146 
147  bool const bNoRipple = ownedItem->getFieldU32(sfFlags) &
148  (bLow ? lsfLowNoRipple : lsfHighNoRipple);
149 
150  std::string problem;
151  bool needFix = false;
152  if (bNoRipple & roleGateway)
153  {
154  problem = "You should clear the no ripple flag on your ";
155  needFix = true;
156  }
157  else if (!roleGateway & !bNoRipple)
158  {
159  problem =
160  "You should probably set the no ripple flag on your ";
161  needFix = true;
162  }
163  if (needFix)
164  {
165  AccountID peer =
166  ownedItem
168  .getIssuer();
169  STAmount peerLimit = ownedItem->getFieldAmount(
170  bLow ? sfHighLimit : sfLowLimit);
171  problem += to_string(peerLimit.getCurrency());
172  problem += " line to ";
173  problem += to_string(peerLimit.getIssuer());
174  problems.append(problem);
175 
176  STAmount limitAmount(ownedItem->getFieldAmount(
177  bLow ? sfLowLimit : sfHighLimit));
178  limitAmount.setIssuer(peer);
179 
180  Json::Value& tx = jvTransactions.append(Json::objectValue);
181  tx["TransactionType"] = jss::TrustSet;
182  tx["LimitAmount"] = limitAmount.getJson(JsonOptions::none);
183  tx["Flags"] = bNoRipple ? tfClearNoRipple : tfSetNoRipple;
184  fillTransaction(context, tx, accountID, seq, *ledger);
185 
186  return true;
187  }
188  }
189  return false;
190  });
191 
192  return result;
193 }
194 
195 } // 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.
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::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:594
ripple::scaleFeeLoad
XRPAmount scaleFeeLoad(FeeUnit64 fee, LoadFeeTrack const &feeTrack, Fees const &fees, bool bUnlimited)
Definition: LoadFeeTrack.cpp:89
ripple::to_string
std::string to_string(ListDisposition disposition)
Definition: ValidatorList.cpp:45
ripple::STAmount::setIssuer
void setIssuer(AccountID const &uIssuer)
Definition: STAmount.h:303
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:535
ripple::Application::accountIDCache
virtual AccountIDCache const & accountIDCache() const =0
ripple::Application::getFeeTrack
virtual LoadFeeTrack & getFeeTrack()=0
ripple::uint256
base_uint< 256 > uint256
Definition: base_uint.h:457
ripple::RPC::missing_field_error
Json::Value missing_field_error(std::string const &name)
Definition: ErrorCodes.h:243
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< 160, detail::AccountIDTag >
ripple::sfLowLimit
const SF_AMOUNT sfLowLimit
ripple::lsfDefaultRipple
@ lsfDefaultRipple
Definition: LedgerFormats.h:112
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:134
ripple::JsonOptions::none
@ none
ripple::rpcACT_NOT_FOUND
@ rpcACT_NOT_FOUND
Definition: ErrorCodes.h:70
ripple::STAmount
Definition: STAmount.h:42
ripple::RPC::Context::app
Application & app
Definition: Context.h:42
ripple::doNoRippleCheck
Json::Value doNoRippleCheck(RPC::JsonContext &)
Definition: NoRippleCheck.cpp:61
std::uint32_t
ripple::sfHighLimit
const SF_AMOUNT sfHighLimit
ripple::tfClearNoRipple
const std::uint32_t tfClearNoRipple
Definition: TxFlags.h:93
ripple::STLedgerEntry::getType
LedgerEntryType getType() const
Definition: STLedgerEntry.h:92
ripple::rpcError
Json::Value rpcError(int iError, Json::Value jvResult)
Definition: RPCErr.cpp:29
ripple::ReadView::read
virtual std::shared_ptr< SLE const > read(Keylet const &k) const =0
Return the state item associated with a key.
ripple::STAmount::getCurrency
Currency const & getCurrency() const
Definition: STAmount.h:204
ripple::STAmount::getIssuer
AccountID const & getIssuer() const
Definition: STAmount.h:209
ripple::ReadView
A view into a ledger.
Definition: ReadView.h:192
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::ltRIPPLE_STATE
@ ltRIPPLE_STATE
Definition: LedgerFormats.h:66
ripple::tfSetNoRipple
const std::uint32_t tfSetNoRipple
Definition: TxFlags.h:92
ripple::sfFlags
const SF_UINT32 sfFlags
ripple::forEachItemAfter
bool forEachItemAfter(ReadView const &view, AccountID const &id, uint256 const &after, std::uint64_t const hint, unsigned int limit, std::function< bool(std::shared_ptr< SLE const > const &)> f)
Iterate all items after an item in an owner directory.
Definition: View.cpp:277
ripple::RPC::JsonContext::params
Json::Value params
Definition: Context.h:64
ripple::RPC::invalid_field_error
Json::Value invalid_field_error(std::string const &name)
Definition: ErrorCodes.h:285
ripple::STObject::getFieldAmount
STAmount const & getFieldAmount(SField const &field) const
Definition: STObject.cpp:576
ripple::RPC::accountFromString
Json::Value accountFromString(AccountID &result, std::string const &strIdent, bool bStrict)
Definition: RPCHelpers.cpp:82
ripple::XRPAmount::jsonClipped
Json::Value jsonClipped() const
Definition: XRPAmount.h:209
Json::Value
Represents a JSON value.
Definition: json_value.h:145
ripple::AccountIDCache::toBase58
std::string toBase58(AccountID const &) const
Return ripple::toBase58 for the AccountID.
Definition: AccountID.cpp:134