20 #include <ripple/app/consensus/RCLConsensus.h>
21 #include <ripple/app/consensus/RCLValidations.h>
22 #include <ripple/app/ledger/AcceptedLedger.h>
23 #include <ripple/app/ledger/InboundLedgers.h>
24 #include <ripple/app/ledger/LedgerMaster.h>
25 #include <ripple/app/ledger/LedgerToJson.h>
26 #include <ripple/app/ledger/LocalTxs.h>
27 #include <ripple/app/ledger/OpenLedger.h>
28 #include <ripple/app/ledger/OrderBookDB.h>
29 #include <ripple/app/ledger/TransactionMaster.h>
30 #include <ripple/app/main/LoadManager.h>
31 #include <ripple/app/misc/AmendmentTable.h>
32 #include <ripple/app/misc/HashRouter.h>
33 #include <ripple/app/misc/LoadFeeTrack.h>
34 #include <ripple/app/misc/NetworkOPs.h>
35 #include <ripple/app/misc/Transaction.h>
36 #include <ripple/app/misc/TxQ.h>
37 #include <ripple/app/misc/ValidatorKeys.h>
38 #include <ripple/app/misc/ValidatorList.h>
39 #include <ripple/app/misc/impl/AccountTxPaging.h>
40 #include <ripple/app/tx/apply.h>
41 #include <ripple/basics/PerfLog.h>
42 #include <ripple/basics/UptimeClock.h>
43 #include <ripple/basics/base64.h>
44 #include <ripple/basics/mulDiv.h>
45 #include <ripple/basics/safe_cast.h>
46 #include <ripple/beast/core/LexicalCast.h>
47 #include <ripple/beast/rfc2616.h>
48 #include <ripple/beast/utility/rngfill.h>
49 #include <ripple/consensus/Consensus.h>
50 #include <ripple/consensus/ConsensusParms.h>
51 #include <ripple/core/ConfigSections.h>
52 #include <ripple/crypto/RFC1751.h>
53 #include <ripple/crypto/csprng.h>
54 #include <ripple/json/to_string.h>
55 #include <ripple/overlay/Cluster.h>
56 #include <ripple/overlay/Overlay.h>
57 #include <ripple/overlay/predicates.h>
58 #include <ripple/protocol/BuildInfo.h>
59 #include <ripple/protocol/Feature.h>
60 #include <ripple/resource/ResourceManager.h>
61 #include <ripple/rpc/DeliveredAmount.h>
62 #include <boost/asio/ip/host_name.hpp>
63 #include <boost/asio/steady_timer.hpp>
137 std::chrono::system_clock::time_point
start_ =
204 return !(*
this != b);
210 boost::optional<TxQ::Metrics>
em = boost::none;
224 boost::asio::io_service& io_svc,
239 app_.logs().journal(
"FeeVote")),
242 app.getInboundTransactions(),
243 beast::get_abstract_clock<
std::chrono::steady_clock>(),
245 app_.logs().journal(
"LedgerConsensus"))
374 protocol::TxSetStatus status);
457 getServerInfo(
bool human,
bool admin,
bool counters)
override;
464 boost::optional<std::chrono::milliseconds> consensusDelay)
override;
508 bool bUnlimited)
override;
518 bool bUnlimited)
override;
531 bool bUnlimited)
override;
541 bool bUnlimited)
override;
552 TER terResult)
override;
645 boost::system::error_code ec;
650 <<
"NetworkOPs: heartbeatTimer cancel error: "
659 <<
"NetworkOPs: clusterTimer cancel error: "
665 using namespace std::chrono_literals;
776 template <
class Handler>
778 Handler
const& handler,
780 :
hook(collector->make_hook(handler))
783 "Disconnected_duration"))
786 "Connected_duration"))
788 collector->make_gauge(
"State_Accounting",
"Syncing_duration"))
791 "Tracking_duration"))
793 collector->make_gauge(
"State_Accounting",
"Full_duration"))
796 "Disconnected_transitions"))
799 "Connected_transitions"))
802 "Syncing_transitions"))
805 "Tracking_transitions"))
807 collector->make_gauge(
"State_Accounting",
"Full_transitions"))
834 std::chrono::duration_cast<std::chrono::microseconds>(
876 {
"disconnected",
"connected",
"syncing",
"tracking",
"full"}};
892 static std::string const hostname = boost::asio::ip::host_name();
899 static std::string const shroudedHostId = [
this]() {
905 return shroudedHostId;
920 [
this](boost::system::error_code
const& e) {
921 if ((e.value() == boost::system::errc::success) &&
922 (!m_job_queue.isStopped()))
925 jtNETOP_TIMER,
"NetOPs.heartbeat", [this](Job&) {
926 processHeartbeatTimer();
930 if (e.value() != boost::system::errc::success &&
931 e.value() != boost::asio::error::operation_aborted)
934 JLOG(m_journal.error())
935 <<
"Heartbeat timer got error '" << e.message()
936 <<
"'. Restarting timer.";
951 [
this](boost::system::error_code
const& e) {
952 if ((e.value() == boost::system::errc::success) &&
953 (!m_job_queue.isStopped()))
956 jtNETOP_CLUSTER,
"NetOPs.cluster", [this](Job&) {
957 processClusterTimer();
961 if (e.value() != boost::system::errc::success &&
962 e.value() != boost::asio::error::operation_aborted)
965 JLOG(m_journal.error())
966 <<
"Cluster timer got error '" << e.message()
967 <<
"'. Restarting timer.";
972 using namespace std::chrono_literals;
973 clusterTimer_.expires_from_now(10s);
974 clusterTimer_.async_wait(std::move(*optionalCountedHandler));
997 <<
"Node count (" << numPeers <<
") has fallen "
1013 <<
"Node count (" << numPeers <<
") is sufficient.";
1039 using namespace std::chrono_literals;
1055 protocol::TMCluster cluster;
1057 protocol::TMClusterNode& n = *cluster.add_clusternodes();
1062 n.set_nodename(node.
name());
1066 for (
auto& item : gossip.
items)
1068 protocol::TMLoadSource& node = *cluster.add_loadsources();
1070 node.set_cost(item.balance);
1073 std::make_shared<Message>(cluster, protocol::mtCLUSTER),
1093 return "validating";
1112 auto const txid = trans->getTransactionID();
1115 if ((flags & SF_BAD) != 0)
1117 JLOG(
m_journal.
warn()) <<
"Submitted transaction cached bad";
1132 <<
"Submitted transaction invalid: " << reason;
1138 JLOG(
m_journal.
warn()) <<
"Exception checking transaction" << txid;
1145 auto tx = std::make_shared<Transaction>(trans, reason,
app_);
1163 if ((newFlags & SF_BAD) != 0)
1166 transaction->setStatus(
INVALID);
1177 *transaction->getSTransaction(),
1185 JLOG(
m_journal.
info()) <<
"Transaction has bad signature: " << reason;
1186 transaction->setStatus(
INVALID);
1209 if (transaction->getApplying())
1214 transaction->setApplying();
1235 if (!transaction->getApplying())
1239 transaction->setApplying();
1265 }
while (transaction->getApplying());
1288 assert(!transactions.
empty());
1297 bool changed =
false;
1315 app_, view, e.transaction->getSTransaction(), flags, j);
1316 e.result = result.first;
1317 e.applied = result.second;
1318 changed = changed || result.second;
1326 boost::optional<LedgerIndex> validatedLedgerIndex;
1328 validatedLedgerIndex = l->info().seq;
1333 e.transaction->clearSubmitResult();
1338 newOL, e.transaction->getSTransaction(), e.result);
1339 e.transaction->setApplied();
1342 e.transaction->setResult(e.result);
1355 <<
"TransactionResult: " << token <<
": " << human;
1360 bool addLocal = e.local;
1365 <<
"Transaction is now included in open ledger";
1366 e.transaction->setStatus(
INCLUDED);
1368 auto const& txCur = e.transaction->getSTransaction();
1374 auto t = std::make_shared<Transaction>(trans, reason,
app_);
1383 e.transaction->setStatus(
OBSOLETE);
1388 <<
"Transaction is likely to claim a"
1389 <<
" fee, but is queued until fee drops";
1391 e.transaction->setStatus(
HELD);
1396 e.transaction->setQueued();
1397 e.transaction->setKept();
1405 <<
"Transaction should be held: " << e.result;
1406 e.transaction->setStatus(
HELD);
1408 e.transaction->setKept();
1414 <<
"Status other than success " << e.result;
1415 e.transaction->setStatus(
INVALID);
1418 auto const enforceFailHard =
1421 if (addLocal && !enforceFailHard)
1425 e.transaction->getSTransaction());
1426 e.transaction->setKept();
1440 protocol::TMTransaction tx;
1443 e.transaction->getSTransaction()->add(s);
1444 tx.set_rawtransaction(s.
data(), s.
size());
1445 tx.set_status(protocol::tsCURRENT);
1446 tx.set_receivetimestamp(
1451 std::make_shared<Message>(tx, protocol::mtTRANSACTION),
1453 e.transaction->setBroadcast();
1457 if (validatedLedgerIndex)
1459 auto [fee, accountSeq, availableSeq] =
1461 *newOL, e.transaction->getSTransaction());
1462 e.transaction->setCurrentLedgerState(
1463 *validatedLedgerIndex, fee, accountSeq, availableSeq);
1471 e.transaction->clearApplying();
1473 if (!submit_held.
empty())
1478 for (
auto& e : submit_held)
1505 for (
auto const& uDirEntry : sleNode->getFieldV256(
sfIndexes))
1510 switch (sleCur->getType())
1513 if (!jvObjects.
isMember(jss::offers))
1514 jvObjects[jss::offers] =
1517 jvObjects[jss::offers].
append(
1522 if (!jvObjects.
isMember(jss::ripple_lines))
1524 jvObjects[jss::ripple_lines] =
1528 jvObjects[jss::ripple_lines].
append(
1544 sleNode = lpLedger->read(
keylet::page(root, uNodeDir));
1574 JLOG(
m_journal.
trace()) <<
"NetworkOPsImp::checkLastClosedLedger";
1581 uint256 closedLedger = ourClosed->info().hash;
1582 uint256 prevClosedLedger = ourClosed->info().parentHash;
1591 <<
"ValidationTrie " <<
Json::Compact(validations.getJsonTrie());
1595 peerCounts[closedLedger] = 0;
1597 peerCounts[closedLedger]++;
1599 for (
auto& peer : peerList)
1601 uint256 peerLedger = peer->getClosedLedgerHash();
1604 ++peerCounts[peerLedger];
1607 for (
auto const& it : peerCounts)
1608 JLOG(
m_journal.
debug()) <<
"L: " << it.first <<
" n=" << it.second;
1610 uint256 preferredLCL = validations.getPreferredLCL(
1615 bool switchLedgers = preferredLCL != closedLedger;
1617 closedLedger = preferredLCL;
1619 if (switchLedgers && (closedLedger == prevClosedLedger))
1622 JLOG(
m_journal.
info()) <<
"We won't switch to our own previous ledger";
1623 networkClosed = ourClosed->info().hash;
1624 switchLedgers =
false;
1627 networkClosed = closedLedger;
1645 networkClosed = ourClosed->info().hash;
1649 JLOG(
m_journal.
warn()) <<
"We are not running on the consensus ledger";
1675 <<
"JUMP last closed ledger to " << newLCL->info().hash;
1689 boost::optional<Rules> rules;
1711 protocol::TMStatusChange s;
1712 s.set_newevent(protocol::neSWITCHED_LEDGER);
1713 s.set_ledgerseq(newLCL->info().seq);
1715 s.set_ledgerhashprevious(
1716 newLCL->info().parentHash.begin(), newLCL->info().parentHash.size());
1717 s.set_ledgerhash(newLCL->info().hash.begin(), newLCL->info().hash.size());
1720 send_always(std::make_shared<Message>(s, protocol::mtSTATUS_CHANGE)));
1730 JLOG(
m_journal.
info()) <<
"Consensus time for #" << closingInfo.seq
1731 <<
" with LCL " << closingInfo.parentHash;
1740 JLOG(
m_journal.
warn()) <<
"Don't have LCL, going to tracking";
1747 assert(prevLedger->info().hash == closingInfo.parentHash);
1749 closingInfo.parentHash ==
1757 if (!changes.
added.empty() || !changes.
removed.empty())
1798 protocol::TMHaveTransactionSet msg;
1799 msg.set_hash(map->getHash().as_uint256().begin(), 256 / 8);
1800 msg.set_status(protocol::tsHAVE);
1802 send_always(std::make_shared<Message>(msg, protocol::mtHAVE_SET)));
1816 if (it && (it->getClosedLedgerHash() == deadLedger))
1827 if (networkClosed.
isZero())
1856 2 *
current->info().closeTimeResolution))
1884 jvObj[jss::type] =
"manifestReceived";
1887 jvObj[jss::signing_key] =
1891 jvObj[jss::signature] =
strHex(*sig);
1897 if (
auto p = i->second.lock())
1899 p->send(jvObj,
true);
1915 , loadBaseServer{loadFeeTrack.getLoadBase()}
1917 , em{std::move(escalationMetrics)}
1927 em.is_initialized() != b.
em.is_initialized())
1933 em->minProcessingFeeLevel != b.
em->minProcessingFeeLevel ||
1934 em->openLedgerFeeLevel != b.
em->openLedgerFeeLevel ||
1935 em->referenceFeeLevel != b.
em->referenceFeeLevel);
1968 jvObj[jss::type] =
"serverStatus";
1970 jvObj[jss::load_base] = f.loadBaseServer;
1971 jvObj[jss::load_factor_server] = f.loadFactorServer;
1972 jvObj[jss::base_fee] = f.baseFee.jsonClipped();
1977 safe_cast<std::uint64_t>(f.loadFactorServer),
1979 f.em->openLedgerFeeLevel,
1981 f.em->referenceFeeLevel)
1984 jvObj[jss::load_factor] =
trunc32(loadFactor);
1985 jvObj[jss::load_factor_fee_escalation] =
1986 f.em->openLedgerFeeLevel.jsonClipped();
1987 jvObj[jss::load_factor_fee_queue] =
1988 f.em->minProcessingFeeLevel.jsonClipped();
1989 jvObj[jss::load_factor_fee_reference] =
1990 f.em->referenceFeeLevel.jsonClipped();
1993 jvObj[jss::load_factor] = f.loadFactorServer;
2007 p->send(jvObj,
true);
2024 if (!streamMap.empty())
2027 jvObj[jss::type] =
"consensusPhase";
2028 jvObj[jss::consensus] =
to_string(phase);
2030 for (
auto i = streamMap.begin(); i != streamMap.end();)
2032 if (
auto p = i->second.lock())
2034 p->send(jvObj,
true);
2039 i = streamMap.erase(i);
2055 auto const signerPublic = val->getSignerPublic();
2057 jvObj[jss::type] =
"validationReceived";
2058 jvObj[jss::validation_public_key] =
2060 jvObj[jss::ledger_hash] =
to_string(val->getLedgerHash());
2061 jvObj[jss::signature] =
strHex(val->getSignature());
2062 jvObj[jss::full] = val->isFull();
2063 jvObj[jss::flags] = val->getFlags();
2066 auto const masterKey =
2069 if (masterKey != signerPublic)
2073 jvObj[jss::ledger_index] =
to_string(*seq);
2078 for (
auto const& amendment : val->getFieldV256(
sfAmendments))
2083 jvObj[jss::close_time] = *closeTime;
2085 if (
auto const loadFee = (*val)[~
sfLoadFee])
2086 jvObj[jss::load_fee] = *loadFee;
2088 if (
auto const baseFee = (*val)[~
sfBaseFee])
2089 jvObj[jss::base_fee] =
static_cast<double>(*baseFee);
2092 jvObj[jss::reserve_base] = *reserveBase;
2095 jvObj[jss::reserve_inc] = *reserveInc;
2100 if (
auto p = i->second.lock())
2102 p->send(jvObj,
true);
2122 jvObj[jss::type] =
"peerStatusChange";
2131 p->send(jvObj,
true);
2145 using namespace std::chrono_literals;
2191 numberOfResults = 1000000000;
2195 numberOfResults = binary ? BINARY_PAGE_LENGTH : NONBINARY_PAGE_LENGTH;
2197 else if (!bUnlimited)
2200 binary ? BINARY_PAGE_LENGTH : NONBINARY_PAGE_LENGTH,
2205 numberOfResults = limit;
2211 if (maxLedger != -1)
2213 maxClause = boost::str(
2214 boost::format(
"AND AccountTransactions.LedgerSeq <= '%u'") %
2218 if (minLedger != -1)
2220 minClause = boost::str(
2221 boost::format(
"AND AccountTransactions.LedgerSeq >= '%u'") %
2229 boost::format(
"SELECT %s FROM AccountTransactions "
2230 "WHERE Account = '%s' %s %s LIMIT %u, %u;") %
2232 minClause % beast::lexicalCastThrow<std::string>(offset) %
2233 beast::lexicalCastThrow<std::string>(numberOfResults));
2238 "AccountTransactions INNER JOIN Transactions "
2239 "ON Transactions.TransID = AccountTransactions.TransID "
2240 "WHERE Account = '%s' %s %s "
2241 "ORDER BY AccountTransactions.LedgerSeq %s, "
2242 "AccountTransactions.TxnSeq %s, AccountTransactions.TransID %s "
2245 minClause % (descending ?
"DESC" :
"ASC") %
2246 (descending ?
"DESC" :
"ASC") % (descending ?
"DESC" :
"ASC") %
2247 beast::lexicalCastThrow<std::string>(offset) %
2248 beast::lexicalCastThrow<std::string>(numberOfResults));
2267 "AccountTransactions.LedgerSeq,Status,RawTxn,TxnMeta",
2281 boost::optional<std::uint64_t> ledgerSeq;
2282 boost::optional<std::string> status;
2283 soci::blob sociTxnBlob(*db), sociTxnMetaBlob(*db);
2284 soci::indicator rti, tmi;
2285 Blob rawTxn, txnMeta;
2287 soci::statement st =
2288 (db->prepare << sql,
2289 soci::into(ledgerSeq),
2291 soci::into(sociTxnBlob, rti),
2292 soci::into(sociTxnMetaBlob, tmi));
2297 if (soci::i_ok == rti)
2302 if (soci::i_ok == tmi)
2303 convert(sociTxnMetaBlob, txnMeta);
2308 ledgerSeq, status, rawTxn,
app_);
2310 if (txnMeta.
empty())
2313 rangeCheckedCast<std::uint32_t>(ledgerSeq.value_or(0));
2316 <<
"Recovering ledger " << seq <<
", txn " << txn->getID();
2325 std::make_shared<TxMeta>(
2326 txn->getID(), txn->getLedger(), txnMeta));
2347 "AccountTransactions.LedgerSeq,Status,RawTxn,TxnMeta",
2361 boost::optional<std::uint64_t> ledgerSeq;
2362 boost::optional<std::string> status;
2363 soci::blob sociTxnBlob(*db), sociTxnMetaBlob(*db);
2364 soci::indicator rti, tmi;
2366 soci::statement st =
2367 (db->prepare << sql,
2368 soci::into(ledgerSeq),
2370 soci::into(sociTxnBlob, rti),
2371 soci::into(sociTxnMetaBlob, tmi));
2377 if (soci::i_ok == rti)
2380 if (soci::i_ok == tmi)
2381 convert(sociTxnMetaBlob, txnMeta);
2384 rangeCheckedCast<std::uint32_t>(ledgerSeq.value_or(0));
2386 ret.
emplace_back(std::move(rawTxn), std::move(txnMeta), seq);
2408 auto bound = [&ret, &app](
2447 auto bound = [&ret](
2452 ret.
emplace_back(std::move(rawTxn), std::move(rawMeta), ledgerIndex);
2477 <<
"recvValidation " << val->getLedgerHash() <<
" from " << source;
2507 "This server is amendment blocked, and must be updated to be "
2508 "able to stay in sync with the network.";
2515 "One or more unsupported amendments have reached majority. "
2516 "Upgrade to the latest version before they are activated "
2517 "to avoid being amendment blocked.";
2518 if (
auto const expected =
2522 d[jss::expected_date] = expected->time_since_epoch().count();
2523 d[jss::expected_date_UTC] =
to_string(*expected);
2527 if (warnings.size())
2528 info[jss::warnings] = std::move(warnings);
2536 info[jss::network_id] =
static_cast<Json::UInt>(*netid);
2542 info[jss::time] =
to_string(date::floor<std::chrono::microseconds>(
2546 info[jss::network_ledger] =
"waiting";
2548 info[jss::validation_quorum] =
2558 info[jss::validator_list_expires] =
2559 safe_cast<Json::UInt>(when->time_since_epoch().count());
2561 info[jss::validator_list_expires] = 0;
2571 if (*when == TimeKeeper::time_point::max())
2573 x[jss::expiration] =
"never";
2574 x[jss::status] =
"active";
2581 x[jss::status] =
"active";
2583 x[jss::status] =
"expired";
2588 x[jss::status] =
"unknown";
2589 x[jss::expiration] =
"unknown";
2593 info[jss::io_latency_ms] =
2600 info[jss::pubkey_validator] =
toBase58(
2605 info[jss::pubkey_validator] =
"none";
2615 info[jss::pubkey_node] =
2621 info[jss::amendment_blocked] =
true;
2635 lastClose[jss::converge_time_s] =
2640 lastClose[jss::converge_time] =
2644 info[jss::last_close] = lastClose;
2651 auto const escalationMetrics =
2659 auto const loadFactorFeeEscalation =
2661 escalationMetrics.openLedgerFeeLevel,
2663 escalationMetrics.referenceFeeLevel)
2667 safe_cast<std::uint64_t>(loadFactorServer), loadFactorFeeEscalation);
2671 info[jss::load_base] = loadBaseServer;
2672 info[jss::load_factor] =
trunc32(loadFactor);
2673 info[jss::load_factor_server] = loadFactorServer;
2680 info[jss::load_factor_fee_escalation] =
2681 escalationMetrics.openLedgerFeeLevel.jsonClipped();
2682 info[jss::load_factor_fee_queue] =
2683 escalationMetrics.minProcessingFeeLevel.jsonClipped();
2684 info[jss::load_factor_fee_reference] =
2685 escalationMetrics.referenceFeeLevel.jsonClipped();
2689 info[jss::load_factor] =
2690 static_cast<double>(loadFactor) / loadBaseServer;
2692 if (loadFactorServer != loadFactor)
2693 info[jss::load_factor_server] =
2694 static_cast<double>(loadFactorServer) / loadBaseServer;
2699 if (fee != loadBaseServer)
2700 info[jss::load_factor_local] =
2701 static_cast<double>(fee) / loadBaseServer;
2703 if (fee != loadBaseServer)
2704 info[jss::load_factor_net] =
2705 static_cast<double>(fee) / loadBaseServer;
2707 if (fee != loadBaseServer)
2708 info[jss::load_factor_cluster] =
2709 static_cast<double>(fee) / loadBaseServer;
2711 if (escalationMetrics.openLedgerFeeLevel !=
2712 escalationMetrics.referenceFeeLevel &&
2713 (admin || loadFactorFeeEscalation != loadFactor))
2714 info[jss::load_factor_fee_escalation] =
2715 escalationMetrics.openLedgerFeeLevel.decimalFromReference(
2716 escalationMetrics.referenceFeeLevel);
2717 if (escalationMetrics.minProcessingFeeLevel !=
2718 escalationMetrics.referenceFeeLevel)
2719 info[jss::load_factor_fee_queue] =
2720 escalationMetrics.minProcessingFeeLevel.decimalFromReference(
2721 escalationMetrics.referenceFeeLevel);
2734 XRPAmount const baseFee = lpClosed->fees().base;
2736 l[jss::seq] =
Json::UInt(lpClosed->info().seq);
2737 l[jss::hash] =
to_string(lpClosed->info().hash);
2742 l[jss::reserve_base] =
2743 lpClosed->fees().accountReserve(0).jsonClipped();
2744 l[jss::reserve_inc] = lpClosed->fees().increment.jsonClipped();
2746 lpClosed->info().closeTime.time_since_epoch().count());
2751 l[jss::reserve_base_xrp] =
2752 lpClosed->fees().accountReserve(0).decimalXRP();
2753 l[jss::reserve_inc_xrp] = lpClosed->fees().increment.decimalXRP();
2756 if (std::abs(nowOffset.count()) >= 60)
2757 l[jss::system_time_offset] = nowOffset.count();
2760 if (std::abs(closeOffset.count()) >= 60)
2761 l[jss::close_time_offset] = closeOffset.count();
2768 Json::UInt(age < highAgeThreshold ? age.count() : 0);
2772 auto lCloseTime = lpClosed->info().closeTime;
2774 if (lCloseTime <= closeTime)
2776 using namespace std::chrono_literals;
2777 auto age = closeTime - lCloseTime;
2779 Json::UInt(age < highAgeThreshold ? age.count() : 0);
2785 info[jss::validated_ledger] = l;
2787 info[jss::closed_ledger] = l;
2791 info[jss::published_ledger] =
"none";
2792 else if (lpPublished->info().seq != lpClosed->info().seq)
2793 info[jss::published_ledger] = lpPublished->info().seq;
2796 std::tie(info[jss::state_accounting], info[jss::server_state_duration_us]) =
2799 info[jss::jq_trans_overflow] =
2801 info[jss::peer_disconnects] =
2803 info[jss::peer_disconnects_resources] =
2839 p->send(jvObj,
true);
2864 alpAccepted = std::make_shared<AcceptedLedger>(
2867 lpAccepted->info().hash, alpAccepted);
2877 jvObj[jss::type] =
"ledgerClosed";
2878 jvObj[jss::ledger_index] = lpAccepted->info().seq;
2879 jvObj[jss::ledger_hash] =
to_string(lpAccepted->info().hash);
2881 lpAccepted->info().closeTime.time_since_epoch().count());
2883 jvObj[jss::fee_ref] = lpAccepted->fees().units.jsonClipped();
2884 jvObj[jss::fee_base] = lpAccepted->fees().base.jsonClipped();
2885 jvObj[jss::reserve_base] =
2886 lpAccepted->fees().accountReserve(0).jsonClipped();
2887 jvObj[jss::reserve_inc] =
2888 lpAccepted->fees().increment.jsonClipped();
2890 jvObj[jss::txn_count] =
Json::UInt(alpAccepted->getTxnCount());
2894 jvObj[jss::validated_ledgers] =
2904 p->send(jvObj,
true);
2914 for (
auto const& [_, accTx] : alpAccepted->getMap())
2934 jtCLIENT,
"reportFeeChange->pubServer", [
this](
Job&) {
2945 "reportConsensusStateChange->pubConsensus",
2964 jvObj[jss::type] =
"transaction";
2969 jvObj[jss::ledger_index] = lpCurrent->info().seq;
2970 jvObj[jss::ledger_hash] =
to_string(lpCurrent->info().hash);
2971 jvObj[jss::transaction][jss::date] =
2972 lpCurrent->info().closeTime.time_since_epoch().count();
2973 jvObj[jss::validated] =
true;
2979 jvObj[jss::validated] =
false;
2980 jvObj[jss::ledger_current_index] = lpCurrent->info().seq;
2983 jvObj[jss::status] = bValidated ?
"closed" :
"proposed";
2984 jvObj[jss::engine_result] = sToken;
2985 jvObj[jss::engine_result_code] = terResult;
2986 jvObj[jss::engine_result_message] = sHuman;
2994 if (account != amount.issue().account)
3002 jvObj[jss::transaction][jss::owner_funds] = ownerFunds.getText();
3017 if (
auto const txMeta = alTx.
getMeta())
3021 jvObj[jss::meta], *alAccepted, stTxn, *txMeta);
3034 p->send(jvObj,
true);
3049 p->send(jvObj,
true);
3078 for (
auto const& affectedAccount : alTx.
getAffected())
3083 auto it = simiIt->second.begin();
3085 while (it != simiIt->second.end())
3096 it = simiIt->second.erase(it);
3106 auto it = simiIt->second.begin();
3107 while (it != simiIt->second.end())
3118 it = simiIt->second.erase(it);
3126 <<
"pubAccountTransaction:"
3127 <<
" iProposed=" << iProposed <<
" iAccepted=" << iAccepted;
3129 if (!notify.
empty())
3137 if (
auto const txMeta = alTx.
getMeta())
3141 jvObj[jss::meta], *lpCurrent, stTxn, *txMeta);
3146 isrListener->send(jvObj,
true);
3162 for (
auto const& naAccountID : vnaAccountIDs)
3165 <<
"subAccount: account: " <<
toBase58(naAccountID);
3167 isrListener->insertSubAccountInfo(naAccountID, rt);
3172 for (
auto const& naAccountID : vnaAccountIDs)
3174 auto simIterator = subMap.
find(naAccountID);
3175 if (simIterator == subMap.
end())
3179 usisElement[isrListener->getSeq()] = isrListener;
3181 subMap.
insert(simIterator, make_pair(naAccountID, usisElement));
3186 simIterator->second[isrListener->getSeq()] = isrListener;
3197 for (
auto const& naAccountID : vnaAccountIDs)
3200 isrListener->deleteSubAccountInfo(naAccountID, rt);
3217 for (
auto const& naAccountID : vnaAccountIDs)
3219 auto simIterator = subMap.
find(naAccountID);
3221 if (simIterator != subMap.
end())
3224 simIterator->second.erase(uSeq);
3226 if (simIterator->second.empty())
3229 subMap.
erase(simIterator);
3239 listeners->addSubscriber(isrListener);
3249 listeners->removeSubscriber(uSeq);
3256 boost::optional<std::chrono::milliseconds> consensusDelay)
3263 Throw<std::runtime_error>(
3264 "Operation only possible in STANDALONE mode.");
3279 jvResult[jss::ledger_index] = lpClosed->info().seq;
3280 jvResult[jss::ledger_hash] =
to_string(lpClosed->info().hash);
3282 lpClosed->info().closeTime.time_since_epoch().count());
3283 jvResult[jss::fee_ref] = lpClosed->fees().units.jsonClipped();
3284 jvResult[jss::fee_base] = lpClosed->fees().base.jsonClipped();
3285 jvResult[jss::reserve_base] =
3286 lpClosed->fees().accountReserve(0).jsonClipped();
3287 jvResult[jss::reserve_inc] = lpClosed->fees().increment.jsonClipped();
3292 jvResult[jss::validated_ledgers] =
3298 .emplace(isrListener->getSeq(), isrListener)
3316 .emplace(isrListener->getSeq(), isrListener)
3344 jvResult[jss::random] =
to_string(uRandom);
3346 jvResult[jss::load_base] = feeTrack.getLoadBase();
3347 jvResult[jss::load_factor] = feeTrack.getLoadFactor();
3348 jvResult[jss::hostid] =
getHostId(admin);
3349 jvResult[jss::pubkey_node] =
3354 .emplace(isrListener->getSeq(), isrListener)
3372 .emplace(isrListener->getSeq(), isrListener)
3390 .emplace(isrListener->getSeq(), isrListener)
3408 .emplace(isrListener->getSeq(), isrListener)
3426 .emplace(isrListener->getSeq(), isrListener)
3444 .emplace(isrListener->getSeq(), isrListener)
3492 if (map.find(pInfo->getSeq()) != map.end())
3499 #ifndef USE_NEW_BOOK_PAGE
3510 unsigned int iLimit,
3520 uint256 uTipIndex = uBookBase;
3524 stream <<
"getBookPage:" << book;
3525 stream <<
"getBookPage: uBookBase=" << uBookBase;
3526 stream <<
"getBookPage: uBookEnd=" << uBookEnd;
3527 stream <<
"getBookPage: uTipIndex=" << uTipIndex;
3536 bool bDirectAdvance =
true;
3540 unsigned int uBookEntry;
3546 while (!bDone && iLimit-- > 0)
3550 bDirectAdvance =
false;
3554 auto const ledgerIndex = view.
succ(uTipIndex, uBookEnd);
3558 sleOfferDir.
reset();
3567 uTipIndex = sleOfferDir->key();
3579 <<
"getBookPage: uTipIndex=" << uTipIndex;
3581 <<
"getBookPage: offerIndex=" << offerIndex;
3591 auto const uOfferOwnerID = sleOffer->getAccountID(
sfAccount);
3592 auto const& saTakerGets = sleOffer->getFieldAmount(
sfTakerGets);
3593 auto const& saTakerPays = sleOffer->getFieldAmount(
sfTakerPays);
3595 bool firstOwnerOffer(
true);
3601 saOwnerFunds = saTakerGets;
3603 else if (bGlobalFreeze)
3611 auto umBalanceEntry = umBalance.
find(uOfferOwnerID);
3612 if (umBalanceEntry != umBalance.
end())
3616 saOwnerFunds = umBalanceEntry->second;
3617 firstOwnerOffer =
false;
3631 if (saOwnerFunds < beast::zero)
3635 saOwnerFunds.
clear();
3643 STAmount saOwnerFundsLimit = saOwnerFunds;
3655 saOwnerFundsLimit =
divide(saOwnerFunds, offerRate);
3658 if (saOwnerFundsLimit >= saTakerGets)
3661 saTakerGetsFunded = saTakerGets;
3667 saTakerGetsFunded = saOwnerFundsLimit;
3669 saTakerGetsFunded.
setJson(jvOffer[jss::taker_gets_funded]);
3673 saTakerGetsFunded, saDirRate, saTakerPays.
issue()))
3674 .setJson(jvOffer[jss::taker_pays_funded]);
3680 saOwnerFunds,
multiply(saTakerGetsFunded, offerRate));
3682 umBalance[uOfferOwnerID] = saOwnerFunds - saOwnerPays;
3686 jvOf[jss::quality] = saDirRate.
getText();
3688 if (firstOwnerOffer)
3689 jvOf[jss::owner_funds] = saOwnerFunds.
getText();
3704 bDirectAdvance =
true;
3709 <<
"getBookPage: offerIndex=" << offerIndex;
3729 unsigned int iLimit,
3737 MetaView lesActive(lpLedger,
tapNONE,
true);
3738 OrderBookIterator obIterator(lesActive, book);
3742 const bool bGlobalFreeze = lesActive.isGlobalFrozen(book.
out.
account) ||
3743 lesActive.isGlobalFrozen(book.
in.
account);
3745 while (iLimit-- > 0 && obIterator.nextOffer())
3750 auto const uOfferOwnerID = sleOffer->getAccountID(
sfAccount);
3751 auto const& saTakerGets = sleOffer->getFieldAmount(
sfTakerGets);
3752 auto const& saTakerPays = sleOffer->getFieldAmount(
sfTakerPays);
3753 STAmount saDirRate = obIterator.getCurrentRate();
3759 saOwnerFunds = saTakerGets;
3761 else if (bGlobalFreeze)
3769 auto umBalanceEntry = umBalance.
find(uOfferOwnerID);
3771 if (umBalanceEntry != umBalance.
end())
3775 saOwnerFunds = umBalanceEntry->second;
3781 saOwnerFunds = lesActive.accountHolds(
3787 if (saOwnerFunds.isNegative())
3791 saOwnerFunds.zero();
3798 STAmount saTakerGetsFunded;
3799 STAmount saOwnerFundsLimit = saOwnerFunds;
3811 saOwnerFundsLimit =
divide(saOwnerFunds, offerRate);
3814 if (saOwnerFundsLimit >= saTakerGets)
3817 saTakerGetsFunded = saTakerGets;
3822 saTakerGetsFunded = saOwnerFundsLimit;
3824 saTakerGetsFunded.setJson(jvOffer[jss::taker_gets_funded]);
3830 multiply(saTakerGetsFunded, saDirRate, saTakerPays.issue()))
3831 .setJson(jvOffer[jss::taker_pays_funded]);
3834 STAmount saOwnerPays = (
parityRate == offerRate)
3837 saOwnerFunds,
multiply(saTakerGetsFunded, offerRate));
3839 umBalance[uOfferOwnerID] = saOwnerFunds - saOwnerPays;
3841 if (!saOwnerFunds.isZero() || uOfferOwnerID == uTakerID)
3845 jvOf[jss::quality] = saDirRate.
getText();
3873 std::chrono::duration_cast<std::chrono::microseconds>(now -
start_);
3882 auto [counters, mode, start] = getCounterData();
3883 auto const current = std::chrono::duration_cast<std::chrono::microseconds>(
3894 auto& state = ret[
states_[i]];
3895 state[jss::transitions] = counters[i].transitions;
3896 state[jss::duration_us] =
std::to_string(counters[i].dur.count());
3915 boost::asio::io_service& io_svc,
3919 return std::make_unique<NetworkOPsImp>(
bool unsubValidations(std::uint64_t uListener) override
beast::insight::Hook hook
TxType getTxnType() const
FeeVote::Setup setup_FeeVote(Section const §ion)
Build FeeVote::Setup from a config section.
RCLCxLedger::ID prevLedgerID() const
bool subValidations(InfoSub::ref ispListener) override
void processHeartbeatTimer()
Provides server functionality for clients.
ConsensusPhase phase() const
Keylet ownerDir(AccountID const &id) noexcept
The root page of an account's directory.
void mapComplete(std::shared_ptr< SHAMap > const &map, bool fromAcquire) override
Rate transferRate(ReadView const &view, AccountID const &issuer)
virtual std::chrono::duration< std::int32_t > nowOffset() const =0
bool unsubConsensus(std::uint64_t uListener) override
static Transaction::pointer transactionFromSQL(boost::optional< std::uint64_t > const &ledgerSeq, boost::optional< std::string > const &status, Blob const &rawTxn, Application &app)
virtual OrderBookDB & getOrderBookDB()=0
uint256 getConsensusLCL() override
A peer's signed, proposed position for use in RCLConsensus.
@ ledgerMaster
ledger master data for signing
bool processTrustedProposal(RCLCxPeerPos proposal) override
virtual Json::Value getInfo()=0
const SF_U32 sfLoadFee(access, STI_UINT32, 24, "LoadFee")
boost::optional< TxQ::Metrics > em
virtual Cluster & cluster()=0
std::string transactionsSQL(std::string selection, AccountID const &account, std::int32_t minLedger, std::int32_t maxLedger, bool descending, std::uint32_t offset, int limit, bool binary, bool count, bool bUnlimited)
void accountTxPage(DatabaseCon &connection, AccountIDCache const &idCache, std::function< void(std::uint32_t)> const &onUnsavedLedger, std::function< void(std::uint32_t, std::string const &, Blob &&, Blob &&)> const &onTransaction, AccountID const &account, std::int32_t minLedger, std::int32_t maxLedger, bool forward, std::optional< NetworkOPs::AccountTxMarker > &marker, int limit, bool bAdmin, std::uint32_t page_length)
const SF_U64 sfIndexNext(access, STI_UINT64, 1, "IndexNext")
std::shared_ptr< ReadView const > getPublishedLedger()
void pubProposedTransaction(std::shared_ptr< ReadView const > const &lpCurrent, std::shared_ptr< STTx const > const &stTxn, TER terResult) override
virtual TaggedCache< uint256, AcceptedLedger > & getAcceptedLedgerCache()=0
std::vector< AccountTx > AccountTxs
std::shared_ptr< OpenView const > current() const
Returns a view to the current open ledger.
ServerFeeSummary mLastFeeSummary
PublicKey localPublicKey() const
Returns local validator public key.
@ proposing
We are normal participant in consensus and propose our position.
boost::asio::steady_timer heartbeatTimer_
PublicKey getMasterKey(PublicKey const &pk) const
Returns ephemeral signing key's master public key.
Json::Value getJson(bool full) const
const std::size_t minPeerCount_
Represents a transfer rate.
void setStateTimer() override
Called to initially start our timers.
void stopped()
Called by derived classes to indicate that the stoppable has stopped.
void startRound(NetClock::time_point const &now, RCLCxLedger::ID const &prevLgrId, RCLCxLedger const &prevLgr, hash_set< NodeID > const &nowUntrusted, hash_set< NodeID > const &nowTrusted)
Adjust the set of trusted validators and kick-off the next round of consensus.
Stream trace() const
Severity stream access functions.
std::shared_ptr< STTx const > const & getTxn() const
int getFlags(uint256 const &key)
std::unique_ptr< FeeVote > make_FeeVote(FeeVote::Setup const &setup, beast::Journal journal)
Create an instance of the FeeVote logic.
std::tuple< Blob, Blob, std::uint32_t > txnMetaLedgerType
MetaTxsList getTxsAccountB(AccountID const &account, std::int32_t minLedger, std::int32_t maxLedger, bool forward, std::optional< AccountTxMarker > &marker, int limit, bool bUnlimited) override
Changes in trusted nodes after updating validator list.
Data format for exchanging consumption information across peers.
void setAmendmentWarned() override
void pubManifest(Manifest const &) override
bool subPeerStatus(InfoSub::ref ispListener) override
DispatchState mDispatchState
@ arrayValue
array value (ordered list)
std::pair< TER, bool > apply(Application &app, OpenView &view, std::shared_ptr< STTx const > const &tx, ApplyFlags flags, beast::Journal j)
Add a new transaction to the open ledger, hold it in the queue, or reject it.
virtual std::uint64_t getJqTransOverflow() const =0
SubInfoMapType mSubRTAccount
std::atomic< bool > amendmentWarned_
static const std::array< char const *, 5 > states_
@ wrongLedger
We have the wrong ledger and are attempting to acquire it.
void convert(soci::blob &from, std::vector< std::uint8_t > &to)
LedgerIndex getValidLedgerIndex()
virtual AmendmentTable & getAmendmentTable()=0
void setMode(OperatingMode om) override
std::string const & name() const
Writable ledger view that accumulates state and tx changes.
bool cdirNext(ReadView const &view, uint256 const &uRootIndex, std::shared_ptr< SLE const > &sleNode, unsigned int &uDirEntry, uint256 &uEntryIndex, beast::Journal j)
std::string strOperatingMode(bool const admin=false) const override
Decorator for streaming out compact json.
uint256 getBookBase(Book const &book)
std::chrono::microseconds dur
PublicKey signingKey
The ephemeral key associated with this manifest.
Manages a client's subscription to data feeds.
void trustChanged(hash_set< NodeID > const &added, hash_set< NodeID > const &removed)
Update trust status of validations.
std::uint32_t acceptLedger(boost::optional< std::chrono::milliseconds > consensusDelay) override
Accepts the current transaction tree, return the new ledger's sequence.
void setNeedNetworkLedger() override
bool tryRemoveRpcSub(std::string const &strUrl) override
PublicKey masterKey
The master key associated with this manifest.
STAmount accountHolds(ReadView const &view, AccountID const &account, Currency const ¤cy, AccountID const &issuer, FreezeHandling zeroIfFrozen, beast::Journal j)
bool empty() const noexcept
std::string getText() const override
bool recvValidation(std::shared_ptr< STValidation > const &val, std::string const &source) override
void setNegativeUNL(hash_set< PublicKey > const &negUnl)
set the Negative UNL with validators' master public keys
std::string getHostId(bool forAdmin)
void gotTxSet(NetClock::time_point const &now, RCLTxSet const &txSet)
const SF_Account sfAccount(access, STI_ACCOUNT, 1, "Account")
csprng_engine & crypto_prng()
The default cryptographically secure PRNG.
Keylet offer(AccountID const &id, std::uint32_t seq) noexcept
An offer from an account.
Rules getValidatedRules()
Json::Value getJson(int c=0)
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
TrustChanges updateTrusted(hash_set< NodeID > const &seenValidators)
Update trusted nodes.
beast::insight::Gauge disconnected_duration
const SF_Amount sfTakerPays(access, STI_AMOUNT, 4, "TakerPays")
void switchLCL(std::shared_ptr< Ledger const > const &lastClosed)
Keylet child(uint256 const &key) noexcept
Any item that can be in an owner dir.
void consensusViewChange() override
StateAccounting accounting_
std::chrono::milliseconds ledgerGRANULARITY
How often we check state or change positions.
std::shared_ptr< Ledger const > getLedgerByHash(uint256 const &hash)
void timerEntry(NetClock::time_point const &now)
virtual std::size_t size() const =0
Returns the number of active peers.
void apply(std::unique_lock< std::mutex > &batchLock)
Attempt to apply transactions and post-process based on the results.
bool addJob(JobType type, std::string const &name, JobHandler &&jobHandler)
Adds a job to the JobQueue.
beast::insight::Gauge syncing_transitions
std::uint32_t getLoadBase() const
std::string to_string(ListDisposition disposition)
uint256 getQualityNext(uint256 const &uBase)
virtual TimeKeeper & timeKeeper()=0
virtual MutexType & getMasterMutex()=0
virtual OpenLedger & openLedger()=0
void pubLedger(std::shared_ptr< ReadView const > const &lpAccepted) override
bool update(PublicKey const &identity, std::string name, std::uint32_t loadFee=0, NetClock::time_point reportTime=NetClock::time_point{})
Store information about the state of a cluster node.
void switchLastClosedLedger(std::shared_ptr< Ledger const > const &newLCL)
void convertBlobsToTxResult(NetworkOPs::AccountTxs &to, std::uint32_t ledger_index, std::string const &status, Blob const &rawTxn, Blob const &rawMeta, Application &app)
void doTransactionAsync(std::shared_ptr< Transaction > transaction, bool bUnlimited, FailHard failtype)
For transactions not submitted by a locally connected client, fire and forget.
Structure returned by TxQ::getMetrics, expressed in reference fee level units.
Select all peers that are in the specified set.
Wraps a ledger instance for use in generic Validations LedgerTrie.
const SF_U32 sfReserveBase(access, STI_UINT32, 31, "ReserveBase")
void accept(Application &app, Rules const &rules, std::shared_ptr< Ledger const > const &ledger, OrderedTxs const &locals, bool retriesFirst, OrderedTxs &retries, ApplyFlags flags, std::string const &suffix="", modify_type const &f={})
Accept a new ledger.
const Rate parityRate(QUALITY_ONE)
A transfer rate signifying a 1:1 exchange.
AccountTxs getAccountTxs(AccountID const &account, std::int32_t minLedger, std::int32_t maxLedger, bool descending, std::uint32_t offset, int limit, bool bUnlimited) override
Validator keys and manifest as set in configuration file.
virtual AccountIDCache const & accountIDCache() const =0
std::shared_ptr< InboundLedger > mAcquiringLedger
virtual InboundLedgers & getInboundLedgers()=0
virtual LoadFeeTrack & getFeeTrack()=0
constexpr static std::size_t size()
std::string getCompleteLedgers()
Sends a message to all peers.
static const Json::StaticString transitions_
@ SYNCING
fallen slightly behind
void processClusterTimer()
bool unsubTransactions(std::uint64_t uListener) override
void const * data() const noexcept
virtual Gossip exportConsumers()=0
Extract packaged consumer information for export.
std::recursive_mutex & peekMutex()
std::uint32_t loadFactorServer
STAmount divide(STAmount const &amount, Rate const &rate)
~NetworkOPsImp() override
std::uint32_t getRemoteFee() const
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, Stoppable &parent, ValidatorKeys const &validatorKeys, boost::asio::io_service &io_svc, beast::Journal journal, beast::insight::Collector::ptr const &collector)
boost::optional< Blob > getSignature() const
Returns manifest signature.
Manages the generic consensus algorithm for use by the RCL.
@ warnRPC_AMENDMENT_BLOCKED
T time_since_epoch(T... args)
bool isGlobalFrozen(ReadView const &view, AccountID const &issuer)
beast::insight::Gauge syncing_duration
bool isAmendmentBlocked() override
InfoSub::pointer addRpcSub(std::string const &strUrl, InfoSub::ref) override
Value & append(const Value &value)
Append value to array at the end.
StateCountersJson json() const
Output state counters in JSON format.
@ DISCONNECTED
not ready to process requests
Provides an interface for starting and stopping.
void clearAmendmentWarned() override
void setJson(Json::Value &) const
void processTxn(std::shared_ptr< ReadView const > const &ledger, const AcceptedLedgerTx &alTx, Json::Value const &jvObj)
std::shared_ptr< TxMeta > const & getMeta() const
virtual std::chrono::milliseconds getIOLatency()=0
Json::Value getOwnerInfo(std::shared_ptr< ReadView const > lpLedger, AccountID const &account) override
std::pair< Validity, std::string > checkValidity(HashRouter &router, STTx const &tx, Rules const &rules, Config const &config)
Checks transaction signature and local checks.
LockedSociSession checkoutDb()
std::vector< txnMetaLedgerType > MetaTxsList
void reportFeeChange() override
std::uint32_t getLocalFee() const
@ CONNECTED
convinced we are talking to the network
virtual LoadManager & getLoadManager()=0
std::shared_ptr< InfoSub > pointer
@ objectValue
object value (collection of name/value pairs).
constexpr double decimalXRP() const
bool hasTXSet(const std::shared_ptr< Peer > &peer, uint256 const &set, protocol::TxSetStatus status)
virtual LedgerMaster & getLedgerMaster()=0
virtual std::shared_ptr< Ledger const > acquire(uint256 const &hash, std::uint32_t seq, InboundLedger::Reason)=0
bool peerProposal(NetClock::time_point const &now, RCLCxPeerPos const &newProposal)
@ TRACKING
convinced we agree with the network
void pubValidatedTransaction(std::shared_ptr< ReadView const > const &alAccepted, const AcceptedLedgerTx &alTransaction)
AccountID getAccountID(SField const &field) const
void saveLedgerAsync(Application &app, std::uint32_t seq)
DispatchState
Synchronization states for transaction batches.
virtual Config & config()=0
Select all peers (except optional excluded) that are in our cluster.
hash_set< NodeID > removed
Represents a set of transactions in RCLConsensus.
Keylet page(uint256 const &key, std::uint64_t index) noexcept
A page in a directory.
const SF_U32 sfSigningTime(access, STI_UINT32, 9, "SigningTime")
void endConsensus() override
void unsubAccount(InfoSub::ref ispListener, hash_set< AccountID > const &vnaAccountIDs, bool rt) override
virtual std::pair< PublicKey, SecretKey > const & nodeIdentity()=0
bool canBeCurrent(std::shared_ptr< Ledger const > const &ledger)
Check the sequence number and parent close time of a ledger against our clock and last validated ledg...
bool unsubRTTransactions(std::uint64_t uListener) override
Manages the current fee schedule.
AccountTxs getTxsAccount(AccountID const &account, std::int32_t minLedger, std::int32_t maxLedger, bool forward, std::optional< AccountTxMarker > &marker, int limit, bool bUnlimited) override
bool subManifests(InfoSub::ref ispListener) override
A transaction that is in a closed ledger.
std::vector< Item > items
bool set(T &target, std::string const &name, Section const §ion)
Set a value from a configuration Section If the named value is not found or doesn't parse as a T,...
const std::shared_ptr< Transaction > transaction
std::shared_ptr< Ledger const > getValidatedLedger()
FeeAndSeq getTxRequiredFeeAndSeq(OpenView const &view, std::shared_ptr< STTx const > const &tx) const
Returns minimum required fee for tx and two sequences: first vaild sequence for this account in curre...
Server fees published on server subscription.
Json::Value transJson(const STTx &stTxn, TER terResult, bool bValidated, std::shared_ptr< ReadView const > const &lpCurrent)
std::unique_ptr< LocalTxs > m_localTX
ConsensusPhase
Phases of consensus for a single ledger round.
const SF_U32 sfLedgerSequence(access, STI_UINT32, 6, "LedgerSequence")
bool isCompatible(ReadView const &, beast::Journal::Stream, char const *reason)
std::string const & getVersionString()
Server version.
void pubAccountTransaction(std::shared_ptr< ReadView const > const &lpCurrent, const AcceptedLedgerTx &alTransaction, bool isAccepted)
std::shared_ptr< Ledger const > getLedgerBySeq(std::uint32_t index)
ConsensusMode mode() const
boost::container::flat_set< AccountID > const & getAffected() const
virtual PeerSequence getActivePeers() const =0
Returns a sequence representing the current list of peers.
decltype(counters_) counters
beast::insight::Gauge tracking_duration
@ warnRPC_UNSUPPORTED_MAJORITY
bool subTransactions(InfoSub::ref ispListener) override
virtual time_point closeTime() const =0
Returns the close time, in network time.
@ current
This was a new validation and was added.
std::array< Counters, 5 > counters_
bool isMember(const char *key) const
Return true if the object has a member named key.
bool unsubLedger(std::uint64_t uListener) override
A generic endpoint for log messages.
bool isAmendmentWarned() override
virtual RCLValidations & getValidations()=0
std::atomic< bool > needNetworkLedger_
std::optional< std::set< PeerShortID > > shouldRelay(uint256 const &key)
Determines whether the hashed item should be relayed.
void addHeldTransaction(std::shared_ptr< Transaction > const &trans)
Blob getMasterSignature() const
Returns manifest master key signature.
void foreach(Function f) const
Visit every active peer.
ServerFeeSummary()=default
boost::optional< Wrapper< Closure > > wrap(Closure &&closure)
Wrap the passed closure with a reference counter.
NetworkOPsImp(Application &app, NetworkOPs::clock_type &clock, bool standalone, std::size_t minPeerCount, bool start_valid, JobQueue &job_queue, LedgerMaster &ledgerMaster, Stoppable &parent, ValidatorKeys const &validatorKeys, boost::asio::io_service &io_svc, beast::Journal journal, beast::insight::Collector::ptr const &collector)
const SF_Vec256 sfIndexes(access, STI_VECTOR256, 1, "Indexes", SField::sMD_Never)
std::uint32_t getClusterFee() const
NetworkOPs(Stoppable &parent)
virtual PublicKey const & getValidationPublicKey() const =0
void pubValidation(std::shared_ptr< STValidation > const &val) override
STAmount amountFromQuality(std::uint64_t rate)
MetaTxsList getAccountTxsB(AccountID const &account, std::int32_t minLedger, std::int32_t maxLedger, bool descending, std::uint32_t offset, int limit, bool bUnlimited) override
BookListeners::pointer makeBookListeners(Book const &)
void processClosedLedger(Application &app, ReadView const &view, bool timeLeap)
Update fee metrics and clean up the queue in preparation for the next ledger.
void subAccount(InfoSub::ref ispListener, hash_set< AccountID > const &vnaAccountIDs, bool rt) override
virtual std::shared_ptr< SLE const > read(Keylet const &k) const =0
Return the state item associated with a key.
std::shared_ptr< ReadView const > getCurrentLedger()
ConsensusParms const & parms() const
Json::Value getJson(JsonOptions options) const override
STAmount accountFunds(ReadView const &view, AccountID const &id, STAmount const &saDefault, FreezeHandling freezeHandling, beast::Journal j)
Transaction with input flags and results to be applied in batches.
virtual ValidatorList & validators()=0
A metric for measuring an integral value.
void transactionBatch()
Apply transactions in batches.
bool isNeedNetworkLedger() override
void resetDeadlockDetector()
Reset the deadlock detection timer.
bool operator!=(ServerFeeSummary const &b) const
TransactionStatus(std::shared_ptr< Transaction > t, bool a, bool l, FailHard f)
void setStandAlone() override
A pool of threads to perform work.
std::recursive_mutex mSubLock
void onStop() override
Override called when the stop notification is issued.
bool operator==(ServerFeeSummary const &b) const
std::chrono::system_clock::time_point start_
STAmount multiply(STAmount const &amount, Rate const &rate)
BookListeners::pointer getBookListeners(Book const &)
std::uint32_t sequence
The sequence number of this manifest.
virtual Resource::Manager & getResourceManager()=0
std::size_t getFetchPackCacheSize() const
Json::Value getJson(LedgerFill const &fill)
Return a new Json::Value representing the ledger with given options.
beast::insight::Gauge tracking_transitions
bool haveValidated()
Whether we have ever fully validated a ledger.
std::chrono::seconds getValidatedLedgerAge()
std::shared_ptr< Ledger const > getClosedLedger()
beast::insight::Gauge connected_transitions
boost::asio::steady_timer clusterTimer_
virtual Json::Value countersJson() const =0
Render performance counters in Json.
std::vector< TransactionStatus > mTransactions
void reportConsensusStateChange(ConsensusPhase phase)
T emplace_back(T... args)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
bool transResultInfo(TER code, std::string &token, std::string &text)
bool unsubServer(std::uint64_t uListener) override
std::chrono::milliseconds prevRoundTime() const
Get duration of the previous round.
std::shared_ptr< STTx const > sterilize(STTx const &stx)
Sterilize a transaction.
std::unordered_set< uint256, beast::uhash<> > features
Stats(Handler const &handler, beast::insight::Collector::ptr const &collector)
virtual beast::Journal journal(std::string const &name)=0
virtual ManifestCache & validatorManifests()=0
std::size_t getLocalTxCount() override
std::array< SubMapType, SubTypes::sLastEntry+1 > mStreamMaps
std::size_t size() const noexcept
std::uint32_t getLoadFactor() const
std::shared_ptr< SHAMap > getTXMap(uint256 const &hash)
Json::Value getLedgerFetchInfo() override
send_if_not_pred< Predicate > send_if_not(std::shared_ptr< Message > const &m, Predicate const &f)
Helper function to aid in type deduction.
@ Valid
Signature and local checks are good / passed.
bool unsubBook(std::uint64_t uListener, Book const &) override
void canonicalize(std::shared_ptr< Transaction > *pTransaction)
SubInfoMapType mSubAccount
void clearNeedNetworkLedger() override
const SF_U32 sfReserveIncrement(access, STI_UINT32, 32, "ReserveIncrement")
void rngfill(void *buffer, std::size_t bytes, Generator &g)
Issue const & issue() const
Lightweight wrapper to tag static string.
const uint256 featureNegativeUNL
bool checkLastClosedLedger(const Overlay::PeerSequence &, uint256 &networkClosed)
std::string strOperatingMode(OperatingMode const mode, bool const admin) const override
void getBookPage(std::shared_ptr< ReadView const > &lpLedger, Book const &, AccountID const &uTakerID, const bool bProof, unsigned int iLimit, Json::Value const &jvMarker, Json::Value &jvResult) override
void insertDeliveredAmount(Json::Value &meta, ReadView const &, std::shared_ptr< STTx const > const &serializedTx, TxMeta const &)
Add a delivered_amount field to the meta input/output parameter.
void pubPeerStatus(std::function< Json::Value(void)> const &) override
std::condition_variable mCond
LedgerIndex getCurrentLedgerIndex()
bool subLedger(InfoSub::ref ispListener, Json::Value &jvResult) override
beast::insight::Gauge full_transitions
static const std::array< char const *, 5 > stateNames
virtual time_point now() const override=0
Returns the estimate of wall time, in network time.
const SF_U32 sfCloseTime(access, STI_UINT32, 7, "CloseTime")
std::size_t prevProposers() const
Get the number of proposing peers that participated in the previous round.
virtual Overlay & overlay()=0
Source(char const *name, Stoppable &parent)
std::atomic< OperatingMode > mMode
bool unsubManifests(std::uint64_t uListener) override
const SF_Amount sfTakerGets(access, STI_AMOUNT, 5, "TakerGets")
std::atomic< bool > amendmentBlocked_
void submitTransaction(std::shared_ptr< STTx const > const &) override
OperatingMode
Specifies the mode under which the server believes it's operating.
bool RELAY_UNTRUSTED_VALIDATIONS
virtual void clearFailures()=0
void join(char const *name, std::chrono::milliseconds wait, beast::Journal j)
Returns once all counted in-flight closures are destroyed.
ConsensusPhase mLastConsensusPhase
void updateLocalTx(ReadView const &view) override
Json::Value getJson() const
void pubConsensus(ConsensusPhase phase)
void for_each(std::function< void(ClusterNode const &)> func) const
Invokes the callback once for every cluster node.
bool subRTTransactions(InfoSub::ref ispListener) override
NetClock::time_point getReportTime() const
beast::insight::Gauge disconnected_transitions
static const Json::StaticString dur_
std::string strHex(FwdIt begin, FwdIt end)
std::pair< bool, Dest > mulDiv(Source1 value, Dest mul, Source2 div)
Json::Value getServerInfo(bool human, bool admin, bool counters) override
virtual Json::Value currentJson() const =0
Render currently executing jobs and RPC calls and durations in Json.
LedgerMaster & m_ledgerMaster
bool subServer(InfoSub::ref ispListener, Json::Value &jvResult, bool admin) override
auto getCurrentNodeIDs() -> hash_set< NodeID >
Get the set of node ids associated with current validations.
@ ltDIR_NODE
Directory node.
const SF_Vec256 sfAmendments(access, STI_VECTOR256, 3, "Amendments")
@ SigBad
Signature is bad. Didn't do local checks.
boost::optional< TimeKeeper::time_point > expires() const
Return the time when the validator list will expire.
bool validating() const
Whether we are validating consensus ledgers.
std::unique_ptr< LocalTxs > make_LocalTxs()
Metrics getMetrics(OpenView const &view) const
Returns fee metrics in reference fee level units.
void doTransactionSync(std::shared_ptr< Transaction > transaction, bool bUnlimited, FailHard failType)
For transactions submitted directly by a client, apply batch of transactions and wait for this transa...
CounterData getCounterData() const
const SF_U64 sfBaseFee(access, STI_UINT64, 5, "BaseFee")
std::unique_ptr< LoadEvent > makeLoadEvent(JobType t, std::string const &name)
Return a scoped LoadEvent.
beast::insight::Gauge full_duration
virtual perf::PerfLog & getPerfLog()=0
send_if_pred< Predicate > send_if(std::shared_ptr< Message > const &m, Predicate const &f)
Helper function to aid in type deduction.
virtual std::uint64_t getPeerDisconnect() const =0
CanonicalTXSet OrderedTxs
bool subBook(InfoSub::ref ispListener, Book const &) override
bool subConsensus(InfoSub::ref ispListener) override
bool pendSaveValidated(Application &app, std::shared_ptr< Ledger const > const &ledger, bool isSynchronous, bool isCurrent)
Save, or arrange to save, a fully-validated ledger Returns false on error.
Json::Value getConsensusInfo() override
beast::insight::Gauge connected_duration
std::size_t count() const
Return the number of configured validator list sites.
ClosureCounter< void, boost::system::error_code const & > waitHandlerCounter_
void mode(OperatingMode om)
Record state transition.
static const std::array< Json::StaticString const, 5 > states_
virtual boost::optional< std::uint32_t > networkID() const =0
Returns the ID of the network this server is configured for, if any.
static std::string getWordFromBlob(void const *blob, size_t bytes)
Chooses a single dictionary word from the data.
void unsubAccountInternal(std::uint64_t seq, hash_set< AccountID > const &vnaAccountIDs, bool rt) override
virtual boost::optional< key_type > succ(key_type const &key, boost::optional< key_type > const &last=boost::none) const =0
Return the key of the next state item.
std::shared_ptr< STTx const > popAcctTransaction(std::shared_ptr< STTx const > const &tx)
Get the next transaction held for a particular account if any.
State accounting records two attributes for each possible server state: 1) Amount of time spent in ea...
A reference to a handler for performing polled collection.
std::uint64_t getQuality(uint256 const &uBase)
virtual std::uint64_t getPeerDisconnectCharges() const =0
virtual HashRouter & getHashRouter()=0
bool modify(modify_type const &f)
Modify the open ledger.
std::uint32_t transitions
STAmount const & getFieldAmount(SField const &field) const
bool unsubPeerStatus(std::uint64_t uListener) override
bool setFlags(uint256 const &key, int flags)
Set the flags on a hash.
void handleNewValidation(Application &app, std::shared_ptr< STValidation > const &val, std::string const &source)
Handle a new validation.
bool isTemMalformed(TER x)
static std::uint32_t trunc32(std::uint64_t v)
virtual boost::optional< NetClock::time_point > firstUnsupportedExpected() const =0
Json::Value jsonClipped() const
OperatingMode getOperatingMode() const override
PublicKey const & identity() const
std::size_t quorum() const
Get quorum value for current trusted key set.
virtual std::chrono::duration< std::int32_t > closeOffset() const =0
InfoSub::pointer findRpcSub(std::string const &strUrl) override
void set(value_type value) const
Set the value on the gauge.
std::uint32_t loadBaseServer
virtual DatabaseCon & getTxnDB()=0
void clearLedgerFetch() override
std::string toBase58(AccountID const &) const
Return ripple::toBase58 for the AccountID.
void simulate(NetClock::time_point const &now, boost::optional< std::chrono::milliseconds > consensusDelay)
std::uint32_t getLoadFee() const
Json::Value rate(Account const &account, double multiplier)
Set a transfer rate.
bool cdirFirst(ReadView const &view, uint256 const &uRootIndex, std::shared_ptr< SLE const > &sleNode, unsigned int &uDirEntry, uint256 &uEntryIndex, beast::Journal j)
virtual TransactionMaster & getMasterTransaction()=0
bool beginConsensus(uint256 const &networkClosed) override
void setAmendmentBlocked() override
void processTransaction(std::shared_ptr< Transaction > &transaction, bool bUnlimited, bool bLocal, FailHard failType) override
Process transactions as they arrive from the network or which are submitted by clients.
@ FULL
we have the ledger and can even validate