Skip to content

Commit

Permalink
Handle SUBMIT_SOLUTION
Browse files Browse the repository at this point in the history
  • Loading branch information
Sjors committed Dec 19, 2024
1 parent f315fd6 commit 4c2b3f1
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 0 deletions.
19 changes: 19 additions & 0 deletions src/sv2/connman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,25 @@ void Sv2Connman::ProcessSv2Message(const Sv2NetMsg& sv2_net_msg, Sv2Client& clie

break;
}
case Sv2MsgType::SUBMIT_SOLUTION: {
if (!client.m_setup_connection_confirmed && !client.m_coinbase_output_data_size_recv) {
client.m_disconnect_flag = true;
return;
}

node::Sv2SubmitSolutionMsg submit_solution;
try {
ss >> submit_solution;
} catch (const std::exception& e) {
LogPrintLevel(BCLog::SV2, BCLog::Level::Error, "Received invalid SubmitSolution message from client id=%zu: %e\n",
client.m_id, e.what());
return;
}

m_msgproc->SubmitSolution(submit_solution);

break;
}
case Sv2MsgType::REQUEST_TRANSACTION_DATA:
{
node::Sv2RequestTransactionDataMsg request_tx_data;
Expand Down
5 changes: 5 additions & 0 deletions src/sv2/connman.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ class Sv2EventsInterface
*/
virtual void RequestTransactionData(Sv2Client& client, node::Sv2RequestTransactionDataMsg msg) = 0;

/**
* We received and successfully parsed a SubmitSolution message.
*/
virtual void SubmitSolution(node::Sv2SubmitSolutionMsg solution) = 0;

virtual ~Sv2EventsInterface() = default;
};

Expand Down
45 changes: 45 additions & 0 deletions src/sv2/template_provider.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include <sv2/template_provider.h>

#include <base58.h>
#include <consensus/merkle.h>
#include <crypto/hex_base.h>
#include <common/args.h>
#include <logging.h>
Expand Down Expand Up @@ -291,6 +292,50 @@ void Sv2TemplateProvider::RequestTransactionData(Sv2Client& client, node::Sv2Req
client.m_send_messages.emplace_back(request_tx_data_success);
}

void Sv2TemplateProvider::SubmitSolution(node::Sv2SubmitSolutionMsg solution)
{
LogPrintLevel(BCLog::SV2, BCLog::Level::Debug, "id=%lu version=%d, timestamp=%d, nonce=%d\n",
solution.m_template_id,
solution.m_version,
solution.m_header_timestamp,
solution.m_header_nonce
);

std::shared_ptr<BlockTemplate> block_template;
{
// We can't hold this lock until submitSolution() because it's
// possible that the new block arrives via the p2p network at the
// same time. That leads to a deadlock in g_best_block_mutex.
LOCK(m_tp_mutex);
auto cached_block_template = m_block_template_cache.find(solution.m_template_id);
if (cached_block_template == m_block_template_cache.end()) {
LogPrintLevel(BCLog::SV2, BCLog::Level::Debug, "Template with id=%lu is no longer in cache\n",
solution.m_template_id);
return;
}
/**
* It's important to not delete this template from the cache in case
* another solution is submitted for the same template later.
*
* This is very unlikely on mainnet, but not impossible. Many mining
* devices may be working on the default pool template at the same
* time and they may not update the new tip right away.
*
* The node will never broadcast the second block. It's marked
* valid-headers in getchaintips. However a node or pool operator
* may wish to manually inspect the block or keep it as a souvenir.
* Additionally, because in Stratum v2 the block solution is sent
* to both the pool node and the template provider node, it's
* possibly they arrive out of order and two competing blocks propagate
* on the network. In case of a reorg the node will be able to switch
* faster because it already has (but not fully validated) the block.
*/
block_template = cached_block_template->second;
}

block_template->submitSolution(solution.m_version, solution.m_header_timestamp, solution.m_header_nonce, MakeTransactionRef(solution.m_coinbase_tx));
}

void Sv2TemplateProvider::PruneBlockTemplateCache()
{
AssertLockHeld(m_tp_mutex);
Expand Down
2 changes: 2 additions & 0 deletions src/sv2/template_provider.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ class Sv2TemplateProvider : public Sv2EventsInterface

void RequestTransactionData(Sv2Client& client, node::Sv2RequestTransactionDataMsg msg) EXCLUSIVE_LOCKS_REQUIRED(!m_tp_mutex) override;

void SubmitSolution(node::Sv2SubmitSolutionMsg solution) EXCLUSIVE_LOCKS_REQUIRED(!m_tp_mutex) override;

/* Block templates that connected clients may be working on, only used for tests */
BlockTemplateCache& GetBlockTemplates() EXCLUSIVE_LOCKS_REQUIRED(m_tp_mutex) { return m_block_template_cache; }

Expand Down
4 changes: 4 additions & 0 deletions src/test/sv2_connman_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,10 @@ class ConnTester : Sv2EventsInterface {
BOOST_TEST_MESSAGE("Process RequestTransactionData");
}

void SubmitSolution(node::Sv2SubmitSolutionMsg solution) override {
BOOST_TEST_MESSAGE("Process SubmitSolution");
}

};

BOOST_AUTO_TEST_CASE(client_tests)
Expand Down

0 comments on commit 4c2b3f1

Please sign in to comment.