Skip to content

Commit debc0c1

Browse files
committed
Add prevhash to template cache
Also cache the most recent template prev_hash between while iterations. This prevents repeating calls to getBlockHeader()
1 parent 3f699b9 commit debc0c1

File tree

2 files changed

+14
-12
lines changed

2 files changed

+14
-12
lines changed

src/sv2/template_provider.cpp

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ void Sv2TemplateProvider::Interrupt()
130130
LOCK(m_tp_mutex);
131131
try {
132132
for (auto& t : GetBlockTemplates()) {
133-
t.second->interruptWait();
133+
t.second.second->interruptWait();
134134
}
135135
} catch (const ipc::Exception& e) {
136136
// Bitcoin Core v30 does not yet implement interruptWait(), fall back
@@ -250,7 +250,6 @@ void Sv2TemplateProvider::ThreadSv2ClientHandler(size_t client_id)
250250
{
251251
try {
252252
Timer timer(m_options.fee_check_interval);
253-
std::shared_ptr<BlockTemplate> block_template;
254253

255254
const auto prepare_block_create_options = [this, client_id](node::BlockCreateOptions& options) -> bool {
256255
{
@@ -265,6 +264,9 @@ void Sv2TemplateProvider::ThreadSv2ClientHandler(size_t client_id)
265264
return true;
266265
};
267266

267+
std::shared_ptr<BlockTemplate> block_template;
268+
// Cache most recent block_template->getBlockHeader().hashPrevBlock result.
269+
uint256 prev_hash;
268270
while (!m_flag_interrupt_sv2) {
269271
if (!block_template) {
270272
LogPrintLevel(BCLog::SV2, BCLog::Level::Trace, "Generate initial block template for client id=%zu\n",
@@ -288,7 +290,7 @@ void Sv2TemplateProvider::ThreadSv2ClientHandler(size_t client_id)
288290
LogPrintLevel(BCLog::SV2, BCLog::Level::Trace, "Assemble template: %.2fms\n",
289291
Ticks<MillisecondsDouble>(SteadyClock::now() - time_start));
290292

291-
uint256 prev_hash{block_template->getBlockHeader().hashPrevBlock};
293+
prev_hash = block_template->getBlockHeader().hashPrevBlock;
292294
{
293295
LOCK(m_tp_mutex);
294296
if (prev_hash != m_best_prev_hash) {
@@ -299,7 +301,7 @@ void Sv2TemplateProvider::ThreadSv2ClientHandler(size_t client_id)
299301

300302
// Add template to cache before sending it, to prevent race
301303
// condition: https://github.com/stratum-mining/stratum/issues/1773
302-
m_block_template_cache.insert({template_id,block_template});
304+
m_block_template_cache.insert({template_id,std::make_pair(prev_hash, block_template)});
303305
}
304306

305307
{
@@ -346,7 +348,6 @@ void Sv2TemplateProvider::ThreadSv2ClientHandler(size_t client_id)
346348
client_id);
347349
}
348350

349-
uint256 old_prev_hash{block_template->getBlockHeader().hashPrevBlock};
350351
std::shared_ptr<BlockTemplate> tmpl = block_template->waitNext(options);
351352
// The client may have disconnected during the wait, check now to avoid
352353
// a spurious IPC call and confusing log statements.
@@ -362,7 +363,7 @@ void Sv2TemplateProvider::ThreadSv2ClientHandler(size_t client_id)
362363

363364
{
364365
LOCK(m_tp_mutex);
365-
if (new_prev_hash != old_prev_hash) {
366+
if (new_prev_hash != prev_hash) {
366367
LogPrintLevel(BCLog::SV2, BCLog::Level::Trace, "Tip changed, client id=%zu\n",
367368
client_id);
368369
future_template = true;
@@ -375,7 +376,7 @@ void Sv2TemplateProvider::ThreadSv2ClientHandler(size_t client_id)
375376

376377
// Add template to cache before sending it, to prevent race
377378
// condition: https://github.com/stratum-mining/stratum/issues/1773
378-
m_block_template_cache.insert({m_template_id,block_template});
379+
m_block_template_cache.insert({m_template_id, std::make_pair(new_prev_hash,block_template)});
379380
}
380381

381382
{
@@ -422,7 +423,7 @@ void Sv2TemplateProvider::RequestTransactionData(Sv2Client& client, node::Sv2Req
422423

423424
return;
424425
}
425-
block = (*cached_block->second).getBlock();
426+
block = (*cached_block->second.second).getBlock();
426427
}
427428

428429
{
@@ -497,7 +498,7 @@ void Sv2TemplateProvider::SubmitSolution(node::Sv2SubmitSolutionMsg solution)
497498
* on the network. In case of a reorg the node will be able to switch
498499
* faster because it already has (but not fully validated) the block.
499500
*/
500-
block_template = cached_block_template->second;
501+
block_template = cached_block_template->second.second;
501502
}
502503

503504
// Submit the solution to construct and process the block
@@ -555,7 +556,7 @@ void Sv2TemplateProvider::PruneBlockTemplateCache()
555556
// If the blocks prevout is not the tip's prevout, delete it.
556557
uint256 prev_hash = m_best_prev_hash;
557558
std::erase_if(m_block_template_cache, [prev_hash] (const auto& kv) {
558-
if (kv.second->getBlockHeader().hashPrevBlock != prev_hash) {
559+
if (kv.second.first != prev_hash) {
559560
return true;
560561
}
561562
return false;

src/sv2/template_provider.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,10 @@ class Sv2TemplateProvider : public Sv2EventsInterface
104104
std::chrono::nanoseconds m_last_block_time GUARDED_BY(m_tp_mutex);
105105

106106
/**
107-
* A cache that maps ids used in NewTemplate messages and its associated block template.
107+
* A cache that maps ids used in NewTemplate messages and its associated
108+
* <prevhash,block template>.
108109
*/
109-
using BlockTemplateCache = std::map<uint64_t, std::shared_ptr<BlockTemplate>>;
110+
using BlockTemplateCache = std::map<uint64_t, std::pair<uint256, std::shared_ptr<BlockTemplate>>>;
110111
BlockTemplateCache m_block_template_cache GUARDED_BY(m_tp_mutex);
111112

112113
public:

0 commit comments

Comments
 (0)