Skip to content

Commit a54d5fb

Browse files
committed
Block dashboard during startup — only loading page until fully ready
- Redirect all .html requests to loading.html when is_node_ready() returns false (verified shares + work template + window fn wired) - Fix window cache poisoning: don't cache stub responses with empty best_hash — during early startup the fn isn't wired yet and the null response was cached permanently - loading.html checks currency_info.block_value for true readiness
1 parent 2ee2c0e commit a54d5fb

2 files changed

Lines changed: 54 additions & 2 deletions

File tree

src/core/web_server.cpp

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,21 @@ void HttpSession::process_request()
576576
std::string file_path = target;
577577
if (file_path == "/" || file_path.empty()) file_path = "/loading.html";
578578

579+
// During startup, redirect all HTML pages to loading.html
580+
// (except loading.html itself). Only loading.html + sync_status
581+
// + currency_info work during early startup.
582+
if (file_path != "/loading.html" && file_path.find(".html") != std::string::npos) {
583+
bool node_ready = mining_interface_->is_node_ready();
584+
if (!node_ready) {
585+
response.result(http::status::temporary_redirect);
586+
response.set(http::field::location, "/loading.html");
587+
response.body() = "";
588+
response.prepare_payload();
589+
send_response(std::move(response));
590+
return;
591+
}
592+
}
593+
579594
std::error_code fec;
580595
std::filesystem::path base = std::filesystem::weakly_canonical(dashboard_dir);
581596
std::filesystem::path requested = base / file_path.substr(1);
@@ -3486,7 +3501,7 @@ nlohmann::json MiningInterface::get_pplns_for_tip(const std::string& tip_hash)
34863501
std::pair<std::string, std::string> MiningInterface::get_cached_window_response()
34873502
{
34883503
std::lock_guard<std::mutex> lock(m_window_cache_mutex);
3489-
// Check if cache is valid (has etag = current tip)
3504+
// Check if cache is valid (has real tip hash, not empty/stub)
34903505
if (!m_window_cache_etag.empty())
34913506
return {m_window_cache_json, m_window_cache_etag};
34923507

@@ -3497,8 +3512,14 @@ std::pair<std::string, std::string> MiningInterface::get_cached_window_response(
34973512
tip = data["best_hash"].get<std::string>();
34983513
if (tip.size() > 16) tip = tip.substr(0, 16);
34993514
}
3515+
// Don't cache stub responses (empty best_hash) — during early startup
3516+
// the sharechain_window_fn may not be wired yet or return empty data.
3517+
// Return the stub without caching so next request retries.
3518+
if (tip.empty()) {
3519+
return {data.dump(), ""};
3520+
}
35003521
m_window_cache_json = data.dump();
3501-
m_window_cache_etag = tip.empty() ? "none" : tip;
3522+
m_window_cache_etag = tip;
35023523
return {m_window_cache_json, m_window_cache_etag};
35033524
}
35043525

@@ -4369,6 +4390,36 @@ nlohmann::json MiningInterface::rest_sync_status()
43694390
return result;
43704391
}
43714392

4393+
bool MiningInterface::is_node_ready()
4394+
{
4395+
// Check sharechain has verified shares
4396+
if (m_sharechain_stats_fn) {
4397+
auto sc = m_sharechain_stats_fn();
4398+
if (sc.value("verified_count", 0) <= 0)
4399+
return false;
4400+
} else {
4401+
return false;
4402+
}
4403+
4404+
// Check work template exists
4405+
{
4406+
std::lock_guard<std::mutex> lock(m_work_mutex);
4407+
if (m_cached_template.is_null() ||
4408+
m_cached_template.value("coinbasevalue", uint64_t(0)) == 0)
4409+
return false;
4410+
}
4411+
4412+
// Check sharechain window has data (not a stub)
4413+
if (m_sharechain_window_fn) {
4414+
// Don't call the fn here (expensive) — just check if it's wired
4415+
// The window cache will be populated on first real request
4416+
} else {
4417+
return false;
4418+
}
4419+
4420+
return true;
4421+
}
4422+
43724423
// ── Log endpoints (read directly from debug.log) ───────────────────────
43734424

43744425
static std::string tail_file(const std::filesystem::path& path, size_t max_lines)

src/core/web_server.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ class MiningInterface : public jsonrpccxx::JsonRpc2Server
193193
nlohmann::json rest_payout_addrs();
194194
nlohmann::json rest_web_best_share_hash();
195195
nlohmann::json rest_sync_status();
196+
bool is_node_ready(); // true when dashboard data is fully available
196197

197198
// Additional p2pool-compatible REST endpoints (peer network, stale rates, mining details)
198199
nlohmann::json rest_rate(); // /rate — pool hashrate (single number)

0 commit comments

Comments
 (0)