diff --git a/src/block_template.cpp b/src/block_template.cpp index 44eba34..317d860 100644 --- a/src/block_template.cpp +++ b/src/block_template.cpp @@ -1293,6 +1293,22 @@ uint32_t BlockTemplate::get_hashing_blobs(uint32_t extra_nonce_start, uint32_t c return blob_size; } +std::vector BlockTemplate::get_aux_chains(const uint32_t template_id) const +{ + ReadLock lock(m_lock); + + if (template_id != m_templateId) { + const BlockTemplate* old = m_oldTemplates[template_id % array_size(&BlockTemplate::m_oldTemplates)]; + if (old && (template_id == old->m_templateId)) { + return old->get_aux_chains(template_id); + } + + return {}; + } + + return m_poolBlockTemplate->m_auxChains; +} + std::vector BlockTemplate::get_block_template_blob(uint32_t template_id, uint32_t sidechain_extra_nonce, size_t& nonce_offset, size_t& extra_nonce_offset, size_t& sidechain_id_offset, hash& sidechain_id) const { ReadLock lock(m_lock); diff --git a/src/block_template.h b/src/block_template.h index 2a66a61..a245fd2 100644 --- a/src/block_template.h +++ b/src/block_template.h @@ -48,6 +48,8 @@ public: uint32_t get_hashing_blob(uint32_t extra_nonce, uint8_t (&blob)[128], uint64_t& height, uint64_t& sidechain_height, difficulty_type& difficulty, difficulty_type& aux_diff, difficulty_type& sidechain_difficulty, hash& seed_hash, size_t& nonce_offset, uint32_t& template_id) const; uint32_t get_hashing_blobs(uint32_t extra_nonce_start, uint32_t count, std::vector& blobs, uint64_t& height, difficulty_type& difficulty, difficulty_type& aux_diff, difficulty_type& sidechain_difficulty, hash& seed_hash, size_t& nonce_offset, uint32_t& template_id) const; + std::vector get_aux_chains(const uint32_t template_id) const; + std::vector get_block_template_blob(uint32_t template_id, uint32_t sidechain_extra_nonce, size_t& nonce_offset, size_t& extra_nonce_offset, size_t& sidechain_id_offset, hash& sidechain_id) const; FORCEINLINE uint64_t height() const { return m_height; } diff --git a/src/miner.cpp b/src/miner.cpp index ba7b9fe..02d266c 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -108,6 +108,7 @@ void Miner::on_block(const BlockTemplate& block) const uint32_t extra_nonce = static_cast(m_rng() >> 32); j.m_blobSize = block.get_hashing_blob(extra_nonce, j.m_blob, j.m_height, j.m_sidechainHeight, j.m_diff, j.m_auxDiff, j.m_sidechainDiff, seed, j.m_nonceOffset, j.m_templateId); + j.m_auxChains = block.get_aux_chains(j.m_templateId); const uint64_t next_full_nonce = (static_cast(extra_nonce) << 32) | std::numeric_limits::max(); const uint32_t hash_count = std::numeric_limits::max() - static_cast(m_fullNonce.exchange(next_full_nonce)); @@ -208,7 +209,7 @@ void Miner::run(WorkerData* data) if (first) { first = false; - memcpy(&job[index], &miner->m_job[miner->m_jobIndex], sizeof(Job)); + job[index] = miner->m_job[miner->m_jobIndex]; const uint64_t full_nonce = miner->m_fullNonce.fetch_sub(1); job[index].set_nonce(static_cast(full_nonce), static_cast(full_nonce >> 32)); @@ -218,7 +219,7 @@ void Miner::run(WorkerData* data) const Job& j = job[index]; index ^= 1; - memcpy(&job[index], &miner->m_job[miner->m_jobIndex], sizeof(Job)); + job[index] = miner->m_job[miner->m_jobIndex]; const uint64_t full_nonce = miner->m_fullNonce.fetch_sub(1); job[index].set_nonce(static_cast(full_nonce), static_cast(full_nonce >> 32)); @@ -241,7 +242,11 @@ void Miner::run(WorkerData* data) } if (j.m_auxDiff.check_pow(h)) { - // TODO + for (const AuxChainData& aux_data : j.m_auxChains) { + if (aux_data.difficulty.check_pow(h)) { + m_pool->submit_aux_block_async(aux_data, j.m_templateId, j.m_nonce, j.m_extraNonce); + } + } } if (j.m_sidechainDiff.check_pow(h)) { diff --git a/src/miner.h b/src/miner.h index 4153d98..4901456 100644 --- a/src/miner.h +++ b/src/miner.h @@ -76,6 +76,7 @@ private: size_t m_nonceOffset = 0; uint32_t m_nonce = 0; uint32_t m_extraNonce = 0; + std::vector m_auxChains = {}; void set_nonce(uint32_t nonce, uint32_t extra_nonce); }; diff --git a/src/p2pool.cpp b/src/p2pool.cpp index 7275104..9f7a139 100644 --- a/src/p2pool.cpp +++ b/src/p2pool.cpp @@ -136,6 +136,7 @@ p2pool::p2pool(int argc, char* argv[]) uv_mutex_init_checked(&m_minerLock); #endif uv_mutex_init_checked(&m_submitBlockDataLock); + uv_mutex_init_checked(&m_submitAuxBlockDataLock); m_api = p->m_apiPath.empty() ? nullptr : new p2pool_api(p->m_apiPath, p->m_localStats); @@ -200,6 +201,7 @@ p2pool::~p2pool() uv_mutex_destroy(&m_minerLock); #endif uv_mutex_destroy(&m_submitBlockDataLock); + uv_mutex_destroy(&m_submitAuxBlockDataLock); delete m_api; delete m_sideChain; @@ -588,6 +590,17 @@ void p2pool::submit_block_async(std::vector&& blob) } } +void p2pool::submit_aux_block_async(const AuxChainData& aux_data, uint32_t template_id, uint32_t nonce, uint32_t extra_nonce) +{ + // TODO + MutexLock lock(m_submitAuxBlockDataLock); + + (void)aux_data; + (void)template_id; + (void)nonce; + (void)extra_nonce; +} + bool init_signals(p2pool* pool, bool init); void p2pool::on_stop(uv_async_t* async) diff --git a/src/p2pool.h b/src/p2pool.h index 3cccabd..ba942e4 100644 --- a/src/p2pool.h +++ b/src/p2pool.h @@ -86,6 +86,9 @@ public: void submit_block_async(uint32_t template_id, uint32_t nonce, uint32_t extra_nonce); void submit_block_async(std::vector&& blob); + + void submit_aux_block_async(const AuxChainData& aux_data, uint32_t template_id, uint32_t nonce, uint32_t extra_nonce); + bool submit_sidechain_block(uint32_t template_id, uint32_t nonce, uint32_t extra_nonce); void update_block_template_async(bool is_alternative_block = false); @@ -214,6 +217,8 @@ private: mutable uv_mutex_t m_submitBlockDataLock; SubmitBlockData m_submitBlockData; + uv_mutex_t m_submitAuxBlockDataLock; + uv_async_t m_submitBlockAsync; uv_async_t m_blockTemplateAsync; uv_async_t m_stopAsync; diff --git a/src/stratum_server.cpp b/src/stratum_server.cpp index 4f98c57..e47e0f0 100644 --- a/src/stratum_server.cpp +++ b/src/stratum_server.cpp @@ -401,7 +401,11 @@ bool StratumServer::on_submit(StratumClient* client, uint32_t id, const char* jo } if (aux_diff.check_pow(resultHash)) { - // TODO + for (const AuxChainData& aux_data : block.get_aux_chains(template_id)) { + if (aux_data.difficulty.check_pow(resultHash)) { + m_pool->submit_aux_block_async(aux_data, template_id, nonce, extra_nonce); + } + } } SubmittedShare* share;