20 #include <ripple/app/ledger/LedgerMaster.h>
21 #include <ripple/app/ledger/OpenLedger.h>
22 #include <ripple/app/misc/Transaction.h>
23 #include <ripple/ledger/View.h>
24 #include <ripple/net/RPCErr.h>
25 #include <ripple/protocol/AccountID.h>
26 #include <ripple/protocol/Feature.h>
27 #include <ripple/rpc/Context.h>
28 #include <ripple/rpc/DeliveredAmount.h>
29 #include <ripple/rpc/impl/RPCHelpers.h>
30 #include <boost/algorithm/string/case_conv.hpp>
32 #include <ripple/rpc/impl/GRPCHelpers.h>
37 boost::optional<AccountID>
40 boost::optional<AccountID> result;
42 auto const publicKey =
48 result = parseBase58<AccountID>(account);
118 auto const& entries = dir->getFieldV256(
sfIndexes);
119 auto iter = entries.begin();
123 iter =
std::find(iter, entries.end(), entryIndex);
124 if (iter == entries.end())
130 for (; iter != entries.end(); ++iter)
134 auto typeMatchesFilter =
138 typeFilter.
begin(), typeFilter.
end(), ledgerType);
139 return it != typeFilter.
end();
142 if (!typeFilter.has_value() ||
143 typeMatchesFilter(typeFilter.value(), sleNode->getType()))
149 if (++iter != entries.end())
151 jvResult[jss::limit] = limit;
152 jvResult[jss::marker] =
162 auto const nodeIndex = dir->getFieldU64(
sfIndexNext);
173 auto const& e = dir->getFieldV256(
sfIndexes);
176 jvResult[jss::limit] = limit;
177 jvResult[jss::marker] =
189 isValidatedOld(
LedgerMaster& ledgerMaster,
bool standalone)
203 auto& params = context.params;
205 auto indexValue = params[jss::ledger_index];
206 auto hashValue = params[jss::ledger_hash];
209 auto& legacyLedger = params[jss::ledger];
212 if (legacyLedger.asString().size() > 12)
213 hashValue = legacyLedger;
215 indexValue = legacyLedger;
220 if (!hashValue.isString())
224 if (!ledgerHash.parseHex(hashValue.asString()))
226 return getLedger(ledger, ledgerHash, context);
229 auto const index = indexValue.asString();
231 if (index.empty() || index ==
"current")
232 return getLedger(ledger, LedgerShortcut::CURRENT, context);
234 if (index ==
"validated")
235 return getLedger(ledger, LedgerShortcut::VALIDATED, context);
237 if (index ==
"closed")
238 return getLedger(ledger, LedgerShortcut::CLOSED, context);
256 org::xrpl::rpc::v1::GetAccountInfoRequest& request = context.
params;
258 using LedgerCase = org::xrpl::rpc::v1::LedgerSpecifier::LedgerCase;
259 LedgerCase ledgerCase = request.ledger().ledger_case();
262 case LedgerCase::kHash: {
265 return getLedger(ledger, ledgerHash, context);
267 case LedgerCase::kSequence:
268 return getLedger(ledger, request.ledger().sequence(), context);
269 case LedgerCase::kShortcut:
271 case LedgerCase::LEDGER_NOT_SET: {
272 auto const shortcut = request.ledger().shortcut();
274 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_VALIDATED)
275 return getLedger(ledger, LedgerShortcut::VALIDATED, context);
280 org::xrpl::rpc::v1::LedgerSpecifier::
281 SHORTCUT_UNSPECIFIED ||
283 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CURRENT)
285 return getLedger(ledger, LedgerShortcut::CURRENT, context);
289 org::xrpl::rpc::v1::LedgerSpecifier::SHORTCUT_CLOSED)
291 return getLedger(ledger, LedgerShortcut::CLOSED, context);
304 GRPCContext<org::xrpl::rpc::v1::GetAccountInfoRequest>&);
313 if (ledger ==
nullptr)
323 if (ledger ==
nullptr)
326 if (cur->info().seq == ledgerIndex)
332 if (ledger ==
nullptr)
358 if (shortcut == LedgerShortcut::VALIDATED)
361 if (ledger ==
nullptr)
368 assert(!ledger->open());
372 if (shortcut == LedgerShortcut::CURRENT)
375 assert(ledger->open());
377 else if (shortcut == LedgerShortcut::CLOSED)
380 assert(!ledger->open());
387 if (ledger ==
nullptr)
394 static auto const minSequenceGap = 10;
396 if (ledger->info().seq + minSequenceGap <
439 if (!hash || ledger.
info().
hash != *hash)
444 assert(hash->isNonZero());
458 JLOG(stream) <<
"Ledger #" << seq <<
": " << mn.
what();
495 auto& info = ledger->info();
499 result[jss::ledger_hash] =
to_string(info.hash);
500 result[jss::ledger_index] = info.seq;
504 result[jss::ledger_current_index] = info.seq;
507 result[jss::validated] =
516 if (
auto status =
lookupLedger(ledger, context, result))
517 status.inject(result);
526 for (
auto const& jv : jvArray)
530 auto const id = parseBase58<AccountID>(jv.asString());
547 Blob const b(hash.begin(), hash.end());
549 boost::to_lower(md5);
553 jv[jss::urlgravatar] =
554 str(boost::format(
"http://www.gravatar.com/avatar/%s") % md5);
559 jv[jss::Invalid] =
true;
563 boost::optional<Json::Value>
569 limit =
range.rdefault;
570 if (
auto const& jvLimit = context.
params[jss::limit])
572 if (!(jvLimit.isUInt() || (jvLimit.isInt() && jvLimit.asInt() >= 0)))
575 limit = jvLimit.asUInt();
582 boost::optional<Seed>
593 if (result.size() == 18 &&
601 boost::optional<Seed>
605 static char const*
const seedTypes[]{
606 jss::passphrase.c_str(), jss::seed.c_str(), jss::seed_hex.c_str()};
609 char const* seedType =
nullptr;
611 for (
auto t : seedTypes)
623 "Exactly one of the following must be specified: " +
630 if (!params[seedType].isString())
636 auto const fieldContents = params[seedType].
asString();
639 boost::optional<Seed> seed;
641 if (seedType == jss::seed.c_str())
642 seed = parseBase58<Seed>(fieldContents);
643 else if (seedType == jss::passphrase.c_str())
645 else if (seedType == jss::seed_hex.c_str())
662 bool const has_key_type = params.
isMember(jss::key_type);
666 static char const*
const secretTypes[]{
667 jss::passphrase.c_str(),
670 jss::seed_hex.c_str()};
673 char const* secretType =
nullptr;
675 for (
auto t : secretTypes)
684 if (count == 0 || secretType ==
nullptr)
693 "Exactly one of the following must be specified: " +
700 boost::optional<KeyType> keyType;
701 boost::optional<Seed> seed;
705 if (!params[jss::key_type].isString())
719 if (secretType == jss::secret.c_str())
722 "The secret field is not allowed if " +
731 if (secretType != jss::seed_hex.c_str())
742 rpcBAD_SEED,
"Specified seed is for an Ed25519 wallet.");
759 if (!params[jss::secret].isString())
781 LogicError(
"keypairForSignature: invalid key type");
808 auto const& p = params[jss::type];
817 auto const filter = p.asString();
819 types.begin(), types.end(), [&filter](decltype(types.front())& t) {
820 return t.first == filter;
822 if (iter == types.end())
829 result.second = iter->second;
848 requestedVersion = jv.
get(jss::api_version, requestedVersion);
850 if (!(requestedVersion.
isInt() || requestedVersion.
isUInt()) ||
851 requestedVersion < minVersion || requestedVersion > maxVersion)
853 requestedVersion = invalidVersion;
855 return requestedVersion.
asUInt();
virtual LedgerInfo const & info() const =0
Returns information about the ledger.
const SF_UINT64 sfIndexNext
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
Status getLedger(std::shared_ptr< ReadView const > &ledger, uint256 const &ledgerHash, Context &context)
Get ledger by hash If there is no error in the return value, the ledger pointer will have been filled...
@ ledgerMaster
ledger master data for signing
std::enable_if_t< std::is_same< T, char >::value||std::is_same< T, unsigned char >::value, Slice > makeSlice(std::array< T, N > const &a)
Json::Value getJson(JsonOptions options) const override
const beast::SemanticVersion firstVersion("1.0.0")
API version numbers used in API version 1.
const beast::SemanticVersion goodVersion("1.0.0")
unsigned int getAPIVersionNumber(Json::Value const &jv)
Retrieve the api version number from the json value.
An immutable linear range of bytes.
@ arrayValue
array value (ordered list)
void injectSLE(Json::Value &jv, SLE const &sle)
Inject JSON describing ledger entry.
LedgerIndex getValidLedgerIndex()
Value get(UInt index, const Value &defaultValue) const
If the array contains at least index+1 elements, returns the element value, otherwise returns default...
boost::optional< Seed > parseRippleLibSeed(Json::Value const &value)
LedgerMaster & ledgerMaster
std::string decodeBase58Token(std::string const &s, TokenType type)
Decode a token of given type encoded using Base58Check and the XRPL alphabet.
bool getAccountObjects(ReadView const &ledger, AccountID const &account, boost::optional< std::vector< LedgerEntryType >> const &typeFilter, uint256 dirIndex, uint256 const &entryIndex, std::uint32_t const limit, Json::Value &jvResult)
Gathers all objects for an account in a ledger.
Keylet child(uint256 const &key) noexcept
Any item that can be in an owner dir.
uint128 getFieldH128(SField const &field) const
const SF_HASH128 sfEmailHash
std::shared_ptr< Ledger const > getLedgerByHash(uint256 const &hash)
constexpr unsigned int APIVersionIfUnspecified
A Semantic Version number.
std::string to_string(ListDisposition disposition)
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.
std::pair< PublicKey, SecretKey > generateKeyPair(KeyType type, Seed const &seed)
Generate a key pair deterministically.
Json::Value expected_field_error(std::string const &name, std::string const &type)
constexpr static std::size_t size()
uint256 getHashByIndex(std::uint32_t ledgerIndex, Application &app)
Json::Value missing_field_error(std::string const &name)
const SF_VECTOR256 sfIndexes
boost::optional< KeyType > keyTypeFromString(std::string const &s)
boost::optional< Json::Value > readLimitField(unsigned int &limit, Tuning::LimitRange const &range, JsonContext const &context)
Retrieve the limit value from a JsonContext, or set a default - then restrict the limit by max and mi...
Integers of any length that is a multiple of 32-bits.
constexpr unsigned int ApiMinimumSupportedVersion
@ objectValue
object value (collection of name/value pairs).
bool contains_error(Json::Value const &json)
Returns true if the json contains an rpc error specification.
error_code_i accountFromStringWithCode(AccountID &result, std::string const &strIdent, bool bStrict)
Decode account ID from string.
virtual Config & config()=0
Keylet page(uint256 const &key, std::uint64_t index) noexcept
A page in a directory.
AccountID calcAccountID(PublicKey const &pk)
std::shared_ptr< Ledger const > getValidatedLedger()
constexpr unsigned int ApiMaximumSupportedVersion
boost::optional< AccountID > accountFromStringStrict(std::string const &account)
Get an AccountID from an account ID or public key.
boost::optional< Seed > parseGenericSeed(std::string const &str)
Attempt to parse a string as a seed.
std::shared_ptr< Ledger const > getLedgerBySeq(std::uint32_t index)
bool isMember(const char *key) const
Return true if the object has a member named key.
ClosedInterval< T > range(T low, T high)
Create a closed range interval.
LedgerEntryType getType() const
Json::Value rpcError(int iError, Json::Value jvResult)
std::shared_ptr< ReadView const > getCurrentLedger()
virtual std::shared_ptr< SLE const > read(Keylet const &k) const =0
Return the state item associated with a key.
constexpr unsigned int APIInvalidVersion
API version numbers used in later API versions.
Status represents the results of an operation that might fail.
bool isUnlimited(Role const &role)
ADMIN and IDENTIFIED roles shall have unlimited resources.
Status
Return codes from Backend operations.
std::shared_ptr< Ledger const > getClosedLedger()
std::string invalid_field_message(std::string const &name)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
virtual beast::Journal journal(std::string const &name)=0
bool isValidated(LedgerMaster &ledgerMaster, ReadView const &ledger, Application &app)
Seeds are used to generate deterministic secret keys.
bool parseHex(std::string_view sv)
Parse a hex string into a base_uint.
LedgerEntryType
Ledger entry types.
bool lexicalCastChecked(Out &out, In in)
Intelligently convert from one type to another.
std::pair< RPC::Status, LedgerEntryType > chooseLedgerEntryType(Json::Value const ¶ms)
void LogicError(std::string const &how) noexcept
Called when faulty logic causes a broken invariant.
bool isFieldPresent(SField const &field) const
static base_uint fromVoid(void const *data)
std::pair< PublicKey, SecretKey > keypairForSignature(Json::Value const ¶ms, Json::Value &error)
std::string strHex(FwdIt begin, FwdIt end)
@ ltDIR_NODE
Directory node.
hash_set< AccountID > parseAccountIds(Json::Value const &jvArray)
Represents RPC limit parameter values that have a min, default and max.
Json::Value make_param_error(std::string const &message)
Returns a new json object that indicates invalid parameters.
virtual bool open() const =0
Returns true if this reflects an open ledger.
const beast::SemanticVersion lastVersion("1.0.0")
Json::Value invalid_field_error(std::string const &name)
The context of information needed to call an RPC.
Json::Value accountFromString(AccountID &result, std::string const &strIdent, bool bStrict)
Json::Value make_error(error_code_i code)
Returns a new json object that reflects the error code.
constexpr auto maxValidatedLedgerAge
boost::optional< Seed > getSeedFromRPC(Json::Value const ¶ms, Json::Value &error)
std::string asString() const
Returns the unquoted string value.
Status ledgerFromRequest(T &ledger, GRPCContext< org::xrpl::rpc::v1::GetAccountInfoRequest > &context)