Tari: more efficient polling
Use `GetTipInfo` gRPC call to quickly check for changes
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user