diff --git a/src/block_template.cpp b/src/block_template.cpp index 7c743d8..7cdb84a 100644 --- a/src/block_template.cpp +++ b/src/block_template.cpp @@ -27,7 +27,6 @@ #include "p2pool.h" #include "side_chain.h" #include "pool_block.h" -#include "params.h" #include "merkle.h" #include #include @@ -205,7 +204,7 @@ void BlockTemplate::shuffle_tx_order() } } -void BlockTemplate::update(const MinerData& data, const Mempool& mempool, const Wallet* miner_wallet) +void BlockTemplate::update(const MinerData& data, const Mempool& mempool, const Wallet* miner_wallet, const Wallet* subaddress) { if (data.major_version > HARDFORK_SUPPORTED_VERSION) { LOGERR(1, "got hardfork version " << data.major_version << ", expected <= " << HARDFORK_SUPPORTED_VERSION); @@ -626,6 +625,17 @@ void BlockTemplate::update(const MinerData& data, const Mempool& mempool, const m_poolBlockTemplate->m_mergeMiningExtra.emplace(c.unique_id, std::move(v)); } + if (subaddress->valid()) { + std::vector v; + v.reserve(HASH_SIZE + 1); + + const hash& key = subaddress->view_public_key(); + v.insert(v.end(), key.h, key.h + HASH_SIZE); + v.insert(v.end(), 0); + + m_poolBlockTemplate->m_mergeMiningExtra.emplace(keccak_subaddress_viewpub, std::move(v)); + } + init_merge_mining_merkle_proof(); const std::vector sidechain_data = m_poolBlockTemplate->serialize_sidechain_data(); diff --git a/src/block_template.h b/src/block_template.h index 8e61386..2a1f7e9 100644 --- a/src/block_template.h +++ b/src/block_template.h @@ -39,7 +39,7 @@ public: BlockTemplate(const BlockTemplate& b); BlockTemplate& operator=(const BlockTemplate& b); - void update(const MinerData& data, const Mempool& mempool, const Wallet* miner_wallet); + void update(const MinerData& data, const Mempool& mempool, const Wallet* miner_wallet, const Wallet* subaddress); uint64_t last_updated() const { return m_lastUpdated.load(); } bool get_difficulties(const uint32_t template_id, uint64_t& height, uint64_t& sidechain_height, difficulty_type& mainchain_difficulty, difficulty_type& aux_diff, difficulty_type& sidechain_difficulty) const; diff --git a/src/keccak.h b/src/keccak.h index 3b18993..e97b297 100644 --- a/src/keccak.h +++ b/src/keccak.h @@ -29,6 +29,9 @@ extern const uint64_t keccakf_rndc[24]; // keccak hash of a single 0x00 byte constexpr hash keccak_0x00{ 0xbc, 0x36, 0x78, 0x9e, 0x7a, 0x1e, 0x28, 0x14, 0x36, 0x46, 0x42, 0x29, 0x82, 0x8f, 0x81, 0x7d, 0x66, 0x12, 0xf7, 0xb4, 0x77, 0xd6, 0x65, 0x91, 0xff, 0x96, 0xa9, 0xe0, 0x64, 0xbc, 0xc9, 0x8a }; +// keccak hash of "subaddress_viewpub" +constexpr hash keccak_subaddress_viewpub{ 0x40, 0xb2, 0x0e, 0x14, 0xc5, 0x9e, 0xdc, 0x32, 0x57, 0xb1, 0x71, 0xb0, 0xf3, 0x76, 0x27, 0x01, 0x8e, 0x92, 0x45, 0xed, 0xd5, 0x2a, 0x69, 0x0b, 0xf6, 0xd9, 0xe6, 0x21, 0xa0, 0x98, 0xb9, 0x6a }; + typedef void (*keccakf_func)(std::array&); extern keccakf_func keccakf; diff --git a/src/merge_mining_client_tari.cpp b/src/merge_mining_client_tari.cpp index 9384ac9..ad3c8e6 100644 --- a/src/merge_mining_client_tari.cpp +++ b/src/merge_mining_client_tari.cpp @@ -235,16 +235,26 @@ void MergeMiningClientTari::on_external_block(const PoolBlock& block) return; } + std::vector>> mm_extra; + mm_extra.reserve(block.m_mergeMiningExtra.size()); + + // Filter aux chain data only + for (const auto& i : block.m_mergeMiningExtra) { + if (i.first != keccak_subaddress_viewpub) { + mm_extra.emplace_back(i.first, i.second); + } + } + std::vector aux_ids; std::vector aux_chains; // All aux chains in this block + the P2Pool sidechain - aux_ids.reserve(block.m_mergeMiningExtra.size() + 1); + aux_ids.reserve(mm_extra.size() + 1); // All aux chains in this block - aux_chains.reserve(block.m_mergeMiningExtra.size()); + aux_chains.reserve(mm_extra.size()); - for (const auto& i : block.m_mergeMiningExtra) { + for (const auto& i : mm_extra) { const std::vector& v = i.second; const uint8_t* p = v.data(); @@ -356,7 +366,7 @@ void MergeMiningClientTari::on_external_block(const PoolBlock& block) uint32_t aux_merkle_proof_path = 0; const hash sidechain_id = block.m_sidechainId; - const uint32_t n_aux_chains = static_cast(block.m_mergeMiningExtra.size() + 1); + const uint32_t n_aux_chains = static_cast(mm_extra.size() + 1); std::vector hashes(n_aux_chains); diff --git a/src/p2pool.cpp b/src/p2pool.cpp index 3fe99cb..4d648fb 100644 --- a/src/p2pool.cpp +++ b/src/p2pool.cpp @@ -1240,7 +1240,7 @@ void p2pool::update_block_template() if (m_updateSeed.exchange(false)) { m_hasher->set_seed_async(data.seed_hash); } - m_blockTemplate->update(data, *m_mempool, &m_params->m_miningWallet); + m_blockTemplate->update(data, *m_mempool, &m_params->m_miningWallet, &m_params->m_subaddress); stratum_on_block(); api_update_pool_stats(); diff --git a/src/pool_block.h b/src/pool_block.h index 95a0f9a..7ac884b 100644 --- a/src/pool_block.h +++ b/src/pool_block.h @@ -143,8 +143,15 @@ struct PoolBlock uint32_t m_merkleProofPath; // Merge mining extra data + // // Format: vector of (chain ID, chain data) pairs + // // Chain data always has merge mining hash and difficulty in the beginning, the rest is arbitrary and depends on the merge mined chain's requirements + // + // Some chain IDs are used for other purposes: + // + // - keccak("subaddress_viewpub") stores the public viewkey part of the subaddress, if it's used for mining ("merge mining hash" = viewkey, "difficulty" = 0) + // std::map> m_mergeMiningExtra; // Arbitrary extra data