From 9cded76cf0ed30416201631911baec0b2c07f1c4 Mon Sep 17 00:00:00 2001 From: Miguel Portilla Date: Thu, 7 May 2015 17:36:41 -0400 Subject: [PATCH] Fix RPC ledger synchronization requirements: * Better rules specific to each lookup case: * By hash: Any ledger found by hash is valid. * By numeric index: If rippled is out of sync, and the index is after the * validated ledger, return "InsufficientNetworkMode" error. * By named index: If rippled is out of sync, or closed/current is requested and significantly older than the validated ledger, return "InsufficientNetworkMode" error. --- src/ripple/rpc/impl/LookupLedger.cpp | 102 ++++++++++++++------------- 1 file changed, 52 insertions(+), 50 deletions(-) diff --git a/src/ripple/rpc/impl/LookupLedger.cpp b/src/ripple/rpc/impl/LookupLedger.cpp index 4a49c7555a..cf7fd717a8 100644 --- a/src/ripple/rpc/impl/LookupLedger.cpp +++ b/src/ripple/rpc/impl/LookupLedger.cpp @@ -25,34 +25,13 @@ namespace RPC { namespace { -bool -synced (NetworkOPs& netOps, Ledger::pointer ledger) +bool isValidatedOld () { - 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); + return getApp ().getLedgerMaster ().getValidatedLedgerAge () > + Tuning::maxValidatedLedgerAge; } Status ledgerFromRequest ( @@ -60,6 +39,8 @@ Status ledgerFromRequest ( Ledger::pointer& ledger, NetworkOPs& netOps) { + static auto const minSequenceGap = 10; + ledger.reset(); auto indexValue = params[jss::ledger_index]; @@ -83,46 +64,67 @@ Status ledgerFromRequest ( uint256 ledgerHash; if (! ledgerHash.SetHex (hashValue.asString ())) return {rpcINVALID_PARAMS, "ledgerHashMalformed"}; - + ledger = netOps.getLedgerByHash (ledgerHash); + if (ledger == nullptr) + return {rpcLGR_NOT_FOUND, "ledgerNotFound"}; } else if (indexValue.isNumeric()) { ledger = netOps.getLedgerBySeq (indexValue.asInt ()); + if (ledger == nullptr) + return {rpcLGR_NOT_FOUND, "ledgerNotFound"}; + + if (ledger->getLedgerSeq () > netOps.getValidatedSeq () && + isValidatedOld ()) + { + ledger.reset(); + return {rpcNO_NETWORK, "InsufficientNetworkMode"}; + } } else { + if (isValidatedOld ()) + return {rpcNO_NETWORK, "InsufficientNetworkMode"}; + auto const index = indexValue.asString (); - auto const isCurrent = index.empty() || index == "current"; - if (isCurrent) - ledger = netOps.getCurrentLedger (); - else if (index == "closed") - ledger = netOps.getClosedLedger (); - else if (index == "validated") + if (index == "validated") + { ledger = netOps.getValidatedLedger (); + if (ledger == nullptr) + return {rpcNO_NETWORK, "InsufficientNetworkMode"}; + + assert (ledger->isClosed ()); + } else - return {rpcINVALID_PARAMS, "ledgerIndexMalformed"}; + { + if (index.empty () || index == "current") + { + ledger = netOps.getCurrentLedger (); + assert (! ledger->isClosed ()); + } + else if (index == "closed") + { + ledger = netOps.getClosedLedger (); + assert (ledger->isClosed ()); + } + else + { + return {rpcINVALID_PARAMS, "ledgerIndexMalformed"}; + } - if (ledger == nullptr) - return {rpcNO_NETWORK, "InsufficientNetworkMode"}; + if (ledger == nullptr) + return {rpcNO_NETWORK, "InsufficientNetworkMode"}; - assert (ledger->isImmutable()); - assert (ledger->isClosed() == !isCurrent); - } + if (ledger->getLedgerSeq () + minSequenceGap < + netOps.getValidatedSeq ()) + { + ledger.reset (); + return {rpcNO_NETWORK, "InsufficientNetworkMode"}; + } + } - 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"}; + assert (ledger->isImmutable ()); } return Status::OK;