Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2071a24a9f | |||
| 1c0da4513f | |||
| 6a002cda46 | |||
| c21c9615a3 | |||
| c0c210664a | |||
| 6859d11445 | |||
| 111324b6e0 | |||
| 148b9dd294 | |||
| 04d18cdf1d | |||
| 352ad81a0a | |||
| d26902468d | |||
| 0382027d70 | |||
| 966b499e5c | |||
| 9885f82e9e | |||
| 32a58d1534 | |||
| bc341918f6 |
@@ -0,0 +1,61 @@
|
||||
# This workflow uses actions that are not certified by GitHub.
|
||||
# They are provided by a third-party and are governed by
|
||||
# separate terms of service, privacy policy, and support
|
||||
# documentation.
|
||||
#
|
||||
# Find more information at:
|
||||
# https://github.com/microsoft/msvc-code-analysis-action
|
||||
|
||||
name: Microsoft C++ Code Analysis
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
schedule:
|
||||
- cron: '40 10 * * 0'
|
||||
|
||||
env:
|
||||
# Path to the CMake build directory.
|
||||
build: '${{ github.workspace }}/build'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
submodules: true
|
||||
|
||||
- name: Configure CMake
|
||||
run: cmake -B ${{ env.build }}
|
||||
|
||||
# Build is not required unless generated source files are used
|
||||
# - name: Build CMake
|
||||
# run: cmake --build ${{ env.build }}
|
||||
|
||||
- name: Initialize MSVC Code Analysis
|
||||
uses: microsoft/msvc-code-analysis-action@04825f6d9e00f87422d6bf04e1a38b1f3ed60d99
|
||||
# Provide a unique ID to access the sarif output path
|
||||
id: run-analysis
|
||||
with:
|
||||
cmakeBuildDirectory: ${{ env.build }}
|
||||
# Ruleset file that will determine what checks will be run
|
||||
ruleset: NativeRecommendedRules.ruleset
|
||||
|
||||
# Upload SARIF file to GitHub Code Scanning Alerts
|
||||
- name: Upload SARIF to GitHub
|
||||
uses: github/codeql-action/upload-sarif@v1
|
||||
with:
|
||||
sarif_file: ${{ steps.run-analysis.outputs.sarif }}
|
||||
|
||||
# Upload SARIF file as an Artifact to download and view
|
||||
- name: Upload SARIF as an Artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: sarif-file
|
||||
path: ${{ steps.run-analysis.outputs.sarif }}
|
||||
@@ -19,3 +19,6 @@
|
||||
[submodule "external/src/libzmq"]
|
||||
path = external/src/libzmq
|
||||
url = https://github.com/SChernykh/libzmq
|
||||
[submodule "external/src/robin-hood-hashing"]
|
||||
path = external/src/robin-hood-hashing
|
||||
url = https://github.com/SChernykh/robin-hood-hashing
|
||||
|
||||
@@ -82,6 +82,7 @@ include_directories(external/src/libzmq/include)
|
||||
include_directories(external/src/llhttp)
|
||||
include_directories(external/src/RandomX/src)
|
||||
include_directories(external/src/rapidjson/include)
|
||||
include_directories(external/src/robin-hood-hashing/src/include)
|
||||
|
||||
if (WIN32)
|
||||
set(LIBS ${LIBS} ws2_32 iphlpapi userenv psapi)
|
||||
|
||||
+4
-4
@@ -9,10 +9,10 @@ if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
|
||||
set(WARNING_FLAGS "-Wall -Wextra -Werror")
|
||||
set(OPTIMIZATION_FLAGS "-Ofast -s")
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS}")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS} ${OPTIMIZATION_FLAGS}")
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${WARNING_FLAGS} ${OPTIMIZATION_FLAGS}")
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS} ${OPTIMIZATION_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${WARNING_FLAGS} ${OPTIMIZATION_FLAGS}")
|
||||
|
||||
if (WIN32)
|
||||
@@ -42,9 +42,9 @@ elseif (CMAKE_CXX_COMPILER_ID MATCHES Clang)
|
||||
set(WARNING_FLAGS "-Wall -Wextra -Wno-undefined-internal -Werror")
|
||||
set(OPTIMIZATION_FLAGS "-Ofast -funroll-loops -fmerge-all-constants")
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS}")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS} ${OPTIMIZATION_FLAGS}")
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${WARNING_FLAGS} ${OPTIMIZATION_FLAGS}")
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS} ${OPTIMIZATION_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${WARNING_FLAGS} ${OPTIMIZATION_FLAGS}")
|
||||
endif()
|
||||
|
||||
@@ -7,3 +7,4 @@
|
||||
../external/src/llhttp/
|
||||
../external/src/RandomX/src/
|
||||
../external/src/rapidjson/include
|
||||
../external/src/robin-hood-hashing/src/include
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
#!/bin/bash
|
||||
cppcheck ../src -DZMQ_STATIC --platform=unix64 --std=c++14 --enable=all --inconclusive --inline-suppr --template="{file}:{line}:{id}{inconclusive: INCONCLUSIVE} {message}" -I ../src/ -I ../external/src/ -I ../external/src/cryptonote/ -I ../external/src/libuv/ -I ../external/src/cppzmq/ -I ../external/src/libzmq/ -I ../external/src/llhttp/ -I ../external/src/RandomX/src/ -I ../external/src/rapidjson/include --suppressions-list=suppressions.txt --output-file=errors_full.txt
|
||||
cppcheck ../src -DZMQ_STATIC --platform=unix64 --std=c++14 --enable=all --inconclusive --inline-suppr --template="{file}:{line}:{id}{inconclusive: INCONCLUSIVE} {message}" -I ../src/ -I ../external/src/ -I ../external/src/cryptonote/ -I ../external/src/libuv/ -I ../external/src/cppzmq/ -I ../external/src/libzmq/ -I ../external/src/llhttp/ -I ../external/src/RandomX/src/ -I ../external/src/rapidjson/include -I ../external/src/robin-hood-hashing/src/include --suppressions-list=suppressions.txt --output-file=errors_full.txt
|
||||
grep -v 'external' errors_full.txt | grep -v 'unmatchedSuppression' > errors_filtered.txt
|
||||
if [ -s errors_filtered.txt ]; then
|
||||
cat errors_filtered.txt
|
||||
|
||||
+1
Submodule external/src/robin-hood-hashing added at 668936f62e
@@ -279,6 +279,11 @@ enum class NetworkType {
|
||||
Stagenet,
|
||||
};
|
||||
|
||||
void* malloc_hook(size_t n) noexcept;
|
||||
void* realloc_hook(void* ptr, size_t size) noexcept;
|
||||
void* calloc_hook(size_t count, size_t size) noexcept;
|
||||
void free_hook(void* p) noexcept;
|
||||
|
||||
} // namespace p2pool
|
||||
|
||||
#include "util.h"
|
||||
|
||||
@@ -69,7 +69,7 @@ typedef struct cmd {
|
||||
cmdfunc *func;
|
||||
} cmd;
|
||||
|
||||
static cmdfunc do_help, do_status, do_loglevel, do_addpeers, do_droppeers, do_exit;
|
||||
static cmdfunc do_help, do_status, do_loglevel, do_addpeers, do_droppeers, do_showpeers, do_exit;
|
||||
|
||||
static cmd cmds[] = {
|
||||
{ STRCONST("help"), "", "display list of commands", do_help },
|
||||
@@ -77,6 +77,7 @@ static cmd cmds[] = {
|
||||
{ STRCONST("loglevel"), "<level>", "set log level", do_loglevel },
|
||||
{ STRCONST("addpeers"), "<peeraddr>", "add peer", do_addpeers },
|
||||
{ STRCONST("droppeers"), "", "disconnect all peers", do_droppeers },
|
||||
{ STRCONST("peers"), "", "show all peers", do_showpeers },
|
||||
{ STRCONST("exit"), "", "terminate p2pool", do_exit },
|
||||
{ STRCNULL, NULL, NULL, NULL }
|
||||
};
|
||||
@@ -129,6 +130,14 @@ static int do_droppeers(p2pool *m_pool, const char * /* args */)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_showpeers(p2pool* m_pool, const char* /* args */)
|
||||
{
|
||||
if (m_pool->p2p_server()) {
|
||||
m_pool->p2p_server()->show_peers();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_exit(p2pool *m_pool, const char * /* args */)
|
||||
{
|
||||
bkg_jobs_tracker.wait();
|
||||
|
||||
+2
-3
@@ -20,7 +20,6 @@
|
||||
#include "keccak.h"
|
||||
#include "uv_util.h"
|
||||
#include <random>
|
||||
#include <unordered_map>
|
||||
|
||||
extern "C" {
|
||||
#include "crypto-ops.h"
|
||||
@@ -237,8 +236,8 @@ public:
|
||||
|
||||
private:
|
||||
uv_mutex_t m;
|
||||
std::unordered_map<std::array<uint8_t, HASH_SIZE * 2>, hash> derivations;
|
||||
std::unordered_map<std::array<uint8_t, HASH_SIZE * 2 + sizeof(size_t)>, hash> public_keys;
|
||||
unordered_map<std::array<uint8_t, HASH_SIZE * 2>, hash> derivations;
|
||||
unordered_map<std::array<uint8_t, HASH_SIZE * 2 + sizeof(size_t)>, hash> public_keys;
|
||||
};
|
||||
|
||||
static Cache* cache = nullptr;
|
||||
|
||||
+12
-1
@@ -28,6 +28,7 @@ namespace p2pool {
|
||||
namespace log {
|
||||
|
||||
int GLOBAL_LOG_LEVEL = 3;
|
||||
bool CONSOLE_COLORS = true;
|
||||
|
||||
#ifndef P2POOL_LOG_DISABLE
|
||||
|
||||
@@ -35,6 +36,7 @@ static volatile bool stopped = false;
|
||||
static volatile bool worker_started = false;
|
||||
|
||||
#ifdef _WIN32
|
||||
static const HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE);
|
||||
static const HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
static const HANDLE hStdErr = GetStdHandle(STD_ERROR_HANDLE);
|
||||
#endif
|
||||
@@ -69,6 +71,9 @@ public:
|
||||
|
||||
#ifdef _WIN32
|
||||
DWORD dwConsoleMode;
|
||||
if (GetConsoleMode(hStdIn, &dwConsoleMode)) {
|
||||
SetConsoleMode(hStdIn, dwConsoleMode & ~ENABLE_QUICK_EDIT_MODE);
|
||||
}
|
||||
if (GetConsoleMode(hStdOut, &dwConsoleMode)) {
|
||||
SetConsoleMode(hStdOut, dwConsoleMode | ENABLE_VIRTUAL_TERMINAL_PROCESSING);
|
||||
}
|
||||
@@ -155,6 +160,10 @@ private:
|
||||
p += 3;
|
||||
size -= 3;
|
||||
|
||||
if (!CONSOLE_COLORS) {
|
||||
strip_colors(p, size);
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
DWORD k;
|
||||
WriteConsole((severity == 1) ? hStdOut : hStdErr, p, size, &k, nullptr);
|
||||
@@ -172,7 +181,9 @@ private:
|
||||
}
|
||||
|
||||
if (m_logFile.is_open()) {
|
||||
strip_colors(p, size);
|
||||
if (CONSOLE_COLORS) {
|
||||
strip_colors(p, size);
|
||||
}
|
||||
|
||||
if (severity == 1) {
|
||||
m_logFile.write("NOTICE ", 8);
|
||||
|
||||
@@ -22,6 +22,7 @@ namespace p2pool {
|
||||
namespace log {
|
||||
|
||||
extern int GLOBAL_LOG_LEVEL;
|
||||
extern bool CONSOLE_COLORS;
|
||||
constexpr int MAX_GLOBAL_LOG_LEVEL = 6;
|
||||
|
||||
enum class Severity {
|
||||
|
||||
@@ -38,6 +38,7 @@ static void usage()
|
||||
"--data-api Path to the p2pool JSON data (use it in tandem with an external web-server)\n"
|
||||
"--stratum-api Enable /local/ path in api path for Stratum Server statistics\n"
|
||||
"--no-cache Disable p2pool.cache\n"
|
||||
"--no-color Disable colors in console output\n"
|
||||
"--help Show this help message\n\n"
|
||||
"Example command line:\n\n"
|
||||
"%s --host 127.0.0.1 --rpc-port 18081 --zmq-port 18083 --wallet YOUR_WALLET_ADDRESS --stratum 0.0.0.0:%d --p2p 0.0.0.0:%d\n\n",
|
||||
|
||||
+40
-10
@@ -120,9 +120,9 @@ FORCEINLINE static void remove_allocation(void* p)
|
||||
__debugbreak();
|
||||
}
|
||||
|
||||
FORCEINLINE static void* allocate_noexcept(size_t n) noexcept
|
||||
void* malloc_hook(size_t n) noexcept
|
||||
{
|
||||
void* p = malloc(n + sizeof(TrackedAllocation));
|
||||
void* p = malloc(n);
|
||||
if (p) {
|
||||
add_alocation(p, n);
|
||||
}
|
||||
@@ -131,25 +131,46 @@ FORCEINLINE static void* allocate_noexcept(size_t n) noexcept
|
||||
|
||||
FORCEINLINE static void* allocate(size_t n)
|
||||
{
|
||||
void* p = allocate_noexcept(n);
|
||||
void* p = malloc_hook(n);
|
||||
if (!p) {
|
||||
throw std::bad_alloc();
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
FORCEINLINE static void deallocate(void* p)
|
||||
void free_hook(void* p) noexcept
|
||||
{
|
||||
remove_allocation(p);
|
||||
free(p);
|
||||
}
|
||||
|
||||
void* realloc_hook(void* ptr, size_t size) noexcept
|
||||
{
|
||||
remove_allocation(ptr);
|
||||
|
||||
void* p = realloc(ptr, size);
|
||||
if (p) {
|
||||
add_alocation(p, size);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
void* calloc_hook(size_t count, size_t size) noexcept
|
||||
{
|
||||
void* p = calloc(count, size);
|
||||
if (p) {
|
||||
add_alocation(p, size);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
} // p2pool
|
||||
|
||||
void memory_tracking_start()
|
||||
{
|
||||
using namespace p2pool;
|
||||
|
||||
uv_replace_allocator(malloc_hook, realloc_hook, calloc_hook, free_hook);
|
||||
uv_mutex_init_checked(&allocation_lock);
|
||||
track_memory = true;
|
||||
}
|
||||
@@ -207,14 +228,23 @@ void memory_tracking_stop()
|
||||
|
||||
NOINLINE void* operator new(size_t n) { return p2pool::allocate(n); }
|
||||
NOINLINE void* operator new[](size_t n) { return p2pool::allocate(n); }
|
||||
NOINLINE void* operator new(size_t n, const std::nothrow_t&) noexcept { return p2pool::allocate_noexcept(n); }
|
||||
NOINLINE void* operator new[](size_t n, const std::nothrow_t&) noexcept { return p2pool::allocate_noexcept(n); }
|
||||
NOINLINE void operator delete(void* p) noexcept { p2pool::deallocate(p); }
|
||||
NOINLINE void operator delete[](void* p) noexcept { p2pool::deallocate(p); }
|
||||
NOINLINE void operator delete(void* p, size_t) noexcept { p2pool::deallocate(p); }
|
||||
NOINLINE void operator delete[](void* p, size_t) noexcept { p2pool::deallocate(p); }
|
||||
NOINLINE void* operator new(size_t n, const std::nothrow_t&) noexcept { return p2pool::malloc_hook(n); }
|
||||
NOINLINE void* operator new[](size_t n, const std::nothrow_t&) noexcept { return p2pool::malloc_hook(n); }
|
||||
NOINLINE void operator delete(void* p) noexcept { p2pool::free_hook(p); }
|
||||
NOINLINE void operator delete[](void* p) noexcept { p2pool::free_hook(p); }
|
||||
NOINLINE void operator delete(void* p, size_t) noexcept { p2pool::free_hook(p); }
|
||||
NOINLINE void operator delete[](void* p, size_t) noexcept { p2pool::free_hook(p); }
|
||||
|
||||
#else
|
||||
void memory_tracking_start() {}
|
||||
void memory_tracking_stop() {}
|
||||
|
||||
namespace p2pool {
|
||||
|
||||
void* malloc_hook(size_t n) noexcept { return malloc(n); }
|
||||
void* realloc_hook(void* ptr, size_t size) noexcept { return realloc(ptr, size); }
|
||||
void* calloc_hook(size_t count, size_t size) noexcept { return calloc(count, size); }
|
||||
void free_hook(void* p) noexcept { free(p); }
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
+1
-2
@@ -18,7 +18,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "uv_util.h"
|
||||
#include <unordered_map>
|
||||
|
||||
namespace p2pool {
|
||||
|
||||
@@ -35,7 +34,7 @@ public:
|
||||
|
||||
public:
|
||||
mutable uv_rwlock_t m_lock;
|
||||
std::unordered_map<hash, TxMempoolData> m_transactions;
|
||||
unordered_map<hash, TxMempoolData> m_transactions;
|
||||
};
|
||||
|
||||
} // namespace p2pool
|
||||
|
||||
+50
-7
@@ -94,6 +94,7 @@ P2PServer::P2PServer(p2pool* pool)
|
||||
P2PServer::~P2PServer()
|
||||
{
|
||||
uv_timer_stop(&m_timer);
|
||||
uv_close(reinterpret_cast<uv_handle_t*>(&m_timer), nullptr);
|
||||
uv_close(reinterpret_cast<uv_handle_t*>(&m_broadcastAsync), nullptr);
|
||||
|
||||
shutdown_tcp();
|
||||
@@ -225,8 +226,8 @@ void P2PServer::update_peer_connections()
|
||||
peer_list = m_peerList;
|
||||
}
|
||||
|
||||
// Try to have at least 8 outgoing connections
|
||||
for (uint32_t i = m_numConnections - m_numIncomingConnections; (i < 8) && !peer_list.empty();) {
|
||||
// Try to have at least 10 outgoing connections
|
||||
for (uint32_t i = m_numConnections - m_numIncomingConnections; (i < 10) && !peer_list.empty();) {
|
||||
const uint64_t k = get_random64() % peer_list.size();
|
||||
const Peer& peer = peer_list[k];
|
||||
|
||||
@@ -277,6 +278,7 @@ void P2PServer::update_peer_list()
|
||||
});
|
||||
|
||||
if (result) {
|
||||
client->m_lastPeerListRequestTime = std::chrono::system_clock::now();
|
||||
++client->m_peerListPendingRequests;
|
||||
}
|
||||
}
|
||||
@@ -314,7 +316,7 @@ void P2PServer::save_peer_list_async()
|
||||
});
|
||||
|
||||
if (err) {
|
||||
LOGERR(1, "update_peer_list: uv_queue_work failed, error " << uv_err_name(err));
|
||||
LOGERR(1, "save_peer_list_async: uv_queue_work failed, error " << uv_err_name(err));
|
||||
delete work;
|
||||
}
|
||||
}
|
||||
@@ -686,12 +688,39 @@ uint64_t P2PServer::get_random64()
|
||||
|
||||
void P2PServer::print_status()
|
||||
{
|
||||
const int64_t uptime = time(nullptr) - m_pool->start_time();
|
||||
|
||||
const int64_t s = uptime % 60;
|
||||
const int64_t m = (uptime / 60) % 60;
|
||||
const int64_t h = (uptime / 3600) % 24;
|
||||
const int64_t d = uptime / 86400;
|
||||
|
||||
char buf[log::Stream::BUF_SIZE + 1];
|
||||
log::Stream s1(buf);
|
||||
|
||||
if (d > 0) {
|
||||
s1 << d << "d ";
|
||||
}
|
||||
s1 << h << "h " << m << "m " << s << 's';
|
||||
|
||||
LOGINFO(0, "status" <<
|
||||
"\nConnections = " << m_numConnections << " (" << m_numIncomingConnections << " incoming)" <<
|
||||
"\nPeer list size = " << m_peerList.size()
|
||||
"\nPeer list size = " << m_peerList.size() <<
|
||||
"\nUptime = " << log::const_buf(buf, s1.m_pos)
|
||||
);
|
||||
}
|
||||
|
||||
void P2PServer::show_peers()
|
||||
{
|
||||
MutexLock lock(m_clientsListLock);
|
||||
|
||||
for (P2PClient* client = static_cast<P2PClient*>(m_connectedClientsList->m_next); client != m_connectedClientsList; client = static_cast<P2PClient*>(client->m_next)) {
|
||||
if (client->m_listenPort >= 0) {
|
||||
LOGINFO(0, (client->m_isIncoming ? "I " : "O ") << client->m_pingTime << " ms\t" << static_cast<char*>(client->m_addrString));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void P2PServer::on_timer()
|
||||
{
|
||||
++m_timerCounter;
|
||||
@@ -831,7 +860,9 @@ P2PServer::P2PClient::P2PClient()
|
||||
, m_handshakeInvalid(false)
|
||||
, m_listenPort(-1)
|
||||
, m_nextPeerListRequest(0)
|
||||
, m_lastPeerListRequestTime{}
|
||||
, m_peerListPendingRequests(0)
|
||||
, m_pingTime(0)
|
||||
, m_lastAlive(0)
|
||||
, m_lastBroadcastTimestamp(0)
|
||||
, m_lastBlockrequestTimestamp(0)
|
||||
@@ -855,7 +886,9 @@ void P2PServer::P2PClient::reset()
|
||||
m_handshakeInvalid = false;
|
||||
m_listenPort = -1;
|
||||
m_nextPeerListRequest = 0;
|
||||
m_lastPeerListRequestTime = {};
|
||||
m_peerListPendingRequests = 0;
|
||||
m_pingTime = 0;
|
||||
m_lastAlive = 0;
|
||||
m_lastBroadcastTimestamp = 0;
|
||||
m_lastBlockrequestTimestamp = 0;
|
||||
@@ -1041,7 +1074,7 @@ bool P2PServer::P2PClient::on_read(char* data, uint32_t size)
|
||||
LOGINFO(5, "peer " << log::Gray() << static_cast<char*>(m_addrString) << log::NoColor() << " sent PEER_LIST_RESPONSE");
|
||||
|
||||
if (bytes_left >= 2) {
|
||||
const uint8_t num_peers = buf[1];
|
||||
const uint32_t num_peers = buf[1];
|
||||
if (num_peers > PEER_LIST_RESPONSE_MAX_PEERS) {
|
||||
LOGWARN(5, "peer " << log::Gray() << static_cast<char*>(m_addrString) << log::NoColor() << " sent too long peer list (" << num_peers << ')');
|
||||
ban(DEFAULT_BAN_TIME);
|
||||
@@ -1049,8 +1082,11 @@ bool P2PServer::P2PClient::on_read(char* data, uint32_t size)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bytes_left >= 2u + num_peers * 19) {
|
||||
bytes_read = 2u + num_peers * 19;
|
||||
if (bytes_left >= 2u + num_peers * 19u) {
|
||||
bytes_read = 2u + num_peers * 19u;
|
||||
|
||||
using namespace std::chrono;
|
||||
m_pingTime = duration_cast<milliseconds>(system_clock::now() - m_lastPeerListRequestTime).count();
|
||||
|
||||
--m_peerListPendingRequests;
|
||||
if (!on_peer_list_response(buf + 1)) {
|
||||
@@ -1609,6 +1645,13 @@ bool P2PServer::P2PClient::on_peer_list_response(const uint8_t* buf) const
|
||||
memcpy(ip.data, buf, sizeof(ip.data));
|
||||
buf += sizeof(ip.data);
|
||||
|
||||
// Fill in default bytes for IPv4 addresses
|
||||
if (!is_v6) {
|
||||
memset(ip.data, 0, 10);
|
||||
ip.data[10] = 0xFF;
|
||||
ip.data[11] = 0xFF;
|
||||
}
|
||||
|
||||
int port = 0;
|
||||
memcpy(&port, buf, 2);
|
||||
buf += 2;
|
||||
|
||||
+6
-2
@@ -19,7 +19,6 @@
|
||||
|
||||
#include "tcp_server.h"
|
||||
#include <random>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace p2pool {
|
||||
|
||||
@@ -109,8 +108,12 @@ public:
|
||||
bool m_handshakeComplete;
|
||||
bool m_handshakeInvalid;
|
||||
int m_listenPort;
|
||||
|
||||
time_t m_nextPeerListRequest;
|
||||
std::chrono::system_clock::time_point m_lastPeerListRequestTime;
|
||||
int m_peerListPendingRequests;
|
||||
int64_t m_pingTime;
|
||||
|
||||
time_t m_lastAlive;
|
||||
time_t m_lastBroadcastTimestamp;
|
||||
time_t m_lastBlockrequestTimestamp;
|
||||
@@ -124,6 +127,7 @@ public:
|
||||
uint64_t get_peerId() const { return m_peerId; }
|
||||
|
||||
void print_status() override;
|
||||
void show_peers();
|
||||
|
||||
private:
|
||||
p2pool* m_pool;
|
||||
@@ -132,7 +136,7 @@ private:
|
||||
std::string m_initialPeerList;
|
||||
|
||||
uv_rwlock_t m_cachedBlocksLock;
|
||||
std::unordered_map<hash, PoolBlock*> m_cachedBlocks;
|
||||
unordered_map<hash, PoolBlock*> m_cachedBlocks;
|
||||
|
||||
private:
|
||||
static void on_timer(uv_timer_t* timer) { reinterpret_cast<P2PServer*>(timer->data)->on_timer(); }
|
||||
|
||||
@@ -49,6 +49,8 @@ p2pool::p2pool(int argc, char* argv[])
|
||||
, m_params(new Params(argc, argv))
|
||||
, m_updateSeed(true)
|
||||
, m_submitBlockData{}
|
||||
, m_zmqLastActive(0)
|
||||
, m_startTime(time(nullptr))
|
||||
{
|
||||
LOGINFO(1, log::LightCyan() << VERSION);
|
||||
|
||||
|
||||
+7
-6
@@ -19,7 +19,6 @@
|
||||
|
||||
#include "uv_util.h"
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace p2pool {
|
||||
|
||||
@@ -79,6 +78,7 @@ public:
|
||||
bool get_difficulty_at_height(uint64_t height, difficulty_type& diff);
|
||||
|
||||
time_t zmq_last_active() const { return m_zmqLastActive; }
|
||||
time_t start_time() const { return m_startTime; }
|
||||
|
||||
private:
|
||||
p2pool(const p2pool&) = delete;
|
||||
@@ -104,7 +104,7 @@ private:
|
||||
|
||||
mutable uv_rwlock_t m_mainchainLock;
|
||||
std::map<uint64_t, ChainMain> m_mainchainByHeight;
|
||||
std::unordered_map<hash, ChainMain> m_mainchainByHash;
|
||||
unordered_map<hash, ChainMain> m_mainchainByHash;
|
||||
|
||||
enum { TIMESTAMP_WINDOW = 60 };
|
||||
bool get_timestamps(uint64_t (×tamps)[TIMESTAMP_WINDOW]) const;
|
||||
@@ -157,9 +157,9 @@ private:
|
||||
|
||||
struct SubmitBlockData
|
||||
{
|
||||
uint32_t template_id;
|
||||
uint32_t nonce;
|
||||
uint32_t extra_nonce;
|
||||
uint32_t template_id = 0;
|
||||
uint32_t nonce = 0;
|
||||
uint32_t extra_nonce = 0;
|
||||
std::vector<uint8_t> blob;
|
||||
};
|
||||
|
||||
@@ -170,7 +170,8 @@ private:
|
||||
uv_async_t m_blockTemplateAsync;
|
||||
uv_async_t m_stopAsync;
|
||||
|
||||
time_t m_zmqLastActive = 0;
|
||||
time_t m_zmqLastActive;
|
||||
time_t m_startTime;
|
||||
};
|
||||
|
||||
} // namespace p2pool
|
||||
|
||||
+1
-1
@@ -127,7 +127,7 @@ void p2pool_api::dump_to_file_async_internal(const Category& category, const cha
|
||||
|
||||
void p2pool_api::dump_to_file()
|
||||
{
|
||||
std::unordered_map<std::string, std::vector<char>> data;
|
||||
unordered_map<std::string, std::vector<char>> data;
|
||||
{
|
||||
MutexLock lock(m_dumpDataLock);
|
||||
data = std::move(m_dumpData);
|
||||
|
||||
+1
-2
@@ -18,7 +18,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "uv_util.h"
|
||||
#include <unordered_map>
|
||||
|
||||
namespace p2pool {
|
||||
|
||||
@@ -84,7 +83,7 @@ private:
|
||||
std::string m_localPath;
|
||||
|
||||
uv_mutex_t m_dumpDataLock;
|
||||
std::unordered_map<std::string, std::vector<char>> m_dumpData;
|
||||
unordered_map<std::string, std::vector<char>> m_dumpData;
|
||||
|
||||
uv_async_t m_dumpToFileAsync;
|
||||
};
|
||||
|
||||
@@ -77,6 +77,10 @@ Params::Params(int argc, char* argv[])
|
||||
if (strcmp(argv[i], "--no-cache") == 0) {
|
||||
m_blockCache = false;
|
||||
}
|
||||
|
||||
if (strcmp(argv[i], "--no-color") == 0) {
|
||||
log::CONSOLE_COLORS = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_stratumAddresses.empty()) {
|
||||
|
||||
+3
-3
@@ -44,8 +44,8 @@ private:
|
||||
|
||||
struct ThreadSafeVM
|
||||
{
|
||||
uv_mutex_t mutex;
|
||||
randomx_vm* vm;
|
||||
uv_mutex_t mutex{};
|
||||
randomx_vm* vm = nullptr;
|
||||
};
|
||||
|
||||
p2pool* m_pool;
|
||||
@@ -62,7 +62,7 @@ private:
|
||||
// 1: light VM for the previous seed
|
||||
// 2: full dataset VM for the current seed
|
||||
enum { FULL_DATASET_VM = 2 };
|
||||
ThreadSafeVM m_vm[3];
|
||||
ThreadSafeVM m_vm[3]{};
|
||||
|
||||
hash m_seed[2];
|
||||
uint32_t m_index;
|
||||
|
||||
+3
-5
@@ -19,8 +19,6 @@
|
||||
|
||||
#include "uv_util.h"
|
||||
#include <map>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace p2pool {
|
||||
|
||||
@@ -98,9 +96,9 @@ private:
|
||||
mutable uv_mutex_t m_sidechainLock;
|
||||
PoolBlock* m_chainTip;
|
||||
std::map<uint64_t, std::vector<PoolBlock*>> m_blocksByHeight;
|
||||
std::unordered_map<hash, PoolBlock*> m_blocksById;
|
||||
std::unordered_set<hash> m_seenBlocks;
|
||||
std::unordered_map<hash, time_t> m_seenWallets;
|
||||
unordered_map<hash, PoolBlock*> m_blocksById;
|
||||
unordered_set<hash> m_seenBlocks;
|
||||
unordered_map<hash, time_t> m_seenWallets;
|
||||
|
||||
std::vector<DifficultyData> m_difficultyData;
|
||||
|
||||
|
||||
+43
-5
@@ -176,6 +176,28 @@ void StratumServer::on_block(const BlockTemplate& block)
|
||||
}
|
||||
}
|
||||
|
||||
bool StratumServer::get_custom_user(const char* s, std::string& user)
|
||||
{
|
||||
user.clear();
|
||||
// Find first of '+' or '.', drop non-printable characters
|
||||
while (s && (user.length() < 64)) {
|
||||
const char c = *s;
|
||||
if (!c) {
|
||||
break;
|
||||
}
|
||||
if ((c == '+') || (c == '.')) {
|
||||
break;
|
||||
}
|
||||
// Limit to printable ASCII characters
|
||||
if (c >= ' ' && c <= '~') {
|
||||
user += c;
|
||||
}
|
||||
++s;
|
||||
}
|
||||
|
||||
return !user.empty();
|
||||
}
|
||||
|
||||
bool StratumServer::get_custom_diff(const char* s, difficulty_type& diff)
|
||||
{
|
||||
const char* diff_str = nullptr;
|
||||
@@ -225,6 +247,10 @@ bool StratumServer::on_login(StratumClient* client, uint32_t id, const char* log
|
||||
target = std::max(target, client->m_customDiff.target());
|
||||
}
|
||||
|
||||
if (get_custom_user(login, client->m_customUser)) {
|
||||
LOGINFO(5, "client " << log::Gray() << static_cast<char*>(client->m_addrString) << " set custom user " << client->m_customUser);
|
||||
}
|
||||
|
||||
uint32_t job_id;
|
||||
{
|
||||
MutexLock lock(client->m_jobsLock);
|
||||
@@ -334,7 +360,8 @@ bool StratumServer::on_submit(StratumClient* client, uint32_t id, const char* jo
|
||||
}
|
||||
|
||||
if (mainchain_diff.check_pow(resultHash)) {
|
||||
LOGINFO(0, log::Green() << "client " << static_cast<char*>(client->m_addrString) << " found a mainchain block, submitting it");
|
||||
const std::string& s = client->m_customUser;
|
||||
LOGINFO(0, log::Green() << "client " << static_cast<char*>(client->m_addrString) << (!s.empty() ? " user " : "") << s << " found a mainchain block, submitting it");
|
||||
m_pool->submit_block_async(template_id, nonce, extra_nonce);
|
||||
block.update_tx_keys();
|
||||
}
|
||||
@@ -367,12 +394,21 @@ bool StratumServer::on_submit(StratumClient* client, uint32_t id, const char* jo
|
||||
share->m_resultHash = resultHash;
|
||||
share->m_sidechainDifficulty = sidechain_diff;
|
||||
|
||||
// If this share is below sidechain difficulty, process it in this thread because it'll be quick
|
||||
if (!share->m_sidechainDifficulty.check_pow(share->m_resultHash)) {
|
||||
on_share_found(&share->m_req);
|
||||
on_after_share_found(&share->m_req, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Else switch to a worker thread to check PoW which can take a long time
|
||||
const int err = uv_queue_work(&m_loop, &share->m_req, on_share_found, on_after_share_found);
|
||||
if (err) {
|
||||
LOGERR(1, "uv_queue_work failed, error " << uv_err_name(err));
|
||||
MutexLock lock(m_submittedSharesPoolLock);
|
||||
m_submittedSharesPool.push_back(share);
|
||||
return false;
|
||||
|
||||
// If uv_queue_work failed, process this share here anyway
|
||||
on_share_found(&share->m_req);
|
||||
on_after_share_found(&share->m_req, 0);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -645,7 +681,8 @@ void StratumServer::on_share_found(uv_work_t* req)
|
||||
server->m_cumulativeFoundSharesDiff += diff;
|
||||
++server->m_totalFoundShares;
|
||||
|
||||
LOGINFO(0, log::Green() << "SHARE FOUND: mainchain height " << height << ", diff " << sidechain_difficulty << ", effort " << effort << '%');
|
||||
const std::string& s = client->m_customUser;
|
||||
LOGINFO(0, log::Green() << "SHARE FOUND: mainchain height " << height << ", diff " << sidechain_difficulty << ", client " << static_cast<char*>(client->m_addrString) << (!s.empty() ? " user " : "") << s << ", effort " << effort << '%');
|
||||
pool->submit_sidechain_block(share->m_templateId, share->m_nonce, share->m_extraNonce);
|
||||
}
|
||||
|
||||
@@ -742,6 +779,7 @@ void StratumServer::StratumClient::reset()
|
||||
memset(m_jobs, 0, sizeof(m_jobs));
|
||||
m_perConnectionJobId = 0;
|
||||
m_customDiff = {};
|
||||
m_customUser.clear();
|
||||
}
|
||||
|
||||
bool StratumServer::StratumClient::on_read(char* data, uint32_t size)
|
||||
|
||||
@@ -65,6 +65,7 @@ public:
|
||||
|
||||
uint32_t m_perConnectionJobId;
|
||||
difficulty_type m_customDiff;
|
||||
std::string m_customUser;
|
||||
};
|
||||
|
||||
bool on_login(StratumClient* client, uint32_t id, const char* login);
|
||||
@@ -77,6 +78,7 @@ private:
|
||||
void print_stratum_status() const;
|
||||
|
||||
static bool get_custom_diff(const char* s, difficulty_type& diff);
|
||||
static bool get_custom_user(const char* s, std::string& user);
|
||||
|
||||
static void on_share_found(uv_work_t* req);
|
||||
static void on_after_share_found(uv_work_t* req, int status);
|
||||
|
||||
@@ -308,7 +308,6 @@ bool TCPServer<READ_BUF_SIZE, WRITE_BUF_SIZE>::connect_to_peer(bool is_v6, const
|
||||
return connect_to_peer_nolock(client, is_v6, reinterpret_cast<sockaddr*>(&addr));
|
||||
}
|
||||
|
||||
|
||||
template<size_t READ_BUF_SIZE, size_t WRITE_BUF_SIZE>
|
||||
void TCPServer<READ_BUF_SIZE, WRITE_BUF_SIZE>::on_connect_failed(bool, const raw_ip&, int)
|
||||
{
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@ namespace p2pool {
|
||||
#define STR2(X) STR(X)
|
||||
#define STR(X) #X
|
||||
|
||||
const char* VERSION = "v1.2 (built"
|
||||
const char* VERSION = "v1.3 (built"
|
||||
#if defined(__clang__)
|
||||
" with clang/" __clang_version__
|
||||
#elif defined(__GNUC__)
|
||||
|
||||
+25
-12
@@ -17,6 +17,21 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 5027)
|
||||
#endif
|
||||
|
||||
#define ROBIN_HOOD_MALLOC(size) p2pool::malloc_hook(size)
|
||||
#define ROBIN_HOOD_CALLOC(count, size) p2pool::calloc_hook((count), (size))
|
||||
#define ROBIN_HOOD_FREE(ptr) p2pool::free_hook(ptr)
|
||||
|
||||
#include "robin_hood.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
namespace p2pool {
|
||||
|
||||
extern const char* VERSION;
|
||||
@@ -122,20 +137,22 @@ extern thread_local bool is_main_thread;
|
||||
|
||||
bool resolve_host(std::string& host, bool& is_v6);
|
||||
|
||||
template <typename Key, typename T>
|
||||
using unordered_map = robin_hood::detail::Table<false, 80, Key, T, robin_hood::hash<Key>, std::equal_to<Key>>;
|
||||
|
||||
template <typename Key>
|
||||
using unordered_set = robin_hood::detail::Table<false, 80, Key, void, robin_hood::hash<Key>, std::equal_to<Key>>;
|
||||
|
||||
} // namespace p2pool
|
||||
|
||||
namespace std {
|
||||
namespace robin_hood {
|
||||
|
||||
template<>
|
||||
struct hash<p2pool::hash>
|
||||
{
|
||||
FORCEINLINE size_t operator()(const p2pool::hash& value) const noexcept
|
||||
{
|
||||
uint64_t result = 0xcbf29ce484222325ull;
|
||||
for (size_t i = 0; i < p2pool::HASH_SIZE; ++i) {
|
||||
result = (result ^ value.h[i]) * 0x100000001b3ull;
|
||||
}
|
||||
return static_cast<size_t>(result);
|
||||
return hash_bytes(value.h, p2pool::HASH_SIZE);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -144,12 +161,8 @@ struct hash<std::array<uint8_t, N>>
|
||||
{
|
||||
FORCEINLINE size_t operator()(const std::array<uint8_t, N>& value) const noexcept
|
||||
{
|
||||
uint64_t result = 0xcbf29ce484222325ull;
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
result = (result ^ value[i]) * 0x100000001b3ull;
|
||||
}
|
||||
return static_cast<size_t>(result);
|
||||
return hash_bytes(value.data(), N);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace std
|
||||
} // namespace robin_hood
|
||||
|
||||
+8
-7
@@ -76,20 +76,22 @@ ZMQReader::~ZMQReader()
|
||||
}
|
||||
}
|
||||
|
||||
void ZMQReader::run_wrapper(void* arg)
|
||||
{
|
||||
reinterpret_cast<ZMQReader*>(arg)->run();
|
||||
LOGINFO(1, "worker thread stopped");
|
||||
}
|
||||
|
||||
void ZMQReader::run()
|
||||
{
|
||||
try {
|
||||
char addr[32];
|
||||
|
||||
snprintf(addr, sizeof(addr), "tcp://%s:%u", m_address, m_zmqPort);
|
||||
if (!connect(addr, m_zmqPort)) {
|
||||
throw zmq::error_t();
|
||||
}
|
||||
while (!connect(addr, m_zmqPort)) { if (m_finished.load()) return; }
|
||||
|
||||
snprintf(addr, sizeof(addr), "tcp://127.0.0.1:%u", m_publisherPort);
|
||||
if (!connect(addr, m_publisherPort)) {
|
||||
throw zmq::error_t();
|
||||
}
|
||||
while (!connect(addr, m_publisherPort)) { if (m_finished.load()) return; }
|
||||
|
||||
m_subscriber.set(zmq::sockopt::subscribe, "json-full-chain_main");
|
||||
m_subscriber.set(zmq::sockopt::subscribe, "json-full-miner_data");
|
||||
@@ -122,7 +124,6 @@ void ZMQReader::run()
|
||||
LOGERR(1, "exception " << e.what() << ", aborting");
|
||||
panic();
|
||||
}
|
||||
LOGINFO(1, "worker thread stopped");
|
||||
}
|
||||
|
||||
bool ZMQReader::connect(const char* address, uint32_t id)
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ public:
|
||||
~ZMQReader();
|
||||
|
||||
private:
|
||||
static void run_wrapper(void* arg) { reinterpret_cast<ZMQReader*>(arg)->run(); }
|
||||
static void run_wrapper(void* arg);
|
||||
void run();
|
||||
bool connect(const char* address, uint32_t id);
|
||||
|
||||
|
||||
@@ -84,6 +84,7 @@ set(SOURCES
|
||||
../src/json_rpc_request.cpp
|
||||
../src/keccak.cpp
|
||||
../src/log.cpp
|
||||
../src/memory_leak_debug.cpp
|
||||
../src/mempool.cpp
|
||||
../src/p2p_server.cpp
|
||||
../src/p2pool.cpp
|
||||
@@ -107,6 +108,7 @@ include_directories(../external/src/libzmq/include)
|
||||
include_directories(../external/src/llhttp)
|
||||
include_directories(../external/src/RandomX/src)
|
||||
include_directories(../external/src/rapidjson/include)
|
||||
include_directories(../external/src/robin-hood-hashing/src/include)
|
||||
include_directories(src)
|
||||
include_directories(googletest/googletest/include)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user