|
19 | 19 | #include <context.h> |
20 | 20 | #include <consensus/amount.h> |
21 | 21 | #include <deploymentstatus.h> |
22 | | -#include <node/coinstats.h> |
23 | 22 | #include <fs.h> |
24 | 23 | #include <hash.h> |
25 | 24 | #include <httpserver.h> |
|
32 | 31 | #include <interfaces/init.h> |
33 | 32 | #include <interfaces/node.h> |
34 | 33 | #include <interfaces/wallet.h> |
| 34 | +#include <kernel/coinstats.h> |
35 | 35 | #include <mapport.h> |
36 | 36 | #include <node/miner.h> |
37 | 37 | #include <net.h> |
|
134 | 134 | #include <zmq/zmqrpc.h> |
135 | 135 | #endif |
136 | 136 |
|
| 137 | +using kernel::CoinStatsHashType; |
| 138 | + |
137 | 139 | using node::CacheSizes; |
138 | 140 | using node::CalculateCacheSizes; |
139 | | -using node::CCoinsStats; |
140 | | -using node::CoinStatsHashType; |
141 | 141 | using node::ChainstateLoadingError; |
142 | 142 | using node::ChainstateLoadVerifyError; |
143 | 143 | using node::DashChainstateSetupClose; |
@@ -224,8 +224,24 @@ static fs::path GetPidFile(const ArgsManager& args) |
224 | 224 | // shutdown thing. |
225 | 225 | // |
226 | 226 |
|
| 227 | +#if HAVE_SYSTEM |
| 228 | +static void ShutdownNotify(const ArgsManager& args) |
| 229 | +{ |
| 230 | + std::vector<std::thread> threads; |
| 231 | + for (const auto& cmd : args.GetArgs("-shutdownnotify")) { |
| 232 | + threads.emplace_back(runCommand, cmd); |
| 233 | + } |
| 234 | + for (auto& t : threads) { |
| 235 | + t.join(); |
| 236 | + } |
| 237 | +} |
| 238 | +#endif |
| 239 | + |
227 | 240 | void Interrupt(NodeContext& node) |
228 | 241 | { |
| 242 | +#if HAVE_SYSTEM |
| 243 | + ShutdownNotify(*node.args); |
| 244 | +#endif |
229 | 245 | InterruptHTTPServer(); |
230 | 246 | InterruptHTTPRPC(); |
231 | 247 | InterruptRPC(); |
@@ -439,7 +455,6 @@ void Shutdown(NodeContext& node) |
439 | 455 | LogPrintf("%s: Unable to remove PID file: %s\n", __func__, fsbridge::get_filesystem_error_message(e)); |
440 | 456 | } |
441 | 457 |
|
442 | | - node.args = nullptr; |
443 | 458 | LogPrintf("%s: done\n", __func__); |
444 | 459 | } |
445 | 460 |
|
@@ -553,6 +568,7 @@ void SetupServerArgs(ArgsManager& argsman) |
553 | 568 | argsman.AddArg("-syncmempool", strprintf("Sync mempool from other nodes on start (default: %u)", DEFAULT_SYNC_MEMPOOL), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); |
554 | 569 | #if HAVE_SYSTEM |
555 | 570 | argsman.AddArg("-startupnotify=<cmd>", "Execute command on startup.", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); |
| 571 | + argsman.AddArg("-shutdownnotify=<cmd>", "Execute command immediately before beginning shutdown. The need for shutdown may be urgent, so be careful not to delay it long (if the command doesn't require interaction with the server, consider having it fork into the background).", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); |
556 | 572 | #endif |
557 | 573 | #ifndef WIN32 |
558 | 574 | argsman.AddArg("-sysperms", "Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); |
@@ -840,15 +856,15 @@ static void PeriodicStats(NodeContext& node) |
840 | 856 | ChainstateManager& chainman = *Assert(node.chainman); |
841 | 857 | const CTxMemPool& mempool = *Assert(node.mempool); |
842 | 858 | const llmq::CInstantSendManager& isman = *Assert(node.llmq_ctx->isman); |
843 | | - CCoinsStats stats{CoinStatsHashType::NONE}; |
844 | 859 | chainman.ActiveChainstate().ForceFlushStateToDisk(); |
845 | | - if (WITH_LOCK(cs_main, return GetUTXOStats(&chainman.ActiveChainstate().CoinsDB(), chainman.m_blockman, stats, node.rpc_interruption_point, chainman.ActiveChain().Tip()))) { |
846 | | - ::g_stats_client->gauge("utxoset.tx", stats.nTransactions, 1.0f); |
847 | | - ::g_stats_client->gauge("utxoset.txOutputs", stats.nTransactionOutputs, 1.0f); |
848 | | - ::g_stats_client->gauge("utxoset.dbSizeBytes", stats.nDiskSize, 1.0f); |
849 | | - ::g_stats_client->gauge("utxoset.blockHeight", stats.nHeight, 1.0f); |
850 | | - if (stats.total_amount.has_value()) { |
851 | | - ::g_stats_client->gauge("utxoset.totalAmount", (double)stats.total_amount.value() / (double)COIN, 1.0f); |
| 860 | + const auto maybe_stats = WITH_LOCK(::cs_main, return GetUTXOStats(&chainman.ActiveChainstate().CoinsDB(), chainman.m_blockman, /*hash_type=*/CoinStatsHashType::NONE, node.rpc_interruption_point, chainman.ActiveChain().Tip(), /*index_requested=*/true)); |
| 861 | + if (maybe_stats.has_value()) { |
| 862 | + ::g_stats_client->gauge("utxoset.tx", maybe_stats->nTransactions, 1.0f); |
| 863 | + ::g_stats_client->gauge("utxoset.txOutputs", maybe_stats->nTransactionOutputs, 1.0f); |
| 864 | + ::g_stats_client->gauge("utxoset.dbSizeBytes", maybe_stats->nDiskSize, 1.0f); |
| 865 | + ::g_stats_client->gauge("utxoset.blockHeight", maybe_stats->nHeight, 1.0f); |
| 866 | + if (maybe_stats->total_amount.has_value()) { |
| 867 | + ::g_stats_client->gauge("utxoset.totalAmount", (double)maybe_stats->total_amount.value() / (double)COIN, 1.0f); |
852 | 868 | } |
853 | 869 | } else { |
854 | 870 | // something went wrong |
@@ -2306,6 +2322,24 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) |
2306 | 2322 | return false; |
2307 | 2323 | } |
2308 | 2324 |
|
| 2325 | + int chain_active_height = WITH_LOCK(cs_main, return chainman.ActiveChain().Height()); |
| 2326 | + |
| 2327 | + // On first startup, warn on low block storage space |
| 2328 | + if (!fReindex && !fReindexChainState && chain_active_height <= 1) { |
| 2329 | + uint64_t additional_bytes_needed = fPruneMode ? nPruneTarget |
| 2330 | + : chainparams.AssumedBlockchainSize() * 1024 * 1024 * 1024; |
| 2331 | + |
| 2332 | + if (!CheckDiskSpace(args.GetBlocksDirPath(), additional_bytes_needed)) { |
| 2333 | + InitWarning(strprintf(_( |
| 2334 | + "Disk space for %s may not accommodate the block files. " \ |
| 2335 | + "Approximately %u GB of data will be stored in this directory." |
| 2336 | + ), |
| 2337 | + fs::quoted(fs::PathToString(args.GetBlocksDirPath())), |
| 2338 | + chainparams.AssumedBlockchainSize() |
| 2339 | + )); |
| 2340 | + } |
| 2341 | + } |
| 2342 | + |
2309 | 2343 | // Either install a handler to notify us when genesis activates, or set fHaveGenesis directly. |
2310 | 2344 | // No locking, as this happens before any background thread is started. |
2311 | 2345 | boost::signals2::connection block_notify_genesis_wait_connection; |
@@ -2396,8 +2430,6 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) |
2396 | 2430 |
|
2397 | 2431 | // ********************************************************* Step 12: start node |
2398 | 2432 |
|
2399 | | - int chain_active_height; |
2400 | | - |
2401 | 2433 | //// debug print |
2402 | 2434 | { |
2403 | 2435 | LOCK(cs_main); |
|
0 commit comments