Tari: more efficient polling

Use `GetTipInfo` gRPC call to quickly check for changes
This commit is contained in:
SChernykh
2025-05-14 11:24:42 +02:00
parent 27a2461d1d
commit 1f3872254d
+45 -15
View File
@@ -499,16 +499,47 @@ void MergeMiningClientTari::run()
using namespace std::chrono;
auto last_update_time = high_resolution_clock::now();
TipInfoResponse prev_tip_info{};
auto prev_tip_info_update_time = high_resolution_clock::now();
auto same_tip = [](const TipInfoResponse& a, const TipInfoResponse& b) -> bool {
return
(a.metadata().best_block_height() == b.metadata().best_block_height()) &&
(a.metadata().best_block_hash() == b.metadata().best_block_hash()) &&
(a.metadata().accumulated_difficulty() == b.metadata().accumulated_difficulty()) &&
(a.initial_sync_achieved() == b.initial_sync_achieved()) &&
(a.base_node_state() == b.base_node_state()) &&
(a.failed_checkpoints() == b.failed_checkpoints());
};
for (;;) {
const auto t1 = high_resolution_clock::now();
const auto start_time = high_resolution_clock::now();
// Force frequent enough updates (at least every 30 seconds)
if (duration_cast<seconds>(start_time - prev_tip_info_update_time).count() >= 30) {
prev_tip_info.mutable_metadata()->set_best_block_height(0);
}
MutexLock lock(m_workerLock);
GetNewBlockTemplateWithCoinbasesRequest request;
grpc::ClientContext get_tip_info_ctx{};
Empty get_tip_info_request{};
TipInfoResponse cur_tip_info{};
const grpc::Status get_tip_info_status = m_TariNode->GetTipInfo(&get_tip_info_ctx, get_tip_info_request, &cur_tip_info);
if (!get_tip_info_status.ok()) {
LOGWARN(4, "GetTipInfo failed: " << get_tip_info_status.error_message());
if (!get_tip_info_status.error_details().empty()) {
LOGWARN(4, "GetTipInfo failed: " << get_tip_info_status.error_details());
}
}
else if (!same_tip(cur_tip_info, prev_tip_info)) {
GetNewBlockTemplateWithCoinbasesRequest request{};
PowAlgo* algo = new PowAlgo();
algo->set_pow_algo(PowAlgo_PowAlgos_POW_ALGOS_RANDOMX);
request.clear_algo();
request.set_allocated_algo(algo);
request.set_max_weight(0);
@@ -523,8 +554,8 @@ void MergeMiningClientTari::run()
coinbase->set_revealed_value_proof(true);
coinbase->clear_coinbase_extra();
grpc::ClientContext ctx;
GetNewBlockResult response;
grpc::ClientContext ctx{};
GetNewBlockResult response{};
const grpc::Status status = m_TariNode->GetNewBlockTemplateWithCoinbases(&ctx, request, &response);
@@ -535,6 +566,9 @@ void MergeMiningClientTari::run()
}
}
else {
prev_tip_info = cur_tip_info;
prev_tip_info_update_time = start_time;
const std::string& id = response.tari_unique_id();
const std::string& mm_hash = response.merge_mining_hash();
@@ -563,16 +597,7 @@ void MergeMiningClientTari::run()
WriteLock lock2(m_chainParamsLock);
if (job_params != m_tariJobParams) {
// Don't update if only fees changed and it's been less than 10 seconds since the last update
if ((job_params.height == m_tariJobParams.height) &&
(job_params.diff == m_tariJobParams.diff) &&
(job_params.reward == m_tariJobParams.reward) &&
(duration_cast<milliseconds>(t1 - last_update_time).count() < 10'000)) {
break;
}
m_tariJobParams = job_params;
last_update_time = t1;
if (m_chainParams.aux_id.empty()) {
LOGINFO(1, m_hostStr << " uses chain_id " << log::LightCyan() << log::hex_buf(id.data(), id.size()));
@@ -600,8 +625,13 @@ void MergeMiningClientTari::run()
}
}
}
}
const int64_t timeout = std::max<int64_t>(500'000'000 - duration_cast<nanoseconds>(high_resolution_clock::now() - t1).count(), 1'000'000);
auto dt = duration_cast<nanoseconds>(high_resolution_clock::now() - start_time).count();
LOGINFO(6, "Polling loop took " << (static_cast<double>(dt) * 1e-6) << " ms");
const int64_t timeout = std::max<int64_t>(500'000'000 - dt, 1'000'000);
if ((m_workerStop.load() != 0) || (uv_cond_timedwait(&m_workerCond, &m_workerLock, timeout) != UV_ETIMEDOUT)) {
return;