Added a check for unstable hardware

pull/253/head
SChernykh 2023-03-28 10:14:47 +02:00
parent 5c67f0df20
commit bb80fe12a0
9 changed files with 36 additions and 16 deletions

View File

@ -219,9 +219,9 @@ p2pool::~p2pool()
delete m_params; delete m_params;
} }
bool p2pool::calculate_hash(const void* data, size_t size, uint64_t height, const hash& seed, hash& result) bool p2pool::calculate_hash(const void* data, size_t size, uint64_t height, const hash& seed, hash& result, bool force_light_mode)
{ {
return m_hasher->calculate(data, size, height, seed, result); return m_hasher->calculate(data, size, height, seed, result, force_light_mode);
} }
uint64_t p2pool::get_seed_height(uint64_t height) uint64_t p2pool::get_seed_height(uint64_t height)

View File

@ -60,7 +60,7 @@ public:
p2pool_api* api() const { return m_api; } p2pool_api* api() const { return m_api; }
RandomX_Hasher_Base* hasher() const { return m_hasher; } RandomX_Hasher_Base* hasher() const { return m_hasher; }
bool calculate_hash(const void* data, size_t size, uint64_t height, const hash& seed, hash& result); bool calculate_hash(const void* data, size_t size, uint64_t height, const hash& seed, hash& result, bool force_light_mode);
static uint64_t get_seed_height(uint64_t height); static uint64_t get_seed_height(uint64_t height);
bool get_seed(uint64_t height, hash& seed) const; bool get_seed(uint64_t height, hash& seed) const;

View File

@ -271,7 +271,7 @@ void PoolBlock::reset_offchain_data()
m_receivedTimestamp = 0; m_receivedTimestamp = 0;
} }
bool PoolBlock::get_pow_hash(RandomX_Hasher_Base* hasher, uint64_t height, const hash& seed_hash, hash& pow_hash) bool PoolBlock::get_pow_hash(RandomX_Hasher_Base* hasher, uint64_t height, const hash& seed_hash, hash& pow_hash, bool force_light_mode)
{ {
alignas(8) uint8_t hashes[HASH_SIZE * 3]; alignas(8) uint8_t hashes[HASH_SIZE * 3];
@ -349,7 +349,7 @@ bool PoolBlock::get_pow_hash(RandomX_Hasher_Base* hasher, uint64_t height, const
writeVarint(count, [&blob, &blob_size](uint8_t b) { blob[blob_size++] = b; }); writeVarint(count, [&blob, &blob_size](uint8_t b) { blob[blob_size++] = b; });
return hasher->calculate(blob, blob_size, height, seed_hash, pow_hash); return hasher->calculate(blob, blob_size, height, seed_hash, pow_hash, force_light_mode);
} }
uint64_t PoolBlock::get_payout(const Wallet& w) const uint64_t PoolBlock::get_payout(const Wallet& w) const

View File

@ -141,7 +141,7 @@ struct PoolBlock
int deserialize(const uint8_t* data, size_t size, const SideChain& sidechain, uv_loop_t* loop, bool compact); int deserialize(const uint8_t* data, size_t size, const SideChain& sidechain, uv_loop_t* loop, bool compact);
void reset_offchain_data(); void reset_offchain_data();
bool get_pow_hash(RandomX_Hasher_Base* hasher, uint64_t height, const hash& seed_hash, hash& pow_hash); bool get_pow_hash(RandomX_Hasher_Base* hasher, uint64_t height, const hash& seed_hash, hash& pow_hash, bool force_light_mode = false);
uint64_t get_payout(const Wallet& w) const; uint64_t get_payout(const Wallet& w) const;

View File

@ -322,10 +322,10 @@ void RandomX_Hasher::sync_wait()
ReadLock lock2(m_cacheLock); ReadLock lock2(m_cacheLock);
} }
bool RandomX_Hasher::calculate(const void* data, size_t size, uint64_t /*height*/, const hash& seed, hash& result) bool RandomX_Hasher::calculate(const void* data, size_t size, uint64_t /*height*/, const hash& seed, hash& result, bool force_light_mode)
{ {
// First try to use the dataset if it's ready // First try to use the dataset if it's ready
if (uv_rwlock_tryrdlock(&m_datasetLock) == 0) { if (!force_light_mode && (uv_rwlock_tryrdlock(&m_datasetLock) == 0)) {
ON_SCOPE_LEAVE([this]() { uv_rwlock_rdunlock(&m_datasetLock); }); ON_SCOPE_LEAVE([this]() { uv_rwlock_rdunlock(&m_datasetLock); });
if (m_stopped.load()) { if (m_stopped.load()) {
@ -340,7 +340,7 @@ bool RandomX_Hasher::calculate(const void* data, size_t size, uint64_t /*height*
} }
} }
// If dataset is not ready, use the cache and wait if necessary // If dataset is not ready, or force_light_mode = true, use the cache and wait if necessary
ReadLock lock(m_cacheLock); ReadLock lock(m_cacheLock);
if (m_stopped.load()) { if (m_stopped.load()) {
@ -429,7 +429,7 @@ void RandomX_Hasher_RPC::loop(void* data)
LOGINFO(1, "event loop stopped"); LOGINFO(1, "event loop stopped");
} }
bool RandomX_Hasher_RPC::calculate(const void* data_ptr, size_t size, uint64_t height, const hash& /*seed*/, hash& h) bool RandomX_Hasher_RPC::calculate(const void* data_ptr, size_t size, uint64_t height, const hash& /*seed*/, hash& h, bool /*force_light_mode*/)
{ {
MutexLock lock(m_requestMutex); MutexLock lock(m_requestMutex);

View File

@ -40,7 +40,7 @@ public:
virtual uint32_t seed_counter() const { return 0; } virtual uint32_t seed_counter() const { return 0; }
virtual void sync_wait() {} virtual void sync_wait() {}
virtual bool calculate(const void* data, size_t size, uint64_t height, const hash& seed, hash& result) = 0; virtual bool calculate(const void* data, size_t size, uint64_t height, const hash& seed, hash& result, bool force_light_mode) = 0;
}; };
#ifdef WITH_RANDOMX #ifdef WITH_RANDOMX
@ -60,7 +60,7 @@ public:
uint32_t seed_counter() const override { return m_seedCounter.load(); } uint32_t seed_counter() const override { return m_seedCounter.load(); }
void sync_wait() override; void sync_wait() override;
bool calculate(const void* data, size_t size, uint64_t height, const hash& seed, hash& result) override; bool calculate(const void* data, size_t size, uint64_t height, const hash& seed, hash& result, bool force_light_mode) override;
private: private:
@ -100,7 +100,7 @@ public:
explicit RandomX_Hasher_RPC(p2pool* pool); explicit RandomX_Hasher_RPC(p2pool* pool);
~RandomX_Hasher_RPC(); ~RandomX_Hasher_RPC();
bool calculate(const void* data_ptr, size_t size, uint64_t height, const hash& seed, hash& h) override; bool calculate(const void* data_ptr, size_t size, uint64_t height, const hash& seed, hash& h, bool force_light_mode) override;
private: private:
static void loop(void* data); static void loop(void* data);

View File

@ -570,7 +570,20 @@ bool SideChain::add_external_block(PoolBlock& block, std::vector<hash>& missing_
} }
if (!block.m_difficulty.check_pow(pow_hash)) { if (!block.m_difficulty.check_pow(pow_hash)) {
LOGWARN(3, "add_external_block mined by " << block.m_minerWallet << ": not enough PoW for height = " << block.m_sidechainHeight << ", mainchain height " << block.m_txinGenHeight); LOGWARN(3,
"add_external_block mined by " << block.m_minerWallet <<
": not enough PoW for height = " << block.m_sidechainHeight <<
", id = " << block.m_sidechainId <<
", nonce = " << block.m_nonce <<
", mainchain height = " << block.m_txinGenHeight
);
// Calculate the same hash second time to check if it's an unstable hardware that caused this
hash pow_hash2;
if (block.get_pow_hash(m_pool->hasher(), block.m_txinGenHeight, seed, pow_hash2, true) && (pow_hash2 != pow_hash)) {
LOGERR(0, "UNSTABLE HARDWARE DETECTED: Calculated the same hash twice, got different results: " << pow_hash << " != " << pow_hash2 << " (sidechain id = " << block.m_sidechainId << ')');
}
return false; return false;
} }

View File

@ -881,7 +881,7 @@ void StratumServer::on_share_found(uv_work_t* req)
} }
hash pow_hash; hash pow_hash;
if (!pool->calculate_hash(blob, blob_size, height, seed_hash, pow_hash)) { if (!pool->calculate_hash(blob, blob_size, height, seed_hash, pow_hash, false)) {
LOGWARN(3, "client " << static_cast<char*>(client->m_addrString) << " couldn't check share PoW"); LOGWARN(3, "client " << static_cast<char*>(client->m_addrString) << " couldn't check share PoW");
share->m_result = SubmittedShare::Result::COULDNT_CHECK_POW; share->m_result = SubmittedShare::Result::COULDNT_CHECK_POW;
return; return;
@ -891,6 +891,13 @@ void StratumServer::on_share_found(uv_work_t* req)
LOGWARN(4, "client " << static_cast<char*>(client->m_addrString) << " submitted a share with invalid PoW"); LOGWARN(4, "client " << static_cast<char*>(client->m_addrString) << " submitted a share with invalid PoW");
share->m_result = SubmittedShare::Result::INVALID_POW; share->m_result = SubmittedShare::Result::INVALID_POW;
share->m_score = BAD_SHARE_POINTS; share->m_score = BAD_SHARE_POINTS;
// Calculate the same hash second time to check if it's an unstable hardware that caused this
hash pow_hash2;
if (pool->calculate_hash(blob, blob_size, height, seed_hash, pow_hash2, true) && (pow_hash2 != pow_hash)) {
LOGERR(0, "UNSTABLE HARDWARE DETECTED: Calculated the same hash twice, got different results: " << pow_hash << " != " << pow_hash2);
}
return; return;
} }

View File

@ -87,7 +87,7 @@ TEST(pool_block, deserialize)
class RandomX_Hasher_Test : public RandomX_Hasher_Base class RandomX_Hasher_Test : public RandomX_Hasher_Base
{ {
public: public:
bool calculate(const void* data, size_t size, uint64_t, const hash&, hash& result) override bool calculate(const void* data, size_t size, uint64_t, const hash&, hash& result, bool force_light_mode) override
{ {
if (size == 76) { if (size == 76) {
char buf[76 * 2 + 1]; char buf[76 * 2 + 1];