mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-20 19:15:54 +00:00
Add new validator_info and manifest rpc methods
Returns local validator details and specified manifest information respectively. Folded and rebased on latest develop
This commit is contained in:
@@ -650,6 +650,7 @@ else ()
|
|||||||
src/ripple/rpc/handlers/LedgerRequest.cpp
|
src/ripple/rpc/handlers/LedgerRequest.cpp
|
||||||
src/ripple/rpc/handlers/LogLevel.cpp
|
src/ripple/rpc/handlers/LogLevel.cpp
|
||||||
src/ripple/rpc/handlers/LogRotate.cpp
|
src/ripple/rpc/handlers/LogRotate.cpp
|
||||||
|
src/ripple/rpc/handlers/Manifest.cpp
|
||||||
src/ripple/rpc/handlers/NoRippleCheck.cpp
|
src/ripple/rpc/handlers/NoRippleCheck.cpp
|
||||||
src/ripple/rpc/handlers/OwnerInfo.cpp
|
src/ripple/rpc/handlers/OwnerInfo.cpp
|
||||||
src/ripple/rpc/handlers/PathFind.cpp
|
src/ripple/rpc/handlers/PathFind.cpp
|
||||||
@@ -676,6 +677,7 @@ else ()
|
|||||||
src/ripple/rpc/handlers/ValidationCreate.cpp
|
src/ripple/rpc/handlers/ValidationCreate.cpp
|
||||||
src/ripple/rpc/handlers/ValidatorListSites.cpp
|
src/ripple/rpc/handlers/ValidatorListSites.cpp
|
||||||
src/ripple/rpc/handlers/Validators.cpp
|
src/ripple/rpc/handlers/Validators.cpp
|
||||||
|
src/ripple/rpc/handlers/ValidatorInfo.cpp
|
||||||
src/ripple/rpc/handlers/WalletPropose.cpp
|
src/ripple/rpc/handlers/WalletPropose.cpp
|
||||||
src/ripple/rpc/impl/DeliveredAmount.cpp
|
src/ripple/rpc/impl/DeliveredAmount.cpp
|
||||||
src/ripple/rpc/impl/Handler.cpp
|
src/ripple/rpc/impl/Handler.cpp
|
||||||
@@ -967,6 +969,7 @@ else ()
|
|||||||
src/test/rpc/LedgerData_test.cpp
|
src/test/rpc/LedgerData_test.cpp
|
||||||
src/test/rpc/LedgerRPC_test.cpp
|
src/test/rpc/LedgerRPC_test.cpp
|
||||||
src/test/rpc/LedgerRequestRPC_test.cpp
|
src/test/rpc/LedgerRequestRPC_test.cpp
|
||||||
|
src/test/rpc/ManifestRPC_test.cpp
|
||||||
src/test/rpc/NoRippleCheck_test.cpp
|
src/test/rpc/NoRippleCheck_test.cpp
|
||||||
src/test/rpc/NoRipple_test.cpp
|
src/test/rpc/NoRipple_test.cpp
|
||||||
src/test/rpc/OwnerInfo_test.cpp
|
src/test/rpc/OwnerInfo_test.cpp
|
||||||
@@ -983,6 +986,7 @@ else ()
|
|||||||
src/test/rpc/TransactionEntry_test.cpp
|
src/test/rpc/TransactionEntry_test.cpp
|
||||||
src/test/rpc/TransactionHistory_test.cpp
|
src/test/rpc/TransactionHistory_test.cpp
|
||||||
src/test/rpc/Tx_test.cpp
|
src/test/rpc/Tx_test.cpp
|
||||||
|
src/test/rpc/ValidatorInfo_test.cpp
|
||||||
src/test/rpc/ValidatorRPC_test.cpp
|
src/test/rpc/ValidatorRPC_test.cpp
|
||||||
src/test/rpc/Version_test.cpp
|
src/test/rpc/Version_test.cpp
|
||||||
#[===============================[
|
#[===============================[
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ class AcceptedLedger;
|
|||||||
class LedgerMaster;
|
class LedgerMaster;
|
||||||
class LoadManager;
|
class LoadManager;
|
||||||
class ManifestCache;
|
class ManifestCache;
|
||||||
|
class ValidatorKeys;
|
||||||
class NetworkOPs;
|
class NetworkOPs;
|
||||||
class OpenLedger;
|
class OpenLedger;
|
||||||
class OrderBookDB;
|
class OrderBookDB;
|
||||||
|
|||||||
@@ -257,6 +257,30 @@ public:
|
|||||||
PublicKey
|
PublicKey
|
||||||
getMasterKey (PublicKey const& pk) const;
|
getMasterKey (PublicKey const& pk) const;
|
||||||
|
|
||||||
|
/** Returns master key's current manifest sequence.
|
||||||
|
|
||||||
|
@return sequence corresponding to Master public key
|
||||||
|
if configured or boost::none otherwise
|
||||||
|
*/
|
||||||
|
boost::optional<std::uint32_t>
|
||||||
|
getSequence (PublicKey const& pk) const;
|
||||||
|
|
||||||
|
/** Returns domain claimed by a given public key
|
||||||
|
|
||||||
|
@return domain corresponding to Master public key
|
||||||
|
if present, otherwise boost::none
|
||||||
|
*/
|
||||||
|
boost::optional<std::string>
|
||||||
|
getDomain (PublicKey const& pk) const;
|
||||||
|
|
||||||
|
/** Returns mainfest corresponding to a given public key
|
||||||
|
|
||||||
|
@return manifest corresponding to Master public key
|
||||||
|
if present, otherwise boost::none
|
||||||
|
*/
|
||||||
|
boost::optional<std::string>
|
||||||
|
getManifest (PublicKey const& pk) const;
|
||||||
|
|
||||||
/** Returns `true` if master key has been revoked in a manifest.
|
/** Returns `true` if master key has been revoked in a manifest.
|
||||||
|
|
||||||
@param pk Master public key
|
@param pk Master public key
|
||||||
|
|||||||
@@ -309,6 +309,42 @@ ManifestCache::getMasterKey (PublicKey const& pk) const
|
|||||||
return pk;
|
return pk;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boost::optional<std::uint32_t>
|
||||||
|
ManifestCache::getSequence (PublicKey const& pk) const
|
||||||
|
{
|
||||||
|
std::lock_guard lock{read_mutex_};
|
||||||
|
auto const iter = map_.find (pk);
|
||||||
|
|
||||||
|
if (iter != map_.end () && !iter->second.revoked ())
|
||||||
|
return iter->second.sequence;
|
||||||
|
|
||||||
|
return boost::none;
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::optional<std::string>
|
||||||
|
ManifestCache::getDomain (PublicKey const& pk) const
|
||||||
|
{
|
||||||
|
std::lock_guard lock{read_mutex_};
|
||||||
|
auto const iter = map_.find (pk);
|
||||||
|
|
||||||
|
if (iter != map_.end () && !iter->second.revoked ())
|
||||||
|
return iter->second.domain;
|
||||||
|
|
||||||
|
return boost::none;
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::optional<std::string>
|
||||||
|
ManifestCache::getManifest (PublicKey const& pk) const
|
||||||
|
{
|
||||||
|
std::lock_guard lock{read_mutex_};
|
||||||
|
auto const iter = map_.find (pk);
|
||||||
|
|
||||||
|
if (iter != map_.end () && !iter->second.revoked ())
|
||||||
|
return iter->second.serialized;
|
||||||
|
|
||||||
|
return boost::none;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ManifestCache::revoked (PublicKey const& pk) const
|
ManifestCache::revoked (PublicKey const& pk) const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -145,6 +145,21 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool validPublicKey (std::string const& strPk)
|
||||||
|
{
|
||||||
|
if (parseBase58<PublicKey> (TokenType::AccountPublic, strPk))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
auto pkHex = strUnHex (strPk);
|
||||||
|
if (!pkHex)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!publicKeyType(makeSlice(*pkHex)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using parseFuncPtr = Json::Value (RPCParser::*) (Json::Value const& jvParams);
|
using parseFuncPtr = Json::Value (RPCParser::*) (Json::Value const& jvParams);
|
||||||
|
|
||||||
@@ -203,6 +218,24 @@ private:
|
|||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Json::Value parseManifest (Json::Value const& jvParams)
|
||||||
|
{
|
||||||
|
if (jvParams.size () == 1)
|
||||||
|
{
|
||||||
|
Json::Value jvRequest (Json::objectValue);
|
||||||
|
|
||||||
|
std::string const strPk = jvParams[0u].asString ();
|
||||||
|
if (!validPublicKey (strPk))
|
||||||
|
return rpcError (rpcPUBLIC_MALFORMED);
|
||||||
|
|
||||||
|
jvRequest[jss::public_key] = strPk;
|
||||||
|
|
||||||
|
return jvRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rpcError (rpcINVALID_PARAMS);
|
||||||
|
}
|
||||||
|
|
||||||
// fetch_info [clear]
|
// fetch_info [clear]
|
||||||
Json::Value parseFetchInfo (Json::Value const& jvParams)
|
Json::Value parseFetchInfo (Json::Value const& jvParams)
|
||||||
{
|
{
|
||||||
@@ -764,21 +797,7 @@ private:
|
|||||||
{
|
{
|
||||||
std::string const strPk = jvParams[0u].asString ();
|
std::string const strPk = jvParams[0u].asString ();
|
||||||
|
|
||||||
bool const validPublicKey = [&strPk]{
|
if (!validPublicKey(strPk))
|
||||||
if (parseBase58<PublicKey> (TokenType::AccountPublic, strPk))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
auto pkHex = strUnHex (strPk);
|
|
||||||
if (!pkHex)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!publicKeyType(makeSlice(*pkHex)))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}();
|
|
||||||
|
|
||||||
if (!validPublicKey)
|
|
||||||
return rpcError (rpcPUBLIC_MALFORMED);
|
return rpcError (rpcPUBLIC_MALFORMED);
|
||||||
|
|
||||||
Json::Value jvRequest (Json::objectValue);
|
Json::Value jvRequest (Json::objectValue);
|
||||||
@@ -1171,6 +1190,7 @@ public:
|
|||||||
{ "ledger_request", &RPCParser::parseLedgerId, 1, 1 },
|
{ "ledger_request", &RPCParser::parseLedgerId, 1, 1 },
|
||||||
{ "log_level", &RPCParser::parseLogLevel, 0, 2 },
|
{ "log_level", &RPCParser::parseLogLevel, 0, 2 },
|
||||||
{ "logrotate", &RPCParser::parseAsIs, 0, 0 },
|
{ "logrotate", &RPCParser::parseAsIs, 0, 0 },
|
||||||
|
{ "manifest", &RPCParser::parseManifest, 1, 1 },
|
||||||
{ "owner_info", &RPCParser::parseAccountItems, 1, 2 },
|
{ "owner_info", &RPCParser::parseAccountItems, 1, 2 },
|
||||||
{ "peers", &RPCParser::parseAsIs, 0, 0 },
|
{ "peers", &RPCParser::parseAsIs, 0, 0 },
|
||||||
{ "ping", &RPCParser::parseAsIs, 0, 0 },
|
{ "ping", &RPCParser::parseAsIs, 0, 0 },
|
||||||
@@ -1195,6 +1215,7 @@ public:
|
|||||||
{ "tx_history", &RPCParser::parseTxHistory, 1, 1 },
|
{ "tx_history", &RPCParser::parseTxHistory, 1, 1 },
|
||||||
{ "unl_list", &RPCParser::parseAsIs, 0, 0 },
|
{ "unl_list", &RPCParser::parseAsIs, 0, 0 },
|
||||||
{ "validation_create", &RPCParser::parseValidationCreate, 0, 1 },
|
{ "validation_create", &RPCParser::parseValidationCreate, 0, 1 },
|
||||||
|
{ "validator_info", &RPCParser::parseAsIs, 0, 0 },
|
||||||
{ "version", &RPCParser::parseAsIs, 0, 0 },
|
{ "version", &RPCParser::parseAsIs, 0, 0 },
|
||||||
{ "wallet_propose", &RPCParser::parseWalletPropose, 0, 1 },
|
{ "wallet_propose", &RPCParser::parseWalletPropose, 0, 1 },
|
||||||
{ "internal", &RPCParser::parseInternal, 1, -1 },
|
{ "internal", &RPCParser::parseInternal, 1, -1 },
|
||||||
|
|||||||
@@ -285,6 +285,11 @@ inline Json::Value expected_field_error (
|
|||||||
return expected_field_error (std::string (name), type);
|
return expected_field_error (std::string (name), type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline Json::Value not_validator_error ()
|
||||||
|
{
|
||||||
|
return make_param_error ("not a validator");
|
||||||
|
}
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/** Returns `true` if the json contains an rpc error specification. */
|
/** Returns `true` if the json contains an rpc error specification. */
|
||||||
|
|||||||
@@ -202,16 +202,20 @@ JSS ( destination_amount ); // in: PathRequest, RipplePathFind
|
|||||||
JSS ( destination_currencies ); // in: PathRequest, RipplePathFind
|
JSS ( destination_currencies ); // in: PathRequest, RipplePathFind
|
||||||
JSS ( destination_tag ); // in: PathRequest
|
JSS ( destination_tag ); // in: PathRequest
|
||||||
// out: AccountChannels
|
// out: AccountChannels
|
||||||
|
JSS ( details ); // out: Manifest
|
||||||
JSS ( dir_entry ); // out: DirectoryEntryIterator
|
JSS ( dir_entry ); // out: DirectoryEntryIterator
|
||||||
JSS ( dir_index ); // out: DirectoryEntryIterator
|
JSS ( dir_index ); // out: DirectoryEntryIterator
|
||||||
JSS ( dir_root ); // out: DirectoryEntryIterator
|
JSS ( dir_root ); // out: DirectoryEntryIterator
|
||||||
JSS ( directory ); // in: LedgerEntry
|
JSS ( directory ); // in: LedgerEntry
|
||||||
|
JSS ( domain ); // out: ValidatorInfo, Manifest
|
||||||
JSS ( drops ); // out: TxQ
|
JSS ( drops ); // out: TxQ
|
||||||
JSS ( duration_us ); // out: NetworkOPs
|
JSS ( duration_us ); // out: NetworkOPs
|
||||||
JSS ( enabled ); // out: AmendmentTable
|
JSS ( enabled ); // out: AmendmentTable
|
||||||
JSS ( engine_result ); // out: NetworkOPs, TransactionSign, Submit
|
JSS ( engine_result ); // out: NetworkOPs, TransactionSign, Submit
|
||||||
JSS ( engine_result_code ); // out: NetworkOPs, TransactionSign, Submit
|
JSS ( engine_result_code ); // out: NetworkOPs, TransactionSign, Submit
|
||||||
JSS ( engine_result_message ); // out: NetworkOPs, TransactionSign, Submit
|
JSS ( engine_result_message ); // out: NetworkOPs, TransactionSign, Submit
|
||||||
|
JSS ( ephemeral_key ); // out: ValidatorInfo
|
||||||
|
// in/out: Manifest
|
||||||
JSS ( error ); // out: error
|
JSS ( error ); // out: error
|
||||||
JSS ( errored );
|
JSS ( errored );
|
||||||
JSS ( error_code ); // out: error
|
JSS ( error_code ); // out: error
|
||||||
@@ -331,11 +335,14 @@ JSS ( local_txs ); // out: GetCounts
|
|||||||
JSS ( local_static_keys ); // out: ValidatorList
|
JSS ( local_static_keys ); // out: ValidatorList
|
||||||
JSS ( lowest_sequence ); // out: AccountInfo
|
JSS ( lowest_sequence ); // out: AccountInfo
|
||||||
JSS ( majority ); // out: RPC feature
|
JSS ( majority ); // out: RPC feature
|
||||||
|
JSS ( manifest ); // out: ValidatorInfo, Manifest
|
||||||
JSS ( marker ); // in/out: AccountTx, AccountOffers,
|
JSS ( marker ); // in/out: AccountTx, AccountOffers,
|
||||||
// AccountLines, AccountObjects,
|
// AccountLines, AccountObjects,
|
||||||
// LedgerData
|
// LedgerData
|
||||||
// in: BookOffers
|
// in: BookOffers
|
||||||
JSS ( master_key ); // out: WalletPropose, NetworkOPs
|
JSS ( master_key ); // out: WalletPropose, NetworkOPs,
|
||||||
|
// ValidatorInfo
|
||||||
|
// in/out: Manifest
|
||||||
JSS ( master_seed ); // out: WalletPropose
|
JSS ( master_seed ); // out: WalletPropose
|
||||||
JSS ( master_seed_hex ); // out: WalletPropose
|
JSS ( master_seed_hex ); // out: WalletPropose
|
||||||
JSS ( master_signature ); // out: pubManifest
|
JSS ( master_signature ); // out: pubManifest
|
||||||
@@ -412,7 +419,9 @@ JSS ( proxied ); // out: RPC ping
|
|||||||
JSS ( pubkey_node ); // out: NetworkOPs
|
JSS ( pubkey_node ); // out: NetworkOPs
|
||||||
JSS ( pubkey_publisher ); // out: ValidatorList
|
JSS ( pubkey_publisher ); // out: ValidatorList
|
||||||
JSS ( pubkey_validator ); // out: NetworkOPs, ValidatorList
|
JSS ( pubkey_validator ); // out: NetworkOPs, ValidatorList
|
||||||
JSS ( public_key ); // out: OverlayImpl, PeerImp, WalletPropose
|
JSS ( public_key ); // out: OverlayImpl, PeerImp, WalletPropose,
|
||||||
|
// ValidatorInfo
|
||||||
|
// in/out: Manifest
|
||||||
JSS ( public_key_hex ); // out: WalletPropose
|
JSS ( public_key_hex ); // out: WalletPropose
|
||||||
JSS ( published_ledger ); // out: NetworkOPs
|
JSS ( published_ledger ); // out: NetworkOPs
|
||||||
JSS ( publisher_lists ); // out: ValidatorList
|
JSS ( publisher_lists ); // out: ValidatorList
|
||||||
@@ -431,6 +440,7 @@ JSS ( refresh_interval_min ); // out: ValidatorSites
|
|||||||
JSS ( regular_seed ); // in/out: LedgerEntry
|
JSS ( regular_seed ); // in/out: LedgerEntry
|
||||||
JSS ( remote ); // out: Logic.h
|
JSS ( remote ); // out: Logic.h
|
||||||
JSS ( request ); // RPC
|
JSS ( request ); // RPC
|
||||||
|
JSS ( requested ); // out: Manifest
|
||||||
JSS ( reservations ); // out: Reservations
|
JSS ( reservations ); // out: Reservations
|
||||||
JSS ( reserve_base ); // out: NetworkOPs
|
JSS ( reserve_base ); // out: NetworkOPs
|
||||||
JSS ( reserve_base_xrp ); // out: NetworkOPs
|
JSS ( reserve_base_xrp ); // out: NetworkOPs
|
||||||
@@ -457,7 +467,7 @@ JSS ( send_currencies ); // out: AccountCurrencies
|
|||||||
JSS ( send_max ); // in: PathRequest, RipplePathFind
|
JSS ( send_max ); // in: PathRequest, RipplePathFind
|
||||||
JSS ( seq ); // in: LedgerEntry;
|
JSS ( seq ); // in: LedgerEntry;
|
||||||
// out: NetworkOPs, RPCSub, AccountOffers,
|
// out: NetworkOPs, RPCSub, AccountOffers,
|
||||||
// ValidatorList
|
// ValidatorList, ValidatorInfo, Manifest
|
||||||
JSS ( seqNum ); // out: LedgerToJson
|
JSS ( seqNum ); // out: LedgerToJson
|
||||||
JSS ( server_state ); // out: NetworkOPs
|
JSS ( server_state ); // out: NetworkOPs
|
||||||
JSS ( server_state_duration_us ); // out: NetworkOPs
|
JSS ( server_state_duration_us ); // out: NetworkOPs
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ Json::Value doLedgerHeader (RPC::JsonContext&);
|
|||||||
Json::Value doLedgerRequest (RPC::JsonContext&);
|
Json::Value doLedgerRequest (RPC::JsonContext&);
|
||||||
Json::Value doLogLevel (RPC::JsonContext&);
|
Json::Value doLogLevel (RPC::JsonContext&);
|
||||||
Json::Value doLogRotate (RPC::JsonContext&);
|
Json::Value doLogRotate (RPC::JsonContext&);
|
||||||
|
Json::Value doManifest (RPC::JsonContext&);
|
||||||
Json::Value doNoRippleCheck (RPC::JsonContext&);
|
Json::Value doNoRippleCheck (RPC::JsonContext&);
|
||||||
Json::Value doOwnerInfo (RPC::JsonContext&);
|
Json::Value doOwnerInfo (RPC::JsonContext&);
|
||||||
Json::Value doPathFind (RPC::JsonContext&);
|
Json::Value doPathFind (RPC::JsonContext&);
|
||||||
@@ -86,6 +87,7 @@ Json::Value doValidationCreate (RPC::JsonContext&);
|
|||||||
Json::Value doWalletPropose (RPC::JsonContext&);
|
Json::Value doWalletPropose (RPC::JsonContext&);
|
||||||
Json::Value doValidators (RPC::JsonContext&);
|
Json::Value doValidators (RPC::JsonContext&);
|
||||||
Json::Value doValidatorListSites (RPC::JsonContext&);
|
Json::Value doValidatorListSites (RPC::JsonContext&);
|
||||||
|
Json::Value doValidatorInfo (RPC::JsonContext&);
|
||||||
} // ripple
|
} // ripple
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
75
src/ripple/rpc/handlers/Manifest.cpp
Normal file
75
src/ripple/rpc/handlers/Manifest.cpp
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
This file is part of rippled: https://github.com/ripple/rippled
|
||||||
|
Copyright (c) 2019 Dev Null Productions
|
||||||
|
|
||||||
|
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 <ripple/app/main/Application.h>
|
||||||
|
#include <ripple/basics/base64.h>
|
||||||
|
#include <ripple/json/json_value.h>
|
||||||
|
#include <ripple/protocol/ErrorCodes.h>
|
||||||
|
#include <ripple/protocol/jss.h>
|
||||||
|
#include <ripple/rpc/Context.h>
|
||||||
|
|
||||||
|
namespace ripple {
|
||||||
|
Json::Value doManifest (RPC::JsonContext& context)
|
||||||
|
{
|
||||||
|
auto& params = context.params;
|
||||||
|
|
||||||
|
if (!params.isMember(jss::public_key))
|
||||||
|
return RPC::missing_field_error (jss::public_key);
|
||||||
|
|
||||||
|
auto const requested = params[jss::public_key].asString();
|
||||||
|
|
||||||
|
Json::Value ret;
|
||||||
|
ret[jss::requested] = requested;
|
||||||
|
|
||||||
|
auto const pk = parseBase58<PublicKey>(TokenType::NodePublic, requested);
|
||||||
|
if (!pk)
|
||||||
|
{
|
||||||
|
RPC::inject_error(rpcINVALID_PARAMS, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// first attempt to use params as ephemeral key,
|
||||||
|
// if this lookup succeeds master key will be returned,
|
||||||
|
// else pk will just be returned and we will assume that
|
||||||
|
// is master key anyways
|
||||||
|
auto const mk = context.app.validatorManifests().getMasterKey(*pk);
|
||||||
|
|
||||||
|
auto const ek = context.app.validatorManifests().getSigningKey(mk);
|
||||||
|
|
||||||
|
// if ephemeral key not found, we don't have specified manifest
|
||||||
|
if (ek == mk)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (auto const manifest = context.app.validatorManifests().getManifest(mk))
|
||||||
|
ret[jss::manifest] = base64_encode(*manifest);
|
||||||
|
Json::Value details;
|
||||||
|
|
||||||
|
details[jss::master_key] = toBase58(TokenType::NodePublic, mk);
|
||||||
|
details[jss::ephemeral_key] = toBase58(TokenType::NodePublic, ek);
|
||||||
|
|
||||||
|
if (auto const seq = context.app.validatorManifests().getSequence(mk))
|
||||||
|
details[jss::seq] = *seq;
|
||||||
|
|
||||||
|
if (auto const domain = context.app.validatorManifests().getDomain(mk))
|
||||||
|
details[jss::domain] = *domain;
|
||||||
|
|
||||||
|
ret[jss::details] = details;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
} // ripple
|
||||||
62
src/ripple/rpc/handlers/ValidatorInfo.cpp
Normal file
62
src/ripple/rpc/handlers/ValidatorInfo.cpp
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
This file is part of rippled: https://github.com/ripple/rippled
|
||||||
|
Copyright (c) 2019 Dev Null Productions
|
||||||
|
|
||||||
|
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 <ripple/app/misc/ValidatorKeys.h>
|
||||||
|
#include <ripple/app/main/Application.h>
|
||||||
|
#include <ripple/basics/base64.h>
|
||||||
|
#include <ripple/json/json_value.h>
|
||||||
|
#include <ripple/protocol/ErrorCodes.h>
|
||||||
|
#include <ripple/protocol/jss.h>
|
||||||
|
#include <ripple/rpc/Context.h>
|
||||||
|
|
||||||
|
namespace ripple {
|
||||||
|
Json::Value doValidatorInfo (RPC::JsonContext& context)
|
||||||
|
{
|
||||||
|
// return error if not configured as validator
|
||||||
|
if (context.app.getValidationPublicKey().empty())
|
||||||
|
return RPC::not_validator_error ();
|
||||||
|
|
||||||
|
Json::Value ret;
|
||||||
|
|
||||||
|
auto const pk = context.app.getValidationPublicKey();
|
||||||
|
|
||||||
|
// assume pk is ephemeral key, get master key
|
||||||
|
auto const mk = context.app.validatorManifests().getMasterKey(pk);
|
||||||
|
ret[jss::master_key] = toBase58(TokenType::NodePublic, mk);
|
||||||
|
|
||||||
|
// pk is maskter key, eg no ephemeral key, eg no manifest, just return
|
||||||
|
if (mk == pk)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
// lookup ephemeral key
|
||||||
|
auto const ek = context.app.validatorManifests().getSigningKey(mk);
|
||||||
|
ret[jss::ephemeral_key] = toBase58(TokenType::NodePublic, ek);
|
||||||
|
|
||||||
|
if (auto const manifest = context.app.validatorManifests().getManifest(mk))
|
||||||
|
ret[jss::manifest] = base64_encode(*manifest);
|
||||||
|
|
||||||
|
if (auto const seq = context.app.validatorManifests().getSequence(mk))
|
||||||
|
ret[jss::seq] = *seq;
|
||||||
|
|
||||||
|
if (auto const domain = context.app.validatorManifests().getDomain(mk))
|
||||||
|
ret[jss::domain] = *domain;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
} // ripple
|
||||||
@@ -90,6 +90,7 @@ Handler const handlerArray[] {
|
|||||||
{ "ledger_request", byRef (&doLedgerRequest), Role::ADMIN, NO_CONDITION },
|
{ "ledger_request", byRef (&doLedgerRequest), Role::ADMIN, NO_CONDITION },
|
||||||
{ "log_level", byRef (&doLogLevel), Role::ADMIN, NO_CONDITION },
|
{ "log_level", byRef (&doLogLevel), Role::ADMIN, NO_CONDITION },
|
||||||
{ "logrotate", byRef (&doLogRotate), Role::ADMIN, NO_CONDITION },
|
{ "logrotate", byRef (&doLogRotate), Role::ADMIN, NO_CONDITION },
|
||||||
|
{ "manifest", byRef (&doManifest), Role::ADMIN, NO_CONDITION },
|
||||||
{ "noripple_check", byRef (&doNoRippleCheck), Role::USER, NO_CONDITION },
|
{ "noripple_check", byRef (&doNoRippleCheck), Role::USER, NO_CONDITION },
|
||||||
{ "owner_info", byRef (&doOwnerInfo), Role::USER, NEEDS_CURRENT_LEDGER },
|
{ "owner_info", byRef (&doOwnerInfo), Role::USER, NEEDS_CURRENT_LEDGER },
|
||||||
{ "peers", byRef (&doPeers), Role::ADMIN, NO_CONDITION },
|
{ "peers", byRef (&doPeers), Role::ADMIN, NO_CONDITION },
|
||||||
@@ -117,6 +118,7 @@ Handler const handlerArray[] {
|
|||||||
{ "validation_create", byRef (&doValidationCreate), Role::ADMIN, NO_CONDITION },
|
{ "validation_create", byRef (&doValidationCreate), Role::ADMIN, NO_CONDITION },
|
||||||
{ "validators", byRef (&doValidators), Role::ADMIN, NO_CONDITION },
|
{ "validators", byRef (&doValidators), Role::ADMIN, NO_CONDITION },
|
||||||
{ "validator_list_sites", byRef (&doValidatorListSites), Role::ADMIN, NO_CONDITION },
|
{ "validator_list_sites", byRef (&doValidatorListSites), Role::ADMIN, NO_CONDITION },
|
||||||
|
{ "validator_info", byRef (&doValidatorInfo), Role::ADMIN, NO_CONDITION },
|
||||||
{ "wallet_propose", byRef (&doWalletPropose), Role::ADMIN, NO_CONDITION },
|
{ "wallet_propose", byRef (&doWalletPropose), Role::ADMIN, NO_CONDITION },
|
||||||
|
|
||||||
// Evented methods
|
// Evented methods
|
||||||
|
|||||||
@@ -58,5 +58,7 @@
|
|||||||
#include <ripple/rpc/handlers/LedgerRequest.cpp>
|
#include <ripple/rpc/handlers/LedgerRequest.cpp>
|
||||||
#include <ripple/rpc/handlers/LogLevel.cpp>
|
#include <ripple/rpc/handlers/LogLevel.cpp>
|
||||||
#include <ripple/rpc/handlers/LogRotate.cpp>
|
#include <ripple/rpc/handlers/LogRotate.cpp>
|
||||||
|
#include <ripple/rpc/handlers/Manifest.cpp>
|
||||||
#include <ripple/rpc/handlers/NoRippleCheck.cpp>
|
#include <ripple/rpc/handlers/NoRippleCheck.cpp>
|
||||||
#include <ripple/rpc/handlers/OwnerInfo.cpp>
|
#include <ripple/rpc/handlers/OwnerInfo.cpp>
|
||||||
|
#include <ripple/rpc/handlers/ValidatorInfo.cpp>
|
||||||
|
|||||||
85
src/test/rpc/ManifestRPC_test.cpp
Normal file
85
src/test/rpc/ManifestRPC_test.cpp
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
This file is part of rippled: https://github.com/ripple/rippled
|
||||||
|
Copyright (c) 2020 Dev Null Productions, LLC
|
||||||
|
|
||||||
|
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 <test/jtx.h>
|
||||||
|
#include <ripple/beast/unit_test.h>
|
||||||
|
#include <ripple/core/ConfigSections.h>
|
||||||
|
#include <ripple/protocol/jss.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace ripple {
|
||||||
|
namespace test {
|
||||||
|
|
||||||
|
class ManifestRPC_test : public beast::unit_test::suite
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void testErrors()
|
||||||
|
{
|
||||||
|
testcase ("Errors");
|
||||||
|
|
||||||
|
using namespace jtx;
|
||||||
|
Env env(*this);
|
||||||
|
{
|
||||||
|
// manifest with no public key
|
||||||
|
auto const info = env.rpc ("json", "manifest", "{ }");
|
||||||
|
BEAST_EXPECT(info[jss::result][jss::error_message] ==
|
||||||
|
"Missing field 'public_key'.");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// manifest with manlformed public key
|
||||||
|
auto const info = env.rpc ("json", "manifest", "{ \"public_key\": "
|
||||||
|
"\"abcdef12345\"}");
|
||||||
|
BEAST_EXPECT(info[jss::result][jss::error_message] ==
|
||||||
|
"Invalid parameters.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void testLookup()
|
||||||
|
{
|
||||||
|
testcase ("Lookup");
|
||||||
|
|
||||||
|
using namespace jtx;
|
||||||
|
std::string const key =
|
||||||
|
"n949f75evCHwgyP4fPVgaHqNHxUVN15PsJEZ3B3HnXPcPjcZAoy7";
|
||||||
|
Env env{
|
||||||
|
*this,
|
||||||
|
envconfig([&key](std::unique_ptr<Config> cfg) {
|
||||||
|
cfg->section(SECTION_VALIDATORS).append(key);
|
||||||
|
return cfg;
|
||||||
|
})
|
||||||
|
};
|
||||||
|
{
|
||||||
|
auto const info = env.rpc ("json", "manifest", "{ \"public_key\": "
|
||||||
|
"\"" + key + "\"}");
|
||||||
|
BEAST_EXPECT(info[jss::result][jss::requested] == key);
|
||||||
|
BEAST_EXPECT(info[jss::result][jss::status] == "success");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void run() override
|
||||||
|
{
|
||||||
|
testErrors();
|
||||||
|
testLookup();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
BEAST_DEFINE_TESTSUITE(ManifestRPC,rpc,ripple);
|
||||||
|
}
|
||||||
|
}
|
||||||
108
src/test/rpc/ValidatorInfo_test.cpp
Normal file
108
src/test/rpc/ValidatorInfo_test.cpp
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
This file is part of rippled: https://github.com/ripple/rippled
|
||||||
|
Copyright (c) 2020 Dev Null Productions, LLC
|
||||||
|
|
||||||
|
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 <test/jtx.h>
|
||||||
|
#include <ripple/beast/unit_test.h>
|
||||||
|
#include <ripple/core/ConfigSections.h>
|
||||||
|
#include <ripple/protocol/jss.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace ripple {
|
||||||
|
namespace test {
|
||||||
|
|
||||||
|
class ValidatorInfo_test : public beast::unit_test::suite
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void testErrors()
|
||||||
|
{
|
||||||
|
testcase ("Errors");
|
||||||
|
|
||||||
|
using namespace jtx;
|
||||||
|
{
|
||||||
|
Env env(*this);
|
||||||
|
auto const info = env.rpc ("validator_info");
|
||||||
|
BEAST_EXPECT(info[jss::result][jss::error_message] ==
|
||||||
|
"not a validator");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
testPrivileges()
|
||||||
|
{
|
||||||
|
using namespace test::jtx;
|
||||||
|
Env env{*this, envconfig(no_admin)};
|
||||||
|
auto const info = env.rpc ("validator_info")[jss::result];
|
||||||
|
BEAST_EXPECT(info.isNull());
|
||||||
|
}
|
||||||
|
|
||||||
|
void testLookup()
|
||||||
|
{
|
||||||
|
testcase ("Lookup");
|
||||||
|
|
||||||
|
using namespace jtx;
|
||||||
|
const std::vector<std::string> tokenBlob = {
|
||||||
|
" "
|
||||||
|
"eyJ2YWxpZGF0aW9uX3NlY3JldF9rZXkiOiI5ZWQ0NWY4NjYyNDFjYzE4YTI3NDdiNT\n",
|
||||||
|
" \tQzODdjMDYyNTkwNzk3MmY0ZTcxOTAyMzFmYWE5Mzc0NTdmYTlkYWY2IiwibWFuaWZl "
|
||||||
|
" \n",
|
||||||
|
"\tc3QiOiJKQUFBQUFGeEllMUZ0d21pbXZHdEgyaUNjTUpxQzlnVkZLaWxHZncxL3ZDeE"
|
||||||
|
"\n",
|
||||||
|
"\t "
|
||||||
|
"hYWExwbGMyR25NaEFrRTFhZ3FYeEJ3RHdEYklENk9NU1l1TTBGREFscEFnTms4U0tG\t "
|
||||||
|
"\t\n",
|
||||||
|
"bjdNTzJmZGtjd1JRSWhBT25ndTlzQUtxWFlvdUorbDJWMFcrc0FPa1ZCK1pSUzZQU2\n",
|
||||||
|
"hsSkFmVXNYZkFpQnNWSkdlc2FhZE9KYy9hQVpva1MxdnltR21WcmxIUEtXWDNZeXd1\n",
|
||||||
|
"NmluOEhBU1FLUHVnQkQ2N2tNYVJGR3ZtcEFUSGxHS0pkdkRGbFdQWXk1QXFEZWRGdj\n",
|
||||||
|
"VUSmEydzBpMjFlcTNNWXl3TFZKWm5GT3I3QzBrdzJBaVR6U0NqSXpkaXRROD0ifQ==\n"};
|
||||||
|
|
||||||
|
std::string const master_key = "nHBt9fsb4849WmZiCds4r5TXyBeQjqnH5kzPtqgMAQMgi39YZRPa";
|
||||||
|
std::string const ephemeral_key = "n9KsDYGKhABVc4wK5u3MnVhgPinyJimyKGpr9VJYuBaY8EnJXR2x";
|
||||||
|
std::string const manifest = "JAAAAAFxIe1FtwmimvGtH2iCcMJqC9gVFKilGfw1/vCxHXXLplc2GnMhAkE1agqXxBwDwDbID6OMSYuM0FDAlpAgNk8SKFn7MO2fdkcwRQIhAOngu9sAKqXYouJ+l2V0W+sAOkVB+ZRS6PShlJAfUsXfAiBsVJGesaadOJc/aAZokS1vymGmVrlHPKWX3Yywu6in8HASQKPugBD67kMaRFGvmpATHlGKJdvDFlWPYy5AqDedFv5TJa2w0i21eq3MYywLVJZnFOr7C0kw2AiTzSCjIzditQ8=";
|
||||||
|
|
||||||
|
Env env{
|
||||||
|
*this,
|
||||||
|
envconfig([&tokenBlob](std::unique_ptr<Config> cfg) {
|
||||||
|
cfg->section(SECTION_VALIDATOR_TOKEN).append(tokenBlob);
|
||||||
|
return cfg;
|
||||||
|
})
|
||||||
|
};
|
||||||
|
{
|
||||||
|
auto const info = env.rpc ("validator_info");
|
||||||
|
BEAST_EXPECT(info[jss::result][jss::status] == "success");
|
||||||
|
BEAST_EXPECT(info[jss::result][jss::seq] == 1);
|
||||||
|
BEAST_EXPECT(info[jss::result][jss::master_key] == master_key);
|
||||||
|
BEAST_EXPECT(info[jss::result][jss::manifest] == manifest);
|
||||||
|
BEAST_EXPECT(info[jss::result][jss::ephemeral_key] == ephemeral_key);
|
||||||
|
BEAST_EXPECT(info[jss::result][jss::domain] == "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void run() override
|
||||||
|
{
|
||||||
|
testErrors();
|
||||||
|
testPrivileges();
|
||||||
|
testLookup();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
BEAST_DEFINE_TESTSUITE(ValidatorInfo,rpc,ripple);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -39,6 +39,7 @@
|
|||||||
#include <test/rpc/LedgerData_test.cpp>
|
#include <test/rpc/LedgerData_test.cpp>
|
||||||
#include <test/rpc/LedgerRPC_test.cpp>
|
#include <test/rpc/LedgerRPC_test.cpp>
|
||||||
#include <test/rpc/LedgerRequestRPC_test.cpp>
|
#include <test/rpc/LedgerRequestRPC_test.cpp>
|
||||||
|
#include <test/rpc/ManifestRPC_test.cpp>
|
||||||
#include <test/rpc/NoRipple_test.cpp>
|
#include <test/rpc/NoRipple_test.cpp>
|
||||||
#include <test/rpc/NoRippleCheck_test.cpp>
|
#include <test/rpc/NoRippleCheck_test.cpp>
|
||||||
#include <test/rpc/OwnerInfo_test.cpp>
|
#include <test/rpc/OwnerInfo_test.cpp>
|
||||||
@@ -54,6 +55,7 @@
|
|||||||
#include <test/rpc/Transaction_test.cpp>
|
#include <test/rpc/Transaction_test.cpp>
|
||||||
#include <test/rpc/TransactionEntry_test.cpp>
|
#include <test/rpc/TransactionEntry_test.cpp>
|
||||||
#include <test/rpc/TransactionHistory_test.cpp>
|
#include <test/rpc/TransactionHistory_test.cpp>
|
||||||
|
#include <test/rpc/ValidatorInfo_test.cpp>
|
||||||
#include <test/rpc/Tx_test.cpp>
|
#include <test/rpc/Tx_test.cpp>
|
||||||
#include <test/rpc/ValidatorRPC_test.cpp>
|
#include <test/rpc/ValidatorRPC_test.cpp>
|
||||||
#include <test/rpc/Version_test.cpp>
|
#include <test/rpc/Version_test.cpp>
|
||||||
|
|||||||
Reference in New Issue
Block a user