Tari merge mining: added more checks

This commit is contained in:
SChernykh
2025-05-15 12:12:12 +02:00
parent 293c6f3930
commit 604ef13aa6
2 changed files with 55 additions and 7 deletions
+46 -6
View File
@@ -34,6 +34,8 @@ namespace p2pool {
MergeMiningClientTari::MergeMiningClientTari(p2pool* pool, std::string host, const std::string& wallet) MergeMiningClientTari::MergeMiningClientTari(p2pool* pool, std::string host, const std::string& wallet)
: m_chainParams{} : m_chainParams{}
, m_previousAuxHashes{}
, m_previousAuxHashesIndex(0)
, m_auxWallet(wallet) , m_auxWallet(wallet)
, m_pool(pool) , m_pool(pool)
, m_tariJobParams{} , m_tariJobParams{}
@@ -140,12 +142,22 @@ bool MergeMiningClientTari::get_params(ChainParameters& out_params) const
void MergeMiningClientTari::on_external_block(const PoolBlock& block) void MergeMiningClientTari::on_external_block(const PoolBlock& block)
{ {
// Sanity check // Sanity check
if (block.m_transactions.empty() || (block.m_hashingBlob.size() > 128)) { if (block.m_transactions.empty() || block.m_hashingBlob.empty() || (block.m_hashingBlob.size() > 128)) {
LOGWARN(3, "on_external_block: sanity check failed - " << block.m_transactions.size() << " transactions, hashing blob size = " << block.m_hashingBlob.size());
return; return;
} }
ChainParameters chain_params;
uint64_t previous_aux_hashes[NUM_PREVIOUS_HASHES];
{
ReadLock lock(m_chainParamsLock);
chain_params = m_chainParams;
memcpy(previous_aux_hashes, m_previousAuxHashes, sizeof(m_previousAuxHashes));
}
// Don't continue if our aux chain is not there // Don't continue if our aux chain is not there
if (block.m_mergeMiningExtra.find(m_chainParams.aux_id) == block.m_mergeMiningExtra.end()) { if (block.m_mergeMiningExtra.find(chain_params.aux_id) == block.m_mergeMiningExtra.end()) {
return; return;
} }
@@ -165,6 +177,7 @@ void MergeMiningClientTari::on_external_block(const PoolBlock& block)
const uint8_t* e = v.data() + v.size(); const uint8_t* e = v.data() + v.size();
if (p + HASH_SIZE > e) { if (p + HASH_SIZE > e) {
LOGWARN(3, "on_external_block: sanity check failed - invalid merge mining extra data " << '1');
return; return;
} }
@@ -175,20 +188,32 @@ void MergeMiningClientTari::on_external_block(const PoolBlock& block)
difficulty_type diff; difficulty_type diff;
p = readVarint(p, e, diff.lo); p = readVarint(p, e, diff.lo);
if (!p) { if (!p) {
LOGWARN(3, "on_external_block: sanity check failed - invalid merge mining extra data " << '2');
return; return;
} }
p = readVarint(p, e, diff.hi); p = readVarint(p, e, diff.hi);
if (!p) { if (!p) {
LOGWARN(3, "on_external_block: sanity check failed - invalid merge mining extra data " << '3');
return; return;
} }
// If it's our aux chain, check that it's the same job and that there is enough PoW // If it's our aux chain, check that it's the same job and that there is enough PoW
if (i.first == m_chainParams.aux_id) { if (i.first == chain_params.aux_id) {
if ((data != m_chainParams.aux_hash) || (diff != m_chainParams.aux_diff)) { if ((data != chain_params.aux_hash) || (diff != chain_params.aux_diff)) {
const uint64_t* a = previous_aux_hashes;
const uint64_t* b = previous_aux_hashes + NUM_PREVIOUS_HASHES;
if (std::find(a, b, *data.u64()) == b) {
LOGWARN(4, "External aux job solution found, but it's not our");
}
else {
LOGWARN(3, "External aux job solution found, but it's stale"); LOGWARN(3, "External aux job solution found, but it's stale");
}
return; return;
} }
if (!diff.check_pow(block.m_powHash)) { if (!diff.check_pow(block.m_powHash)) {
LOGINFO(3, "External aux job solution found, but it doesn't have enough PoW"); LOGINFO(3, "External aux job solution found, but it doesn't have enough PoW");
return; return;
@@ -201,7 +226,7 @@ void MergeMiningClientTari::on_external_block(const PoolBlock& block)
aux_ids.emplace_back(m_pool->side_chain().consensus_hash()); aux_ids.emplace_back(m_pool->side_chain().consensus_hash());
LOGINFO(3, log::LightGreen() << "External aux job solution found. Processing it!"); LOGINFO(0, log::LightGreen() << "External aux job solution found. Processing it!");
// coinbase_merkle_proof // coinbase_merkle_proof
@@ -257,10 +282,22 @@ void MergeMiningClientTari::on_external_block(const PoolBlock& block)
for (const AuxChainData& aux_data : aux_chains) { for (const AuxChainData& aux_data : aux_chains) {
const uint32_t aux_slot = get_aux_slot(aux_data.unique_id, aux_nonce, n_aux_chains); const uint32_t aux_slot = get_aux_slot(aux_data.unique_id, aux_nonce, n_aux_chains);
if (!hashes[aux_slot].empty()) {
LOGWARN(3, "on_external_block: found an incorrect aux_nonce " << '1');
return;
}
hashes[aux_slot] = aux_data.data; hashes[aux_slot] = aux_data.data;
} }
const uint32_t aux_slot = get_aux_slot(m_pool->side_chain().consensus_hash(), aux_nonce, n_aux_chains); const uint32_t aux_slot = get_aux_slot(m_pool->side_chain().consensus_hash(), aux_nonce, n_aux_chains);
if (!hashes[aux_slot].empty()) {
LOGWARN(3, "on_external_block: found an incorrect aux_nonce " << '2');
return;
}
hashes[aux_slot] = sidechain_id; hashes[aux_slot] = sidechain_id;
merkle_hash_full_tree(hashes, tree); merkle_hash_full_tree(hashes, tree);
@@ -270,7 +307,7 @@ void MergeMiningClientTari::on_external_block(const PoolBlock& block)
return; return;
} }
if (!get_merkle_proof(tree, m_chainParams.aux_hash, aux_merkle_proof, aux_merkle_proof_path)) { if (!get_merkle_proof(tree, chain_params.aux_hash, aux_merkle_proof, aux_merkle_proof_path)) {
LOGWARN(3, "on_external_block: get_merkle_proof failed for the aux hash"); LOGWARN(3, "on_external_block: get_merkle_proof failed for the aux hash");
return; return;
} }
@@ -606,7 +643,10 @@ void MergeMiningClientTari::run()
chain_id = m_chainParams.aux_id; chain_id = m_chainParams.aux_id;
m_previousAuxHashes[(m_previousAuxHashesIndex++) % NUM_PREVIOUS_HASHES] = *m_chainParams.aux_hash.u64();
std::copy(mm_hash.begin(), mm_hash.end(), m_chainParams.aux_hash.h); std::copy(mm_hash.begin(), mm_hash.end(), m_chainParams.aux_hash.h);
m_chainParams.aux_diff = static_cast<difficulty_type>(response.miner_data().target_difficulty()); m_chainParams.aux_diff = static_cast<difficulty_type>(response.miner_data().target_difficulty());
m_tariBlock = response.block(); m_tariBlock = response.block();
+8
View File
@@ -42,6 +42,14 @@ public:
private: private:
mutable uv_rwlock_t m_chainParamsLock; mutable uv_rwlock_t m_chainParamsLock;
ChainParameters m_chainParams; ChainParameters m_chainParams;
enum {
NUM_PREVIOUS_HASHES = 8,
};
uint64_t m_previousAuxHashes[NUM_PREVIOUS_HASHES];
uint32_t m_previousAuxHashesIndex;
tari::rpc::Block m_tariBlock; tari::rpc::Block m_tariBlock;
std::string m_auxWallet; std::string m_auxWallet;