mirror of
https://github.com/SChernykh/p2pool.git
synced 2024-12-22 11:29:23 +00:00
api: store difficulty and totalHashes for each block
This commit is contained in:
parent
2d8530798d
commit
661d596107
9 changed files with 122 additions and 18 deletions
|
@ -52,6 +52,7 @@
|
|||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
|
@ -187,6 +188,9 @@ struct difficulty_type
|
|||
FORCEINLINE bool operator==(const difficulty_type& other) const { return (lo == other.lo) && (hi == other.hi); }
|
||||
FORCEINLINE bool operator!=(const difficulty_type& other) const { return (lo != other.lo) || (hi != other.hi); }
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& s, const difficulty_type& d);
|
||||
friend std::istream& operator>>(std::istream& s, difficulty_type& d);
|
||||
|
||||
FORCEINLINE double to_double() const { return static_cast<double>(hi) * 18446744073709551616.0 + static_cast<double>(lo); }
|
||||
|
||||
// Finds a 64-bit target for mining (target = 2^64 / difficulty) and rounds up the result of division
|
||||
|
|
|
@ -29,6 +29,8 @@ namespace log {
|
|||
|
||||
int GLOBAL_LOG_LEVEL = 4;
|
||||
|
||||
#ifndef P2POOL_LOG_DISABLE
|
||||
|
||||
static volatile bool stopped = false;
|
||||
static volatile bool worker_started = false;
|
||||
|
||||
|
@ -234,9 +236,9 @@ private:
|
|||
std::ofstream m_logFile;
|
||||
};
|
||||
|
||||
#ifndef P2POOL_LOG_DISABLE
|
||||
static Worker worker;
|
||||
#endif
|
||||
|
||||
#endif // P2POOL_LOG_DISABLE
|
||||
|
||||
NOINLINE Writer::Writer(Severity severity) : Stream(m_stackBuf)
|
||||
{
|
||||
|
|
|
@ -34,7 +34,8 @@ struct Stream
|
|||
{
|
||||
enum params : int { BUF_SIZE = 1024 - 1 };
|
||||
|
||||
explicit FORCEINLINE Stream(char* buf) : m_pos(0), m_numberWidth(1), m_buf(buf) {}
|
||||
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<int>(size)) {}
|
||||
|
||||
template<typename T>
|
||||
struct Entry
|
||||
|
@ -88,8 +89,8 @@ struct Stream
|
|||
FORCEINLINE void writeBuf(const char* buf, size_t n0)
|
||||
{
|
||||
const int n = static_cast<int>(n0);
|
||||
int pos = m_pos;
|
||||
if (pos > BUF_SIZE - n) {
|
||||
const int pos = m_pos;
|
||||
if (pos + n > m_bufSize) {
|
||||
return;
|
||||
}
|
||||
memcpy(m_buf + pos, buf, n);
|
||||
|
@ -104,6 +105,7 @@ struct Stream
|
|||
int m_pos;
|
||||
int m_numberWidth;
|
||||
char* m_buf;
|
||||
int m_bufSize;
|
||||
};
|
||||
|
||||
struct Writer : public Stream
|
||||
|
|
|
@ -583,8 +583,16 @@ void p2pool::get_info()
|
|||
|
||||
uint64_t height;
|
||||
f >> height;
|
||||
if (f.eof()) break;
|
||||
|
||||
m_foundBlocks.emplace_back(std::make_pair(timestamp, height));
|
||||
difficulty_type block_difficulty;
|
||||
f >> block_difficulty;
|
||||
if (f.eof()) break;
|
||||
|
||||
difficulty_type cumulative_difficulty;
|
||||
f >> cumulative_difficulty;
|
||||
|
||||
m_foundBlocks.emplace_back(timestamp, height, block_difficulty, cumulative_difficulty);
|
||||
}
|
||||
api_update_block_found(nullptr);
|
||||
}
|
||||
|
@ -821,8 +829,8 @@ void p2pool::api_update_pool_stats()
|
|||
MutexLock lock(m_foundBlocksLock);
|
||||
if (!m_foundBlocks.empty()) {
|
||||
total_blocks_found = m_foundBlocks.size();
|
||||
last_block_found_time = m_foundBlocks.back().first;
|
||||
last_block_found_height = m_foundBlocks.back().second;
|
||||
last_block_found_time = m_foundBlocks.back().timestamp;
|
||||
last_block_found_height = m_foundBlocks.back().height;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -846,22 +854,28 @@ void p2pool::api_update_block_found(const ChainMain* data)
|
|||
}
|
||||
|
||||
const time_t cur_time = time(nullptr);
|
||||
const difficulty_type total_hashes = m_sideChain->total_hashes();
|
||||
difficulty_type diff;
|
||||
|
||||
if (data) {
|
||||
{
|
||||
ReadLock lock(m_mainchainLock);
|
||||
diff.lo = m_mainchainByHeight[data->height].difficulty;
|
||||
}
|
||||
|
||||
std::ofstream f(FOUND_BLOCKS_FILE, std::ios::app);
|
||||
if (f.is_open()) {
|
||||
f << cur_time << ' ' << data->height << '\n';
|
||||
f << cur_time << ' ' << data->height << ' ' << diff << ' ' << total_hashes << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::vector<std::pair<time_t, uint64_t>> found_blocks;
|
||||
std::vector<FoundBlock> found_blocks;
|
||||
{
|
||||
MutexLock lock(m_foundBlocksLock);
|
||||
if (data) {
|
||||
m_foundBlocks.emplace_back(std::make_pair(cur_time, data->height));
|
||||
m_foundBlocks.emplace_back(cur_time, data->height, diff, total_hashes);
|
||||
}
|
||||
found_blocks.assign(m_foundBlocks.end() - std::min<size_t>(m_foundBlocks.size(), 25), m_foundBlocks.end());
|
||||
found_blocks.assign(m_foundBlocks.end() - std::min<size_t>(m_foundBlocks.size(), 100), m_foundBlocks.end());
|
||||
}
|
||||
|
||||
m_api->set(p2pool_api::Category::POOL, "blocks",
|
||||
|
@ -873,8 +887,10 @@ void p2pool::api_update_block_found(const ChainMain* data)
|
|||
if (!first) {
|
||||
s << ',';
|
||||
}
|
||||
s << "{\"height\":" << i->second << ',';
|
||||
s << "\"ts\":" << i->first << '}';
|
||||
s << "{\"height\":" << i->height << ','
|
||||
<< "\"difficulty\":" << i->block_diff << ','
|
||||
<< "\"totalHashes\":" << i->total_hashes << ','
|
||||
<< "\"ts\":" << i->timestamp << '}';
|
||||
first = false;
|
||||
}
|
||||
s << ']';
|
||||
|
|
17
src/p2pool.h
17
src/p2pool.h
|
@ -117,8 +117,23 @@ private:
|
|||
void api_update_pool_stats();
|
||||
void api_update_block_found(const ChainMain* data);
|
||||
|
||||
struct FoundBlock
|
||||
{
|
||||
FORCEINLINE FoundBlock(time_t _t, uint64_t _h, const difficulty_type& _block_diff, const difficulty_type& _total_hashes)
|
||||
: timestamp(_t)
|
||||
, height(_h)
|
||||
, block_diff(_block_diff)
|
||||
, total_hashes(_total_hashes)
|
||||
{}
|
||||
|
||||
time_t timestamp;
|
||||
uint64_t height;
|
||||
difficulty_type block_diff;
|
||||
difficulty_type total_hashes;
|
||||
};
|
||||
|
||||
uv_mutex_t m_foundBlocksLock;
|
||||
std::vector<std::pair<time_t, uint64_t>> m_foundBlocks;
|
||||
std::vector<FoundBlock> m_foundBlocks;
|
||||
|
||||
std::atomic<uint32_t> m_serversStarted{ 0 };
|
||||
StratumServer* m_stratumServer = nullptr;
|
||||
|
|
|
@ -94,8 +94,8 @@ void p2pool_api::on_stop()
|
|||
|
||||
void p2pool_api::dump_to_file_async_internal(const Category& category, const char* filename, DumpFileCallbackBase&& callback)
|
||||
{
|
||||
std::vector<char> buf(log::Stream::BUF_SIZE + 1);
|
||||
log::Stream s(buf.data());
|
||||
std::vector<char> buf(16384);
|
||||
log::Stream s(buf.data(), buf.size());
|
||||
callback(s);
|
||||
buf.resize(s.m_pos);
|
||||
|
||||
|
|
|
@ -667,6 +667,7 @@ void SideChain::print_status()
|
|||
|
||||
difficulty_type SideChain::total_hashes() const
|
||||
{
|
||||
MutexLock lock(m_sidechainLock);
|
||||
return m_chainTip ? m_chainTip->m_cumulativeDifficulty : difficulty_type();
|
||||
}
|
||||
|
||||
|
|
38
src/util.cpp
38
src/util.cpp
|
@ -117,6 +117,44 @@ difficulty_type operator+(const difficulty_type& a, const difficulty_type& b)
|
|||
return result;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& s, const difficulty_type& d)
|
||||
{
|
||||
char buf[log::Stream::BUF_SIZE + 1];
|
||||
log::Stream s1(buf);
|
||||
s1 << d << '\0';
|
||||
s << buf;
|
||||
return s;
|
||||
}
|
||||
|
||||
std::istream& operator>>(std::istream& s, difficulty_type& diff)
|
||||
{
|
||||
diff.lo = 0;
|
||||
diff.hi = 0;
|
||||
|
||||
bool found_number = false;
|
||||
char c;
|
||||
while (s.good() && !s.eof()) {
|
||||
s.read(&c, 1);
|
||||
if (!s.good() || s.eof()) {
|
||||
break;
|
||||
}
|
||||
if ('0' <= c && c <= '9') {
|
||||
found_number = true;
|
||||
const uint32_t digit = static_cast<uint32_t>(c - '0');
|
||||
uint64_t hi;
|
||||
diff.lo = umul128(diff.lo, 10, &hi) + digit;
|
||||
if (diff.lo < digit) {
|
||||
++hi;
|
||||
}
|
||||
diff.hi = diff.hi * 10 + hi;
|
||||
}
|
||||
else if (found_number) {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
void uv_mutex_init_checked(uv_mutex_t* mutex)
|
||||
{
|
||||
const int result = uv_mutex_init(mutex);
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "common.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include <random>
|
||||
#include <sstream>
|
||||
|
||||
namespace p2pool {
|
||||
|
||||
|
@ -103,6 +104,31 @@ TEST(difficulty_type, compare)
|
|||
}
|
||||
}
|
||||
|
||||
TEST(difficulty_type, input_output)
|
||||
{
|
||||
auto test_value = [](uint64_t lo, uint64_t hi, const char* s) {
|
||||
difficulty_type diff{ lo, hi };
|
||||
std::stringstream ss;
|
||||
ss << diff;
|
||||
ASSERT_EQ(ss.str(), s);
|
||||
difficulty_type diff2;
|
||||
ss >> diff2;
|
||||
ASSERT_EQ(diff2, diff);
|
||||
};
|
||||
|
||||
test_value(0, 0, "0");
|
||||
test_value(1, 0, "1");
|
||||
test_value(340599339356ull, 0, "340599339356");
|
||||
test_value(std::numeric_limits<uint64_t>::max(), 0, "18446744073709551615");
|
||||
test_value(0, 1, "18446744073709551616");
|
||||
test_value(1, 1, "18446744073709551617");
|
||||
test_value(7766279631452241919ull, 5, "99999999999999999999");
|
||||
test_value(7766279631452241920ull, 5, "100000000000000000000");
|
||||
test_value(7766279631452241921ull, 5, "100000000000000000001");
|
||||
test_value(14083847773837265618ull, 6692605942ull, "123456789012345678901234567890");
|
||||
test_value(std::numeric_limits<uint64_t>::max(), std::numeric_limits<uint64_t>::max(), "340282366920938463463374607431768211455");
|
||||
}
|
||||
|
||||
TEST(difficulty_type, check_pow)
|
||||
{
|
||||
hash h;
|
||||
|
|
Loading…
Reference in a new issue