mirror of
https://github.com/SChernykh/p2pool.git
synced 2025-01-03 09:19:24 +00:00
Added a check for unstable hardware
This commit is contained in:
parent
5c67f0df20
commit
bb80fe12a0
9 changed files with 36 additions and 16 deletions
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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];
|
||||||
|
|
Loading…
Reference in a new issue