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:
Miguel Portilla
2015-04-14 13:37:06 -04:00
committed by Nik Bougalis
parent dc2260adbe
commit d182d1455e
3 changed files with 73 additions and 24 deletions

View File

@@ -59,7 +59,7 @@ public:
static Condition condition()
{
return NEEDS_NETWORK_CONNECTION;
return NO_CONDITION;
}
private:

View File

@@ -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 },

View File

@@ -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;
}