diff --git a/src/common.h b/src/common.h index 7a9f895..8e433ed 100644 --- a/src/common.h +++ b/src/common.h @@ -148,6 +148,9 @@ struct hash const uint64_t* a = reinterpret_cast(h); return (a[0] == 0) && (a[1] == 0) && (a[2] == 0) && (a[3] == 0); } + + friend std::ostream& operator<<(std::ostream& s, const hash& d); + friend std::istream& operator>>(std::istream& s, hash& d); }; static_assert(sizeof(hash) == HASH_SIZE, "struct hash has invalid size, check your compiler options"); diff --git a/src/log.h b/src/log.h index 5b9db9f..53e481b 100644 --- a/src/log.h +++ b/src/log.h @@ -35,7 +35,7 @@ struct Stream enum params : int { BUF_SIZE = 1024 - 1 }; explicit FORCEINLINE Stream(char* buf) : m_pos(0), m_numberWidth(1), m_buf(buf), m_bufSize(BUF_SIZE) {} - FORCEINLINE Stream(char* buf, size_t size) : m_pos(0), m_numberWidth(1), m_buf(buf), m_bufSize(static_cast(size)) {} + FORCEINLINE Stream(char* buf, size_t size) : m_pos(0), m_numberWidth(1), m_buf(buf), m_bufSize(static_cast(size) - 1) {} template struct Entry diff --git a/src/p2pool.cpp b/src/p2pool.cpp index 04ff054..71c1701 100644 --- a/src/p2pool.cpp +++ b/src/p2pool.cpp @@ -585,6 +585,10 @@ void p2pool::get_info() f >> height; if (f.eof()) break; + hash id; + f >> id; + if (f.eof()) break; + difficulty_type block_difficulty; f >> block_difficulty; if (f.eof()) break; @@ -592,7 +596,7 @@ void p2pool::get_info() difficulty_type cumulative_difficulty; f >> cumulative_difficulty; - m_foundBlocks.emplace_back(timestamp, height, block_difficulty, cumulative_difficulty); + m_foundBlocks.emplace_back(timestamp, height, id, block_difficulty, cumulative_difficulty); } api_update_block_found(nullptr); } @@ -884,9 +888,9 @@ void p2pool::api_update_block_found(const ChainMain* data) { MutexLock lock(m_foundBlocksLock); if (data) { - m_foundBlocks.emplace_back(cur_time, data->height, diff, total_hashes); + m_foundBlocks.emplace_back(cur_time, data->height, data->id, diff, total_hashes); } - found_blocks.assign(m_foundBlocks.end() - std::min(m_foundBlocks.size(), 100), m_foundBlocks.end()); + found_blocks.assign(m_foundBlocks.end() - std::min(m_foundBlocks.size(), 50), m_foundBlocks.end()); } m_api->set(p2pool_api::Category::POOL, "blocks", @@ -899,6 +903,7 @@ void p2pool::api_update_block_found(const ChainMain* data) s << ','; } s << "{\"height\":" << i->height << ',' + << "\"hash\":\"" << i->id << "\"," << "\"difficulty\":" << i->block_diff << ',' << "\"totalHashes\":" << i->total_hashes << ',' << "\"ts\":" << i->timestamp << '}'; diff --git a/src/p2pool.h b/src/p2pool.h index 0d1820c..e156a1e 100644 --- a/src/p2pool.h +++ b/src/p2pool.h @@ -119,15 +119,17 @@ private: struct FoundBlock { - FORCEINLINE FoundBlock(time_t _t, uint64_t _h, const difficulty_type& _block_diff, const difficulty_type& _total_hashes) + FORCEINLINE FoundBlock(time_t _t, uint64_t _h, const hash& _id, const difficulty_type& _block_diff, const difficulty_type& _total_hashes) : timestamp(_t) , height(_h) + , id(_id) , block_diff(_block_diff) , total_hashes(_total_hashes) {} time_t timestamp; uint64_t height; + hash id; difficulty_type block_diff; difficulty_type total_hashes; }; diff --git a/src/util.cpp b/src/util.cpp index 46558ab..fb65741 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -155,6 +155,40 @@ std::istream& operator>>(std::istream& s, difficulty_type& diff) return s; } +std::ostream& operator<<(std::ostream& s, const hash& h) +{ + char buf[log::Stream::BUF_SIZE + 1]; + log::Stream s1(buf); + s1 << h << '\0'; + s << buf; + return s; +} + +std::istream& operator>>(std::istream& s, hash& h) +{ + memset(h.h, 0, HASH_SIZE); + + bool found_number = false; + uint32_t index = 0; + char c; + while (s.good() && !s.eof()) { + s.read(&c, 1); + if (!s.good() || s.eof()) { + break; + } + uint8_t digit; + if (from_hex(c, digit)) { + found_number = true; + h.h[index >> 1] = (h.h[index >> 1] << 4) | digit; + ++index; + } + else if (found_number) { + return s; + } + } + return s; +} + void uv_mutex_init_checked(uv_mutex_t* mutex) { const int result = uv_mutex_init(mutex); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 61c59f7..3b2d06b 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -60,6 +60,7 @@ set(HEADERS set(SOURCES src/crypto_tests.cpp src/difficulty_type_tests.cpp + src/hash_tests.cpp src/keccak_tests.cpp src/main.cpp src/wallet_tests.cpp diff --git a/tests/src/hash_tests.cpp b/tests/src/hash_tests.cpp new file mode 100644 index 0000000..525fa84 --- /dev/null +++ b/tests/src/hash_tests.cpp @@ -0,0 +1,72 @@ +/* + * This file is part of the Monero P2Pool + * Copyright (c) 2021 SChernykh + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "common.h" +#include "gtest/gtest.h" +#include +#include + +namespace p2pool { + +TEST(hash, constructor) +{ + hash h; + uint8_t buf[HASH_SIZE]{}; + ASSERT_EQ(memcmp(h.h, buf, HASH_SIZE), 0); +} + +TEST(hash, empty) +{ + hash h; + ASSERT_EQ(h.empty(), true); + + for (int i = 0; i < HASH_SIZE; ++i) { + hash h2; + h2.h[i] = 1; + ASSERT_EQ(h2.empty(), false); + } +} + +TEST(hash, input_output) +{ + auto check = [](const hash& h, const char* s) { + std::stringstream ss; + ss << h; + ASSERT_EQ(ss.str(), s); + hash h2; + ss >> h2; + ASSERT_EQ(h2, h); + }; + + hash h; + check(h, "0000000000000000000000000000000000000000000000000000000000000000"); + + memset(h.h, -1, HASH_SIZE); + check(h, "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); + + for (uint8_t i = 0; i < HASH_SIZE; ++i) { + h.h[i] = i; + } + check(h, "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"); + + for (uint8_t i = 0; i < HASH_SIZE; ++i) { + h.h[i] = 0xff - i; + } + check(h, "fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0efeeedecebeae9e8e7e6e5e4e3e2e1e0"); +} + +}