diff --git a/Application_8cpp_source.html b/Application_8cpp_source.html index 47241fcb0f..0ea4213145 100644 --- a/Application_8cpp_source.html +++ b/Application_8cpp_source.html @@ -1118,1158 +1118,1154 @@ $(document).ready(function() { init_codefold(0); });
909 << "; size after: " << masterTxCache.size();
910 }
911 {
-
912 // Does not appear to have an associated cache.
-
913 getNodeStore().sweep();
-
914 }
-
915 {
-
916 std::size_t const oldLedgerMasterCacheSize = getLedgerMaster().getFetchPackCacheSize();
-
917
-
918 getLedgerMaster().sweep();
-
919
-
920 JLOG(m_journal.debug()) << "LedgerMaster sweep. Size before: " << oldLedgerMasterCacheSize
-
921 << "; size after: " << getLedgerMaster().getFetchPackCacheSize();
-
922 }
-
923 {
-
924 // NodeCache == TaggedCache<SHAMapHash, Blob>
-
925 std::size_t const oldTempNodeCacheSize = getTempNodeCache().size();
-
926
-
927 getTempNodeCache().sweep();
-
928
-
929 JLOG(m_journal.debug()) << "TempNodeCache sweep. Size before: " << oldTempNodeCacheSize
-
930 << "; size after: " << getTempNodeCache().size();
-
931 }
-
932 {
-
933 std::size_t const oldCurrentCacheSize = getValidations().sizeOfCurrentCache();
-
934 std::size_t const oldSizeSeqEnforcesSize = getValidations().sizeOfSeqEnforcersCache();
-
935 std::size_t const oldByLedgerSize = getValidations().sizeOfByLedgerCache();
-
936 std::size_t const oldBySequenceSize = getValidations().sizeOfBySequenceCache();
-
937
-
938 getValidations().expire(m_journal);
-
939
-
940 JLOG(m_journal.debug()) << "Validations Current expire. Size before: " << oldCurrentCacheSize
-
941 << "; size after: " << getValidations().sizeOfCurrentCache();
-
942
-
943 JLOG(m_journal.debug()) << "Validations SeqEnforcer expire. Size before: " << oldSizeSeqEnforcesSize
-
944 << "; size after: " << getValidations().sizeOfSeqEnforcersCache();
-
945
-
946 JLOG(m_journal.debug()) << "Validations ByLedger expire. Size before: " << oldByLedgerSize
-
947 << "; size after: " << getValidations().sizeOfByLedgerCache();
-
948
-
949 JLOG(m_journal.debug()) << "Validations BySequence expire. Size before: " << oldBySequenceSize
-
950 << "; size after: " << getValidations().sizeOfBySequenceCache();
-
951 }
-
952 {
-
953 std::size_t const oldInboundLedgersSize = getInboundLedgers().cacheSize();
-
954
-
955 getInboundLedgers().sweep();
-
956
-
957 JLOG(m_journal.debug()) << "InboundLedgers sweep. Size before: " << oldInboundLedgersSize
-
958 << "; size after: " << getInboundLedgers().cacheSize();
-
959 }
-
960 {
-
961 size_t const oldTasksSize = getLedgerReplayer().tasksSize();
-
962 size_t const oldDeltasSize = getLedgerReplayer().deltasSize();
-
963 size_t const oldSkipListsSize = getLedgerReplayer().skipListsSize();
-
964
-
965 getLedgerReplayer().sweep();
-
966
-
967 JLOG(m_journal.debug()) << "LedgerReplayer tasks sweep. Size before: " << oldTasksSize
-
968 << "; size after: " << getLedgerReplayer().tasksSize();
-
969
-
970 JLOG(m_journal.debug()) << "LedgerReplayer deltas sweep. Size before: " << oldDeltasSize
-
971 << "; size after: " << getLedgerReplayer().deltasSize();
-
972
-
973 JLOG(m_journal.debug()) << "LedgerReplayer skipLists sweep. Size before: " << oldSkipListsSize
-
974 << "; size after: " << getLedgerReplayer().skipListsSize();
-
975 }
-
976 {
-
977 std::size_t const oldAcceptedLedgerSize = m_acceptedLedgerCache.size();
-
978
-
979 m_acceptedLedgerCache.sweep();
-
980
-
981 JLOG(m_journal.debug()) << "AcceptedLedgerCache sweep. Size before: " << oldAcceptedLedgerSize
-
982 << "; size after: " << m_acceptedLedgerCache.size();
-
983 }
-
984 {
-
985 std::size_t const oldCachedSLEsSize = cachedSLEs_.size();
-
986
-
987 cachedSLEs_.sweep();
+
912 std::size_t const oldLedgerMasterCacheSize = getLedgerMaster().getFetchPackCacheSize();
+
913
+
914 getLedgerMaster().sweep();
+
915
+
916 JLOG(m_journal.debug()) << "LedgerMaster sweep. Size before: " << oldLedgerMasterCacheSize
+
917 << "; size after: " << getLedgerMaster().getFetchPackCacheSize();
+
918 }
+
919 {
+
920 // NodeCache == TaggedCache<SHAMapHash, Blob>
+
921 std::size_t const oldTempNodeCacheSize = getTempNodeCache().size();
+
922
+
923 getTempNodeCache().sweep();
+
924
+
925 JLOG(m_journal.debug()) << "TempNodeCache sweep. Size before: " << oldTempNodeCacheSize
+
926 << "; size after: " << getTempNodeCache().size();
+
927 }
+
928 {
+
929 std::size_t const oldCurrentCacheSize = getValidations().sizeOfCurrentCache();
+
930 std::size_t const oldSizeSeqEnforcesSize = getValidations().sizeOfSeqEnforcersCache();
+
931 std::size_t const oldByLedgerSize = getValidations().sizeOfByLedgerCache();
+
932 std::size_t const oldBySequenceSize = getValidations().sizeOfBySequenceCache();
+
933
+
934 getValidations().expire(m_journal);
+
935
+
936 JLOG(m_journal.debug()) << "Validations Current expire. Size before: " << oldCurrentCacheSize
+
937 << "; size after: " << getValidations().sizeOfCurrentCache();
+
938
+
939 JLOG(m_journal.debug()) << "Validations SeqEnforcer expire. Size before: " << oldSizeSeqEnforcesSize
+
940 << "; size after: " << getValidations().sizeOfSeqEnforcersCache();
+
941
+
942 JLOG(m_journal.debug()) << "Validations ByLedger expire. Size before: " << oldByLedgerSize
+
943 << "; size after: " << getValidations().sizeOfByLedgerCache();
+
944
+
945 JLOG(m_journal.debug()) << "Validations BySequence expire. Size before: " << oldBySequenceSize
+
946 << "; size after: " << getValidations().sizeOfBySequenceCache();
+
947 }
+
948 {
+
949 std::size_t const oldInboundLedgersSize = getInboundLedgers().cacheSize();
+
950
+
951 getInboundLedgers().sweep();
+
952
+
953 JLOG(m_journal.debug()) << "InboundLedgers sweep. Size before: " << oldInboundLedgersSize
+
954 << "; size after: " << getInboundLedgers().cacheSize();
+
955 }
+
956 {
+
957 size_t const oldTasksSize = getLedgerReplayer().tasksSize();
+
958 size_t const oldDeltasSize = getLedgerReplayer().deltasSize();
+
959 size_t const oldSkipListsSize = getLedgerReplayer().skipListsSize();
+
960
+
961 getLedgerReplayer().sweep();
+
962
+
963 JLOG(m_journal.debug()) << "LedgerReplayer tasks sweep. Size before: " << oldTasksSize
+
964 << "; size after: " << getLedgerReplayer().tasksSize();
+
965
+
966 JLOG(m_journal.debug()) << "LedgerReplayer deltas sweep. Size before: " << oldDeltasSize
+
967 << "; size after: " << getLedgerReplayer().deltasSize();
+
968
+
969 JLOG(m_journal.debug()) << "LedgerReplayer skipLists sweep. Size before: " << oldSkipListsSize
+
970 << "; size after: " << getLedgerReplayer().skipListsSize();
+
971 }
+
972 {
+
973 std::size_t const oldAcceptedLedgerSize = m_acceptedLedgerCache.size();
+
974
+
975 m_acceptedLedgerCache.sweep();
+
976
+
977 JLOG(m_journal.debug()) << "AcceptedLedgerCache sweep. Size before: " << oldAcceptedLedgerSize
+
978 << "; size after: " << m_acceptedLedgerCache.size();
+
979 }
+
980 {
+
981 std::size_t const oldCachedSLEsSize = cachedSLEs_.size();
+
982
+
983 cachedSLEs_.sweep();
+
984
+
985 JLOG(m_journal.debug()) << "CachedSLEs sweep. Size before: " << oldCachedSLEsSize
+
986 << "; size after: " << cachedSLEs_.size();
+
987 }
988
-
989 JLOG(m_journal.debug()) << "CachedSLEs sweep. Size before: " << oldCachedSLEsSize
-
990 << "; size after: " << cachedSLEs_.size();
-
991 }
+
989 // Set timer to do another sweep later.
+
990 setSweepTimer();
+
991 }
+
992
-
993 // Set timer to do another sweep later.
-
994 setSweepTimer();
-
995 }
+
993 LedgerIndex
+
+
994 getMaxDisallowedLedger() override
+
995 {
+
996 return maxDisallowedLedger_;
+
997 }
-
996
-
997 LedgerIndex
-
-
998 getMaxDisallowedLedger() override
-
999 {
-
1000 return maxDisallowedLedger_;
-
1001 }
+
998
+
999 virtual std::optional<uint256> const&
+
+
1000 trapTxID() const override
+
1001 {
+
1002 return trapTxID_;
+
1003 }
-
1002
-
1003 virtual std::optional<uint256> const&
-
-
1004 trapTxID() const override
-
1005 {
-
1006 return trapTxID_;
-
1007 }
+
1004
+
1005private:
+
1006 // For a newly-started validator, this is the greatest persisted ledger
+
1007 // and new validations must be greater than this.
+
1008 std::atomic<LedgerIndex> maxDisallowedLedger_{0};
+
1009
+
1010 void
+
1011 startGenesisLedger();
+
1012
+ +
1014 getLastFullLedger();
+
1015
+ +
1017 loadLedgerFromFile(std::string const& ledgerID);
+
1018
+
1019 bool
+
1020 loadOldLedger(std::string const& ledgerID, bool replay, bool isFilename, std::optional<uint256> trapTxID);
+
1021
+
1022 void
+
1023 setMaxDisallowedLedger();
+
1024};
-
1008
-
1009private:
-
1010 // For a newly-started validator, this is the greatest persisted ledger
-
1011 // and new validations must be greater than this.
-
1012 std::atomic<LedgerIndex> maxDisallowedLedger_{0};
-
1013
-
1014 void
-
1015 startGenesisLedger();
-
1016
-
1017 std::shared_ptr<Ledger>
-
1018 getLastFullLedger();
-
1019
-
1020 std::shared_ptr<Ledger>
-
1021 loadLedgerFromFile(std::string const& ledgerID);
-
1022
-
1023 bool
-
1024 loadOldLedger(std::string const& ledgerID, bool replay, bool isFilename, std::optional<uint256> trapTxID);
1025
-
1026 void
-
1027 setMaxDisallowedLedger();
-
1028};
-
-
1029
-
1030//------------------------------------------------------------------------------
-
1031
-
1032// TODO Break this up into smaller, more digestible initialization segments.
-
1033bool
-
-
1034ApplicationImp::setup(boost::program_options::variables_map const& cmdline)
-
1035{
-
1036 // We want to intercept CTRL-C and the standard termination signal SIGTERM
-
1037 // and terminate the process. This handler will NEVER be invoked twice.
-
1038 //
-
1039 // Note that async_wait is "one-shot": for each call, the handler will be
-
1040 // invoked exactly once, either when one of the registered signals in the
-
1041 // signal set occurs or the signal set is cancelled. Subsequent signals are
-
1042 // effectively ignored (technically, they are queued up, waiting for a call
-
1043 // to async_wait).
-
1044 m_signals.add(SIGINT);
-
1045 m_signals.add(SIGTERM);
-
1046 m_signals.async_wait([this](boost::system::error_code const& ec, int signum) {
-
1047 // Indicates the signal handler has been aborted; do nothing
-
1048 if (ec == boost::asio::error::operation_aborted)
-
1049 return;
-
1050
-
1051 JLOG(m_journal.info()) << "Received signal " << signum;
+
1026//------------------------------------------------------------------------------
+
1027
+
1028// TODO Break this up into smaller, more digestible initialization segments.
+
1029bool
+
+
1030ApplicationImp::setup(boost::program_options::variables_map const& cmdline)
+
1031{
+
1032 // We want to intercept CTRL-C and the standard termination signal SIGTERM
+
1033 // and terminate the process. This handler will NEVER be invoked twice.
+
1034 //
+
1035 // Note that async_wait is "one-shot": for each call, the handler will be
+
1036 // invoked exactly once, either when one of the registered signals in the
+
1037 // signal set occurs or the signal set is cancelled. Subsequent signals are
+
1038 // effectively ignored (technically, they are queued up, waiting for a call
+
1039 // to async_wait).
+
1040 m_signals.add(SIGINT);
+
1041 m_signals.add(SIGTERM);
+
1042 m_signals.async_wait([this](boost::system::error_code const& ec, int signum) {
+
1043 // Indicates the signal handler has been aborted; do nothing
+
1044 if (ec == boost::asio::error::operation_aborted)
+
1045 return;
+
1046
+
1047 JLOG(m_journal.info()) << "Received signal " << signum;
+
1048
+
1049 if (signum == SIGTERM || signum == SIGINT)
+
1050 signalStop("Signal: " + to_string(signum));
+
1051 });
1052
-
1053 if (signum == SIGTERM || signum == SIGINT)
-
1054 signalStop("Signal: " + to_string(signum));
-
1055 });
-
1056
-
1057 auto debug_log = config_->getDebugLogFile();
-
1058
-
1059 if (!debug_log.empty())
-
1060 {
-
1061 // Let debug messages go to the file but only WARNING or higher to
-
1062 // regular output (unless verbose)
-
1063
-
1064 if (!logs_->open(debug_log))
-
1065 std::cerr << "Can't open log file " << debug_log << '\n';
-
1066
-
1067 using namespace beast::severities;
-
1068 if (logs_->threshold() > kDebug)
-
1069 logs_->threshold(kDebug);
-
1070 }
-
1071
-
1072 JLOG(m_journal.info()) << "Process starting: " << BuildInfo::getFullVersionString()
-
1073 << ", Instance Cookie: " << instanceCookie_;
-
1074
-
1075 if (numberOfThreads(*config_) < 2)
-
1076 {
-
1077 JLOG(m_journal.warn()) << "Limited to a single I/O service thread by "
-
1078 "system configuration.";
-
1079 }
-
1080
-
1081 // Optionally turn off logging to console.
-
1082 logs_->silent(config_->silent());
-
1083
-
1084 if (!initRelationalDatabase() || !initNodeStore())
-
1085 return false;
-
1086
-
1087 if (!peerReservations_->load(getWalletDB()))
-
1088 {
-
1089 JLOG(m_journal.fatal()) << "Cannot find peer reservations!";
-
1090 return false;
-
1091 }
-
1092
-
1093 if (validatorKeys_.keys)
-
1094 setMaxDisallowedLedger();
-
1095
-
1096 // Configure the amendments the server supports
-
1097 {
-
1098 auto const supported = []() {
-
1099 auto const& amendments = detail::supportedAmendments();
- -
1101 supported.reserve(amendments.size());
-
1102 for (auto const& [a, vote] : amendments)
-
1103 {
-
1104 auto const f = xrpl::getRegisteredFeature(a);
-
1105 XRPL_ASSERT(f, "xrpl::ApplicationImp::setup : registered feature");
-
1106 if (f)
-
1107 supported.emplace_back(a, *f, vote);
-
1108 }
-
1109 return supported;
-
1110 }();
-
1111 Section const& downVoted = config_->section(SECTION_VETO_AMENDMENTS);
-
1112
-
1113 Section const& upVoted = config_->section(SECTION_AMENDMENTS);
+
1053 auto debug_log = config_->getDebugLogFile();
+
1054
+
1055 if (!debug_log.empty())
+
1056 {
+
1057 // Let debug messages go to the file but only WARNING or higher to
+
1058 // regular output (unless verbose)
+
1059
+
1060 if (!logs_->open(debug_log))
+
1061 std::cerr << "Can't open log file " << debug_log << '\n';
+
1062
+
1063 using namespace beast::severities;
+
1064 if (logs_->threshold() > kDebug)
+
1065 logs_->threshold(kDebug);
+
1066 }
+
1067
+
1068 JLOG(m_journal.info()) << "Process starting: " << BuildInfo::getFullVersionString()
+
1069 << ", Instance Cookie: " << instanceCookie_;
+
1070
+
1071 if (numberOfThreads(*config_) < 2)
+
1072 {
+
1073 JLOG(m_journal.warn()) << "Limited to a single I/O service thread by "
+
1074 "system configuration.";
+
1075 }
+
1076
+
1077 // Optionally turn off logging to console.
+
1078 logs_->silent(config_->silent());
+
1079
+
1080 if (!initRelationalDatabase() || !initNodeStore())
+
1081 return false;
+
1082
+
1083 if (!peerReservations_->load(getWalletDB()))
+
1084 {
+
1085 JLOG(m_journal.fatal()) << "Cannot find peer reservations!";
+
1086 return false;
+
1087 }
+
1088
+
1089 if (validatorKeys_.keys)
+
1090 setMaxDisallowedLedger();
+
1091
+
1092 // Configure the amendments the server supports
+
1093 {
+
1094 auto const supported = []() {
+
1095 auto const& amendments = detail::supportedAmendments();
+ +
1097 supported.reserve(amendments.size());
+
1098 for (auto const& [a, vote] : amendments)
+
1099 {
+
1100 auto const f = xrpl::getRegisteredFeature(a);
+
1101 XRPL_ASSERT(f, "xrpl::ApplicationImp::setup : registered feature");
+
1102 if (f)
+
1103 supported.emplace_back(a, *f, vote);
+
1104 }
+
1105 return supported;
+
1106 }();
+
1107 Section const& downVoted = config_->section(SECTION_VETO_AMENDMENTS);
+
1108
+
1109 Section const& upVoted = config_->section(SECTION_AMENDMENTS);
+
1110
+
1111 m_amendmentTable = make_AmendmentTable(
+
1112 *this, config().AMENDMENT_MAJORITY_TIME, supported, upVoted, downVoted, logs_->journal("Amendments"));
+
1113 }
1114
-
1115 m_amendmentTable = make_AmendmentTable(
-
1116 *this, config().AMENDMENT_MAJORITY_TIME, supported, upVoted, downVoted, logs_->journal("Amendments"));
-
1117 }
-
1118
-
1119 Pathfinder::initPathTable();
-
1120
-
1121 auto const startUp = config_->START_UP;
-
1122 JLOG(m_journal.debug()) << "startUp: " << startUp;
-
1123 if (startUp == Config::FRESH)
-
1124 {
-
1125 JLOG(m_journal.info()) << "Starting new Ledger";
-
1126
-
1127 startGenesisLedger();
-
1128 }
-
1129 else if (startUp == Config::LOAD || startUp == Config::LOAD_FILE || startUp == Config::REPLAY)
-
1130 {
-
1131 JLOG(m_journal.info()) << "Loading specified Ledger";
-
1132
-
1133 if (!loadOldLedger(
-
1134 config_->START_LEDGER, startUp == Config::REPLAY, startUp == Config::LOAD_FILE, config_->TRAP_TX_HASH))
-
1135 {
-
1136 JLOG(m_journal.error()) << "The specified ledger could not be loaded.";
-
1137 if (config_->FAST_LOAD)
-
1138 {
-
1139 // Fall back to syncing from the network, such as
-
1140 // when there's no existing data.
-
1141 startGenesisLedger();
+
1115 Pathfinder::initPathTable();
+
1116
+
1117 auto const startUp = config_->START_UP;
+
1118 JLOG(m_journal.debug()) << "startUp: " << startUp;
+
1119 if (startUp == Config::FRESH)
+
1120 {
+
1121 JLOG(m_journal.info()) << "Starting new Ledger";
+
1122
+
1123 startGenesisLedger();
+
1124 }
+
1125 else if (startUp == Config::LOAD || startUp == Config::LOAD_FILE || startUp == Config::REPLAY)
+
1126 {
+
1127 JLOG(m_journal.info()) << "Loading specified Ledger";
+
1128
+
1129 if (!loadOldLedger(
+
1130 config_->START_LEDGER, startUp == Config::REPLAY, startUp == Config::LOAD_FILE, config_->TRAP_TX_HASH))
+
1131 {
+
1132 JLOG(m_journal.error()) << "The specified ledger could not be loaded.";
+
1133 if (config_->FAST_LOAD)
+
1134 {
+
1135 // Fall back to syncing from the network, such as
+
1136 // when there's no existing data.
+
1137 startGenesisLedger();
+
1138 }
+
1139 else
+
1140 {
+
1141 return false;
1142 }
-
1143 else
-
1144 {
-
1145 return false;
-
1146 }
-
1147 }
-
1148 }
-
1149 else if (startUp == Config::NETWORK)
-
1150 {
-
1151 // This should probably become the default once we have a stable
-
1152 // network.
-
1153 if (!config_->standalone())
-
1154 m_networkOPs->setNeedNetworkLedger();
-
1155
+
1143 }
+
1144 }
+
1145 else if (startUp == Config::NETWORK)
+
1146 {
+
1147 // This should probably become the default once we have a stable
+
1148 // network.
+
1149 if (!config_->standalone())
+
1150 m_networkOPs->setNeedNetworkLedger();
+
1151
+
1152 startGenesisLedger();
+
1153 }
+
1154 else
+
1155 {
1156 startGenesisLedger();
1157 }
-
1158 else
-
1159 {
-
1160 startGenesisLedger();
-
1161 }
-
1162
-
1163 if (auto const& forcedRange = config().FORCED_LEDGER_RANGE_PRESENT)
-
1164 {
-
1165 m_ledgerMaster->setLedgerRangePresent(forcedRange->first, forcedRange->second);
-
1166 }
+
1158
+
1159 if (auto const& forcedRange = config().FORCED_LEDGER_RANGE_PRESENT)
+
1160 {
+
1161 m_ledgerMaster->setLedgerRangePresent(forcedRange->first, forcedRange->second);
+
1162 }
+
1163
+
1164 m_orderBookDB.setup(getLedgerMaster().getCurrentLedger());
+
1165
+
1166 nodeIdentity_ = getNodeIdentity(*this, cmdline);
1167
-
1168 m_orderBookDB.setup(getLedgerMaster().getCurrentLedger());
-
1169
-
1170 nodeIdentity_ = getNodeIdentity(*this, cmdline);
-
1171
-
1172 if (!cluster_->load(config().section(SECTION_CLUSTER_NODES)))
-
1173 {
-
1174 JLOG(m_journal.fatal()) << "Invalid entry in cluster configuration.";
-
1175 return false;
-
1176 }
+
1168 if (!cluster_->load(config().section(SECTION_CLUSTER_NODES)))
+
1169 {
+
1170 JLOG(m_journal.fatal()) << "Invalid entry in cluster configuration.";
+
1171 return false;
+
1172 }
+
1173
+
1174 {
+
1175 if (validatorKeys_.configInvalid())
+
1176 return false;
1177
-
1178 {
-
1179 if (validatorKeys_.configInvalid())
-
1180 return false;
-
1181
-
1182 if (!validatorManifests_->load(
-
1183 getWalletDB(),
-
1184 "ValidatorManifests",
-
1185 validatorKeys_.manifest,
-
1186 config().section(SECTION_VALIDATOR_KEY_REVOCATION).values()))
-
1187 {
-
1188 JLOG(m_journal.fatal()) << "Invalid configured validator manifest.";
-
1189 return false;
-
1190 }
-
1191
-
1192 publisherManifests_->load(getWalletDB(), "PublisherManifests");
-
1193
-
1194 // It is possible to have a valid ValidatorKeys object without
-
1195 // setting the signingKey or masterKey. This occurs if the
-
1196 // configuration file does not have either
-
1197 // SECTION_VALIDATOR_TOKEN or SECTION_VALIDATION_SEED section.
-
1198
-
1199 // masterKey for the configuration-file specified validator keys
-
1200 std::optional<PublicKey> localSigningKey;
-
1201 if (validatorKeys_.keys)
-
1202 localSigningKey = validatorKeys_.keys->publicKey;
-
1203
-
1204 // Setup trusted validators
-
1205 if (!validators_->load(
-
1206 localSigningKey,
-
1207 config().section(SECTION_VALIDATORS).values(),
-
1208 config().section(SECTION_VALIDATOR_LIST_KEYS).values(),
-
1209 config().VALIDATOR_LIST_THRESHOLD))
-
1210 {
-
1211 JLOG(m_journal.fatal()) << "Invalid entry in validator configuration.";
-
1212 return false;
-
1213 }
-
1214 }
-
1215
-
1216 if (!validatorSites_->load(config().section(SECTION_VALIDATOR_LIST_SITES).values()))
-
1217 {
-
1218 JLOG(m_journal.fatal()) << "Invalid entry in [" << SECTION_VALIDATOR_LIST_SITES << "]";
-
1219 return false;
-
1220 }
-
1221
-
1222 // Tell the AmendmentTable who the trusted validators are.
-
1223 m_amendmentTable->trustChanged(validators_->getQuorumKeys().second);
-
1224
+
1178 if (!validatorManifests_->load(
+
1179 getWalletDB(),
+
1180 "ValidatorManifests",
+
1181 validatorKeys_.manifest,
+
1182 config().section(SECTION_VALIDATOR_KEY_REVOCATION).values()))
+
1183 {
+
1184 JLOG(m_journal.fatal()) << "Invalid configured validator manifest.";
+
1185 return false;
+
1186 }
+
1187
+
1188 publisherManifests_->load(getWalletDB(), "PublisherManifests");
+
1189
+
1190 // It is possible to have a valid ValidatorKeys object without
+
1191 // setting the signingKey or masterKey. This occurs if the
+
1192 // configuration file does not have either
+
1193 // SECTION_VALIDATOR_TOKEN or SECTION_VALIDATION_SEED section.
+
1194
+
1195 // masterKey for the configuration-file specified validator keys
+
1196 std::optional<PublicKey> localSigningKey;
+
1197 if (validatorKeys_.keys)
+
1198 localSigningKey = validatorKeys_.keys->publicKey;
+
1199
+
1200 // Setup trusted validators
+
1201 if (!validators_->load(
+
1202 localSigningKey,
+
1203 config().section(SECTION_VALIDATORS).values(),
+
1204 config().section(SECTION_VALIDATOR_LIST_KEYS).values(),
+
1205 config().VALIDATOR_LIST_THRESHOLD))
+
1206 {
+
1207 JLOG(m_journal.fatal()) << "Invalid entry in validator configuration.";
+
1208 return false;
+
1209 }
+
1210 }
+
1211
+
1212 if (!validatorSites_->load(config().section(SECTION_VALIDATOR_LIST_SITES).values()))
+
1213 {
+
1214 JLOG(m_journal.fatal()) << "Invalid entry in [" << SECTION_VALIDATOR_LIST_SITES << "]";
+
1215 return false;
+
1216 }
+
1217
+
1218 // Tell the AmendmentTable who the trusted validators are.
+
1219 m_amendmentTable->trustChanged(validators_->getQuorumKeys().second);
+
1220
+
1221 //----------------------------------------------------------------------
+
1222 //
+
1223 // Server
+
1224 //
1225 //----------------------------------------------------------------------
-
1226 //
-
1227 // Server
-
1228 //
-
1229 //----------------------------------------------------------------------
-
1230
-
1231 // VFALCO NOTE Unfortunately, in stand-alone mode some code still
-
1232 // foolishly calls overlay(). When this is fixed we can
-
1233 // move the instantiation inside a conditional:
-
1234 //
-
1235 // if (!config_.standalone())
-
1236 overlay_ = make_Overlay(
-
1237 *this,
-
1238 setup_Overlay(*config_),
-
1239 *serverHandler_,
-
1240 *m_resourceManager,
-
1241 *m_resolver,
-
1242 get_io_context(),
-
1243 *config_,
-
1244 m_collectorManager->collector());
-
1245 add(*overlay_); // add to PropertyStream
-
1246
-
1247 // start first consensus round
-
1248 if (!m_networkOPs->beginConsensus(m_ledgerMaster->getClosedLedger()->header().hash, {}))
-
1249 {
-
1250 JLOG(m_journal.fatal()) << "Unable to start consensus";
-
1251 return false;
-
1252 }
-
1253
-
1254 {
-
1255 try
-
1256 {
-
1257 auto setup = setup_ServerHandler(*config_, beast::logstream{m_journal.error()});
-
1258 setup.makeContexts();
-
1259 serverHandler_->setup(setup, m_journal);
-
1260 fixConfigPorts(*config_, serverHandler_->endpoints());
-
1261 }
-
1262 catch (std::exception const& e)
-
1263 {
-
1264 if (auto stream = m_journal.fatal())
-
1265 {
-
1266 stream << "Unable to setup server handler";
-
1267 if (std::strlen(e.what()) > 0)
-
1268 stream << ": " << e.what();
-
1269 }
-
1270 return false;
-
1271 }
-
1272 }
-
1273
-
1274 // Begin connecting to network.
-
1275 if (!config_->standalone())
-
1276 {
-
1277 // Should this message be here, conceptually? In theory this sort
-
1278 // of message, if displayed, should be displayed from PeerFinder.
-
1279 if (config_->PEER_PRIVATE && config_->IPS_FIXED.empty())
-
1280 {
-
1281 JLOG(m_journal.warn()) << "No outbound peer connections will be made";
-
1282 }
-
1283
-
1284 // VFALCO NOTE the state timer resets the deadlock detector.
-
1285 //
-
1286 m_networkOPs->setStateTimer();
-
1287 }
-
1288 else
-
1289 {
-
1290 JLOG(m_journal.warn()) << "Running in standalone mode";
-
1291
-
1292 m_networkOPs->setStandAlone();
-
1293 }
-
1294
-
1295 if (config_->canSign())
-
1296 {
-
1297 JLOG(m_journal.warn()) << "*** The server is configured to allow the "
-
1298 "'sign' and 'sign_for'";
-
1299 JLOG(m_journal.warn()) << "*** commands. These commands have security "
-
1300 "implications and have";
-
1301 JLOG(m_journal.warn()) << "*** been deprecated. They will be removed "
-
1302 "in a future release of";
-
1303 JLOG(m_journal.warn()) << "*** rippled.";
-
1304 JLOG(m_journal.warn()) << "*** If you do not use them to sign "
-
1305 "transactions please edit your";
-
1306 JLOG(m_journal.warn()) << "*** configuration file and remove the [enable_signing] stanza.";
-
1307 JLOG(m_journal.warn()) << "*** If you do use them to sign transactions "
-
1308 "please migrate to a";
-
1309 JLOG(m_journal.warn()) << "*** standalone signing solution as soon as possible.";
-
1310 }
-
1311
-
1312 //
-
1313 // Execute start up rpc commands.
-
1314 //
-
1315 for (auto cmd : config_->section(SECTION_RPC_STARTUP).lines())
-
1316 {
-
1317 Json::Reader jrReader;
-
1318 Json::Value jvCommand;
-
1319
-
1320 if (!jrReader.parse(cmd, jvCommand))
-
1321 {
-
1322 JLOG(m_journal.fatal()) << "Couldn't parse entry in [" << SECTION_RPC_STARTUP << "]: '" << cmd;
-
1323 }
-
1324
-
1325 if (!config_->quiet())
-
1326 {
-
1327 JLOG(m_journal.fatal()) << "Startup RPC: " << jvCommand << std::endl;
-
1328 }
-
1329
-
1330 Resource::Charge loadType = Resource::feeReferenceRPC;
- -
1332 RPC::JsonContext context{
-
1333 {journal("RPCHandler"),
-
1334 *this,
-
1335 loadType,
-
1336 getOPs(),
-
1337 getLedgerMaster(),
-
1338 c,
-
1339 Role::ADMIN,
-
1340 {},
-
1341 {},
-
1342 RPC::apiMaximumSupportedVersion},
-
1343 jvCommand};
-
1344
-
1345 Json::Value jvResult;
-
1346 RPC::doCommand(context, jvResult);
-
1347
-
1348 if (!config_->quiet())
-
1349 {
-
1350 JLOG(m_journal.fatal()) << "Result: " << jvResult << std::endl;
-
1351 }
-
1352 }
-
1353
-
1354 validatorSites_->start();
-
1355
-
1356 return true;
-
1357}
+
1226
+
1227 // VFALCO NOTE Unfortunately, in stand-alone mode some code still
+
1228 // foolishly calls overlay(). When this is fixed we can
+
1229 // move the instantiation inside a conditional:
+
1230 //
+
1231 // if (!config_.standalone())
+
1232 overlay_ = make_Overlay(
+
1233 *this,
+
1234 setup_Overlay(*config_),
+
1235 *serverHandler_,
+
1236 *m_resourceManager,
+
1237 *m_resolver,
+
1238 get_io_context(),
+
1239 *config_,
+
1240 m_collectorManager->collector());
+
1241 add(*overlay_); // add to PropertyStream
+
1242
+
1243 // start first consensus round
+
1244 if (!m_networkOPs->beginConsensus(m_ledgerMaster->getClosedLedger()->header().hash, {}))
+
1245 {
+
1246 JLOG(m_journal.fatal()) << "Unable to start consensus";
+
1247 return false;
+
1248 }
+
1249
+
1250 {
+
1251 try
+
1252 {
+
1253 auto setup = setup_ServerHandler(*config_, beast::logstream{m_journal.error()});
+
1254 setup.makeContexts();
+
1255 serverHandler_->setup(setup, m_journal);
+
1256 fixConfigPorts(*config_, serverHandler_->endpoints());
+
1257 }
+
1258 catch (std::exception const& e)
+
1259 {
+
1260 if (auto stream = m_journal.fatal())
+
1261 {
+
1262 stream << "Unable to setup server handler";
+
1263 if (std::strlen(e.what()) > 0)
+
1264 stream << ": " << e.what();
+
1265 }
+
1266 return false;
+
1267 }
+
1268 }
+
1269
+
1270 // Begin connecting to network.
+
1271 if (!config_->standalone())
+
1272 {
+
1273 // Should this message be here, conceptually? In theory this sort
+
1274 // of message, if displayed, should be displayed from PeerFinder.
+
1275 if (config_->PEER_PRIVATE && config_->IPS_FIXED.empty())
+
1276 {
+
1277 JLOG(m_journal.warn()) << "No outbound peer connections will be made";
+
1278 }
+
1279
+
1280 // VFALCO NOTE the state timer resets the deadlock detector.
+
1281 //
+
1282 m_networkOPs->setStateTimer();
+
1283 }
+
1284 else
+
1285 {
+
1286 JLOG(m_journal.warn()) << "Running in standalone mode";
+
1287
+
1288 m_networkOPs->setStandAlone();
+
1289 }
+
1290
+
1291 if (config_->canSign())
+
1292 {
+
1293 JLOG(m_journal.warn()) << "*** The server is configured to allow the "
+
1294 "'sign' and 'sign_for'";
+
1295 JLOG(m_journal.warn()) << "*** commands. These commands have security "
+
1296 "implications and have";
+
1297 JLOG(m_journal.warn()) << "*** been deprecated. They will be removed "
+
1298 "in a future release of";
+
1299 JLOG(m_journal.warn()) << "*** rippled.";
+
1300 JLOG(m_journal.warn()) << "*** If you do not use them to sign "
+
1301 "transactions please edit your";
+
1302 JLOG(m_journal.warn()) << "*** configuration file and remove the [enable_signing] stanza.";
+
1303 JLOG(m_journal.warn()) << "*** If you do use them to sign transactions "
+
1304 "please migrate to a";
+
1305 JLOG(m_journal.warn()) << "*** standalone signing solution as soon as possible.";
+
1306 }
+
1307
+
1308 //
+
1309 // Execute start up rpc commands.
+
1310 //
+
1311 for (auto cmd : config_->section(SECTION_RPC_STARTUP).lines())
+
1312 {
+
1313 Json::Reader jrReader;
+
1314 Json::Value jvCommand;
+
1315
+
1316 if (!jrReader.parse(cmd, jvCommand))
+
1317 {
+
1318 JLOG(m_journal.fatal()) << "Couldn't parse entry in [" << SECTION_RPC_STARTUP << "]: '" << cmd;
+
1319 }
+
1320
+
1321 if (!config_->quiet())
+
1322 {
+
1323 JLOG(m_journal.fatal()) << "Startup RPC: " << jvCommand << std::endl;
+
1324 }
+
1325
+
1326 Resource::Charge loadType = Resource::feeReferenceRPC;
+ +
1328 RPC::JsonContext context{
+
1329 {journal("RPCHandler"),
+
1330 *this,
+
1331 loadType,
+
1332 getOPs(),
+
1333 getLedgerMaster(),
+
1334 c,
+
1335 Role::ADMIN,
+
1336 {},
+
1337 {},
+
1338 RPC::apiMaximumSupportedVersion},
+
1339 jvCommand};
+
1340
+
1341 Json::Value jvResult;
+
1342 RPC::doCommand(context, jvResult);
+
1343
+
1344 if (!config_->quiet())
+
1345 {
+
1346 JLOG(m_journal.fatal()) << "Result: " << jvResult << std::endl;
+
1347 }
+
1348 }
+
1349
+
1350 validatorSites_->start();
+
1351
+
1352 return true;
+
1353}
+
+
1354
+
1355void
+
+
1356ApplicationImp::start(bool withTimers)
+
1357{
+
1358 JLOG(m_journal.info()) << "Application starting. Version is " << BuildInfo::getVersionString();
+
1359
+
1360 if (withTimers)
+
1361 {
+
1362 setSweepTimer();
+
1363 setEntropyTimer();
+
1364 }
+
1365
+
1366 m_io_latency_sampler.start();
+
1367 m_resolver->start();
+
1368 m_loadManager->start();
+
1369 m_shaMapStore->start();
+
1370 if (overlay_)
+
1371 overlay_->start();
+
1372
+
1373 if (grpcServer_->start())
+
1374 fixConfigPorts(*config_, {{SECTION_PORT_GRPC, grpcServer_->getEndpoint()}});
+
1375
+
1376 ledgerCleaner_->start();
+
1377 perfLog_->start();
+
1378}
-
1358
-
1359void
-
-
1360ApplicationImp::start(bool withTimers)
-
1361{
-
1362 JLOG(m_journal.info()) << "Application starting. Version is " << BuildInfo::getVersionString();
-
1363
-
1364 if (withTimers)
-
1365 {
-
1366 setSweepTimer();
-
1367 setEntropyTimer();
-
1368 }
-
1369
-
1370 m_io_latency_sampler.start();
-
1371 m_resolver->start();
-
1372 m_loadManager->start();
-
1373 m_shaMapStore->start();
-
1374 if (overlay_)
-
1375 overlay_->start();
-
1376
-
1377 if (grpcServer_->start())
-
1378 fixConfigPorts(*config_, {{SECTION_PORT_GRPC, grpcServer_->getEndpoint()}});
1379
-
1380 ledgerCleaner_->start();
-
1381 perfLog_->start();
-
1382}
-
-
1383
-
1384void
-
-
1385ApplicationImp::run()
-
1386{
-
1387 if (!config_->standalone())
-
1388 {
-
1389 // VFALCO NOTE This seems unnecessary. If we properly refactor the load
-
1390 // manager then the stall detector can just always be
-
1391 // "armed"
-
1392 //
-
1393 getLoadManager().activateStallDetector();
-
1394 }
+
1380void
+
+
1381ApplicationImp::run()
+
1382{
+
1383 if (!config_->standalone())
+
1384 {
+
1385 // VFALCO NOTE This seems unnecessary. If we properly refactor the load
+
1386 // manager then the stall detector can just always be
+
1387 // "armed"
+
1388 //
+
1389 getLoadManager().activateStallDetector();
+
1390 }
+
1391
+
1392 isTimeToStop.wait(false, std::memory_order_relaxed);
+
1393
+
1394 JLOG(m_journal.debug()) << "Application stopping";
1395
-
1396 isTimeToStop.wait(false, std::memory_order_relaxed);
+
1396 m_io_latency_sampler.cancel_async();
1397
-
1398 JLOG(m_journal.debug()) << "Application stopping";
-
1399
-
1400 m_io_latency_sampler.cancel_async();
-
1401
-
1402 // VFALCO Enormous hack, we have to force the probe to cancel
-
1403 // before we stop the io_context queue or else it never
-
1404 // unblocks in its destructor. The fix is to make all
-
1405 // io_objects gracefully handle exit so that we can
-
1406 // naturally return from io_context::run() instead of
-
1407 // forcing a call to io_context::stop()
-
1408 m_io_latency_sampler.cancel();
-
1409
-
1410 m_resolver->stop_async();
-
1411
-
1412 // NIKB This is a hack - we need to wait for the resolver to
-
1413 // stop. before we stop the io_server_queue or weird
-
1414 // things will happen.
-
1415 m_resolver->stop();
-
1416
-
1417 {
-
1418 try
+
1398 // VFALCO Enormous hack, we have to force the probe to cancel
+
1399 // before we stop the io_context queue or else it never
+
1400 // unblocks in its destructor. The fix is to make all
+
1401 // io_objects gracefully handle exit so that we can
+
1402 // naturally return from io_context::run() instead of
+
1403 // forcing a call to io_context::stop()
+
1404 m_io_latency_sampler.cancel();
+
1405
+
1406 m_resolver->stop_async();
+
1407
+
1408 // NIKB This is a hack - we need to wait for the resolver to
+
1409 // stop. before we stop the io_server_queue or weird
+
1410 // things will happen.
+
1411 m_resolver->stop();
+
1412
+
1413 {
+
1414 try
+
1415 {
+
1416 sweepTimer_.cancel();
+
1417 }
+
1418 catch (boost::system::system_error const& e)
1419 {
-
1420 sweepTimer_.cancel();
+
1420 JLOG(m_journal.error()) << "Application: sweepTimer cancel error: " << e.what();
1421 }
-
1422 catch (boost::system::system_error const& e)
-
1423 {
-
1424 JLOG(m_journal.error()) << "Application: sweepTimer cancel error: " << e.what();
-
1425 }
-
1426
-
1427 try
+
1422
+
1423 try
+
1424 {
+
1425 entropyTimer_.cancel();
+
1426 }
+
1427 catch (boost::system::system_error const& e)
1428 {
-
1429 entropyTimer_.cancel();
+
1429 JLOG(m_journal.error()) << "Application: entropyTimer cancel error: " << e.what();
1430 }
-
1431 catch (boost::system::system_error const& e)
-
1432 {
-
1433 JLOG(m_journal.error()) << "Application: entropyTimer cancel error: " << e.what();
-
1434 }
-
1435 }
+
1431 }
+
1432
+
1433 // Make sure that any waitHandlers pending in our timers are done
+
1434 // before we declare ourselves stopped.
+
1435 using namespace std::chrono_literals;
1436
-
1437 // Make sure that any waitHandlers pending in our timers are done
-
1438 // before we declare ourselves stopped.
-
1439 using namespace std::chrono_literals;
+
1437 waitHandlerCounter_.join("Application", 1s, m_journal);
+
1438
+
1439 mValidations.flush();
1440
-
1441 waitHandlerCounter_.join("Application", 1s, m_journal);
+
1441 validatorSites_->stop();
1442
-
1443 mValidations.flush();
-
1444
-
1445 validatorSites_->stop();
+
1443 // TODO Store manifests in manifests.sqlite instead of wallet.db
+
1444 validatorManifests_->save(
+
1445 getWalletDB(), "ValidatorManifests", [this](PublicKey const& pubKey) { return validators().listed(pubKey); });
1446
-
1447 // TODO Store manifests in manifests.sqlite instead of wallet.db
-
1448 validatorManifests_->save(
-
1449 getWalletDB(), "ValidatorManifests", [this](PublicKey const& pubKey) { return validators().listed(pubKey); });
+
1447 publisherManifests_->save(getWalletDB(), "PublisherManifests", [this](PublicKey const& pubKey) {
+
1448 return validators().trustedPublisher(pubKey);
+
1449 });
1450
-
1451 publisherManifests_->save(getWalletDB(), "PublisherManifests", [this](PublicKey const& pubKey) {
-
1452 return validators().trustedPublisher(pubKey);
-
1453 });
-
1454
-
1455 // The order of these stop calls is delicate.
-
1456 // Re-ordering them risks undefined behavior.
-
1457 m_loadManager->stop();
-
1458 m_shaMapStore->stop();
-
1459 m_jobQueue->stop();
-
1460 if (overlay_)
-
1461 overlay_->stop();
-
1462 grpcServer_->stop();
-
1463 m_networkOPs->stop();
-
1464 serverHandler_->stop();
-
1465 m_ledgerReplayer->stop();
-
1466 m_inboundTransactions->stop();
-
1467 m_inboundLedgers->stop();
-
1468 ledgerCleaner_->stop();
-
1469 m_nodeStore->stop();
-
1470 perfLog_->stop();
-
1471
-
1472 JLOG(m_journal.info()) << "Done.";
-
1473}
+
1451 // The order of these stop calls is delicate.
+
1452 // Re-ordering them risks undefined behavior.
+
1453 m_loadManager->stop();
+
1454 m_shaMapStore->stop();
+
1455 m_jobQueue->stop();
+
1456 if (overlay_)
+
1457 overlay_->stop();
+
1458 grpcServer_->stop();
+
1459 m_networkOPs->stop();
+
1460 serverHandler_->stop();
+
1461 m_ledgerReplayer->stop();
+
1462 m_inboundTransactions->stop();
+
1463 m_inboundLedgers->stop();
+
1464 ledgerCleaner_->stop();
+
1465 m_nodeStore->stop();
+
1466 perfLog_->stop();
+
1467
+
1468 JLOG(m_journal.info()) << "Done.";
+
1469}
+
+
1470
+
1471void
+
+
1472ApplicationImp::signalStop(std::string msg)
+
1473{
+
1474 if (!isTimeToStop.test_and_set(std::memory_order_acquire))
+
1475 {
+
1476 if (msg.empty())
+
1477 JLOG(m_journal.warn()) << "Server stopping";
+
1478 else
+
1479 JLOG(m_journal.warn()) << "Server stopping: " << msg;
+
1480
+
1481 isTimeToStop.notify_all();
+
1482 }
+
1483}
-
1474
-
1475void
-
-
1476ApplicationImp::signalStop(std::string msg)
-
1477{
-
1478 if (!isTimeToStop.test_and_set(std::memory_order_acquire))
-
1479 {
-
1480 if (msg.empty())
-
1481 JLOG(m_journal.warn()) << "Server stopping";
-
1482 else
-
1483 JLOG(m_journal.warn()) << "Server stopping: " << msg;
1484
-
1485 isTimeToStop.notify_all();
-
1486 }
-
1487}
+
1485bool
+
+
1486ApplicationImp::checkSigs() const
+
1487{
+
1488 return checkSigs_;
+
1489}
-
1488
-
1489bool
-
-
1490ApplicationImp::checkSigs() const
-
1491{
-
1492 return checkSigs_;
-
1493}
+
1490
+
1491void
+
+
1492ApplicationImp::checkSigs(bool check)
+
1493{
+
1494 checkSigs_ = check;
+
1495}
-
1494
-
1495void
-
-
1496ApplicationImp::checkSigs(bool check)
-
1497{
-
1498 checkSigs_ = check;
-
1499}
+
1496
+
1497bool
+
+
1498ApplicationImp::isStopping() const
+
1499{
+
1500 return isTimeToStop.test(std::memory_order_relaxed);
+
1501}
-
1500
-
1501bool
-
-
1502ApplicationImp::isStopping() const
-
1503{
-
1504 return isTimeToStop.test(std::memory_order_relaxed);
-
1505}
-
-
1506
-
1507int
-
-
1508ApplicationImp::fdRequired() const
-
1509{
-
1510 // Standard handles, config file, misc I/O etc:
-
1511 int needed = 128;
+
1502
+
1503int
+
+
1504ApplicationImp::fdRequired() const
+
1505{
+
1506 // Standard handles, config file, misc I/O etc:
+
1507 int needed = 128;
+
1508
+
1509 // 2x the configured peer limit for peer connections:
+
1510 if (overlay_)
+
1511 needed += 2 * overlay_->limit();
1512
-
1513 // 2x the configured peer limit for peer connections:
-
1514 if (overlay_)
-
1515 needed += 2 * overlay_->limit();
+
1513 // the number of fds needed by the backend (internally
+
1514 // doubled if online delete is enabled).
+
1515 needed += std::max(5, m_shaMapStore->fdRequired());
1516
-
1517 // the number of fds needed by the backend (internally
-
1518 // doubled if online delete is enabled).
-
1519 needed += std::max(5, m_shaMapStore->fdRequired());
-
1520
-
1521 // One fd per incoming connection a port can accept, or
-
1522 // if no limit is set, assume it'll handle 256 clients.
-
1523 for (auto const& p : serverHandler_->setup().ports)
-
1524 needed += std::max(256, p.limit);
+
1517 // One fd per incoming connection a port can accept, or
+
1518 // if no limit is set, assume it'll handle 256 clients.
+
1519 for (auto const& p : serverHandler_->setup().ports)
+
1520 needed += std::max(256, p.limit);
+
1521
+
1522 // The minimum number of file descriptors we need is 1024:
+
1523 return std::max(1024, needed);
+
1524}
+
1525
-
1526 // The minimum number of file descriptors we need is 1024:
-
1527 return std::max(1024, needed);
-
1528}
-
-
1529
-
1530//------------------------------------------------------------------------------
-
1531
-
1532void
-
-
1533ApplicationImp::startGenesisLedger()
-
1534{
-
1535 std::vector<uint256> const initialAmendments =
-
1536 (config_->START_UP == Config::FRESH) ? m_amendmentTable->getDesired() : std::vector<uint256>{};
+
1526//------------------------------------------------------------------------------
+
1527
+
1528void
+
+
1529ApplicationImp::startGenesisLedger()
+
1530{
+
1531 std::vector<uint256> const initialAmendments =
+
1532 (config_->START_UP == Config::FRESH) ? m_amendmentTable->getDesired() : std::vector<uint256>{};
+
1533
+
1534 std::shared_ptr<Ledger> const genesis =
+
1535 std::make_shared<Ledger>(create_genesis, *config_, initialAmendments, nodeFamily_);
+
1536 m_ledgerMaster->storeLedger(genesis);
1537
-
1538 std::shared_ptr<Ledger> const genesis =
-
1539 std::make_shared<Ledger>(create_genesis, *config_, initialAmendments, nodeFamily_);
-
1540 m_ledgerMaster->storeLedger(genesis);
-
1541
-
1542 auto const next = std::make_shared<Ledger>(*genesis, timeKeeper().closeTime());
-
1543 next->updateSkipList();
-
1544 XRPL_ASSERT(
-
1545 next->header().seq < XRP_LEDGER_EARLIEST_FEES || next->read(keylet::fees()),
-
1546 "xrpl::ApplicationImp::startGenesisLedger : valid ledger fees");
-
1547 next->setImmutable();
-
1548 openLedger_.emplace(next, cachedSLEs_, logs_->journal("OpenLedger"));
-
1549 m_ledgerMaster->storeLedger(next);
-
1550 m_ledgerMaster->switchLCL(next);
-
1551}
+
1538 auto const next = std::make_shared<Ledger>(*genesis, timeKeeper().closeTime());
+
1539 next->updateSkipList();
+
1540 XRPL_ASSERT(
+
1541 next->header().seq < XRP_LEDGER_EARLIEST_FEES || next->read(keylet::fees()),
+
1542 "xrpl::ApplicationImp::startGenesisLedger : valid ledger fees");
+
1543 next->setImmutable();
+
1544 openLedger_.emplace(next, cachedSLEs_, logs_->journal("OpenLedger"));
+
1545 m_ledgerMaster->storeLedger(next);
+
1546 m_ledgerMaster->switchLCL(next);
+
1547}
-
1552
- -
-
1554ApplicationImp::getLastFullLedger()
-
1555{
-
1556 auto j = journal("Ledger");
+
1548
+ +
+
1550ApplicationImp::getLastFullLedger()
+
1551{
+
1552 auto j = journal("Ledger");
+
1553
+
1554 try
+
1555 {
+
1556 auto const [ledger, seq, hash] = getLatestLedger(*this);
1557
-
1558 try
-
1559 {
-
1560 auto const [ledger, seq, hash] = getLatestLedger(*this);
-
1561
-
1562 if (!ledger)
-
1563 return ledger;
-
1564
-
1565 XRPL_ASSERT(
-
1566 ledger->header().seq < XRP_LEDGER_EARLIEST_FEES || ledger->read(keylet::fees()),
-
1567 "xrpl::ApplicationImp::getLastFullLedger : valid ledger fees");
-
1568 ledger->setImmutable();
-
1569
-
1570 if (getLedgerMaster().haveLedger(seq))
-
1571 ledger->setValidated();
-
1572
-
1573 if (ledger->header().hash == hash)
-
1574 {
-
1575 JLOG(j.trace()) << "Loaded ledger: " << hash;
-
1576 return ledger;
-
1577 }
-
1578
-
1579 if (auto stream = j.error())
-
1580 {
-
1581 stream << "Failed on ledger";
-
1582 Json::Value p;
-
1583 addJson(p, {*ledger, nullptr, LedgerFill::full});
-
1584 stream << p;
-
1585 }
-
1586
-
1587 return {};
-
1588 }
-
1589 catch (SHAMapMissingNode const& mn)
-
1590 {
-
1591 JLOG(j.warn()) << "Ledger in database: " << mn.what();
-
1592 return {};
-
1593 }
-
1594}
+
1558 if (!ledger)
+
1559 return ledger;
+
1560
+
1561 XRPL_ASSERT(
+
1562 ledger->header().seq < XRP_LEDGER_EARLIEST_FEES || ledger->read(keylet::fees()),
+
1563 "xrpl::ApplicationImp::getLastFullLedger : valid ledger fees");
+
1564 ledger->setImmutable();
+
1565
+
1566 if (getLedgerMaster().haveLedger(seq))
+
1567 ledger->setValidated();
+
1568
+
1569 if (ledger->header().hash == hash)
+
1570 {
+
1571 JLOG(j.trace()) << "Loaded ledger: " << hash;
+
1572 return ledger;
+
1573 }
+
1574
+
1575 if (auto stream = j.error())
+
1576 {
+
1577 stream << "Failed on ledger";
+
1578 Json::Value p;
+
1579 addJson(p, {*ledger, nullptr, LedgerFill::full});
+
1580 stream << p;
+
1581 }
+
1582
+
1583 return {};
+
1584 }
+
1585 catch (SHAMapMissingNode const& mn)
+
1586 {
+
1587 JLOG(j.warn()) << "Ledger in database: " << mn.what();
+
1588 return {};
+
1589 }
+
1590}
-
1595
- -
-
1597ApplicationImp::loadLedgerFromFile(std::string const& name)
-
1598{
-
1599 try
-
1600 {
-
1601 std::ifstream ledgerFile(name, std::ios::in);
-
1602
-
1603 if (!ledgerFile)
-
1604 {
-
1605 JLOG(m_journal.fatal()) << "Unable to open file '" << name << "'";
-
1606 return nullptr;
-
1607 }
-
1608
-
1609 Json::Reader reader;
-
1610 Json::Value jLedger;
-
1611
-
1612 if (!reader.parse(ledgerFile, jLedger))
-
1613 {
-
1614 JLOG(m_journal.fatal()) << "Unable to parse ledger JSON";
-
1615 return nullptr;
-
1616 }
-
1617
- +
1591
+ +
+
1593ApplicationImp::loadLedgerFromFile(std::string const& name)
+
1594{
+
1595 try
+
1596 {
+
1597 std::ifstream ledgerFile(name, std::ios::in);
+
1598
+
1599 if (!ledgerFile)
+
1600 {
+
1601 JLOG(m_journal.fatal()) << "Unable to open file '" << name << "'";
+
1602 return nullptr;
+
1603 }
+
1604
+
1605 Json::Reader reader;
+
1606 Json::Value jLedger;
+
1607
+
1608 if (!reader.parse(ledgerFile, jLedger))
+
1609 {
+
1610 JLOG(m_journal.fatal()) << "Unable to parse ledger JSON";
+
1611 return nullptr;
+
1612 }
+
1613
+ +
1615
+
1616 // accept a wrapped ledger
+
1617 if (ledger.get().isMember("result"))
+
1618 ledger = ledger.get()["result"];
1619
-
1620 // accept a wrapped ledger
-
1621 if (ledger.get().isMember("result"))
-
1622 ledger = ledger.get()["result"];
-
1623
-
1624 if (ledger.get().isMember("ledger"))
-
1625 ledger = ledger.get()["ledger"];
-
1626
-
1627 std::uint32_t seq = 1;
-
1628 auto closeTime = timeKeeper().closeTime();
-
1629 using namespace std::chrono_literals;
-
1630 auto closeTimeResolution = 30s;
-
1631 bool closeTimeEstimated = false;
-
1632 std::uint64_t totalDrops = 0;
-
1633
-
1634 if (ledger.get().isMember("accountState"))
-
1635 {
-
1636 if (ledger.get().isMember(jss::ledger_index))
-
1637 {
-
1638 seq = ledger.get()[jss::ledger_index].asUInt();
-
1639 }
-
1640
-
1641 if (ledger.get().isMember("close_time"))
-
1642 {
-
1643 using tp = NetClock::time_point;
-
1644 using d = tp::duration;
-
1645 closeTime = tp{d{ledger.get()["close_time"].asUInt()}};
-
1646 }
-
1647 if (ledger.get().isMember("close_time_resolution"))
-
1648 {
-
1649 using namespace std::chrono;
-
1650 closeTimeResolution = seconds{ledger.get()["close_time_resolution"].asUInt()};
+
1620 if (ledger.get().isMember("ledger"))
+
1621 ledger = ledger.get()["ledger"];
+
1622
+
1623 std::uint32_t seq = 1;
+
1624 auto closeTime = timeKeeper().closeTime();
+
1625 using namespace std::chrono_literals;
+
1626 auto closeTimeResolution = 30s;
+
1627 bool closeTimeEstimated = false;
+
1628 std::uint64_t totalDrops = 0;
+
1629
+
1630 if (ledger.get().isMember("accountState"))
+
1631 {
+
1632 if (ledger.get().isMember(jss::ledger_index))
+
1633 {
+
1634 seq = ledger.get()[jss::ledger_index].asUInt();
+
1635 }
+
1636
+
1637 if (ledger.get().isMember("close_time"))
+
1638 {
+
1639 using tp = NetClock::time_point;
+
1640 using d = tp::duration;
+
1641 closeTime = tp{d{ledger.get()["close_time"].asUInt()}};
+
1642 }
+
1643 if (ledger.get().isMember("close_time_resolution"))
+
1644 {
+
1645 using namespace std::chrono;
+
1646 closeTimeResolution = seconds{ledger.get()["close_time_resolution"].asUInt()};
+
1647 }
+
1648 if (ledger.get().isMember("close_time_estimated"))
+
1649 {
+
1650 closeTimeEstimated = ledger.get()["close_time_estimated"].asBool();
1651 }
-
1652 if (ledger.get().isMember("close_time_estimated"))
+
1652 if (ledger.get().isMember("total_coins"))
1653 {
-
1654 closeTimeEstimated = ledger.get()["close_time_estimated"].asBool();
+
1654 totalDrops = beast::lexicalCastThrow<std::uint64_t>(ledger.get()["total_coins"].asString());
1655 }
-
1656 if (ledger.get().isMember("total_coins"))
-
1657 {
-
1658 totalDrops = beast::lexicalCastThrow<std::uint64_t>(ledger.get()["total_coins"].asString());
-
1659 }
-
1660
-
1661 ledger = ledger.get()["accountState"];
-
1662 }
-
1663
-
1664 if (!ledger.get().isArrayOrNull())
-
1665 {
-
1666 JLOG(m_journal.fatal()) << "State nodes must be an array";
-
1667 return nullptr;
-
1668 }
-
1669
-
1670 auto loadLedger = std::make_shared<Ledger>(seq, closeTime, *config_, nodeFamily_);
-
1671 loadLedger->setTotalDrops(totalDrops);
+
1656
+
1657 ledger = ledger.get()["accountState"];
+
1658 }
+
1659
+
1660 if (!ledger.get().isArrayOrNull())
+
1661 {
+
1662 JLOG(m_journal.fatal()) << "State nodes must be an array";
+
1663 return nullptr;
+
1664 }
+
1665
+
1666 auto loadLedger = std::make_shared<Ledger>(seq, closeTime, *config_, nodeFamily_);
+
1667 loadLedger->setTotalDrops(totalDrops);
+
1668
+
1669 for (Json::UInt index = 0; index < ledger.get().size(); ++index)
+
1670 {
+
1671 Json::Value& entry = ledger.get()[index];
1672
-
1673 for (Json::UInt index = 0; index < ledger.get().size(); ++index)
-
1674 {
-
1675 Json::Value& entry = ledger.get()[index];
-
1676
-
1677 if (!entry.isObjectOrNull())
-
1678 {
-
1679 JLOG(m_journal.fatal()) << "Invalid entry in ledger";
-
1680 return nullptr;
-
1681 }
-
1682
-
1683 uint256 uIndex;
-
1684
-
1685 if (!uIndex.parseHex(entry[jss::index].asString()))
-
1686 {
-
1687 JLOG(m_journal.fatal()) << "Invalid entry in ledger";
-
1688 return nullptr;
-
1689 }
+
1673 if (!entry.isObjectOrNull())
+
1674 {
+
1675 JLOG(m_journal.fatal()) << "Invalid entry in ledger";
+
1676 return nullptr;
+
1677 }
+
1678
+
1679 uint256 uIndex;
+
1680
+
1681 if (!uIndex.parseHex(entry[jss::index].asString()))
+
1682 {
+
1683 JLOG(m_journal.fatal()) << "Invalid entry in ledger";
+
1684 return nullptr;
+
1685 }
+
1686
+
1687 entry.removeMember(jss::index);
+
1688
+
1689 STParsedJSONObject stp("sle", ledger.get()[index]);
1690
-
1691 entry.removeMember(jss::index);
-
1692
-
1693 STParsedJSONObject stp("sle", ledger.get()[index]);
-
1694
-
1695 if (!stp.object || uIndex.isZero())
-
1696 {
-
1697 JLOG(m_journal.fatal()) << "Invalid entry in ledger";
-
1698 return nullptr;
-
1699 }
+
1691 if (!stp.object || uIndex.isZero())
+
1692 {
+
1693 JLOG(m_journal.fatal()) << "Invalid entry in ledger";
+
1694 return nullptr;
+
1695 }
+
1696
+
1697 // VFALCO TODO This is the only place that
+
1698 // constructor is used, try to remove it
+
1699 STLedgerEntry sle(*stp.object, uIndex);
1700
-
1701 // VFALCO TODO This is the only place that
-
1702 // constructor is used, try to remove it
-
1703 STLedgerEntry sle(*stp.object, uIndex);
-
1704
-
1705 if (!loadLedger->addSLE(sle))
-
1706 {
-
1707 JLOG(m_journal.fatal()) << "Couldn't add serialized ledger: " << uIndex;
-
1708 return nullptr;
-
1709 }
-
1710 }
-
1711
-
1712 loadLedger->stateMap().flushDirty(hotACCOUNT_NODE);
-
1713
-
1714 XRPL_ASSERT(
-
1715 loadLedger->header().seq < XRP_LEDGER_EARLIEST_FEES || loadLedger->read(keylet::fees()),
-
1716 "xrpl::ApplicationImp::loadLedgerFromFile : valid ledger fees");
-
1717 loadLedger->setAccepted(closeTime, closeTimeResolution, !closeTimeEstimated);
-
1718
-
1719 return loadLedger;
-
1720 }
-
1721 catch (std::exception const& x)
-
1722 {
-
1723 JLOG(m_journal.fatal()) << "Ledger contains invalid data: " << x.what();
-
1724 return nullptr;
-
1725 }
-
1726}
+
1701 if (!loadLedger->addSLE(sle))
+
1702 {
+
1703 JLOG(m_journal.fatal()) << "Couldn't add serialized ledger: " << uIndex;
+
1704 return nullptr;
+
1705 }
+
1706 }
+
1707
+
1708 loadLedger->stateMap().flushDirty(hotACCOUNT_NODE);
+
1709
+
1710 XRPL_ASSERT(
+
1711 loadLedger->header().seq < XRP_LEDGER_EARLIEST_FEES || loadLedger->read(keylet::fees()),
+
1712 "xrpl::ApplicationImp::loadLedgerFromFile : valid ledger fees");
+
1713 loadLedger->setAccepted(closeTime, closeTimeResolution, !closeTimeEstimated);
+
1714
+
1715 return loadLedger;
+
1716 }
+
1717 catch (std::exception const& x)
+
1718 {
+
1719 JLOG(m_journal.fatal()) << "Ledger contains invalid data: " << x.what();
+
1720 return nullptr;
+
1721 }
+
1722}
-
1727
-
1728bool
-
-
1729ApplicationImp::loadOldLedger(
-
1730 std::string const& ledgerID,
-
1731 bool replay,
-
1732 bool isFileName,
-
1733 std::optional<uint256> trapTxID)
-
1734{
-
1735 try
-
1736 {
-
1737 std::shared_ptr<Ledger const> loadLedger, replayLedger;
-
1738
-
1739 if (isFileName)
-
1740 {
-
1741 if (!ledgerID.empty())
-
1742 loadLedger = loadLedgerFromFile(ledgerID);
-
1743 }
-
1744 else if (ledgerID.length() == 64)
-
1745 {
-
1746 uint256 hash;
+
1723
+
1724bool
+
+
1725ApplicationImp::loadOldLedger(
+
1726 std::string const& ledgerID,
+
1727 bool replay,
+
1728 bool isFileName,
+
1729 std::optional<uint256> trapTxID)
+
1730{
+
1731 try
+
1732 {
+
1733 std::shared_ptr<Ledger const> loadLedger, replayLedger;
+
1734
+
1735 if (isFileName)
+
1736 {
+
1737 if (!ledgerID.empty())
+
1738 loadLedger = loadLedgerFromFile(ledgerID);
+
1739 }
+
1740 else if (ledgerID.length() == 64)
+
1741 {
+
1742 uint256 hash;
+
1743
+
1744 if (hash.parseHex(ledgerID))
+
1745 {
+
1746 loadLedger = loadByHash(hash, *this);
1747
-
1748 if (hash.parseHex(ledgerID))
-
1749 {
-
1750 loadLedger = loadByHash(hash, *this);
-
1751
-
1752 if (!loadLedger)
-
1753 {
-
1754 // Try to build the ledger from the back end
- -
1756 *this, hash, 0, InboundLedger::Reason::GENERIC, stopwatch(), make_DummyPeerSet(*this));
-
1757 if (il->checkLocal())
-
1758 loadLedger = il->getLedger();
-
1759 }
-
1760 }
+
1748 if (!loadLedger)
+
1749 {
+
1750 // Try to build the ledger from the back end
+ +
1752 *this, hash, 0, InboundLedger::Reason::GENERIC, stopwatch(), make_DummyPeerSet(*this));
+
1753 if (il->checkLocal())
+
1754 loadLedger = il->getLedger();
+
1755 }
+
1756 }
+
1757 }
+
1758 else if (ledgerID.empty() || boost::iequals(ledgerID, "latest"))
+
1759 {
+
1760 loadLedger = getLastFullLedger();
1761 }
-
1762 else if (ledgerID.empty() || boost::iequals(ledgerID, "latest"))
+
1762 else
1763 {
-
1764 loadLedger = getLastFullLedger();
-
1765 }
-
1766 else
-
1767 {
-
1768 // assume by sequence
-
1769 std::uint32_t index;
+
1764 // assume by sequence
+
1765 std::uint32_t index;
+
1766
+
1767 if (beast::lexicalCastChecked(index, ledgerID))
+
1768 loadLedger = loadByIndex(index, *this);
+
1769 }
1770
-
1771 if (beast::lexicalCastChecked(index, ledgerID))
-
1772 loadLedger = loadByIndex(index, *this);
-
1773 }
-
1774
-
1775 if (!loadLedger)
-
1776 return false;
+
1771 if (!loadLedger)
+
1772 return false;
+
1773
+
1774 if (replay)
+
1775 {
+
1776 // Replay a ledger close with same prior ledger and transactions
1777
-
1778 if (replay)
-
1779 {
-
1780 // Replay a ledger close with same prior ledger and transactions
-
1781
-
1782 // this ledger holds the transactions we want to replay
-
1783 replayLedger = loadLedger;
-
1784
-
1785 JLOG(m_journal.info()) << "Loading parent ledger";
-
1786
-
1787 loadLedger = loadByHash(replayLedger->header().parentHash, *this);
-
1788 if (!loadLedger)
-
1789 {
-
1790 JLOG(m_journal.info()) << "Loading parent ledger from node store";
-
1791
-
1792 // Try to build the ledger from the back end
- -
1794 *this,
-
1795 replayLedger->header().parentHash,
-
1796 0,
-
1797 InboundLedger::Reason::GENERIC,
-
1798 stopwatch(),
-
1799 make_DummyPeerSet(*this));
-
1800
-
1801 if (il->checkLocal())
-
1802 loadLedger = il->getLedger();
-
1803
-
1804 if (!loadLedger)
-
1805 {
-
1806 // LCOV_EXCL_START
-
1807 JLOG(m_journal.fatal()) << "Replay ledger missing/damaged";
-
1808 UNREACHABLE(
-
1809 "xrpl::ApplicationImp::loadOldLedger : replay ledger "
-
1810 "missing/damaged");
-
1811 return false;
-
1812 // LCOV_EXCL_STOP
-
1813 }
-
1814 }
-
1815 }
-
1816 using namespace std::chrono_literals;
-
1817 using namespace date;
-
1818 static constexpr NetClock::time_point ledgerWarnTimePoint{
-
1819 sys_days{January / 1 / 2018} - sys_days{January / 1 / 2000}};
-
1820 if (loadLedger->header().closeTime < ledgerWarnTimePoint)
-
1821 {
-
1822 JLOG(m_journal.fatal()) << "\n\n*** WARNING ***\n"
-
1823 "You are replaying a ledger from before "
-
1824 << to_string(ledgerWarnTimePoint)
-
1825 << " UTC.\n"
-
1826 "This replay will not handle your ledger as it was "
-
1827 "originally "
-
1828 "handled.\nConsider running an earlier version of rippled "
-
1829 "to "
-
1830 "get the older rules.\n*** CONTINUING ***\n";
-
1831 }
-
1832
-
1833 JLOG(m_journal.info()) << "Loading ledger " << loadLedger->header().hash << " seq:" << loadLedger->header().seq;
-
1834
-
1835 if (loadLedger->header().accountHash.isZero())
-
1836 {
-
1837 // LCOV_EXCL_START
-
1838 JLOG(m_journal.fatal()) << "Ledger is empty.";
-
1839 UNREACHABLE("xrpl::ApplicationImp::loadOldLedger : ledger is empty");
-
1840 return false;
-
1841 // LCOV_EXCL_STOP
-
1842 }
-
1843
-
1844 if (!loadLedger->walkLedger(journal("Ledger"), true))
-
1845 {
-
1846 // LCOV_EXCL_START
-
1847 JLOG(m_journal.fatal()) << "Ledger is missing nodes.";
-
1848 UNREACHABLE(
-
1849 "xrpl::ApplicationImp::loadOldLedger : ledger is missing "
-
1850 "nodes");
-
1851 return false;
-
1852 // LCOV_EXCL_STOP
-
1853 }
-
1854
-
1855 if (!loadLedger->assertSensible(journal("Ledger")))
-
1856 {
-
1857 // LCOV_EXCL_START
-
1858 JLOG(m_journal.fatal()) << "Ledger is not sensible.";
-
1859 UNREACHABLE(
-
1860 "xrpl::ApplicationImp::loadOldLedger : ledger is not "
-
1861 "sensible");
-
1862 return false;
-
1863 // LCOV_EXCL_STOP
-
1864 }
-
1865
-
1866 m_ledgerMaster->setLedgerRangePresent(loadLedger->header().seq, loadLedger->header().seq);
-
1867
-
1868 m_ledgerMaster->switchLCL(loadLedger);
-
1869 loadLedger->setValidated();
-
1870 m_ledgerMaster->setFullLedger(loadLedger, true, false);
-
1871 openLedger_.emplace(loadLedger, cachedSLEs_, logs_->journal("OpenLedger"));
-
1872
-
1873 if (replay)
-
1874 {
-
1875 // inject transaction(s) from the replayLedger into our open ledger
-
1876 // and build replay structure
-
1877 auto replayData = std::make_unique<LedgerReplay>(loadLedger, replayLedger);
-
1878
-
1879 for (auto const& [_, tx] : replayData->orderedTxns())
-
1880 {
-
1881 (void)_;
-
1882 auto txID = tx->getTransactionID();
-
1883 if (trapTxID == txID)
-
1884 {
-
1885 trapTxID_ = txID;
-
1886 JLOG(m_journal.debug()) << "Trap transaction set: " << txID;
-
1887 }
-
1888
- -
1890 tx->add(*s);
-
1891
-
1892 forceValidity(getHashRouter(), txID, Validity::SigGoodOnly);
-
1893
-
1894 openLedger_->modify([&txID, &s](OpenView& view, beast::Journal j) {
-
1895 view.rawTxInsert(txID, std::move(s), nullptr);
-
1896 return true;
-
1897 });
-
1898 }
-
1899
-
1900 m_ledgerMaster->takeReplay(std::move(replayData));
-
1901
-
1902 if (trapTxID && !trapTxID_)
-
1903 {
-
1904 JLOG(m_journal.fatal()) << "Ledger " << replayLedger->header().seq
-
1905 << " does not contain the transaction hash " << *trapTxID;
-
1906 return false;
-
1907 }
-
1908 }
-
1909 }
-
1910 catch (SHAMapMissingNode const& mn)
-
1911 {
-
1912 JLOG(m_journal.fatal()) << "While loading specified ledger: " << mn.what();
-
1913 return false;
-
1914 }
-
1915 catch (boost::bad_lexical_cast&)
-
1916 {
-
1917 JLOG(m_journal.fatal()) << "Ledger specified '" << ledgerID << "' is not valid";
-
1918 return false;
-
1919 }
-
1920
-
1921 return true;
-
1922}
+
1778 // this ledger holds the transactions we want to replay
+
1779 replayLedger = loadLedger;
+
1780
+
1781 JLOG(m_journal.info()) << "Loading parent ledger";
+
1782
+
1783 loadLedger = loadByHash(replayLedger->header().parentHash, *this);
+
1784 if (!loadLedger)
+
1785 {
+
1786 JLOG(m_journal.info()) << "Loading parent ledger from node store";
+
1787
+
1788 // Try to build the ledger from the back end
+ +
1790 *this,
+
1791 replayLedger->header().parentHash,
+
1792 0,
+
1793 InboundLedger::Reason::GENERIC,
+
1794 stopwatch(),
+
1795 make_DummyPeerSet(*this));
+
1796
+
1797 if (il->checkLocal())
+
1798 loadLedger = il->getLedger();
+
1799
+
1800 if (!loadLedger)
+
1801 {
+
1802 // LCOV_EXCL_START
+
1803 JLOG(m_journal.fatal()) << "Replay ledger missing/damaged";
+
1804 UNREACHABLE(
+
1805 "xrpl::ApplicationImp::loadOldLedger : replay ledger "
+
1806 "missing/damaged");
+
1807 return false;
+
1808 // LCOV_EXCL_STOP
+
1809 }
+
1810 }
+
1811 }
+
1812 using namespace std::chrono_literals;
+
1813 using namespace date;
+
1814 static constexpr NetClock::time_point ledgerWarnTimePoint{
+
1815 sys_days{January / 1 / 2018} - sys_days{January / 1 / 2000}};
+
1816 if (loadLedger->header().closeTime < ledgerWarnTimePoint)
+
1817 {
+
1818 JLOG(m_journal.fatal()) << "\n\n*** WARNING ***\n"
+
1819 "You are replaying a ledger from before "
+
1820 << to_string(ledgerWarnTimePoint)
+
1821 << " UTC.\n"
+
1822 "This replay will not handle your ledger as it was "
+
1823 "originally "
+
1824 "handled.\nConsider running an earlier version of rippled "
+
1825 "to "
+
1826 "get the older rules.\n*** CONTINUING ***\n";
+
1827 }
+
1828
+
1829 JLOG(m_journal.info()) << "Loading ledger " << loadLedger->header().hash << " seq:" << loadLedger->header().seq;
+
1830
+
1831 if (loadLedger->header().accountHash.isZero())
+
1832 {
+
1833 // LCOV_EXCL_START
+
1834 JLOG(m_journal.fatal()) << "Ledger is empty.";
+
1835 UNREACHABLE("xrpl::ApplicationImp::loadOldLedger : ledger is empty");
+
1836 return false;
+
1837 // LCOV_EXCL_STOP
+
1838 }
+
1839
+
1840 if (!loadLedger->walkLedger(journal("Ledger"), true))
+
1841 {
+
1842 // LCOV_EXCL_START
+
1843 JLOG(m_journal.fatal()) << "Ledger is missing nodes.";
+
1844 UNREACHABLE(
+
1845 "xrpl::ApplicationImp::loadOldLedger : ledger is missing "
+
1846 "nodes");
+
1847 return false;
+
1848 // LCOV_EXCL_STOP
+
1849 }
+
1850
+
1851 if (!loadLedger->assertSensible(journal("Ledger")))
+
1852 {
+
1853 // LCOV_EXCL_START
+
1854 JLOG(m_journal.fatal()) << "Ledger is not sensible.";
+
1855 UNREACHABLE(
+
1856 "xrpl::ApplicationImp::loadOldLedger : ledger is not "
+
1857 "sensible");
+
1858 return false;
+
1859 // LCOV_EXCL_STOP
+
1860 }
+
1861
+
1862 m_ledgerMaster->setLedgerRangePresent(loadLedger->header().seq, loadLedger->header().seq);
+
1863
+
1864 m_ledgerMaster->switchLCL(loadLedger);
+
1865 loadLedger->setValidated();
+
1866 m_ledgerMaster->setFullLedger(loadLedger, true, false);
+
1867 openLedger_.emplace(loadLedger, cachedSLEs_, logs_->journal("OpenLedger"));
+
1868
+
1869 if (replay)
+
1870 {
+
1871 // inject transaction(s) from the replayLedger into our open ledger
+
1872 // and build replay structure
+
1873 auto replayData = std::make_unique<LedgerReplay>(loadLedger, replayLedger);
+
1874
+
1875 for (auto const& [_, tx] : replayData->orderedTxns())
+
1876 {
+
1877 (void)_;
+
1878 auto txID = tx->getTransactionID();
+
1879 if (trapTxID == txID)
+
1880 {
+
1881 trapTxID_ = txID;
+
1882 JLOG(m_journal.debug()) << "Trap transaction set: " << txID;
+
1883 }
+
1884
+ +
1886 tx->add(*s);
+
1887
+
1888 forceValidity(getHashRouter(), txID, Validity::SigGoodOnly);
+
1889
+
1890 openLedger_->modify([&txID, &s](OpenView& view, beast::Journal j) {
+
1891 view.rawTxInsert(txID, std::move(s), nullptr);
+
1892 return true;
+
1893 });
+
1894 }
+
1895
+
1896 m_ledgerMaster->takeReplay(std::move(replayData));
+
1897
+
1898 if (trapTxID && !trapTxID_)
+
1899 {
+
1900 JLOG(m_journal.fatal()) << "Ledger " << replayLedger->header().seq
+
1901 << " does not contain the transaction hash " << *trapTxID;
+
1902 return false;
+
1903 }
+
1904 }
+
1905 }
+
1906 catch (SHAMapMissingNode const& mn)
+
1907 {
+
1908 JLOG(m_journal.fatal()) << "While loading specified ledger: " << mn.what();
+
1909 return false;
+
1910 }
+
1911 catch (boost::bad_lexical_cast&)
+
1912 {
+
1913 JLOG(m_journal.fatal()) << "Ledger specified '" << ledgerID << "' is not valid";
+
1914 return false;
+
1915 }
+
1916
+
1917 return true;
+
1918}
-
1923
-
1924bool
-
-
1925ApplicationImp::serverOkay(std::string& reason)
-
1926{
-
1927 if (!config().ELB_SUPPORT)
-
1928 return true;
-
1929
-
1930 if (isStopping())
-
1931 {
-
1932 reason = "Server is shutting down";
-
1933 return false;
-
1934 }
-
1935
-
1936 if (getOPs().isNeedNetworkLedger())
-
1937 {
-
1938 reason = "Not synchronized with network yet";
-
1939 return false;
-
1940 }
-
1941
-
1942 if (getOPs().isAmendmentBlocked())
-
1943 {
-
1944 reason = "Server version too old";
-
1945 return false;
-
1946 }
-
1947
-
1948 if (getOPs().isUNLBlocked())
-
1949 {
-
1950 reason = "No valid validator list available";
-
1951 return false;
-
1952 }
-
1953
-
1954 if (getOPs().getOperatingMode() < OperatingMode::SYNCING)
-
1955 {
-
1956 reason = "Not synchronized with network";
+
1919
+
1920bool
+
+
1921ApplicationImp::serverOkay(std::string& reason)
+
1922{
+
1923 if (!config().ELB_SUPPORT)
+
1924 return true;
+
1925
+
1926 if (isStopping())
+
1927 {
+
1928 reason = "Server is shutting down";
+
1929 return false;
+
1930 }
+
1931
+
1932 if (getOPs().isNeedNetworkLedger())
+
1933 {
+
1934 reason = "Not synchronized with network yet";
+
1935 return false;
+
1936 }
+
1937
+
1938 if (getOPs().isAmendmentBlocked())
+
1939 {
+
1940 reason = "Server version too old";
+
1941 return false;
+
1942 }
+
1943
+
1944 if (getOPs().isUNLBlocked())
+
1945 {
+
1946 reason = "No valid validator list available";
+
1947 return false;
+
1948 }
+
1949
+
1950 if (getOPs().getOperatingMode() < OperatingMode::SYNCING)
+
1951 {
+
1952 reason = "Not synchronized with network";
+
1953 return false;
+
1954 }
+
1955
+
1956 if (!getLedgerMaster().isCaughtUp(reason))
1957 return false;
-
1958 }
-
1959
-
1960 if (!getLedgerMaster().isCaughtUp(reason))
-
1961 return false;
-
1962
-
1963 if (getFeeTrack().isLoadedLocal())
-
1964 {
-
1965 reason = "Too much load";
-
1966 return false;
-
1967 }
-
1968
-
1969 return true;
-
1970}
+
1958
+
1959 if (getFeeTrack().isLoadedLocal())
+
1960 {
+
1961 reason = "Too much load";
+
1962 return false;
+
1963 }
+
1964
+
1965 return true;
+
1966}
-
1971
- -
-
1973ApplicationImp::journal(std::string const& name)
-
1974{
-
1975 return logs_->journal(name);
-
1976}
+
1967
+ +
+
1969ApplicationImp::journal(std::string const& name)
+
1970{
+
1971 return logs_->journal(name);
+
1972}
-
1977
-
1978void
-
-
1979ApplicationImp::setMaxDisallowedLedger()
-
1980{
-
1981 auto seq = getRelationalDatabase().getMaxLedgerSeq();
-
1982 if (seq)
-
1983 maxDisallowedLedger_ = *seq;
-
1984
-
1985 JLOG(m_journal.trace()) << "Max persisted ledger is " << maxDisallowedLedger_;
-
1986}
+
1973
+
1974void
+
+
1975ApplicationImp::setMaxDisallowedLedger()
+
1976{
+
1977 auto seq = getRelationalDatabase().getMaxLedgerSeq();
+
1978 if (seq)
+
1979 maxDisallowedLedger_ = *seq;
+
1980
+
1981 JLOG(m_journal.trace()) << "Max persisted ledger is " << maxDisallowedLedger_;
+
1982}
+
+
1983
+
1984//------------------------------------------------------------------------------
+
1985
+
+
1986Application::Application() : beast::PropertyStream::Source("app")
+
1987{
+
1988}
-
1987
-
1988//------------------------------------------------------------------------------
1989
-
-
1990Application::Application() : beast::PropertyStream::Source("app")
-
1991{
-
1992}
+
1990//------------------------------------------------------------------------------
+
1991
+ +
+ +
1994{
+
1995 return std::make_unique<ApplicationImp>(std::move(config), std::move(logs), std::move(timeKeeper));
+
1996}
-
1993
-
1994//------------------------------------------------------------------------------
-
1995
- -
- -
1998{
-
1999 return std::make_unique<ApplicationImp>(std::move(config), std::move(logs), std::move(timeKeeper));
-
2000}
+
1997
+
1998void
+
+
1999fixConfigPorts(Config& config, Endpoints const& endpoints)
+
2000{
+
2001 for (auto const& [name, ep] : endpoints)
+
2002 {
+
2003 if (!config.exists(name))
+
2004 continue;
+
2005
+
2006 auto& section = config[name];
+
2007 auto const optPort = section.get("port");
+
2008 if (optPort)
+
2009 {
+
2010 std::uint16_t const port = beast::lexicalCast<std::uint16_t>(*optPort);
+
2011 if (!port)
+
2012 section.set("port", std::to_string(ep.port()));
+
2013 }
+
2014 }
+
2015}
-
2001
-
2002void
-
-
2003fixConfigPorts(Config& config, Endpoints const& endpoints)
-
2004{
-
2005 for (auto const& [name, ep] : endpoints)
-
2006 {
-
2007 if (!config.exists(name))
-
2008 continue;
-
2009
-
2010 auto& section = config[name];
-
2011 auto const optPort = section.get("port");
-
2012 if (optPort)
-
2013 {
-
2014 std::uint16_t const port = beast::lexicalCast<std::uint16_t>(*optPort);
-
2015 if (!port)
-
2016 section.set("port", std::to_string(ep.port()));
-
2017 }
-
2018 }
-
2019}
-
-
2020
-
2021} // namespace xrpl
+
2016
+
2017} // namespace xrpl
@@ -2318,14 +2314,14 @@ $(document).ready(function() { init_codefold(0); });
std::unique_ptr< LedgerCleaner > ledgerCleaner_
std::unique_ptr< LoadManager > m_loadManager
-
void start(bool withTimers) override
+
void start(bool withTimers) override
LoadFeeTrack & getFeeTrack() override
Cluster & cluster() override
std::unique_ptr< perf::PerfLog > perfLog_
std::unique_ptr< HashRouter > hashRouter_
std::optional< OpenLedger > openLedger_
RCLValidations & getValidations() override
-
void run() override
+
void run() override
OpenLedger & openLedger() override
Resource::Manager & getResourceManager() override
NodeStoreScheduler m_nodeStoreScheduler
@@ -2343,8 +2339,8 @@ $(document).ready(function() { init_codefold(0); });
PendingSaves pendingSaves_
std::unique_ptr< RelationalDatabase > mRelationalDatabase
std::atomic< bool > checkSigs_
-
bool checkSigs() const override
-
bool serverOkay(std::string &reason) override
+
bool checkSigs() const override
+
bool serverOkay(std::string &reason) override
std::unique_ptr< SHAMapStore > m_shaMapStore
Application::MutexType m_masterMutex
InboundTransactions & getInboundTransactions() override
@@ -2357,7 +2353,7 @@ $(document).ready(function() { init_codefold(0); });
std::unique_ptr< LoadFeeTrack > mFeeTrack
boost::asio::steady_timer entropyTimer_
std::unique_ptr< Overlay > overlay_
-
bool setup(boost::program_options::variables_map const &cmdline) override
+
bool setup(boost::program_options::variables_map const &cmdline) override
Overlay & overlay() override
std::unique_ptr< Config > config_
@@ -2376,7 +2372,7 @@ $(document).ready(function() { init_codefold(0); });
std::unique_ptr< ManifestCache > publisherManifests_
-
LedgerIndex getMaxDisallowedLedger() override
Ensure that a newly-started validator does not sign proposals older than the last ledger it persisted...
+
LedgerIndex getMaxDisallowedLedger() override
Ensure that a newly-started validator does not sign proposals older than the last ledger it persisted...
NodeCache & getTempNodeCache() override
Logs & logs() override
OrderBookDB m_orderBookDB
@@ -2390,7 +2386,7 @@ $(document).ready(function() { init_codefold(0); });
std::unique_ptr< DatabaseCon > mWalletDB
CachedSLEs & cachedSLEs() override
ValidatorSite & validatorSites() override
-
virtual std::optional< uint256 > const & trapTxID() const override
+
virtual std::optional< uint256 > const & trapTxID() const override
std::atomic_flag isTimeToStop
std::unique_ptr< LedgerMaster > m_ledgerMaster
std::unique_ptr< GRPCServer > grpcServer_
@@ -2404,17 +2400,17 @@ $(document).ready(function() { init_codefold(0); });
DatabaseCon & getWalletDB() override
Retrieve the "wallet database".
PathRequests & getPathRequests() override
-
bool isStopping() const override
+
bool isStopping() const override
std::unique_ptr< TimeKeeper > timeKeeper_
-
beast::Journal journal(std::string const &name) override
+
beast::Journal journal(std::string const &name) override
std::unique_ptr< ValidatorSite > validatorSites_
RCLValidations mValidations
-
void signalStop(std::string msg) override
+
void signalStop(std::string msg) override
std::uint64_t const instanceCookie_
LedgerCleaner & getLedgerCleaner() override
ManifestCache & validatorManifests() override
AmendmentTable & getAmendmentTable() override
-
int fdRequired() const override
+
int fdRequired() const override
TaggedCache< uint256, AcceptedLedger > m_acceptedLedgerCache
std::unique_ptr< PathRequests > m_pathRequests
std::unique_ptr< JobQueue > m_jobQueue
@@ -2539,14 +2535,14 @@ $(document).ready(function() { init_codefold(0); });
create_genesis_t const create_genesis
Definition Ledger.cpp:32
std::unique_ptr< NetworkOPs > make_NetworkOPs(Application &app, NetworkOPs::clock_type &clock, bool standalone, std::size_t minPeerCount, bool startvalid, JobQueue &job_queue, LedgerMaster &ledgerMaster, ValidatorKeys const &validatorKeys, boost::asio::io_context &io_svc, beast::Journal journal, beast::insight::Collector::ptr const &collector)
std::enable_if_t< std::is_integral< Integral >::value, Integral > rand_int()
-
std::unique_ptr< SHAMapStore > make_SHAMapStore(Application &app, NodeStore::Scheduler &scheduler, beast::Journal journal)
+
std::unique_ptr< SHAMapStore > make_SHAMapStore(Application &app, NodeStore::Scheduler &scheduler, beast::Journal journal)
std::unique_ptr< AmendmentTable > make_AmendmentTable(Application &app, std::chrono::seconds majorityTime, std::vector< AmendmentTable::FeatureInfo > const &supported, Section const &enabled, Section const &vetoed, beast::Journal journal)
std::unique_ptr< PeerSet > make_DummyPeerSet(Application &app)
Make a dummy PeerSet that does not do anything.
Definition PeerSet.cpp:164
@ hotACCOUNT_NODE
Definition NodeObject.h:15
-
std::unique_ptr< Application > make_Application(std::unique_ptr< Config > config, std::unique_ptr< Logs > logs, std::unique_ptr< TimeKeeper > timeKeeper)
+
std::unique_ptr< Application > make_Application(std::unique_ptr< Config > config, std::unique_ptr< Logs > logs, std::unique_ptr< TimeKeeper > timeKeeper)
ServerHandler::Setup setup_ServerHandler(Config const &config, std::ostream &&log)
std::shared_ptr< Ledger > loadByIndex(std::uint32_t ledgerIndex, Application &app, bool acquire)
Definition Ledger.cpp:1026
std::unique_ptr< CollectorManager > make_CollectorManager(Section const &params, beast::Journal journal)
@@ -2554,7 +2550,7 @@ $(document).ready(function() { init_codefold(0); });
std::unique_ptr< InboundLedgers > make_InboundLedgers(Application &app, InboundLedgers::clock_type &clock, beast::insight::Collector::ptr const &collector)
std::unique_ptr< ServerHandler > make_ServerHandler(Application &app, boost::asio::io_context &io_context, JobQueue &jobQueue, NetworkOPs &networkOPs, Resource::Manager &resourceManager, CollectorManager &cm)
constexpr auto megabytes(T value) noexcept
-
static void fixConfigPorts(Config &config, Endpoints const &endpoints)
+
static void fixConfigPorts(Config &config, Endpoints const &endpoints)
DatabaseCon::Setup setup_DatabaseCon(Config const &c, std::optional< beast::Journal > j=std::nullopt)
void initAccountIdCache(std::size_t count)
Initialize the global cache used to map AccountID to base58 conversions.
Definition AccountID.cpp:85
std::unique_ptr< InboundTransactions > make_InboundTransactions(Application &app, beast::insight::Collector::ptr const &collector, std::function< void(std::shared_ptr< SHAMap > const &, bool)> gotSet)
diff --git a/Application_8h_source.html b/Application_8h_source.html index 648cdefb8d..a4b9006b21 100644 --- a/Application_8h_source.html +++ b/Application_8h_source.html @@ -282,7 +282,7 @@ $(document).ready(function() { init_codefold(0); });
virtual DatabaseCon & getWalletDB()=0
Retrieve the "wallet database".
virtual void run()=0
virtual std::optional< uint256 > const & trapTxID() const =0
- +
virtual std::optional< PublicKey const > getValidationPublicKey() const =0
virtual boost::asio::io_context & getIOContext()=0
virtual ~Application()=default
@@ -303,7 +303,7 @@ $(document).ready(function() { init_codefold(0); });
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
TaggedCache< uint256, SLE const > CachedSLEs
Definition CachedSLEs.h:8
-
std::unique_ptr< Application > make_Application(std::unique_ptr< Config > config, std::unique_ptr< Logs > logs, std::unique_ptr< TimeKeeper > timeKeeper)
+
std::unique_ptr< Application > make_Application(std::unique_ptr< Config > config, std::unique_ptr< Logs > logs, std::unique_ptr< TimeKeeper > timeKeeper)
STLedgerEntry SLE
TaggedCache< SHAMapHash, Blob > NodeCache
Validations< RCLValidationsAdaptor > RCLValidations
Alias for RCL-specific instantiation of generic Validations.
diff --git a/DatabaseNodeImp_8cpp_source.html b/DatabaseNodeImp_8cpp_source.html index 0e2b8e16d4..aa27160298 100644 --- a/DatabaseNodeImp_8cpp_source.html +++ b/DatabaseNodeImp_8cpp_source.html @@ -94,191 +94,109 @@ $(document).ready(function() { init_codefold(0); });
10
11 auto obj = NodeObject::createObject(type, std::move(data), hash);
12 backend_->store(obj);
-
13 if (cache_)
-
14 {
-
15 // After the store, replace a negative cache entry if there is one
-
16 cache_->canonicalize(hash, obj, [](std::shared_ptr<NodeObject> const& n) { return n->getType() == hotDUMMY; });
-
17 }
-
18}
+
13}
-
19
-
20void
-
- -
22 uint256 const& hash,
-
23 std::uint32_t ledgerSeq,
-
24 std::function<void(std::shared_ptr<NodeObject> const&)>&& callback)
-
25{
-
26 if (cache_)
-
27 {
-
28 std::shared_ptr<NodeObject> obj = cache_->fetch(hash);
-
29 if (obj)
-
30 {
-
31 callback(obj->getType() == hotDUMMY ? nullptr : obj);
-
32 return;
-
33 }
-
34 }
-
35 Database::asyncFetch(hash, ledgerSeq, std::move(callback));
-
36}
+
14
+
15void
+
+ +
17 uint256 const& hash,
+
18 std::uint32_t ledgerSeq,
+
19 std::function<void(std::shared_ptr<NodeObject> const&)>&& callback)
+
20{
+
21 Database::asyncFetch(hash, ledgerSeq, std::move(callback));
+
22}
-
37
-
38void
-
- -
40{
-
41 if (cache_)
-
42 cache_->sweep();
-
43}
-
-
44
- -
-
46DatabaseNodeImp::fetchNodeObject(uint256 const& hash, std::uint32_t, FetchReport& fetchReport, bool duplicate)
-
47{
-
48 std::shared_ptr<NodeObject> nodeObject = cache_ ? cache_->fetch(hash) : nullptr;
-
49
-
50 if (!nodeObject)
-
51 {
-
52 JLOG(j_.trace()) << "fetchNodeObject " << hash << ": record not " << (cache_ ? "cached" : "found");
-
53
-
54 Status status;
+
23
+ +
+
25DatabaseNodeImp::fetchNodeObject(uint256 const& hash, std::uint32_t, FetchReport& fetchReport, bool duplicate)
+
26{
+
27 std::shared_ptr<NodeObject> nodeObject = nullptr;
+
28 Status status;
+
29
+
30 try
+
31 {
+
32 status = backend_->fetch(hash.data(), &nodeObject);
+
33 }
+
34 catch (std::exception const& e)
+
35 {
+
36 JLOG(j_.fatal()) << "fetchNodeObject " << hash << ": Exception fetching from backend: " << e.what();
+
37 Rethrow();
+
38 }
+
39
+
40 switch (status)
+
41 {
+
42 case ok:
+
43 case notFound:
+
44 break;
+
45 case dataCorrupt:
+
46 JLOG(j_.fatal()) << "fetchNodeObject " << hash << ": nodestore data is corrupted";
+
47 break;
+
48 default:
+
49 JLOG(j_.warn()) << "fetchNodeObject " << hash << ": backend returns unknown result " << status;
+
50 break;
+
51 }
+
52
+
53 if (nodeObject)
+
54 fetchReport.wasFound = true;
55
-
56 try
-
57 {
-
58 status = backend_->fetch(hash.data(), &nodeObject);
-
59 }
-
60 catch (std::exception const& e)
-
61 {
-
62 JLOG(j_.fatal()) << "fetchNodeObject " << hash << ": Exception fetching from backend: " << e.what();
-
63 Rethrow();
-
64 }
-
65
-
66 switch (status)
-
67 {
-
68 case ok:
-
69 if (cache_)
-
70 {
-
71 if (nodeObject)
-
72 cache_->canonicalize_replace_client(hash, nodeObject);
-
73 else
-
74 {
- -
76 cache_->canonicalize_replace_client(hash, notFound);
-
77 if (notFound->getType() != hotDUMMY)
-
78 nodeObject = notFound;
-
79 }
-
80 }
-
81 break;
-
82 case notFound:
-
83 break;
-
84 case dataCorrupt:
-
85 JLOG(j_.fatal()) << "fetchNodeObject " << hash << ": nodestore data is corrupted";
-
86 break;
-
87 default:
-
88 JLOG(j_.warn()) << "fetchNodeObject " << hash << ": backend returns unknown result " << status;
-
89 break;
-
90 }
-
91 }
-
92 else
-
93 {
-
94 JLOG(j_.trace()) << "fetchNodeObject " << hash << ": record found in cache";
-
95 if (nodeObject->getType() == hotDUMMY)
-
96 nodeObject.reset();
-
97 }
-
98
-
99 if (nodeObject)
-
100 fetchReport.wasFound = true;
-
101
-
102 return nodeObject;
-
103}
+
56 return nodeObject;
+
57}
-
104
- -
- -
107{
- -
109 using namespace std::chrono;
-
110 auto const before = steady_clock::now();
- -
112 std::vector<uint256 const*> cacheMisses;
-
113 uint64_t hits = 0;
-
114 uint64_t fetches = 0;
-
115 for (size_t i = 0; i < hashes.size(); ++i)
-
116 {
-
117 auto const& hash = hashes[i];
-
118 // See if the object already exists in the cache
-
119 auto nObj = cache_ ? cache_->fetch(hash) : nullptr;
-
120 ++fetches;
-
121 if (!nObj)
-
122 {
-
123 // Try the database
-
124 indexMap[&hash] = i;
-
125 cacheMisses.push_back(&hash);
-
126 }
-
127 else
-
128 {
-
129 results[i] = nObj->getType() == hotDUMMY ? nullptr : nObj;
-
130 // It was in the cache.
-
131 ++hits;
-
132 }
-
133 }
-
134
-
135 JLOG(j_.debug()) << "fetchBatch - cache hits = " << (hashes.size() - cacheMisses.size())
-
136 << " - cache misses = " << cacheMisses.size();
-
137 auto dbResults = backend_->fetchBatch(cacheMisses).first;
-
138
-
139 for (size_t i = 0; i < dbResults.size(); ++i)
-
140 {
-
141 auto nObj = std::move(dbResults[i]);
-
142 size_t index = indexMap[cacheMisses[i]];
-
143 auto const& hash = hashes[index];
-
144
-
145 if (nObj)
-
146 {
-
147 // Ensure all threads get the same object
-
148 if (cache_)
-
149 cache_->canonicalize_replace_client(hash, nObj);
-
150 }
-
151 else
-
152 {
-
153 JLOG(j_.error()) << "fetchBatch - "
-
154 << "record not found in db or cache. hash = " << strHex(hash);
-
155 if (cache_)
-
156 {
- -
158 cache_->canonicalize_replace_client(hash, notFound);
-
159 if (notFound->getType() != hotDUMMY)
-
160 nObj = std::move(notFound);
-
161 }
-
162 }
-
163 results[index] = std::move(nObj);
-
164 }
-
165
-
166 auto fetchDurationUs = std::chrono::duration_cast<std::chrono::microseconds>(steady_clock::now() - before).count();
-
167 updateFetchMetrics(fetches, hits, fetchDurationUs);
-
168 return results;
-
169}
+
58
+ +
+ +
61{
+
62 using namespace std::chrono;
+
63 auto const before = steady_clock::now();
+
64
+ +
66 batch.reserve(hashes.size());
+
67 for (size_t i = 0; i < hashes.size(); ++i)
+
68 {
+
69 auto const& hash = hashes[i];
+ +
71 }
+
72
+
73 // Get the node objects that match the hashes from the backend. To protect
+
74 // against the backends returning fewer or more results than expected, the
+
75 // container is resized to the number of hashes.
+
76 auto results = backend_->fetchBatch(batch).first;
+
77 XRPL_ASSERT(
+
78 results.size() == hashes.size() || results.empty(),
+
79 "number of output objects either matches number of input hashes or is empty");
+
80 results.resize(hashes.size());
+
81 for (size_t i = 0; i < results.size(); ++i)
+
82 {
+
83 if (!results[i])
+
84 {
+
85 JLOG(j_.error()) << "fetchBatch - "
+
86 << "record not found in db. hash = " << strHex(hashes[i]);
+
87 }
+
88 }
+
89
+
90 auto fetchDurationUs = std::chrono::duration_cast<std::chrono::microseconds>(steady_clock::now() - before).count();
+
91 updateFetchMetrics(hashes.size(), 0, fetchDurationUs);
+
92 return results;
+
93}
-
170
-
171} // namespace NodeStore
-
172} // namespace xrpl
+
94
+
95} // namespace NodeStore
+
96} // namespace xrpl
Stream fatal() const
Definition Journal.h:324
Stream error() const
Definition Journal.h:318
-
Stream debug() const
Definition Journal.h:300
-
Stream trace() const
Severity stream access functions.
Definition Journal.h:294
Stream warn() const
Definition Journal.h:312
static std::shared_ptr< NodeObject > createObject(NodeObjectType type, Blob &&data, uint256 const &hash)
Create an object from fields.
-
std::shared_ptr< TaggedCache< uint256, NodeObject > > cache_
void store(NodeObjectType type, Blob &&data, uint256 const &hash, std::uint32_t) override
Store the object.
-
std::shared_ptr< Backend > backend_
-
std::shared_ptr< NodeObject > fetchNodeObject(uint256 const &hash, std::uint32_t, FetchReport &fetchReport, bool duplicate) override
-
void sweep() override
Remove expired entries from the positive and negative caches.
-
void asyncFetch(uint256 const &hash, std::uint32_t ledgerSeq, std::function< void(std::shared_ptr< NodeObject > const &)> &&callback) override
Fetch an object without waiting.
-
std::vector< std::shared_ptr< NodeObject > > fetchBatch(std::vector< uint256 > const &hashes)
-
void storeStats(std::uint64_t count, std::uint64_t sz)
Definition Database.h:220
-
void updateFetchMetrics(uint64_t fetches, uint64_t hits, uint64_t duration)
Definition Database.h:232
-
beast::Journal const j_
Definition Database.h:199
+
std::shared_ptr< Backend > backend_
+
std::shared_ptr< NodeObject > fetchNodeObject(uint256 const &hash, std::uint32_t, FetchReport &fetchReport, bool duplicate) override
+
void asyncFetch(uint256 const &hash, std::uint32_t ledgerSeq, std::function< void(std::shared_ptr< NodeObject > const &)> &&callback) override
Fetch an object without waiting.
+
std::vector< std::shared_ptr< NodeObject > > fetchBatch(std::vector< uint256 > const &hashes)
+
void storeStats(std::uint64_t count, std::uint64_t sz)
Definition Database.h:216
+
void updateFetchMetrics(uint64_t fetches, uint64_t hits, uint64_t duration)
Definition Database.h:228
+
beast::Journal const j_
Definition Database.h:195
virtual void asyncFetch(uint256 const &hash, std::uint32_t ledgerSeq, std::function< void(std::shared_ptr< NodeObject > const &)> &&callback)
Fetch an object without waiting.
Definition Database.cpp:149
pointer data()
Definition base_uint.h:101
@@ -294,15 +212,14 @@ $(document).ready(function() { init_codefold(0); });
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
std::string strHex(FwdIt begin, FwdIt end)
Definition strHex.h:10
NodeObjectType
The types of node objects.
Definition NodeObject.h:12
-
@ hotDUMMY
Definition NodeObject.h:17
+
void Rethrow()
Rethrow the exception currently being handled.
Definition contract.h:28
T push_back(T... args)
-
T reset(T... args)
+
T reserve(T... args)
T size(T... args)
Contains information about a fetch operation.
-
T what(T... args)
diff --git a/DatabaseNodeImp_8h_source.html b/DatabaseNodeImp_8h_source.html index 3493114496..556373f184 100644 --- a/DatabaseNodeImp_8h_source.html +++ b/DatabaseNodeImp_8h_source.html @@ -108,165 +108,124 @@ $(document).ready(function() { init_codefold(0); });
24 : Database(scheduler, readThreads, config, j), backend_(std::move(backend))
25 {
-
26 std::optional<int> cacheSize, cacheAge;
-
27
-
28 if (config.exists("cache_size"))
-
29 {
-
30 cacheSize = get<int>(config, "cache_size");
-
31 if (cacheSize.value() < 0)
-
32 {
-
33 Throw<std::runtime_error>("Specified negative value for cache_size");
-
34 }
-
35 }
+
26 XRPL_ASSERT(
+ +
28 "xrpl::NodeStore::DatabaseNodeImp::DatabaseNodeImp : non-null "
+
29 "backend");
+
30 }
+
+
31
+
+ +
33 {
+
34 stop();
+
35 }
+
36
-
37 if (config.exists("cache_age"))
-
38 {
-
39 cacheAge = get<int>(config, "cache_age");
-
40 if (cacheAge.value() < 0)
-
41 {
-
42 Throw<std::runtime_error>("Specified negative value for cache_age");
-
43 }
-
44 }
-
45
-
46 if (cacheSize != 0 || cacheAge != 0)
-
47 {
- -
49 "DatabaseNodeImp", cacheSize.value_or(0), std::chrono::minutes(cacheAge.value_or(0)), stopwatch(), j);
-
50 }
-
51
-
52 XRPL_ASSERT(
- -
54 "xrpl::NodeStore::DatabaseNodeImp::DatabaseNodeImp : non-null "
-
55 "backend");
-
56 }
+ +
+
38 getName() const override
+
39 {
+
40 return backend_->getName();
+
41 }
+
42
+ +
+
44 getWriteLoad() const override
+
45 {
+
46 return backend_->getWriteLoad();
+
47 }
+
+
48
+
49 void
+
+
50 importDatabase(Database& source) override
+
51 {
+
52 importInternal(*backend_.get(), source);
+
53 }
+
+
54
+
55 void
+
56 store(NodeObjectType type, Blob&& data, uint256 const& hash, std::uint32_t) override;
57
-
- -
59 {
-
60 stop();
-
61 }
+
58 bool
+
+ +
60 {
+
61 // only one database
+
62 return true;
+
63 }
-
62
- -
-
64 getName() const override
-
65 {
-
66 return backend_->getName();
-
67 }
+
64
+
65 void
+
+
66 sync() override
+
67 {
+
68 backend_->sync();
+
69 }
-
68
- -
-
70 getWriteLoad() const override
-
71 {
-
72 return backend_->getWriteLoad();
-
73 }
-
-
74
-
75 void
-
-
76 importDatabase(Database& source) override
-
77 {
-
78 importInternal(*backend_.get(), source);
-
79 }
-
-
80
-
81 void
-
82 store(NodeObjectType type, Blob&& data, uint256 const& hash, std::uint32_t) override;
+
70
+ +
72 fetchBatch(std::vector<uint256> const& hashes);
+
73
+
74 void
+ +
76 uint256 const& hash,
+
77 std::uint32_t ledgerSeq,
+
78 std::function<void(std::shared_ptr<NodeObject> const&)>&& callback) override;
+
79
+
80private:
+
81 // Persistent key/value storage
+
83
-
84 bool
-
- -
86 {
-
87 // only one database
-
88 return true;
-
89 }
+ +
85 fetchNodeObject(uint256 const& hash, std::uint32_t, FetchReport& fetchReport, bool duplicate) override;
+
86
+
87 void
+
+ +
89 {
+
90 backend_->for_each(f);
+
91 }
-
90
-
91 void
-
-
92 sync() override
-
93 {
-
94 backend_->sync();
-
95 }
+
92};
-
96
- -
98 fetchBatch(std::vector<uint256> const& hashes);
-
99
-
100 void
- -
102 uint256 const& hash,
-
103 std::uint32_t ledgerSeq,
-
104 std::function<void(std::shared_ptr<NodeObject> const&)>&& callback) override;
-
105
-
106 void
-
107 sweep() override;
-
108
-
109private:
-
110 // Cache for database objects. This cache is not always initialized. Check
-
111 // for null before using.
- -
113 // Persistent key/value storage
- -
115
- -
117 fetchNodeObject(uint256 const& hash, std::uint32_t, FetchReport& fetchReport, bool duplicate) override;
-
118
-
119 void
-
- -
121 {
-
122 backend_->for_each(f);
-
123 }
-
-
124};
-
-
125
-
126} // namespace NodeStore
-
127} // namespace xrpl
+
93
+
94} // namespace NodeStore
+
95} // namespace xrpl
A generic endpoint for log messages.
Definition Journal.h:40
-
std::string getName() const override
Retrieve the name associated with this backend.
-
std::shared_ptr< TaggedCache< uint256, NodeObject > > cache_
- +
std::string getName() const override
Retrieve the name associated with this backend.
+
void store(NodeObjectType type, Blob &&data, uint256 const &hash, std::uint32_t) override
Store the object.
-
std::shared_ptr< Backend > backend_
+
std::shared_ptr< Backend > backend_
-
std::int32_t getWriteLoad() const override
Retrieve the estimated number of pending write operations.
-
std::shared_ptr< NodeObject > fetchNodeObject(uint256 const &hash, std::uint32_t, FetchReport &fetchReport, bool duplicate) override
-
void for_each(std::function< void(std::shared_ptr< NodeObject >)> f) override
Visit every object in the database This is usually called during import.
-
void sweep() override
Remove expired entries from the positive and negative caches.
- -
void asyncFetch(uint256 const &hash, std::uint32_t ledgerSeq, std::function< void(std::shared_ptr< NodeObject > const &)> &&callback) override
Fetch an object without waiting.
-
bool isSameDB(std::uint32_t, std::uint32_t) override
+
std::int32_t getWriteLoad() const override
Retrieve the estimated number of pending write operations.
+
std::shared_ptr< NodeObject > fetchNodeObject(uint256 const &hash, std::uint32_t, FetchReport &fetchReport, bool duplicate) override
+
void for_each(std::function< void(std::shared_ptr< NodeObject >)> f) override
Visit every object in the database This is usually called during import.
+ +
void asyncFetch(uint256 const &hash, std::uint32_t ledgerSeq, std::function< void(std::shared_ptr< NodeObject > const &)> &&callback) override
Fetch an object without waiting.
+
bool isSameDB(std::uint32_t, std::uint32_t) override
DatabaseNodeImp(Scheduler &scheduler, int readThreads, std::shared_ptr< Backend > backend, Section const &config, beast::Journal j)
DatabaseNodeImp(DatabaseNodeImp const &)=delete
DatabaseNodeImp & operator=(DatabaseNodeImp const &)=delete
-
std::vector< std::shared_ptr< NodeObject > > fetchBatch(std::vector< uint256 > const &hashes)
-
void importDatabase(Database &source) override
Import objects from another database.
+
std::vector< std::shared_ptr< NodeObject > > fetchBatch(std::vector< uint256 > const &hashes)
+
void importDatabase(Database &source) override
Import objects from another database.
Persistency layer for NodeObject.
Definition Database.h:31
void importInternal(Backend &dstBackend, Database &srcDB)
Definition Database.cpp:164
Scheduling for asynchronous backend activity.
Holds a collection of configuration values.
Definition BasicConfig.h:24
-
bool exists(std::string const &name) const
Returns true if a key with the given name exists.
- -
T is_same_v
STL namespace.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
-
Stopwatch & stopwatch()
Returns an instance of a wall clock.
Definition chrono.h:93
NodeObjectType
The types of node objects.
Definition NodeObject.h:12
-
Contains information about a fetch operation.
-
T value(T... args)
-
T value_or(T... args)
diff --git a/DatabaseRotatingImp_8cpp_source.html b/DatabaseRotatingImp_8cpp_source.html index 356cc86467..325fd094b9 100644 --- a/DatabaseRotatingImp_8cpp_source.html +++ b/DatabaseRotatingImp_8cpp_source.html @@ -190,125 +190,116 @@ $(document).ready(function() { init_codefold(0); });
94}
95
-
96void
+
- +
97DatabaseRotatingImp::fetchNodeObject(uint256 const& hash, std::uint32_t, FetchReport& fetchReport, bool duplicate)
98{
-
99 // nothing to do
-
100}
-
-
101
- -
- -
104{
-
105 auto fetch = [&](std::shared_ptr<Backend> const& backend) {
-
106 Status status;
- -
108 try
-
109 {
-
110 status = backend->fetch(hash.data(), &nodeObject);
-
111 }
-
112 catch (std::exception const& e)
+
99 auto fetch = [&](std::shared_ptr<Backend> const& backend) {
+
100 Status status;
+ +
102 try
+
103 {
+
104 status = backend->fetch(hash.data(), &nodeObject);
+
105 }
+
106 catch (std::exception const& e)
+
107 {
+
108 JLOG(j_.fatal()) << "Exception, " << e.what();
+
109 Rethrow();
+
110 }
+
111
+
112 switch (status)
113 {
-
114 JLOG(j_.fatal()) << "Exception, " << e.what();
-
115 Rethrow();
-
116 }
-
117
-
118 switch (status)
-
119 {
-
120 case ok:
-
121 case notFound:
+
114 case ok:
+
115 case notFound:
+
116 break;
+
117 case dataCorrupt:
+
118 JLOG(j_.fatal()) << "Corrupt NodeObject #" << hash;
+
119 break;
+
120 default:
+
121 JLOG(j_.warn()) << "Unknown status=" << status;
122 break;
-
123 case dataCorrupt:
-
124 JLOG(j_.fatal()) << "Corrupt NodeObject #" << hash;
-
125 break;
-
126 default:
-
127 JLOG(j_.warn()) << "Unknown status=" << status;
-
128 break;
-
129 }
+
123 }
+
124
+
125 return nodeObject;
+
126 };
+
127
+
128 // See if the node object exists in the cache
+
130
-
131 return nodeObject;
-
132 };
-
133
-
134 // See if the node object exists in the cache
- -
136
-
137 auto [writable, archive] = [&] {
- - -
140 }();
-
141
-
142 // Try to fetch from the writable backend
-
143 nodeObject = fetch(writable);
-
144 if (!nodeObject)
-
145 {
-
146 // Otherwise try to fetch from the archive backend
-
147 nodeObject = fetch(archive);
-
148 if (nodeObject)
-
149 {
-
150 {
-
151 // Refresh the writable backend pointer
- -
153 writable = writableBackend_;
-
154 }
+
131 auto [writable, archive] = [&] {
+ + +
134 }();
+
135
+
136 // Try to fetch from the writable backend
+
137 nodeObject = fetch(writable);
+
138 if (!nodeObject)
+
139 {
+
140 // Otherwise try to fetch from the archive backend
+
141 nodeObject = fetch(archive);
+
142 if (nodeObject)
+
143 {
+
144 {
+
145 // Refresh the writable backend pointer
+ +
147 writable = writableBackend_;
+
148 }
+
149
+
150 // Update writable backend with data from the archive backend
+
151 if (duplicate)
+
152 writable->store(nodeObject);
+
153 }
+
154 }
155
-
156 // Update writable backend with data from the archive backend
-
157 if (duplicate)
-
158 writable->store(nodeObject);
-
159 }
-
160 }
+
156 if (nodeObject)
+
157 fetchReport.wasFound = true;
+
158
+
159 return nodeObject;
+
160}
+
161
-
162 if (nodeObject)
-
163 fetchReport.wasFound = true;
-
164
-
165 return nodeObject;
-
166}
+
162void
+
+ +
164{
+
165 auto [writable, archive] = [&] {
+ + +
168 }();
+
169
+
170 // Iterate the writable backend
+
171 writable->for_each(f);
+
172
+
173 // Iterate the archive backend
+
174 archive->for_each(f);
+
175}
-
167
-
168void
-
- -
170{
-
171 auto [writable, archive] = [&] {
- - -
174 }();
-
175
-
176 // Iterate the writable backend
-
177 writable->for_each(f);
-
178
-
179 // Iterate the archive backend
-
180 archive->for_each(f);
-
181}
-
-
182
-
183} // namespace NodeStore
-
184} // namespace xrpl
+
176
+
177} // namespace NodeStore
+
178} // namespace xrpl
A generic endpoint for log messages.
Definition Journal.h:40
Stream fatal() const
Definition Journal.h:324
Stream warn() const
Definition Journal.h:312
static std::shared_ptr< NodeObject > createObject(NodeObjectType type, Blob &&data, uint256 const &hash)
Create an object from fields.
-
std::shared_ptr< Backend > archiveBackend_
- +
std::shared_ptr< Backend > archiveBackend_
+
std::int32_t getWriteLoad() const override
Retrieve the estimated number of pending write operations.
void importDatabase(Database &source) override
Import objects from another database.
-
void sweep() override
Remove expired entries from the positive and negative caches.
-
std::shared_ptr< Backend > writableBackend_
+
std::shared_ptr< Backend > writableBackend_
void rotate(std::unique_ptr< NodeStore::Backend > &&newBackend, std::function< void(std::string const &writableName, std::string const &archiveName)> const &f) override
Rotates the backends.
std::string getName() const override
Retrieve the name associated with this backend.
-
void for_each(std::function< void(std::shared_ptr< NodeObject >)> f) override
Visit every object in the database This is usually called during import.
-
std::shared_ptr< NodeObject > fetchNodeObject(uint256 const &hash, std::uint32_t, FetchReport &fetchReport, bool duplicate) override
+
void for_each(std::function< void(std::shared_ptr< NodeObject >)> f) override
Visit every object in the database This is usually called during import.
+
std::shared_ptr< NodeObject > fetchNodeObject(uint256 const &hash, std::uint32_t, FetchReport &fetchReport, bool duplicate) override
void store(NodeObjectType type, Blob &&data, uint256 const &hash, std::uint32_t) override
Store the object.
Persistency layer for NodeObject.
Definition Database.h:31
-
void storeStats(std::uint64_t count, std::uint64_t sz)
Definition Database.h:220
-
int fdRequired() const
Returns the number of file descriptors the database expects to need.
Definition Database.h:179
-
beast::Journal const j_
Definition Database.h:199
- +
void storeStats(std::uint64_t count, std::uint64_t sz)
Definition Database.h:216
+
int fdRequired() const
Returns the number of file descriptors the database expects to need.
Definition Database.h:175
+
beast::Journal const j_
Definition Database.h:195
+
void importInternal(Backend &dstBackend, Database &srcDB)
Definition Database.cpp:164
Scheduling for asynchronous backend activity.
Holds a collection of configuration values.
Definition BasicConfig.h:24
diff --git a/DatabaseRotatingImp_8h_source.html b/DatabaseRotatingImp_8h_source.html index 0b7c83b4fb..eed9e78069 100644 --- a/DatabaseRotatingImp_8h_source.html +++ b/DatabaseRotatingImp_8h_source.html @@ -143,41 +143,37 @@ $(document).ready(function() { init_codefold(0); });
55 void
56 sync() override;
57
-
58 void
-
59 sweep() override;
-
60
-
61private:
- - - +
58private:
+ + + +
62
+ +
64 fetchNodeObject(uint256 const& hash, std::uint32_t, FetchReport& fetchReport, bool duplicate) override;
65
- -
67 fetchNodeObject(uint256 const& hash, std::uint32_t, FetchReport& fetchReport, bool duplicate) override;
-
68
-
69 void
- -
71};
+
66 void
+ +
68};
-
72
-
73} // namespace NodeStore
-
74} // namespace xrpl
+
69
+
70} // namespace NodeStore
+
71} // namespace xrpl
A generic endpoint for log messages.
Definition Journal.h:40
-
std::shared_ptr< Backend > archiveBackend_
+
std::shared_ptr< Backend > archiveBackend_
bool isSameDB(std::uint32_t, std::uint32_t) override
DatabaseRotatingImp(DatabaseRotatingImp const &)=delete
- +
std::int32_t getWriteLoad() const override
Retrieve the estimated number of pending write operations.
void importDatabase(Database &source) override
Import objects from another database.
-
void sweep() override
Remove expired entries from the positive and negative caches.
-
std::shared_ptr< Backend > writableBackend_
+
std::shared_ptr< Backend > writableBackend_
DatabaseRotatingImp & operator=(DatabaseRotatingImp const &)=delete
void rotate(std::unique_ptr< NodeStore::Backend > &&newBackend, std::function< void(std::string const &writableName, std::string const &archiveName)> const &f) override
Rotates the backends.
std::string getName() const override
Retrieve the name associated with this backend.
-
void for_each(std::function< void(std::shared_ptr< NodeObject >)> f) override
Visit every object in the database This is usually called during import.
-
std::shared_ptr< NodeObject > fetchNodeObject(uint256 const &hash, std::uint32_t, FetchReport &fetchReport, bool duplicate) override
+
void for_each(std::function< void(std::shared_ptr< NodeObject >)> f) override
Visit every object in the database This is usually called during import.
+
std::shared_ptr< NodeObject > fetchNodeObject(uint256 const &hash, std::uint32_t, FetchReport &fetchReport, bool duplicate) override
void store(NodeObjectType type, Blob &&data, uint256 const &hash, std::uint32_t) override
Store the object.
diff --git a/Database_8cpp_source.html b/Database_8cpp_source.html index f9904390d8..bc6e18ac30 100644 --- a/Database_8cpp_source.html +++ b/Database_8cpp_source.html @@ -355,30 +355,30 @@ $(document).ready(function() { init_codefold(0); });
Persistency layer for NodeObject.
Definition Database.h:31
-
void storeStats(std::uint64_t count, std::uint64_t sz)
Definition Database.h:220
-
std::condition_variable readCondVar_
Definition Database.h:247
-
std::atomic< std::uint64_t > fetchTotalCount_
Definition Database.h:242
-
std::atomic< int > readThreads_
Definition Database.h:254
-
std::atomic< int > runningThreads_
Definition Database.h:255
+
void storeStats(std::uint64_t count, std::uint64_t sz)
Definition Database.h:216
+
std::condition_variable readCondVar_
Definition Database.h:243
+
std::atomic< std::uint64_t > fetchTotalCount_
Definition Database.h:238
+
std::atomic< int > readThreads_
Definition Database.h:250
+
std::atomic< int > runningThreads_
Definition Database.h:251
- -
beast::Journal const j_
Definition Database.h:199
+ +
beast::Journal const j_
Definition Database.h:195
virtual void for_each(std::function< void(std::shared_ptr< NodeObject >)> f)=0
Visit every object in the database This is usually called during import.
-
std::atomic< bool > readStopping_
Definition Database.h:253
+
std::atomic< bool > readStopping_
Definition Database.h:249
virtual void asyncFetch(uint256 const &hash, std::uint32_t ledgerSeq, std::function< void(std::shared_ptr< NodeObject > const &)> &&callback)
Fetch an object without waiting.
Definition Database.cpp:149
-
std::map< uint256, std::vector< std::pair< std::uint32_t, std::function< void(std::shared_ptr< NodeObject > const &)> > > > read_
Definition Database.h:251
- -
std::atomic< std::uint64_t > fetchDurationUs_
Definition Database.h:243
+
std::map< uint256, std::vector< std::pair< std::uint32_t, std::function< void(std::shared_ptr< NodeObject > const &)> > > > read_
Definition Database.h:247
+ +
std::atomic< std::uint64_t > fetchDurationUs_
Definition Database.h:239
virtual bool isSameDB(std::uint32_t s1, std::uint32_t s2)=0
virtual ~Database()
Destroy the node store.
Definition Database.cpp:100
-
std::atomic< std::uint64_t > storeSz_
Definition Database.h:241
-
std::uint32_t const earliestLedgerSeq_
Definition Database.h:212
-
std::atomic< std::uint32_t > fetchHitCount_
Definition Database.h:203
-
std::atomic< std::uint64_t > storeCount_
Definition Database.h:240
+
std::atomic< std::uint64_t > storeSz_
Definition Database.h:237
+
std::uint32_t const earliestLedgerSeq_
Definition Database.h:208
+
std::atomic< std::uint32_t > fetchHitCount_
Definition Database.h:199
+
std::atomic< std::uint64_t > storeCount_
Definition Database.h:236
std::shared_ptr< NodeObject > fetchNodeObject(uint256 const &hash, std::uint32_t ledgerSeq=0, FetchType fetchType=FetchType::synchronous, bool duplicate=false)
Fetch a node object.
Definition Database.cpp:202
- +
void getCountsJson(Json::Value &obj)
Definition Database.cpp:225
-
std::atomic< std::uint32_t > fetchSz_
Definition Database.h:204
+
std::atomic< std::uint32_t > fetchSz_
Definition Database.h:200
void importInternal(Backend &dstBackend, Database &srcDB)
Definition Database.cpp:164
Scheduling for asynchronous backend activity.
virtual void onFetch(FetchReport const &report)=0
Reports completion of a fetch Allows the scheduler to monitor the node store's performance.
diff --git a/Database_8h_source.html b/Database_8h_source.html index 6f26d7fb32..6a69b00bc7 100644 --- a/Database_8h_source.html +++ b/Database_8h_source.html @@ -150,200 +150,196 @@ $(document).ready(function() { init_codefold(0); });
133 std::uint32_t ledgerSeq,
134 std::function<void(std::shared_ptr<NodeObject> const&)>&& callback);
135
-
137 virtual void
-
138 sweep() = 0;
-
139
- -
- -
146 {
-
147 return storeCount_;
-
148 }
+ +
+ +
142 {
+
143 return storeCount_;
+
144 }
-
149
- -
- -
152 {
-
153 return fetchTotalCount_;
-
154 }
+
145
+ +
+ +
148 {
+
149 return fetchTotalCount_;
+
150 }
-
155
- -
- -
158 {
-
159 return fetchHitCount_;
-
160 }
+
151
+ +
+ +
154 {
+
155 return fetchHitCount_;
+
156 }
-
161
- -
- -
164 {
-
165 return storeSz_;
-
166 }
+
157
+ +
+ +
160 {
+
161 return storeSz_;
+
162 }
-
167
- -
- -
170 {
-
171 return fetchSz_;
-
172 }
+
163
+ +
+ +
166 {
+
167 return fetchSz_;
+
168 }
-
173
-
174 void
- -
176
-
178 int
-
- -
180 {
-
181 return fdRequired_;
-
182 }
+
169
+
170 void
+ +
172
+
174 int
+
+ +
176 {
+
177 return fdRequired_;
+
178 }
-
183
-
184 virtual void
-
185 stop();
-
186
-
187 bool
-
188 isStopping() const;
-
189
-
192 [[nodiscard]] std::uint32_t
-
-
193 earliestLedgerSeq() const noexcept
-
194 {
-
195 return earliestLedgerSeq_;
-
196 }
+
179
+
180 virtual void
+
181 stop();
+
182
+
183 bool
+
184 isStopping() const;
+
185
+
188 [[nodiscard]] std::uint32_t
+
+
189 earliestLedgerSeq() const noexcept
+
190 {
+
191 return earliestLedgerSeq_;
+
192 }
-
197
-
198protected:
- - - -
202
- - -
205
-
206 // The default is XRP_LEDGER_EARLIEST_SEQ (32570) to match the XRP ledger
-
207 // network's earliest allowed ledger sequence. Can be set through the
-
208 // configuration file using the 'earliest_seq' field under the 'node_db'
-
209 // stanza. If specified, the value must be greater than zero.
-
210 // Only unit tests or alternate
-
211 // networks should change this value.
- -
213
-
214 // The maximum number of requests a thread extracts from the queue in an
-
215 // attempt to minimize the overhead of mutex acquisition. This is an
-
216 // advanced tunable, via the config file. The default value is 4.
-
217 int const requestBundle_;
-
218
-
219 void
-
- -
221 {
-
222 XRPL_ASSERT(count <= sz, "xrpl::NodeStore::Database::storeStats : valid inputs");
-
223 storeCount_ += count;
-
224 storeSz_ += sz;
-
225 }
+
193
+
194protected:
+ + + +
198
+ + +
201
+
202 // The default is XRP_LEDGER_EARLIEST_SEQ (32570) to match the XRP ledger
+
203 // network's earliest allowed ledger sequence. Can be set through the
+
204 // configuration file using the 'earliest_seq' field under the 'node_db'
+
205 // stanza. If specified, the value must be greater than zero.
+
206 // Only unit tests or alternate
+
207 // networks should change this value.
+ +
209
+
210 // The maximum number of requests a thread extracts from the queue in an
+
211 // attempt to minimize the overhead of mutex acquisition. This is an
+
212 // advanced tunable, via the config file. The default value is 4.
+
213 int const requestBundle_;
+
214
+
215 void
+
+ +
217 {
+
218 XRPL_ASSERT(count <= sz, "xrpl::NodeStore::Database::storeStats : valid inputs");
+
219 storeCount_ += count;
+
220 storeSz_ += sz;
+
221 }
+
222
+
223 // Called by the public import function
+
224 void
+
225 importInternal(Backend& dstBackend, Database& srcDB);
226
-
227 // Called by the public import function
-
228 void
-
229 importInternal(Backend& dstBackend, Database& srcDB);
-
230
-
231 void
-
-
232 updateFetchMetrics(uint64_t fetches, uint64_t hits, uint64_t duration)
-
233 {
-
234 fetchTotalCount_ += fetches;
-
235 fetchHitCount_ += hits;
-
236 fetchDurationUs_ += duration;
-
237 }
+
227 void
+
+
228 updateFetchMetrics(uint64_t fetches, uint64_t hits, uint64_t duration)
+
229 {
+
230 fetchTotalCount_ += fetches;
+
231 fetchHitCount_ += hits;
+
232 fetchDurationUs_ += duration;
+
233 }
-
238
-
239private:
- - - - - -
245
- - +
234
+
235private:
+ + + + + +
241
+ + +
244
+
245 // reads to do
+ +
248
-
249 // reads to do
- - + + +
252
- - - -
256
- -
258 fetchNodeObject(uint256 const& hash, std::uint32_t ledgerSeq, FetchReport& fetchReport, bool duplicate) = 0;
-
259
-
267 virtual void
- -
269
-
270 void
- -
272};
+ +
254 fetchNodeObject(uint256 const& hash, std::uint32_t ledgerSeq, FetchReport& fetchReport, bool duplicate) = 0;
+
255
+
263 virtual void
+ +
265
+
266 void
+ +
268};
-
273
-
274} // namespace NodeStore
-
275} // namespace xrpl
+
269
+
270} // namespace NodeStore
+
271} // namespace xrpl
Represents a JSON value.
Definition json_value.h:130
A generic endpoint for log messages.
Definition Journal.h:40
A backend used for the NodeStore.
Definition Backend.h:20
Persistency layer for NodeObject.
Definition Database.h:31
-
std::uint32_t getFetchHitCount() const
Definition Database.h:157
-
virtual void sweep()=0
Remove expired entries from the positive and negative caches.
-
std::uint32_t earliestLedgerSeq() const noexcept
Definition Database.h:193
+
std::uint32_t getFetchHitCount() const
Definition Database.h:153
+
std::uint32_t earliestLedgerSeq() const noexcept
Definition Database.h:189
virtual void importDatabase(Database &source)=0
Import objects from another database.
-
void storeStats(std::uint64_t count, std::uint64_t sz)
Definition Database.h:220
-
std::condition_variable readCondVar_
Definition Database.h:247
-
std::atomic< std::uint64_t > fetchTotalCount_
Definition Database.h:242
-
std::atomic< int > readThreads_
Definition Database.h:254
-
void updateFetchMetrics(uint64_t fetches, uint64_t hits, uint64_t duration)
Definition Database.h:232
-
std::atomic< std::uint64_t > storeDurationUs_
Definition Database.h:244
-
int fdRequired() const
Returns the number of file descriptors the database expects to need.
Definition Database.h:179
-
std::atomic< int > runningThreads_
Definition Database.h:255
+
void storeStats(std::uint64_t count, std::uint64_t sz)
Definition Database.h:216
+
std::condition_variable readCondVar_
Definition Database.h:243
+
std::atomic< std::uint64_t > fetchTotalCount_
Definition Database.h:238
+
std::atomic< int > readThreads_
Definition Database.h:250
+
void updateFetchMetrics(uint64_t fetches, uint64_t hits, uint64_t duration)
Definition Database.h:228
+
std::atomic< std::uint64_t > storeDurationUs_
Definition Database.h:240
+
int fdRequired() const
Returns the number of file descriptors the database expects to need.
Definition Database.h:175
+
std::atomic< int > runningThreads_
Definition Database.h:251
- -
beast::Journal const j_
Definition Database.h:199
+ +
beast::Journal const j_
Definition Database.h:195
virtual void for_each(std::function< void(std::shared_ptr< NodeObject >)> f)=0
Visit every object in the database This is usually called during import.
- -
std::atomic< bool > readStopping_
Definition Database.h:253
+ +
std::atomic< bool > readStopping_
Definition Database.h:249
virtual void asyncFetch(uint256 const &hash, std::uint32_t ledgerSeq, std::function< void(std::shared_ptr< NodeObject > const &)> &&callback)
Fetch an object without waiting.
Definition Database.cpp:149
-
std::map< uint256, std::vector< std::pair< std::uint32_t, std::function< void(std::shared_ptr< NodeObject > const &)> > > > read_
Definition Database.h:251
- -
std::atomic< std::uint64_t > fetchDurationUs_
Definition Database.h:243
+
std::map< uint256, std::vector< std::pair< std::uint32_t, std::function< void(std::shared_ptr< NodeObject > const &)> > > > read_
Definition Database.h:247
+ +
std::atomic< std::uint64_t > fetchDurationUs_
Definition Database.h:239
virtual bool isSameDB(std::uint32_t s1, std::uint32_t s2)=0
virtual ~Database()
Destroy the node store.
Definition Database.cpp:100
virtual void sync()=0
-
std::atomic< std::uint64_t > storeSz_
Definition Database.h:241
-
std::uint32_t const earliestLedgerSeq_
Definition Database.h:212
-
std::atomic< std::uint32_t > fetchHitCount_
Definition Database.h:203
-
std::atomic< std::uint64_t > storeCount_
Definition Database.h:240
+
std::atomic< std::uint64_t > storeSz_
Definition Database.h:237
+
std::uint32_t const earliestLedgerSeq_
Definition Database.h:208
+
std::atomic< std::uint32_t > fetchHitCount_
Definition Database.h:199
+
std::atomic< std::uint64_t > storeCount_
Definition Database.h:236
virtual std::string getName() const =0
Retrieve the name associated with this backend.
std::shared_ptr< NodeObject > fetchNodeObject(uint256 const &hash, std::uint32_t ledgerSeq=0, FetchType fetchType=FetchType::synchronous, bool duplicate=false)
Fetch a node object.
Definition Database.cpp:202
-
std::uint64_t getStoreCount() const
Gather statistics pertaining to read and write activities.
Definition Database.h:145
-
std::uint64_t getStoreSize() const
Definition Database.h:163
+
std::uint64_t getStoreCount() const
Gather statistics pertaining to read and write activities.
Definition Database.h:141
+
std::uint64_t getStoreSize() const
Definition Database.h:159
virtual void store(NodeObjectType type, Blob &&data, uint256 const &hash, std::uint32_t ledgerSeq)=0
Store the object.
virtual std::shared_ptr< NodeObject > fetchNodeObject(uint256 const &hash, std::uint32_t ledgerSeq, FetchReport &fetchReport, bool duplicate)=0
- +
void getCountsJson(Json::Value &obj)
Definition Database.cpp:225
-
std::uint32_t getFetchTotalCount() const
Definition Database.h:151
-
std::uint32_t getFetchSize() const
Definition Database.h:169
+
std::uint32_t getFetchTotalCount() const
Definition Database.h:147
+
std::uint32_t getFetchSize() const
Definition Database.h:165
virtual std::int32_t getWriteLoad() const =0
Retrieve the estimated number of pending write operations.
-
std::atomic< std::uint32_t > fetchSz_
Definition Database.h:204
+
std::atomic< std::uint32_t > fetchSz_
Definition Database.h:200
void importInternal(Backend &dstBackend, Database &srcDB)
Definition Database.cpp:164
Scheduling for asynchronous backend activity.
Holds a collection of configuration values.
Definition BasicConfig.h:24
diff --git a/Env_8cpp_source.html b/Env_8cpp_source.html index c3bc20be7e..8a82565f5d 100644 --- a/Env_8cpp_source.html +++ b/Env_8cpp_source.html @@ -909,7 +909,7 @@ $(document).ready(function() { init_codefold(0); });
std::string transHuman(TER code)
Definition TER.cpp:252
std::pair< int, Json::Value > rpcClient(std::vector< std::string > const &args, Config const &config, Logs &logs, unsigned int apiVersion, std::unordered_map< std::string, std::string > const &headers)
Internal invocation of RPC client.
Definition RPCCall.cpp:1437
std::string transToken(TER code)
Definition TER.cpp:243
-
std::unique_ptr< Application > make_Application(std::unique_ptr< Config > config, std::unique_ptr< Logs > logs, std::unique_ptr< TimeKeeper > timeKeeper)
+
std::unique_ptr< Application > make_Application(std::unique_ptr< Config > config, std::unique_ptr< Logs > logs, std::unique_ptr< TimeKeeper > timeKeeper)
constexpr std::uint32_t asfDefaultRipple
Definition TxFlags.h:64
@ temMALFORMED
Definition TER.h:67
diff --git a/LedgerMaster_8cpp_source.html b/LedgerMaster_8cpp_source.html index 31892e99f9..377a540f47 100644 --- a/LedgerMaster_8cpp_source.html +++ b/LedgerMaster_8cpp_source.html @@ -2455,7 +2455,7 @@ $(document).ready(function() { init_codefold(0); });
virtual void clearNeedNetworkLedger()=0
virtual void setAmendmentWarned()=0
Persistency layer for NodeObject.
Definition Database.h:31
-
std::uint32_t earliestLedgerSeq() const noexcept
Definition Database.h:193
+
std::uint32_t earliestLedgerSeq() const noexcept
Definition Database.h:189
std::shared_ptr< NodeObject > fetchNodeObject(uint256 const &hash, std::uint32_t ledgerSeq=0, FetchType fetchType=FetchType::synchronous, bool duplicate=false)
Fetch a node object.
Definition Database.cpp:202
virtual std::int32_t getWriteLoad() const =0
Retrieve the estimated number of pending write operations.
std::shared_ptr< OpenView const > current() const
Returns a view to the current open ledger.
diff --git a/Main_8cpp_source.html b/Main_8cpp_source.html index 997fc342b0..359ead544a 100644 --- a/Main_8cpp_source.html +++ b/Main_8cpp_source.html @@ -944,7 +944,7 @@ $(document).ready(function() { init_codefold(0); });
int run(int argc, char **argv)
Definition Main.cpp:322
std::unique_ptr< beast::Journal::Sink > setDebugLogSink(std::unique_ptr< beast::Journal::Sink > sink)
Set the sink for the debug journal.
Definition Log.cpp:439
bool adjustDescriptorLimit(int needed, beast::Journal j)
Definition Main.cpp:59
-
std::unique_ptr< Application > make_Application(std::unique_ptr< Config > config, std::unique_ptr< Logs > logs, std::unique_ptr< TimeKeeper > timeKeeper)
+
std::unique_ptr< Application > make_Application(std::unique_ptr< Config > config, std::unique_ptr< Logs > logs, std::unique_ptr< TimeKeeper > timeKeeper)
DatabaseCon::Setup setup_DatabaseCon(Config const &c, std::optional< beast::Journal > j=std::nullopt)
static std::string const & systemName()
diff --git a/SHAMapStoreImp_8cpp_source.html b/SHAMapStoreImp_8cpp_source.html index bc02118906..e1d970d446 100644 --- a/SHAMapStoreImp_8cpp_source.html +++ b/SHAMapStoreImp_8cpp_source.html @@ -228,508 +228,501 @@ $(document).ready(function() { init_codefold(0); });
131{
-
133
-
134 // Provide default values:
-
135 if (!nscfg.exists("cache_size"))
- -
137
-
138 if (!nscfg.exists("cache_age"))
- -
140
- -
142
-
143 if (deleteInterval_)
-
144 {
-
145 SavedState state = state_db_.getState();
-
146 auto writableBackend = makeBackendRotating(state.writableDb);
-
147 auto archiveBackend = makeBackendRotating(state.archiveDb);
-
148 if (!state.writableDb.size())
-
149 {
-
150 state.writableDb = writableBackend->getName();
-
151 state.archiveDb = archiveBackend->getName();
-
152 state_db_.setState(state);
-
153 }
-
154
-
155 // Create NodeStore with two backends to allow online deletion of
-
156 // data
- - -
159 readThreads,
-
160 std::move(writableBackend),
-
161 std::move(archiveBackend),
-
162 nscfg,
- -
164 fdRequired_ += dbr->fdRequired();
-
165 dbRotating_ = dbr.get();
-
166 db.reset(dynamic_cast<NodeStore::Database*>(dbr.release()));
-
167 }
-
168 else
-
169 {
- - - -
173 readThreads,
-
174 nscfg,
- -
176 fdRequired_ += db->fdRequired();
-
177 }
-
178 return db;
-
179}
+ +
134
+
135 if (deleteInterval_)
+
136 {
+
137 SavedState state = state_db_.getState();
+
138 auto writableBackend = makeBackendRotating(state.writableDb);
+
139 auto archiveBackend = makeBackendRotating(state.archiveDb);
+
140 if (!state.writableDb.size())
+
141 {
+
142 state.writableDb = writableBackend->getName();
+
143 state.archiveDb = archiveBackend->getName();
+
144 state_db_.setState(state);
+
145 }
+
146
+
147 // Create NodeStore with two backends to allow online deletion of
+
148 // data
+ + +
151 readThreads,
+
152 std::move(writableBackend),
+
153 std::move(archiveBackend),
+
154 nscfg,
+ +
156 fdRequired_ += dbr->fdRequired();
+
157 dbRotating_ = dbr.get();
+
158 db.reset(dynamic_cast<NodeStore::Database*>(dbr.release()));
+
159 }
+
160 else
+
161 {
+ + + +
165 readThreads,
+
166 nscfg,
+ +
168 fdRequired_ += db->fdRequired();
+
169 }
+
170 return db;
+
171}
-
180
-
181void
-
- -
183{
-
184 {
- -
186 newLedger_ = ledger;
-
187 working_ = true;
-
188 }
- -
190}
+
172
+
173void
+
+ +
175{
+
176 {
+ +
178 newLedger_ = ledger;
+
179 working_ = true;
+
180 }
+ +
182}
-
191
-
192void
-
- -
194{
-
195 if (!working_)
-
196 return;
-
197
- -
199 rendezvous_.wait(lock, [&] { return !working_; });
-
200}
+
183
+
184void
+
+ +
186{
+
187 if (!working_)
+
188 return;
+
189
+ +
191 rendezvous_.wait(lock, [&] { return !working_; });
+
192}
-
201
-
202int
-
- -
204{
-
205 return fdRequired_;
-
206}
+
193
+
194int
+
+ +
196{
+
197 return fdRequired_;
+
198}
-
207
-
208bool
-
- -
210{
-
211 // Copy a single record from node to dbRotating_
- -
213 if (!(++nodeCount % checkHealthInterval_))
-
214 {
-
215 if (healthWait() == stopping)
-
216 return false;
-
217 }
-
218
-
219 return true;
-
220}
+
199
+
200bool
+
+ +
202{
+
203 // Copy a single record from node to dbRotating_
+ +
205 if (!(++nodeCount % checkHealthInterval_))
+
206 {
+
207 if (healthWait() == stopping)
+
208 return false;
+
209 }
+
210
+
211 return true;
+
212}
+
213
+
214void
+
+ +
216{
+
217 beast::setCurrentThreadName("SHAMapStore");
+ +
219 netOPs_ = &app_.getOPs();
+
221
-
222void
-
- -
224{
-
225 beast::setCurrentThreadName("SHAMapStore");
- -
227 netOPs_ = &app_.getOPs();
- - - -
231
-
232 if (advisoryDelete_)
- -
234
-
235 while (true)
-
236 {
-
237 healthy_ = true;
-
238 std::shared_ptr<Ledger const> validatedLedger;
-
239
-
240 {
- -
242 working_ = false;
- -
244 if (stop_)
-
245 {
-
246 return;
-
247 }
-
248 cond_.wait(lock);
-
249 if (newLedger_)
-
250 {
-
251 validatedLedger = std::move(newLedger_);
-
252 }
-
253 else
-
254 continue;
-
255 }
+
222 if (advisoryDelete_)
+ +
224
+
225 while (true)
+
226 {
+
227 healthy_ = true;
+
228 std::shared_ptr<Ledger const> validatedLedger;
+
229
+
230 {
+ +
232 working_ = false;
+ +
234 if (stop_)
+
235 {
+
236 return;
+
237 }
+
238 cond_.wait(lock);
+
239 if (newLedger_)
+
240 {
+
241 validatedLedger = std::move(newLedger_);
+
242 }
+
243 else
+
244 continue;
+
245 }
+
246
+
247 LedgerIndex const validatedSeq = validatedLedger->header().seq;
+
248 if (!lastRotated)
+
249 {
+
250 lastRotated = validatedSeq;
+
251 state_db_.setLastRotated(lastRotated);
+
252 }
+
253
+
254 bool const readyToRotate =
+
255 validatedSeq >= lastRotated + deleteInterval_ && canDelete_ >= lastRotated - 1 && healthWait() == keepGoing;
256
-
257 LedgerIndex const validatedSeq = validatedLedger->header().seq;
-
258 if (!lastRotated)
+
257 // will delete up to (not including) lastRotated
+
258 if (readyToRotate)
259 {
-
260 lastRotated = validatedSeq;
-
261 state_db_.setLastRotated(lastRotated);
-
262 }
-
263
-
264 bool const readyToRotate =
-
265 validatedSeq >= lastRotated + deleteInterval_ && canDelete_ >= lastRotated - 1 && healthWait() == keepGoing;
-
266
-
267 // will delete up to (not including) lastRotated
-
268 if (readyToRotate)
-
269 {
-
270 JLOG(journal_.warn()) << "rotating validatedSeq " << validatedSeq << " lastRotated " << lastRotated
-
271 << " deleteInterval " << deleteInterval_ << " canDelete_ " << canDelete_ << " state "
-
272 << app_.getOPs().strOperatingMode(false) << " age "
- -
274
-
275 clearPrior(lastRotated);
-
276 if (healthWait() == stopping)
-
277 return;
-
278
-
279 JLOG(journal_.debug()) << "copying ledger " << validatedSeq;
-
280 std::uint64_t nodeCount = 0;
-
281
-
282 try
-
283 {
-
284 validatedLedger->stateMap().snapShot(false)->visitNodes(
-
285 std::bind(&SHAMapStoreImp::copyNode, this, std::ref(nodeCount), std::placeholders::_1));
-
286 }
-
287 catch (SHAMapMissingNode const& e)
-
288 {
-
289 JLOG(journal_.error()) << "Missing node while copying ledger before rotate: " << e.what();
-
290 continue;
-
291 }
-
292
-
293 if (healthWait() == stopping)
-
294 return;
-
295 // Only log if we completed without a "health" abort
-
296 JLOG(journal_.debug()) << "copied ledger " << validatedSeq << " nodecount " << nodeCount;
-
297
-
298 JLOG(journal_.debug()) << "freshening caches";
- +
260 JLOG(journal_.warn()) << "rotating validatedSeq " << validatedSeq << " lastRotated " << lastRotated
+
261 << " deleteInterval " << deleteInterval_ << " canDelete_ " << canDelete_ << " state "
+
262 << app_.getOPs().strOperatingMode(false) << " age "
+ +
264
+
265 clearPrior(lastRotated);
+
266 if (healthWait() == stopping)
+
267 return;
+
268
+
269 JLOG(journal_.debug()) << "copying ledger " << validatedSeq;
+
270 std::uint64_t nodeCount = 0;
+
271
+
272 try
+
273 {
+
274 validatedLedger->stateMap().snapShot(false)->visitNodes(
+
275 std::bind(&SHAMapStoreImp::copyNode, this, std::ref(nodeCount), std::placeholders::_1));
+
276 }
+
277 catch (SHAMapMissingNode const& e)
+
278 {
+
279 JLOG(journal_.error()) << "Missing node while copying ledger before rotate: " << e.what();
+
280 continue;
+
281 }
+
282
+
283 if (healthWait() == stopping)
+
284 return;
+
285 // Only log if we completed without a "health" abort
+
286 JLOG(journal_.debug()) << "copied ledger " << validatedSeq << " nodecount " << nodeCount;
+
287
+
288 JLOG(journal_.debug()) << "freshening caches";
+ +
290 if (healthWait() == stopping)
+
291 return;
+
292 // Only log if we completed without a "health" abort
+
293 JLOG(journal_.debug()) << validatedSeq << " freshened caches";
+
294
+
295 JLOG(journal_.trace()) << "Making a new backend";
+
296 auto newBackend = makeBackendRotating();
+
297 JLOG(journal_.debug()) << validatedSeq << " new backend " << newBackend->getName();
+
298
+
299 clearCaches(validatedSeq);
300 if (healthWait() == stopping)
301 return;
-
302 // Only log if we completed without a "health" abort
-
303 JLOG(journal_.debug()) << validatedSeq << " freshened caches";
+
302
+
303 lastRotated = validatedSeq;
304
-
305 JLOG(journal_.trace()) << "Making a new backend";
-
306 auto newBackend = makeBackendRotating();
-
307 JLOG(journal_.debug()) << validatedSeq << " new backend " << newBackend->getName();
-
308
-
309 clearCaches(validatedSeq);
-
310 if (healthWait() == stopping)
-
311 return;
+ +
306 std::move(newBackend), [&](std::string const& writableName, std::string const& archiveName) {
+
307 SavedState savedState;
+
308 savedState.writableDb = writableName;
+
309 savedState.archiveDb = archiveName;
+
310 savedState.lastRotated = lastRotated;
+
311 state_db_.setState(savedState);
312
-
313 lastRotated = validatedSeq;
-
314
- -
316 std::move(newBackend), [&](std::string const& writableName, std::string const& archiveName) {
-
317 SavedState savedState;
-
318 savedState.writableDb = writableName;
-
319 savedState.archiveDb = archiveName;
-
320 savedState.lastRotated = lastRotated;
-
321 state_db_.setState(savedState);
-
322
-
323 clearCaches(validatedSeq);
-
324 });
-
325
-
326 JLOG(journal_.warn()) << "finished rotation " << validatedSeq;
-
327 }
-
328 }
-
329}
+
313 clearCaches(validatedSeq);
+
314 });
+
315
+
316 JLOG(journal_.warn()) << "finished rotation " << validatedSeq;
+
317 }
+
318 }
+
319}
-
330
-
331void
-
- -
333{
- -
335 boost::filesystem::path dbPath = get(section, "path");
-
336
-
337 if (boost::filesystem::exists(dbPath))
-
338 {
-
339 if (!boost::filesystem::is_directory(dbPath))
-
340 {
-
341 journal_.error() << "node db path must be a directory. " << dbPath.string();
-
342 Throw<std::runtime_error>("node db path must be a directory.");
-
343 }
-
344 }
-
345 else
-
346 {
-
347 boost::filesystem::create_directories(dbPath);
-
348 }
-
349
-
350 SavedState state = state_db_.getState();
-
351
-
352 {
-
353 auto update = [&dbPath](std::string& sPath) {
-
354 if (sPath.empty())
-
355 return false;
+
320
+
321void
+
+ +
323{
+ +
325 boost::filesystem::path dbPath = get(section, "path");
+
326
+
327 if (boost::filesystem::exists(dbPath))
+
328 {
+
329 if (!boost::filesystem::is_directory(dbPath))
+
330 {
+
331 journal_.error() << "node db path must be a directory. " << dbPath.string();
+
332 Throw<std::runtime_error>("node db path must be a directory.");
+
333 }
+
334 }
+
335 else
+
336 {
+
337 boost::filesystem::create_directories(dbPath);
+
338 }
+
339
+
340 SavedState state = state_db_.getState();
+
341
+
342 {
+
343 auto update = [&dbPath](std::string& sPath) {
+
344 if (sPath.empty())
+
345 return false;
+
346
+
347 // Check if configured "path" matches stored directory path
+
348 using namespace boost::filesystem;
+
349 auto const stored{path(sPath)};
+
350 if (stored.parent_path() == dbPath)
+
351 return false;
+
352
+
353 sPath = (dbPath / stored.filename()).string();
+
354 return true;
+
355 };
356
-
357 // Check if configured "path" matches stored directory path
-
358 using namespace boost::filesystem;
-
359 auto const stored{path(sPath)};
-
360 if (stored.parent_path() == dbPath)
-
361 return false;
-
362
-
363 sPath = (dbPath / stored.filename()).string();
-
364 return true;
-
365 };
+
357 if (update(state.writableDb))
+
358 {
+
359 update(state.archiveDb);
+
360 state_db_.setState(state);
+
361 }
+
362 }
+
363
+
364 bool writableDbExists = false;
+
365 bool archiveDbExists = false;
366
-
367 if (update(state.writableDb))
-
368 {
-
369 update(state.archiveDb);
-
370 state_db_.setState(state);
-
371 }
-
372 }
-
373
-
374 bool writableDbExists = false;
-
375 bool archiveDbExists = false;
-
376
- -
378 for (boost::filesystem::directory_iterator it(dbPath); it != boost::filesystem::directory_iterator(); ++it)
-
379 {
-
380 if (!state.writableDb.compare(it->path().string()))
-
381 writableDbExists = true;
-
382 else if (!state.archiveDb.compare(it->path().string()))
-
383 archiveDbExists = true;
-
384 else if (!dbPrefix_.compare(it->path().stem().string()))
-
385 pathsToDelete.push_back(it->path());
-
386 }
-
387
-
388 if ((!writableDbExists && state.writableDb.size()) || (!archiveDbExists && state.archiveDb.size()) ||
-
389 (writableDbExists != archiveDbExists) || state.writableDb.empty() != state.archiveDb.empty())
-
390 {
-
391 boost::filesystem::path stateDbPathName = app_.config().legacy("database_path");
-
392 stateDbPathName /= dbName_;
-
393 stateDbPathName += "*";
-
394
-
395 journal_.error() << "state db error:\n"
-
396 << " writableDbExists " << writableDbExists << " archiveDbExists " << archiveDbExists << '\n'
-
397 << " writableDb '" << state.writableDb << "' archiveDb '" << state.archiveDb << "\n\n"
-
398 << "The existing data is in a corrupted state.\n"
-
399 << "To resume operation, remove the files matching " << stateDbPathName.string()
-
400 << " and contents of the directory " << get(section, "path") << '\n'
-
401 << "Optionally, you can move those files to another\n"
-
402 << "location if you wish to analyze or back up the data.\n"
-
403 << "However, there is no guarantee that the data in its\n"
-
404 << "existing form is usable.";
-
405
-
406 Throw<std::runtime_error>("state db error");
-
407 }
-
408
-
409 // The necessary directories exist. Now, remove any others.
-
410 for (boost::filesystem::path& p : pathsToDelete)
-
411 boost::filesystem::remove_all(p);
-
412}
+ +
368 for (boost::filesystem::directory_iterator it(dbPath); it != boost::filesystem::directory_iterator(); ++it)
+
369 {
+
370 if (!state.writableDb.compare(it->path().string()))
+
371 writableDbExists = true;
+
372 else if (!state.archiveDb.compare(it->path().string()))
+
373 archiveDbExists = true;
+
374 else if (!dbPrefix_.compare(it->path().stem().string()))
+
375 pathsToDelete.push_back(it->path());
+
376 }
+
377
+
378 if ((!writableDbExists && state.writableDb.size()) || (!archiveDbExists && state.archiveDb.size()) ||
+
379 (writableDbExists != archiveDbExists) || state.writableDb.empty() != state.archiveDb.empty())
+
380 {
+
381 boost::filesystem::path stateDbPathName = app_.config().legacy("database_path");
+
382 stateDbPathName /= dbName_;
+
383 stateDbPathName += "*";
+
384
+
385 journal_.error() << "state db error:\n"
+
386 << " writableDbExists " << writableDbExists << " archiveDbExists " << archiveDbExists << '\n'
+
387 << " writableDb '" << state.writableDb << "' archiveDb '" << state.archiveDb << "\n\n"
+
388 << "The existing data is in a corrupted state.\n"
+
389 << "To resume operation, remove the files matching " << stateDbPathName.string()
+
390 << " and contents of the directory " << get(section, "path") << '\n'
+
391 << "Optionally, you can move those files to another\n"
+
392 << "location if you wish to analyze or back up the data.\n"
+
393 << "However, there is no guarantee that the data in its\n"
+
394 << "existing form is usable.";
+
395
+
396 Throw<std::runtime_error>("state db error");
+
397 }
+
398
+
399 // The necessary directories exist. Now, remove any others.
+
400 for (boost::filesystem::path& p : pathsToDelete)
+
401 boost::filesystem::remove_all(p);
+
402}
-
413
- -
- -
416{
- -
418 boost::filesystem::path newPath;
-
419
-
420 if (path.size())
-
421 {
-
422 newPath = path;
-
423 }
-
424 else
-
425 {
-
426 boost::filesystem::path p = get(section, "path");
-
427 p /= dbPrefix_;
-
428 p += ".%%%%";
-
429 newPath = boost::filesystem::unique_path(p);
-
430 }
-
431 section.set("path", newPath.string());
-
432
- -
434 section,
- - - -
438 backend->open();
-
439 return backend;
-
440}
+
403
+ +
+ +
406{
+ +
408 boost::filesystem::path newPath;
+
409
+
410 if (path.size())
+
411 {
+
412 newPath = path;
+
413 }
+
414 else
+
415 {
+
416 boost::filesystem::path p = get(section, "path");
+
417 p /= dbPrefix_;
+
418 p += ".%%%%";
+
419 newPath = boost::filesystem::unique_path(p);
+
420 }
+
421 section.set("path", newPath.string());
+
422
+ +
424 section,
+ + + +
428 backend->open();
+
429 return backend;
+
430}
+
431
+
432void
+
+ +
434 LedgerIndex lastRotated,
+
435 std::string const& TableName,
+
436 std::function<std::optional<LedgerIndex>()> const& getMinSeq,
+
437 std::function<void(LedgerIndex)> const& deleteBeforeSeq)
+
438{
+
439 XRPL_ASSERT(deleteInterval_, "xrpl::SHAMapStoreImp::clearSql : nonzero delete interval");
+
441
-
442void
-
- -
444 LedgerIndex lastRotated,
-
445 std::string const& TableName,
-
446 std::function<std::optional<LedgerIndex>()> const& getMinSeq,
-
447 std::function<void(LedgerIndex)> const& deleteBeforeSeq)
-
448{
-
449 XRPL_ASSERT(deleteInterval_, "xrpl::SHAMapStoreImp::clearSql : nonzero delete interval");
- -
451
-
452 {
-
453 JLOG(journal_.trace()) << "Begin: Look up lowest value of: " << TableName;
-
454 auto m = getMinSeq();
-
455 JLOG(journal_.trace()) << "End: Look up lowest value of: " << TableName;
-
456 if (!m)
-
457 return;
-
458 min = *m;
-
459 }
-
460
-
461 if (min > lastRotated || healthWait() == stopping)
-
462 return;
-
463 if (min == lastRotated)
-
464 {
-
465 // Micro-optimization mainly to clarify logs
-
466 JLOG(journal_.trace()) << "Nothing to delete from " << TableName;
-
467 return;
-
468 }
-
469
-
470 JLOG(journal_.debug()) << "start deleting in: " << TableName << " from " << min << " to " << lastRotated;
-
471 while (min < lastRotated)
-
472 {
-
473 min = std::min(lastRotated, min + deleteBatch_);
-
474 JLOG(journal_.trace()) << "Begin: Delete up to " << deleteBatch_ << " rows with LedgerSeq < " << min
-
475 << " from: " << TableName;
-
476 deleteBeforeSeq(min);
-
477 JLOG(journal_.trace()) << "End: Delete up to " << deleteBatch_ << " rows with LedgerSeq < " << min
-
478 << " from: " << TableName;
-
479 if (healthWait() == stopping)
-
480 return;
-
481 if (min < lastRotated)
- -
483 if (healthWait() == stopping)
-
484 return;
-
485 }
-
486 JLOG(journal_.debug()) << "finished deleting from: " << TableName;
+
442 {
+
443 JLOG(journal_.trace()) << "Begin: Look up lowest value of: " << TableName;
+
444 auto m = getMinSeq();
+
445 JLOG(journal_.trace()) << "End: Look up lowest value of: " << TableName;
+
446 if (!m)
+
447 return;
+
448 min = *m;
+
449 }
+
450
+
451 if (min > lastRotated || healthWait() == stopping)
+
452 return;
+
453 if (min == lastRotated)
+
454 {
+
455 // Micro-optimization mainly to clarify logs
+
456 JLOG(journal_.trace()) << "Nothing to delete from " << TableName;
+
457 return;
+
458 }
+
459
+
460 JLOG(journal_.debug()) << "start deleting in: " << TableName << " from " << min << " to " << lastRotated;
+
461 while (min < lastRotated)
+
462 {
+
463 min = std::min(lastRotated, min + deleteBatch_);
+
464 JLOG(journal_.trace()) << "Begin: Delete up to " << deleteBatch_ << " rows with LedgerSeq < " << min
+
465 << " from: " << TableName;
+
466 deleteBeforeSeq(min);
+
467 JLOG(journal_.trace()) << "End: Delete up to " << deleteBatch_ << " rows with LedgerSeq < " << min
+
468 << " from: " << TableName;
+
469 if (healthWait() == stopping)
+
470 return;
+
471 if (min < lastRotated)
+ +
473 if (healthWait() == stopping)
+
474 return;
+
475 }
+
476 JLOG(journal_.debug()) << "finished deleting from: " << TableName;
+
477}
+
+
478
+
479void
+
+ +
481{
+ +
483 // Also clear the FullBelowCache so its generation counter is bumped.
+
484 // This prevents stale "full below" markers from persisting across
+
485 // backend rotation/online deletion and interfering with SHAMap sync.
+
487}
488
489void
-
495
-
496void
-
- -
498{
- -
500 return;
- -
502 return;
-
503}
+
497
+
498void
+
+ +
500{
+
501 // Do not allow ledgers to be acquired from the network
+
502 // that are about to be deleted.
+
503 minimumOnline_ = lastRotated + 1;
+
504 JLOG(journal_.trace()) << "Begin: Clear internal ledgers up to " << lastRotated;
+
505 ledgerMaster_->clearPriorLedgers(lastRotated);
+
506 JLOG(journal_.trace()) << "End: Clear internal ledgers up to " << lastRotated;
+
507 if (healthWait() == stopping)
+
508 return;
+
509
+
510 SQLiteDatabase* const db = dynamic_cast<SQLiteDatabase*>(&app_.getRelationalDatabase());
+
511
+
512 if (!db)
+
513 Throw<std::runtime_error>("Failed to get relational database");
+
514
+
515 clearSql(
+
516 lastRotated,
+
517 "Ledgers",
+
518 [db]() -> std::optional<LedgerIndex> { return db->getMinLedgerSeq(); },
+
519 [db](LedgerIndex min) -> void { db->deleteBeforeLedgerSeq(min); });
+
520 if (healthWait() == stopping)
+
521 return;
+
522
+
523 if (!app_.config().useTxTables())
+
524 return;
+
525
+
526 clearSql(
+
527 lastRotated,
+
528 "Transactions",
+
529 [&db]() -> std::optional<LedgerIndex> { return db->getTransactionsMinLedgerSeq(); },
+
530 [&db](LedgerIndex min) -> void { db->deleteTransactionsBeforeLedgerSeq(min); });
+
531 if (healthWait() == stopping)
+
532 return;
+
533
+
534 clearSql(
+
535 lastRotated,
+
536 "AccountTransactions",
+ +
538 [&db](LedgerIndex min) -> void { db->deleteAccountTransactionsBeforeLedgerSeq(min); });
+
539 if (healthWait() == stopping)
+
540 return;
+
541}
-
504
-
505void
-
- -
507{
-
508 // Do not allow ledgers to be acquired from the network
-
509 // that are about to be deleted.
-
510 minimumOnline_ = lastRotated + 1;
-
511 JLOG(journal_.trace()) << "Begin: Clear internal ledgers up to " << lastRotated;
-
512 ledgerMaster_->clearPriorLedgers(lastRotated);
-
513 JLOG(journal_.trace()) << "End: Clear internal ledgers up to " << lastRotated;
-
514 if (healthWait() == stopping)
-
515 return;
-
516
-
517 SQLiteDatabase* const db = dynamic_cast<SQLiteDatabase*>(&app_.getRelationalDatabase());
-
518
-
519 if (!db)
-
520 Throw<std::runtime_error>("Failed to get relational database");
-
521
-
522 clearSql(
-
523 lastRotated,
-
524 "Ledgers",
-
525 [db]() -> std::optional<LedgerIndex> { return db->getMinLedgerSeq(); },
-
526 [db](LedgerIndex min) -> void { db->deleteBeforeLedgerSeq(min); });
-
527 if (healthWait() == stopping)
-
528 return;
-
529
-
530 if (!app_.config().useTxTables())
-
531 return;
-
532
-
533 clearSql(
-
534 lastRotated,
-
535 "Transactions",
-
536 [&db]() -> std::optional<LedgerIndex> { return db->getTransactionsMinLedgerSeq(); },
-
537 [&db](LedgerIndex min) -> void { db->deleteTransactionsBeforeLedgerSeq(min); });
-
538 if (healthWait() == stopping)
-
539 return;
-
540
-
541 clearSql(
-
542 lastRotated,
-
543 "AccountTransactions",
- -
545 [&db](LedgerIndex min) -> void { db->deleteAccountTransactionsBeforeLedgerSeq(min); });
-
546 if (healthWait() == stopping)
-
547 return;
-
548}
+
542
+ +
+ +
545{
+ + + +
549 while (!stop_ && (mode != OperatingMode::FULL || age > ageThreshold_))
+
550 {
+
551 lock.unlock();
+
552 JLOG(journal_.warn()) << "Waiting " << recoveryWaitTime_.count()
+
553 << "s for node to stabilize. state: " << app_.getOPs().strOperatingMode(mode, false)
+
554 << ". age " << age.count() << 's';
+ + +
557 mode = netOPs_->getOperatingMode();
+
558 lock.lock();
+
559 }
+
560
+
561 return stop_ ? stopping : keepGoing;
+
562}
-
549
- -
- -
552{
- - - -
556 while (!stop_ && (mode != OperatingMode::FULL || age > ageThreshold_))
-
557 {
-
558 lock.unlock();
-
559 JLOG(journal_.warn()) << "Waiting " << recoveryWaitTime_.count()
-
560 << "s for node to stabilize. state: " << app_.getOPs().strOperatingMode(mode, false)
-
561 << ". age " << age.count() << 's';
- - -
564 mode = netOPs_->getOperatingMode();
-
565 lock.lock();
-
566 }
-
567
-
568 return stop_ ? stopping : keepGoing;
-
569}
+
563
+
564void
+
+ +
566{
+
567 if (thread_.joinable())
+
568 {
+
569 {
+ +
571 stop_ = true;
+ +
573 }
+
574 thread_.join();
+
575 }
+
576}
-
570
-
571void
-
- -
573{
-
574 if (thread_.joinable())
-
575 {
-
576 {
- -
578 stop_ = true;
- -
580 }
-
581 thread_.join();
-
582 }
-
583}
+
577
+ +
+ +
580{
+
581 // minimumOnline_ with 0 value is equivalent to unknown/not set.
+
582 // Don't attempt to acquire ledgers if that value is unknown.
+ +
584 return minimumOnline_.load();
+
585 return app_.getLedgerMaster().minSqlSeq();
+
586}
-
584
- -
- -
587{
-
588 // minimumOnline_ with 0 value is equivalent to unknown/not set.
-
589 // Don't attempt to acquire ledgers if that value is unknown.
- -
591 return minimumOnline_.load();
-
592 return app_.getLedgerMaster().minSqlSeq();
-
593}
+
587
+
588//------------------------------------------------------------------------------
+
589
+ +
+ +
592{
+
593 return std::make_unique<SHAMapStoreImp>(app, scheduler, journal);
+
594}
-
594
-
595//------------------------------------------------------------------------------
-
596
- -
- -
599{
-
600 return std::make_unique<SHAMapStoreImp>(app, scheduler, journal);
-
601}
-
-
602
-
603} // namespace xrpl
+
595
+
596} // namespace xrpl
T bind(T... args)
A generic endpoint for log messages.
Definition Journal.h:40
@@ -773,23 +766,21 @@ $(document).ready(function() { init_codefold(0); }); -
void clearSql(LedgerIndex lastRotated, std::string const &TableName, std::function< std::optional< LedgerIndex >()> const &getMinSeq, std::function< void(LedgerIndex)> const &deleteBeforeSeq)
delete from sqlite table in batches to not lock the db excessively.
-
bool copyNode(std::uint64_t &nodeCount, SHAMapTreeNode const &node)
-
std::unique_ptr< NodeStore::Backend > makeBackendRotating(std::string path=std::string())
+
void clearSql(LedgerIndex lastRotated, std::string const &TableName, std::function< std::optional< LedgerIndex >()> const &getMinSeq, std::function< void(LedgerIndex)> const &deleteBeforeSeq)
delete from sqlite table in batches to not lock the db excessively.
+
bool copyNode(std::uint64_t &nodeCount, SHAMapTreeNode const &node)
+
std::unique_ptr< NodeStore::Backend > makeBackendRotating(std::string path=std::string())
std::atomic< bool > working_
std::condition_variable cond_
std::uint32_t deleteBatch_
std::atomic< LedgerIndex > minimumOnline_
std::chrono::seconds recoveryWaitTime_
If the node is out of sync during an online_delete healthWait() call, sleep the thread for this time,...
-
FullBelowCache * fullBelowCache_
- -
std::optional< LedgerIndex > minimumOnline() const override
The minimum ledger to try and maintain in our database.
-
TreeNodeCache * treeNodeCache_
-
static constexpr auto nodeStoreName_
+ +
std::optional< LedgerIndex > minimumOnline() const override
The minimum ledger to try and maintain in our database.
+
static constexpr auto nodeStoreName_
std::uint32_t deleteInterval_
-
int fdRequired() const override
Returns the number of file descriptors that are needed.
+
int fdRequired() const override
Returns the number of file descriptors that are needed.
static std::uint32_t const minimumDeletionInterval_
std::unique_ptr< NodeStore::Database > makeNodeStore(int readThreads) override
@@ -801,30 +792,30 @@ $(document).ready(function() { init_codefold(0); });
std::condition_variable rendezvous_
static std::uint32_t const minimumDeletionIntervalSA_
std::uint64_t const checkHealthInterval_
- -
HealthResult healthWait()
+ +
HealthResult healthWait()
-
void clearCaches(LedgerIndex validatedSeq)
+
void clearCaches(LedgerIndex validatedSeq)
std::chrono::seconds ageThreshold_
-
void rendezvous() const override
+
void rendezvous() const override
LedgerMaster * ledgerMaster_
beast::Journal const journal_
std::string const dbPrefix_
NodeStore::Scheduler & scheduler_
-
HealthResult
This is a health check for online deletion that waits until rippled is stable before returning.
- - -
void onLedgerClosed(std::shared_ptr< Ledger const > const &ledger) override
Called by LedgerMaster every time a ledger validates.
- +
HealthResult
This is a health check for online deletion that waits until rippled is stable before returning.
+ + +
void onLedgerClosed(std::shared_ptr< Ledger const > const &ledger) override
Called by LedgerMaster every time a ledger validates.
+ -
bool freshenCache(CacheInstance &cache)
-
void clearPrior(LedgerIndex lastRotated)
+
bool freshenCache(CacheInstance &cache)
+
void clearPrior(LedgerIndex lastRotated)
SHAMapStoreImp(Application &app, NodeStore::Scheduler &scheduler, beast::Journal journal)
- +
SHAMapHash const & getHash() const
Return the hash of this node.
@@ -834,14 +825,12 @@ $(document).ready(function() { init_codefold(0); });
virtual std::optional< LedgerIndex > getAccountTransactionsMinLedgerSeq()=0
getAccountTransactionsMinLedgerSeq Returns the minimum ledger sequence stored in the AccountTransacti...
virtual void deleteTransactionsBeforeLedgerSeq(LedgerIndex ledgerSeq)=0
deleteTransactionsBeforeLedgerSeq Deletes all transactions with a sequence number less than or equal ...
Holds a collection of configuration values.
Definition BasicConfig.h:24
-
void set(std::string const &key, std::string const &value)
Set a key/value pair.
virtual RelationalDatabase & getRelationalDatabase()=0
virtual NetworkOPs & getOPs()=0
virtual TransactionMaster & getMasterTransaction()=0
virtual LedgerMaster & getLedgerMaster()=0
virtual Family & getNodeFamily()=0
TaggedCache< uint256, Transaction > & getCache()
-
T compare(T... args)
T count(T... args)
@@ -862,11 +851,9 @@ $(document).ready(function() { init_codefold(0); });
void setLastRotated(soci::session &session, LedgerIndex seq)
setLastRotated Updates the last rotated ledger sequence.
Definition State.cpp:93
void setSavedState(soci::session &session, SavedState const &state)
setSavedState Saves the given state.
Definition State.cpp:82
void initStateDB(soci::session &session, BasicConfig const &config, std::string const &dbName)
initStateDB Opens a session with the State database.
Definition State.cpp:6
-
std::unique_ptr< SHAMapStore > make_SHAMapStore(Application &app, NodeStore::Scheduler &scheduler, beast::Journal journal)
+
std::unique_ptr< SHAMapStore > make_SHAMapStore(Application &app, NodeStore::Scheduler &scheduler, beast::Journal journal)
- -
SavedState getSavedState(soci::session &session)
getSavedState Returns the saved state.
Definition State.cpp:71
constexpr auto megabytes(T value) noexcept
bool get_if_exists(Section const &section, std::string const &name, T &v)
diff --git a/SHAMapStoreImp_8h_source.html b/SHAMapStoreImp_8h_source.html index 9f1cdfd6a0..5d84a79be0 100644 --- a/SHAMapStoreImp_8h_source.html +++ b/SHAMapStoreImp_8h_source.html @@ -177,137 +177,135 @@ $(document).ready(function() { init_codefold(0); });
93 // as of run() or before
94 NetworkOPs* netOPs_ = nullptr;
- - +
96
+
97 static constexpr auto nodeStoreName_ = "NodeStore";
98
-
99 static constexpr auto nodeStoreName_ = "NodeStore";
-
100
-
101public:
- -
103
- -
-
105 clampFetchDepth(std::uint32_t fetch_depth) const override
-
106 {
-
107 return deleteInterval_ ? std::min(fetch_depth, deleteInterval_) : fetch_depth;
-
108 }
+
99public:
+ +
101
+ +
+
103 clampFetchDepth(std::uint32_t fetch_depth) const override
+
104 {
+
105 return deleteInterval_ ? std::min(fetch_depth, deleteInterval_) : fetch_depth;
+
106 }
-
109
- -
111 makeNodeStore(int readThreads) override;
-
112
- -
- -
115 {
-
116 if (advisoryDelete_)
-
117 canDelete_ = seq;
-
118 return state_db_.setCanDelete(seq);
-
119 }
+
107
+ +
109 makeNodeStore(int readThreads) override;
+
110
+ +
+ +
113 {
+
114 if (advisoryDelete_)
+
115 canDelete_ = seq;
+
116 return state_db_.setCanDelete(seq);
+
117 }
-
120
-
121 bool
-
-
122 advisoryDelete() const override
-
123 {
-
124 return advisoryDelete_;
-
125 }
+
118
+
119 bool
+
+
120 advisoryDelete() const override
+
121 {
+
122 return advisoryDelete_;
+
123 }
-
126
-
127 // All ledgers prior to this one are eligible
-
128 // for deletion in the next rotation
- -
-
130 getLastRotated() override
-
131 {
- -
133 }
+
124
+
125 // All ledgers prior to this one are eligible
+
126 // for deletion in the next rotation
+ +
+
128 getLastRotated() override
+
129 {
+ +
131 }
-
134
-
135 // All ledgers before and including this are unprotected
-
136 // and online delete may delete them if appropriate
- -
-
138 getCanDelete() override
-
139 {
-
140 return canDelete_;
-
141 }
+
132
+
133 // All ledgers before and including this are unprotected
+
134 // and online delete may delete them if appropriate
+ +
+
136 getCanDelete() override
+
137 {
+
138 return canDelete_;
+
139 }
-
142
-
143 void
-
144 onLedgerClosed(std::shared_ptr<Ledger const> const& ledger) override;
-
145
-
146 void
-
147 rendezvous() const override;
-
148 int
-
149 fdRequired() const override;
-
150
- -
152 minimumOnline() const override;
-
153
-
154private:
-
155 // callback for visitNodes
-
156 bool
-
157 copyNode(std::uint64_t& nodeCount, SHAMapTreeNode const& node);
+
140
+
141 void
+
142 onLedgerClosed(std::shared_ptr<Ledger const> const& ledger) override;
+
143
+
144 void
+
145 rendezvous() const override;
+
146 int
+
147 fdRequired() const override;
+
148
+ +
150 minimumOnline() const override;
+
151
+
152private:
+
153 // callback for visitNodes
+
154 bool
+
155 copyNode(std::uint64_t& nodeCount, SHAMapTreeNode const& node);
+
156 void
+
157 run();
158 void
-
159 run();
-
160 void
-
161 dbPaths();
-
162
- - -
165
-
166 template <class CacheInstance>
-
167 bool
-
-
168 freshenCache(CacheInstance& cache)
-
169 {
-
170 std::uint64_t check = 0;
-
171
-
172 for (auto const& key : cache.getKeys())
-
173 {
- -
175 if (!(++check % checkHealthInterval_) && healthWait() == stopping)
-
176 return true;
-
177 }
-
178
-
179 return false;
-
180 }
+
159 dbPaths();
+
160
+ + +
163
+
164 template <class CacheInstance>
+
165 bool
+
+
166 freshenCache(CacheInstance& cache)
+
167 {
+
168 std::uint64_t check = 0;
+
169
+
170 for (auto const& key : cache.getKeys())
+
171 {
+ +
173 if (!(++check % checkHealthInterval_) && healthWait() == stopping)
+
174 return true;
+
175 }
+
176
+
177 return false;
+
178 }
-
181
-
186 void
-
187 clearSql(
-
188 LedgerIndex lastRotated,
-
189 std::string const& TableName,
-
190 std::function<std::optional<LedgerIndex>()> const& getMinSeq,
-
191 std::function<void(LedgerIndex)> const& deleteBeforeSeq);
+
179
+
184 void
+
185 clearSql(
+
186 LedgerIndex lastRotated,
+
187 std::string const& TableName,
+
188 std::function<std::optional<LedgerIndex>()> const& getMinSeq,
+
189 std::function<void(LedgerIndex)> const& deleteBeforeSeq);
+
190 void
+
191 clearCaches(LedgerIndex validatedSeq);
192 void
-
193 clearCaches(LedgerIndex validatedSeq);
+
194 void
- -
196 void
-
197 clearPrior(LedgerIndex lastRotated);
-
198
- -
207 [[nodiscard]] HealthResult
-
208 healthWait();
-
209
-
210public:
-
211 void
-
-
212 start() override
-
213 {
-
214 if (deleteInterval_)
- -
216 }
+
195 clearPrior(LedgerIndex lastRotated);
+
196
+ +
205 [[nodiscard]] HealthResult
+
206 healthWait();
+
207
+
208public:
+
209 void
+
+
210 start() override
+
211 {
+
212 if (deleteInterval_)
+ +
214 }
-
217
-
218 void
-
219 stop() override;
-
220};
+
215
+
216 void
+
217 stop() override;
+
218};
-
221
-
222} // namespace xrpl
+
219
+
220} // namespace xrpl
@@ -331,27 +329,25 @@ $(document).ready(function() { init_codefold(0); }); -
void clearSql(LedgerIndex lastRotated, std::string const &TableName, std::function< std::optional< LedgerIndex >()> const &getMinSeq, std::function< void(LedgerIndex)> const &deleteBeforeSeq)
delete from sqlite table in batches to not lock the db excessively.
-
LedgerIndex getLastRotated() override
Maximum ledger that has been deleted, or will be deleted if currently in the act of online deletion.
-
bool copyNode(std::uint64_t &nodeCount, SHAMapTreeNode const &node)
-
std::unique_ptr< NodeStore::Backend > makeBackendRotating(std::string path=std::string())
+
void clearSql(LedgerIndex lastRotated, std::string const &TableName, std::function< std::optional< LedgerIndex >()> const &getMinSeq, std::function< void(LedgerIndex)> const &deleteBeforeSeq)
delete from sqlite table in batches to not lock the db excessively.
+
LedgerIndex getLastRotated() override
Maximum ledger that has been deleted, or will be deleted if currently in the act of online deletion.
+
bool copyNode(std::uint64_t &nodeCount, SHAMapTreeNode const &node)
+
std::unique_ptr< NodeStore::Backend > makeBackendRotating(std::string path=std::string())
std::atomic< bool > working_
std::condition_variable cond_
std::uint32_t deleteBatch_
-
void start() override
-
LedgerIndex setCanDelete(LedgerIndex seq) override
Highest ledger that may be deleted.
+
void start() override
+
LedgerIndex setCanDelete(LedgerIndex seq) override
Highest ledger that may be deleted.
std::atomic< LedgerIndex > minimumOnline_
std::chrono::seconds recoveryWaitTime_
If the node is out of sync during an online_delete healthWait() call, sleep the thread for this time,...
-
FullBelowCache * fullBelowCache_
- -
std::optional< LedgerIndex > minimumOnline() const override
The minimum ledger to try and maintain in our database.
-
bool advisoryDelete() const override
Whether advisory delete is enabled.
-
TreeNodeCache * treeNodeCache_
-
static constexpr auto nodeStoreName_
+ +
std::optional< LedgerIndex > minimumOnline() const override
The minimum ledger to try and maintain in our database.
+
bool advisoryDelete() const override
Whether advisory delete is enabled.
+
static constexpr auto nodeStoreName_
std::uint32_t deleteInterval_
-
int fdRequired() const override
Returns the number of file descriptors that are needed.
+
int fdRequired() const override
Returns the number of file descriptors that are needed.
static std::uint32_t const minimumDeletionInterval_
std::unique_ptr< NodeStore::Database > makeNodeStore(int readThreads) override
@@ -363,35 +359,33 @@ $(document).ready(function() { init_codefold(0); });
std::condition_variable rendezvous_
static std::uint32_t const minimumDeletionIntervalSA_
std::uint64_t const checkHealthInterval_
- -
HealthResult healthWait()
+ +
HealthResult healthWait()
-
void clearCaches(LedgerIndex validatedSeq)
+
void clearCaches(LedgerIndex validatedSeq)
std::chrono::seconds ageThreshold_
-
void rendezvous() const override
+
void rendezvous() const override
LedgerMaster * ledgerMaster_
beast::Journal const journal_
-
LedgerIndex getCanDelete() override
Highest ledger that may be deleted.
+
LedgerIndex getCanDelete() override
Highest ledger that may be deleted.
std::string const dbPrefix_
NodeStore::Scheduler & scheduler_
-
HealthResult
This is a health check for online deletion that waits until rippled is stable before returning.
- - -
void onLedgerClosed(std::shared_ptr< Ledger const > const &ledger) override
Called by LedgerMaster every time a ledger validates.
- +
HealthResult
This is a health check for online deletion that waits until rippled is stable before returning.
+ + +
void onLedgerClosed(std::shared_ptr< Ledger const > const &ledger) override
Called by LedgerMaster every time a ledger validates.
+ -
bool freshenCache(CacheInstance &cache)
-
std::uint32_t clampFetchDepth(std::uint32_t fetch_depth) const override
-
void clearPrior(LedgerIndex lastRotated)
+
bool freshenCache(CacheInstance &cache)
+
std::uint32_t clampFetchDepth(std::uint32_t fetch_depth) const override
+
void clearPrior(LedgerIndex lastRotated)
- +
class to create database, launch online delete thread, and related SQLite database
Definition SHAMapStore.h:18
-
Map/cache combination.
Definition TaggedCache.h:42
-
Remembers which tree keys have all descendants resident.
diff --git a/SHAMapStore_8h_source.html b/SHAMapStore_8h_source.html index 7c8c14a179..42c29ca27e 100644 --- a/SHAMapStore_8h_source.html +++ b/SHAMapStore_8h_source.html @@ -161,7 +161,7 @@ $(document).ready(function() { init_codefold(0); });
virtual int fdRequired() const =0
Returns the number of file descriptors that are needed.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
-
std::unique_ptr< SHAMapStore > make_SHAMapStore(Application &app, NodeStore::Scheduler &scheduler, beast::Journal journal)
+
std::unique_ptr< SHAMapStore > make_SHAMapStore(Application &app, NodeStore::Scheduler &scheduler, beast::Journal journal)
diff --git a/SHAMapStore__test_8cpp_source.html b/SHAMapStore__test_8cpp_source.html index 6cddda38e4..df4c03298b 100644 --- a/SHAMapStore__test_8cpp_source.html +++ b/SHAMapStore__test_8cpp_source.html @@ -600,100 +600,88 @@ $(document).ready(function() { init_codefold(0); });
489 using namespace jtx;
490 Env env(*this, envconfig(onlineDelete));
491
-
493 // Create the backend. Normally, SHAMapStoreImp handles all these
-
494 // details
-
495 auto nscfg = env.app().config().section(ConfigSection::nodeDatabase());
+
493 // Create NodeStore with two backends to allow online deletion of data.
+
494 // Normally, SHAMapStoreImp handles all these details.
+
495 NodeStoreScheduler scheduler(env.app().getJobQueue());
496
-
497 // Provide default values:
-
498 if (!nscfg.exists("cache_size"))
-
499 nscfg.set(
- +
497 std::string const writableDb = "write";
+
498 std::string const archiveDb = "archive";
+
499 auto writableBackend = makeBackendRotating(env, scheduler, writableDb);
+
500 auto archiveBackend = makeBackendRotating(env, scheduler, archiveDb);
501
-
502 if (!nscfg.exists("cache_age"))
-
503 nscfg.set(
- -
505
-
506 NodeStoreScheduler scheduler(env.app().getJobQueue());
-
507
-
508 std::string const writableDb = "write";
-
509 std::string const archiveDb = "archive";
-
510 auto writableBackend = makeBackendRotating(env, scheduler, writableDb);
-
511 auto archiveBackend = makeBackendRotating(env, scheduler, archiveDb);
-
512
-
513 // Create NodeStore with two backends to allow online deletion of
-
514 // data
-
515 constexpr int readThreads = 4;
- -
517 scheduler,
-
518 readThreads,
-
519 std::move(writableBackend),
-
520 std::move(archiveBackend),
-
521 nscfg,
-
522 env.app().logs().journal("NodeStoreTest"));
-
523
-
525 // Check basic functionality
-
526 using namespace std::chrono_literals;
-
527 std::atomic<int> threadNum = 0;
-
528
-
529 {
-
530 auto newBackend = makeBackendRotating(env, scheduler, std::to_string(++threadNum));
-
531
-
532 auto const cb = [&](std::string const& writableName, std::string const& archiveName) {
-
533 BEAST_EXPECT(writableName == "1");
-
534 BEAST_EXPECT(archiveName == "write");
-
535 // Ensure that dbr functions can be called from within the
-
536 // callback
-
537 BEAST_EXPECT(dbr->getName() == "1");
-
538 };
-
539
-
540 dbr->rotate(std::move(newBackend), cb);
-
541 }
-
542 BEAST_EXPECT(threadNum == 1);
-
543 BEAST_EXPECT(dbr->getName() == "1");
-
544
-
546 // Do something stupid. Try to re-enter rotate from inside the callback.
-
547 {
-
548 auto const cb = [&](std::string const& writableName, std::string const& archiveName) {
-
549 BEAST_EXPECT(writableName == "3");
-
550 BEAST_EXPECT(archiveName == "2");
-
551 // Ensure that dbr functions can be called from within the
-
552 // callback
-
553 BEAST_EXPECT(dbr->getName() == "3");
-
554 };
-
555 auto const cbReentrant = [&](std::string const& writableName, std::string const& archiveName) {
-
556 BEAST_EXPECT(writableName == "2");
-
557 BEAST_EXPECT(archiveName == "1");
-
558 auto newBackend = makeBackendRotating(env, scheduler, std::to_string(++threadNum));
-
559 // Reminder: doing this is stupid and should never happen
-
560 dbr->rotate(std::move(newBackend), cb);
-
561 };
-
562 auto newBackend = makeBackendRotating(env, scheduler, std::to_string(++threadNum));
-
563 dbr->rotate(std::move(newBackend), cbReentrant);
-
564 }
-
565
-
566 BEAST_EXPECT(threadNum == 3);
-
567 BEAST_EXPECT(dbr->getName() == "3");
-
568 }
+
502 constexpr int readThreads = 4;
+
503 auto nscfg = env.app().config().section(ConfigSection::nodeDatabase());
+ +
505 scheduler,
+
506 readThreads,
+
507 std::move(writableBackend),
+
508 std::move(archiveBackend),
+
509 nscfg,
+
510 env.app().logs().journal("NodeStoreTest"));
+
511
+
513 // Check basic functionality
+
514 using namespace std::chrono_literals;
+
515 std::atomic<int> threadNum = 0;
+
516
+
517 {
+
518 auto newBackend = makeBackendRotating(env, scheduler, std::to_string(++threadNum));
+
519
+
520 auto const cb = [&](std::string const& writableName, std::string const& archiveName) {
+
521 BEAST_EXPECT(writableName == "1");
+
522 BEAST_EXPECT(archiveName == "write");
+
523 // Ensure that dbr functions can be called from within the
+
524 // callback
+
525 BEAST_EXPECT(dbr->getName() == "1");
+
526 };
+
527
+
528 dbr->rotate(std::move(newBackend), cb);
+
529 }
+
530 BEAST_EXPECT(threadNum == 1);
+
531 BEAST_EXPECT(dbr->getName() == "1");
+
532
+
534 // Do something stupid. Try to re-enter rotate from inside the callback.
+
535 {
+
536 auto const cb = [&](std::string const& writableName, std::string const& archiveName) {
+
537 BEAST_EXPECT(writableName == "3");
+
538 BEAST_EXPECT(archiveName == "2");
+
539 // Ensure that dbr functions can be called from within the
+
540 // callback
+
541 BEAST_EXPECT(dbr->getName() == "3");
+
542 };
+
543 auto const cbReentrant = [&](std::string const& writableName, std::string const& archiveName) {
+
544 BEAST_EXPECT(writableName == "2");
+
545 BEAST_EXPECT(archiveName == "1");
+
546 auto newBackend = makeBackendRotating(env, scheduler, std::to_string(++threadNum));
+
547 // Reminder: doing this is stupid and should never happen
+
548 dbr->rotate(std::move(newBackend), cb);
+
549 };
+
550 auto newBackend = makeBackendRotating(env, scheduler, std::to_string(++threadNum));
+
551 dbr->rotate(std::move(newBackend), cbReentrant);
+
552 }
+
553
+
554 BEAST_EXPECT(threadNum == 3);
+
555 BEAST_EXPECT(dbr->getName() == "3");
+
556 }
-
569
-
570 void
-
-
571 run() override
-
572 {
-
573 testClear();
- - -
576 testRotate();
-
577 }
+
557
+
558 void
+
+
559 run() override
+
560 {
+
561 testClear();
+ + +
564 testRotate();
+
565 }
-
578};
+
566};
-
579
-
580// VFALCO This test fails because of thread asynchronous issues
-
581BEAST_DEFINE_TESTSUITE(SHAMapStore, app, xrpl);
-
582
-
583} // namespace test
-
584} // namespace xrpl
+
567
+
568// VFALCO This test fails because of thread asynchronous issues
+
569BEAST_DEFINE_TESTSUITE(SHAMapStore, app, xrpl);
+
570
+
571} // namespace test
+
572} // namespace xrpl
Represents a JSON value.
Definition json_value.h:130
@@ -714,7 +702,6 @@ $(document).ready(function() { init_codefold(0); });
virtual std::size_t getAccountTransactionCount()=0
getAccountTransactionCount Returns the number of account transactions.
virtual std::size_t getTransactionCount()=0
getTransactionCount Returns the number of transactions.
Holds a collection of configuration values.
Definition BasicConfig.h:24
-
void set(std::string const &key, std::string const &value)
Set a key/value pair.
virtual JobQueue & getJobQueue()=0
virtual RelationalDatabase & getRelationalDatabase()=0
virtual SHAMapStore & getSHAMapStore()=0
@@ -729,7 +716,7 @@ $(document).ready(function() { init_codefold(0); });
void ledgerCheck(jtx::Env &env, int const rows, int const first)
void accountTransactionCheck(jtx::Env &env, int const rows)
-
void run() override
Runs the suite.
+
void run() override
Runs the suite.
bool goodLedger(jtx::Env &env, Json::Value const &json, std::string ledgerID, bool checkDB=false)
void transactionCheck(jtx::Env &env, int const rows)
@@ -755,8 +742,6 @@ $(document).ready(function() { init_codefold(0); });
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
std::string to_string(base_uint< Bits, Tag > const &a)
Definition base_uint.h:597
- -
constexpr auto megabytes(T value) noexcept
error_code_i
Definition ErrorCodes.h:20
@ rpcLGR_NOT_FOUND
Definition ErrorCodes.h:52
diff --git a/TestBase_8h_source.html b/TestBase_8h_source.html index 91ef273a76..a993379f0f 100644 --- a/TestBase_8h_source.html +++ b/TestBase_8h_source.html @@ -300,7 +300,7 @@ $(document).ready(function() { init_codefold(0); });
virtual void store(std::shared_ptr< NodeObject > const &object)=0
Store a single object.
virtual Status fetch(void const *key, std::shared_ptr< NodeObject > *pObject)=0
Fetch a single object.
Persistency layer for NodeObject.
Definition Database.h:31
-
std::uint32_t earliestLedgerSeq() const noexcept
Definition Database.h:193
+
std::uint32_t earliestLedgerSeq() const noexcept
Definition Database.h:189
std::shared_ptr< NodeObject > fetchNodeObject(uint256 const &hash, std::uint32_t ledgerSeq=0, FetchType fetchType=FetchType::synchronous, bool duplicate=false)
Fetch a node object.
Definition Database.cpp:202
virtual void store(NodeObjectType type, Blob &&data, uint256 const &hash, std::uint32_t ledgerSeq)=0
Store the object.
diff --git a/classxrpl_1_1Application.html b/classxrpl_1_1Application.html index 222bf6be81..b35d5fcfd5 100644 --- a/classxrpl_1_1Application.html +++ b/classxrpl_1_1Application.html @@ -360,7 +360,7 @@ Private Attributes
-

Definition at line 1990 of file Application.cpp.

+

Definition at line 1986 of file Application.cpp.

diff --git a/classxrpl_1_1ApplicationImp.html b/classxrpl_1_1ApplicationImp.html index 518e03504b..8998ee9d79 100644 --- a/classxrpl_1_1ApplicationImp.html +++ b/classxrpl_1_1ApplicationImp.html @@ -569,7 +569,7 @@ Private Attributes

Implements xrpl::Application.

-

Definition at line 1034 of file Application.cpp.

+

Definition at line 1030 of file Application.cpp.

@@ -599,7 +599,7 @@ Private Attributes

Implements xrpl::Application.

-

Definition at line 1360 of file Application.cpp.

+

Definition at line 1356 of file Application.cpp.

@@ -628,7 +628,7 @@ Private Attributes

Implements xrpl::Application.

-

Definition at line 1385 of file Application.cpp.

+

Definition at line 1381 of file Application.cpp.

@@ -658,7 +658,7 @@ Private Attributes

Implements xrpl::Application.

-

Definition at line 1476 of file Application.cpp.

+

Definition at line 1472 of file Application.cpp.

@@ -687,7 +687,7 @@ Private Attributes

Implements xrpl::Application.

-

Definition at line 1490 of file Application.cpp.

+

Definition at line 1486 of file Application.cpp.

@@ -717,7 +717,7 @@ Private Attributes

Implements xrpl::Application.

-

Definition at line 1496 of file Application.cpp.

+

Definition at line 1492 of file Application.cpp.

@@ -746,7 +746,7 @@ Private Attributes

Implements xrpl::Application.

-

Definition at line 1502 of file Application.cpp.

+

Definition at line 1498 of file Application.cpp.

@@ -775,7 +775,7 @@ Private Attributes

Implements xrpl::Application.

-

Definition at line 1508 of file Application.cpp.

+

Definition at line 1504 of file Application.cpp.

@@ -2202,7 +2202,7 @@ Private Attributes

Implements xrpl::Application.

-

Definition at line 1925 of file Application.cpp.

+

Definition at line 1921 of file Application.cpp.

@@ -2232,7 +2232,7 @@ Private Attributes

Implements xrpl::Application.

-

Definition at line 1973 of file Application.cpp.

+

Definition at line 1969 of file Application.cpp.

@@ -2391,7 +2391,7 @@ Private Attributes

Implements xrpl::Application.

-

Definition at line 998 of file Application.cpp.

+

Definition at line 994 of file Application.cpp.

@@ -2420,7 +2420,7 @@ Private Attributes

Implements xrpl::Application.

-

Definition at line 1004 of file Application.cpp.

+

Definition at line 1000 of file Application.cpp.

@@ -2447,7 +2447,7 @@ Private Attributes
-

Definition at line 1533 of file Application.cpp.

+

Definition at line 1529 of file Application.cpp.

@@ -2474,7 +2474,7 @@ Private Attributes
-

Definition at line 1554 of file Application.cpp.

+

Definition at line 1550 of file Application.cpp.

@@ -2502,7 +2502,7 @@ Private Attributes
-

Definition at line 1597 of file Application.cpp.

+

Definition at line 1593 of file Application.cpp.

@@ -2552,7 +2552,7 @@ Private Attributes
-

Definition at line 1729 of file Application.cpp.

+

Definition at line 1725 of file Application.cpp.

@@ -2579,7 +2579,7 @@ Private Attributes
-

Definition at line 1979 of file Application.cpp.

+

Definition at line 1975 of file Application.cpp.

@@ -3979,7 +3979,7 @@ template<class Derived >
-

Definition at line 1012 of file Application.cpp.

+

Definition at line 1008 of file Application.cpp.

diff --git a/classxrpl_1_1NodeStore_1_1Database-members.html b/classxrpl_1_1NodeStore_1_1Database-members.html index 391234ba64..8af2bdf18e 100644 --- a/classxrpl_1_1NodeStore_1_1Database-members.html +++ b/classxrpl_1_1NodeStore_1_1Database-members.html @@ -120,11 +120,10 @@ $(function() { storeDurationUs_xrpl::NodeStore::Databaseprivate storeStats(std::uint64_t count, std::uint64_t sz)xrpl::NodeStore::Databaseprotected storeSz_xrpl::NodeStore::Databaseprivate - sweep()=0xrpl::NodeStore::Databasepure virtual - sync()=0xrpl::NodeStore::Databasepure virtual - threadEntry()xrpl::NodeStore::Databaseprivate - updateFetchMetrics(uint64_t fetches, uint64_t hits, uint64_t duration)xrpl::NodeStore::Databaseprotected - ~Database()xrpl::NodeStore::Databasevirtual + sync()=0xrpl::NodeStore::Databasepure virtual + threadEntry()xrpl::NodeStore::Databaseprivate + updateFetchMetrics(uint64_t fetches, uint64_t hits, uint64_t duration)xrpl::NodeStore::Databaseprotected + ~Database()xrpl::NodeStore::Databasevirtual