mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Relax RPC ledger synchronization requirements (RIPD-27, RIPD-840):
This enhances the reporting capability of RPC::LookupLedger and reduces the requirement of a current ledger for many RPC commands. The perceived up-time of client handlers improves since requests will not depend on the server being fully synced.
This commit is contained in:
committed by
Nik Bougalis
parent
dc2260adbe
commit
d182d1455e
@@ -59,7 +59,7 @@ public:
|
||||
|
||||
static Condition condition()
|
||||
{
|
||||
return NEEDS_NETWORK_CONNECTION;
|
||||
return NO_CONDITION;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -96,15 +96,16 @@ class HandlerTable {
|
||||
};
|
||||
|
||||
HandlerTable HANDLERS({
|
||||
// Some handlers not specified here are added to the table via addHandler()
|
||||
// Request-response methods
|
||||
{ "account_info", byRef (&doAccountInfo), Role::USER, NEEDS_CURRENT_LEDGER },
|
||||
{ "account_currencies", byRef (&doAccountCurrencies), Role::USER, NEEDS_CURRENT_LEDGER },
|
||||
{ "account_lines", byRef (&doAccountLines), Role::USER, NEEDS_CURRENT_LEDGER },
|
||||
{ "account_objects", byRef (&doAccountObjects), Role::USER, NEEDS_CURRENT_LEDGER },
|
||||
{ "account_offers", byRef (&doAccountOffers), Role::USER, NEEDS_CURRENT_LEDGER },
|
||||
{ "account_tx", byRef (&doAccountTxSwitch), Role::USER, NEEDS_NETWORK_CONNECTION },
|
||||
{ "account_info", byRef (&doAccountInfo), Role::USER, NO_CONDITION },
|
||||
{ "account_currencies", byRef (&doAccountCurrencies), Role::USER, NO_CONDITION },
|
||||
{ "account_lines", byRef (&doAccountLines), Role::USER, NO_CONDITION },
|
||||
{ "account_objects", byRef (&doAccountObjects), Role::USER, NO_CONDITION },
|
||||
{ "account_offers", byRef (&doAccountOffers), Role::USER, NO_CONDITION },
|
||||
{ "account_tx", byRef (&doAccountTxSwitch), Role::USER, NO_CONDITION },
|
||||
{ "blacklist", byRef (&doBlackList), Role::ADMIN, NO_CONDITION },
|
||||
{ "book_offers", byRef (&doBookOffers), Role::USER, NEEDS_CURRENT_LEDGER },
|
||||
{ "book_offers", byRef (&doBookOffers), Role::USER, NO_CONDITION },
|
||||
{ "can_delete", byRef (&doCanDelete), Role::ADMIN, NO_CONDITION },
|
||||
{ "connect", byRef (&doConnect), Role::ADMIN, NO_CONDITION },
|
||||
{ "consensus_info", byRef (&doConsensusInfo), Role::ADMIN, NO_CONDITION },
|
||||
@@ -114,15 +115,15 @@ HandlerTable HANDLERS({
|
||||
{ "fetch_info", byRef (&doFetchInfo), Role::ADMIN, NO_CONDITION },
|
||||
{ "ledger_accept", byRef (&doLedgerAccept), Role::ADMIN, NEEDS_CURRENT_LEDGER },
|
||||
{ "ledger_cleaner", byRef (&doLedgerCleaner), Role::ADMIN, NEEDS_NETWORK_CONNECTION },
|
||||
{ "ledger_closed", byRef (&doLedgerClosed), Role::USER, NEEDS_CLOSED_LEDGER },
|
||||
{ "ledger_closed", byRef (&doLedgerClosed), Role::USER, NO_CONDITION },
|
||||
{ "ledger_current", byRef (&doLedgerCurrent), Role::USER, NEEDS_CURRENT_LEDGER },
|
||||
{ "ledger_data", byRef (&doLedgerData), Role::USER, NEEDS_CURRENT_LEDGER },
|
||||
{ "ledger_entry", byRef (&doLedgerEntry), Role::USER, NEEDS_CURRENT_LEDGER },
|
||||
{ "ledger_header", byRef (&doLedgerHeader), Role::USER, NEEDS_CURRENT_LEDGER },
|
||||
{ "ledger_data", byRef (&doLedgerData), Role::USER, NO_CONDITION },
|
||||
{ "ledger_entry", byRef (&doLedgerEntry), Role::USER, NO_CONDITION },
|
||||
{ "ledger_header", byRef (&doLedgerHeader), Role::USER, NO_CONDITION },
|
||||
{ "ledger_request", byRef (&doLedgerRequest), Role::ADMIN, NO_CONDITION },
|
||||
{ "log_level", byRef (&doLogLevel), Role::ADMIN, NO_CONDITION },
|
||||
{ "logrotate", byRef (&doLogRotate), Role::ADMIN, NO_CONDITION },
|
||||
{ "noripple_check", byRef (&doNoRippleCheck), Role::USER, NEEDS_CURRENT_LEDGER },
|
||||
{ "noripple_check", byRef (&doNoRippleCheck), Role::USER, NO_CONDITION },
|
||||
{ "owner_info", byRef (&doOwnerInfo), Role::USER, NEEDS_CURRENT_LEDGER },
|
||||
{ "peers", byRef (&doPeers), Role::ADMIN, NO_CONDITION },
|
||||
{ "path_find", byRef (&doPathFind), Role::USER, NEEDS_CURRENT_LEDGER },
|
||||
@@ -130,13 +131,13 @@ HandlerTable HANDLERS({
|
||||
{ "print", byRef (&doPrint), Role::ADMIN, NO_CONDITION },
|
||||
// { "profile", byRef (&doProfile), Role::USER, NEEDS_CURRENT_LEDGER },
|
||||
{ "random", byRef (&doRandom), Role::USER, NO_CONDITION },
|
||||
{ "ripple_path_find", byRef (&doRipplePathFind), Role::USER, NEEDS_CURRENT_LEDGER },
|
||||
{ "ripple_path_find", byRef (&doRipplePathFind), Role::USER, NO_CONDITION },
|
||||
{ "sign", byRef (&doSign), Role::USER, NO_CONDITION },
|
||||
{ "submit", byRef (&doSubmit), Role::USER, NEEDS_CURRENT_LEDGER },
|
||||
{ "server_info", byRef (&doServerInfo), Role::USER, NO_CONDITION },
|
||||
{ "server_state", byRef (&doServerState), Role::USER, NO_CONDITION },
|
||||
{ "stop", byRef (&doStop), Role::ADMIN, NO_CONDITION },
|
||||
{ "transaction_entry", byRef (&doTransactionEntry), Role::USER, NEEDS_CURRENT_LEDGER },
|
||||
{ "transaction_entry", byRef (&doTransactionEntry), Role::USER, NO_CONDITION },
|
||||
{ "tx", byRef (&doTx), Role::USER, NEEDS_NETWORK_CONNECTION },
|
||||
{ "tx_history", byRef (&doTxHistory), Role::USER, NO_CONDITION },
|
||||
{ "unl_add", byRef (&doUnlAdd), Role::ADMIN, NO_CONDITION },
|
||||
@@ -148,7 +149,7 @@ HandlerTable HANDLERS({
|
||||
{ "unl_score", byRef (&doUnlScore), Role::ADMIN, NO_CONDITION },
|
||||
{ "validation_create", byRef (&doValidationCreate), Role::ADMIN, NO_CONDITION },
|
||||
{ "validation_seed", byRef (&doValidationSeed), Role::ADMIN, NO_CONDITION },
|
||||
{ "wallet_accounts", byRef (&doWalletAccounts), Role::USER, NEEDS_CURRENT_LEDGER },
|
||||
{ "wallet_accounts", byRef (&doWalletAccounts), Role::USER, NO_CONDITION },
|
||||
{ "wallet_propose", byRef (&doWalletPropose), Role::ADMIN, NO_CONDITION },
|
||||
{ "wallet_seed", byRef (&doWalletSeed), Role::ADMIN, NO_CONDITION },
|
||||
|
||||
|
||||
@@ -25,6 +25,36 @@ namespace RPC {
|
||||
|
||||
namespace {
|
||||
|
||||
bool
|
||||
synced (NetworkOPs& netOps, Ledger::pointer ledger)
|
||||
{
|
||||
static auto const minSequenceGap = 10;
|
||||
|
||||
if (getConfig ().RUN_STANDALONE)
|
||||
return true;
|
||||
|
||||
if (ledger == netOps.getValidatedLedger ())
|
||||
{
|
||||
return getApp ().getLedgerMaster ().getValidatedLedgerAge () <=
|
||||
Tuning::maxValidatedLedgerAge;
|
||||
}
|
||||
|
||||
if (ledger != netOps.getCurrentLedger () &&
|
||||
ledger != netOps.getClosedLedger ())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (getApp ().getLedgerMaster ().getValidatedLedgerAge () >
|
||||
Tuning::maxValidatedLedgerAge)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return ledger->getLedgerSeq () >
|
||||
(netOps.getValidatedSeq () + minSequenceGap);
|
||||
}
|
||||
|
||||
Status ledgerFromRequest (
|
||||
Json::Value const& params,
|
||||
Ledger::pointer& ledger,
|
||||
@@ -47,35 +77,53 @@ Status ledgerFromRequest (
|
||||
|
||||
if (!hashValue.empty())
|
||||
{
|
||||
if (! hashValue.isString ())
|
||||
return {rpcINVALID_PARAMS, "ledgerHashNotString"};
|
||||
|
||||
uint256 ledgerHash;
|
||||
if (hashValue.isString() && ledgerHash.SetHex (hashValue.asString ()))
|
||||
ledger = netOps.getLedgerByHash (ledgerHash);
|
||||
else
|
||||
if (! ledgerHash.SetHex (hashValue.asString ()))
|
||||
return {rpcINVALID_PARAMS, "ledgerHashMalformed"};
|
||||
|
||||
ledger = netOps.getLedgerByHash (ledgerHash);
|
||||
}
|
||||
else if (indexValue.isNumeric())
|
||||
{
|
||||
ledger = netOps.getLedgerBySeq (indexValue.asInt());
|
||||
ledger = netOps.getLedgerBySeq (indexValue.asInt ());
|
||||
}
|
||||
else
|
||||
{
|
||||
auto index = indexValue.asString();
|
||||
auto isCurrent = index.empty() || index == "current";
|
||||
auto const index = indexValue.asString ();
|
||||
auto const isCurrent = index.empty() || index == "current";
|
||||
if (isCurrent)
|
||||
ledger = netOps.getCurrentLedger ();
|
||||
else if (index == "closed")
|
||||
ledger = getApp().getLedgerMaster ().getClosedLedger ();
|
||||
ledger = netOps.getClosedLedger ();
|
||||
else if (index == "validated")
|
||||
ledger = netOps.getValidatedLedger ();
|
||||
else
|
||||
return {rpcINVALID_PARAMS, "ledgerIndexMalformed"};
|
||||
|
||||
if (ledger == nullptr)
|
||||
return {rpcNO_NETWORK, "InsufficientNetworkMode"};
|
||||
|
||||
assert (ledger->isImmutable());
|
||||
assert (ledger->isClosed() == !isCurrent);
|
||||
}
|
||||
|
||||
if (!ledger)
|
||||
if (ledger == nullptr)
|
||||
{
|
||||
auto cl = netOps.getCurrentLedger ();
|
||||
if (cl == nullptr || ! synced (netOps, cl))
|
||||
return {rpcNO_NETWORK, "InsufficientNetworkMode"};
|
||||
|
||||
return {rpcLGR_NOT_FOUND, "ledgerNotFound"};
|
||||
}
|
||||
|
||||
if (! synced (netOps, ledger))
|
||||
{
|
||||
ledger.reset ();
|
||||
return {rpcNO_NETWORK, "InsufficientNetworkMode"};
|
||||
}
|
||||
|
||||
return Status::OK;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user