Skip to content

Commit

Permalink
Implement a Log Manager, use Colors to highlight Errors/Warnings, wri…
Browse files Browse the repository at this point in the history
…te to a Debug.log File

Also a few minor changes like small StatsManager Refactoring and no longer resetting the Share Counts in case of disconnect

Signed-off-by: Pttn <28868425+Pttn@users.noreply.github.com>
  • Loading branch information
Pttn committed Nov 28, 2022
1 parent dca7d3c commit 434eab2
Show file tree
Hide file tree
Showing 17 changed files with 441 additions and 354 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@ rieMiner*
rieMiner.exe.stackdump
.*.swp
*.bin
debug.log
Tuples.txt
28 changes: 13 additions & 15 deletions API.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// (c) 2021 Pttn (https://riecoin.dev/en/rieMiner)
// (c) 2021-2022 Pttn (https://riecoin.dev/en/rieMiner)

#ifdef _WIN32
#include <winsock2.h>
Expand All @@ -19,19 +19,19 @@

constexpr uint16_t maxMessageSize(64);
void API::_process() {
std::cout << "Starting rieMiner's API server, port " << _port << std::endl;
logger.log("Starting rieMiner's API server, port "s + std::to_string(_port) + "\n"s);
#ifdef _WIN32
WORD wVersionRequested(MAKEWORD(2, 2));
WSADATA wsaData;
const int err(WSAStartup(wVersionRequested, &wsaData));
if (err != 0) {
ERRORMSG("WSAStartup failed with error " << err);
logger.log("WSAStartup failed with error "s + std::to_string(err) + "\n"s, MessageType::ERROR);
return;
}
#endif
int apiFd;
if ((apiFd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
ERRORMSG("Could not get a File Descriptor for the API Server");
logger.log("Could not get a File Descriptor for the API Server\n"s, MessageType::ERROR);
return;
}
#ifdef _WIN32
Expand All @@ -40,7 +40,7 @@ void API::_process() {
#else
if (fcntl(apiFd, F_SETFL, fcntl(apiFd, F_GETFL, 0) | O_NONBLOCK) == -1) {
#endif
ERRORMSG("Unable to make the socket non-blocking");
logger.log("Unable to make the socket non-blocking\n"s, MessageType::ERROR);
return;
}

Expand All @@ -51,15 +51,15 @@ void API::_process() {
#ifndef _WIN32
int optval(1);
if (setsockopt(apiFd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &optval, sizeof(decltype(optval))) != 0) {
ERRORMSG("Setsockopt could not set SO_REUSEADDR | SO_REUSEPORT");
logger.log("Setsockopt could not set SO_REUSEADDR | SO_REUSEPORT\n"s, MessageType::ERROR);
}
#endif
if (bind(apiFd, reinterpret_cast<sockaddr*>(&address), sizeof(address)) < 0) {
ERRORMSG("Could not bind");
logger.log("Could not bind\n"s, MessageType::ERROR);
return;
}
if (listen(apiFd, 1) < 0) {
ERRORMSG("Could not listen");
logger.log("Could not listen\n"s, MessageType::ERROR);
return;
}

Expand All @@ -73,7 +73,7 @@ void API::_process() {
#endif
std::this_thread::sleep_for(std::chrono::milliseconds(100));
else
ERRORMSG("Could not accept connection");
logger.log("Could not accept connection\n"s, MessageType::ERROR);
}
else {
#ifdef _WIN32
Expand Down Expand Up @@ -103,8 +103,8 @@ void API::_process() {
double uptime(0.), cps(0.), r(0.), bpd(0.), miningPower(0.), difficulty(600.);
uint16_t patternLength(0U);
uint32_t shares(0ULL), sharesRejected(0ULL);
if (_miner != nullptr && _client != nullptr ? _miner->inited() : false) {
const Stats statsRecent(_miner->getStatsRecent()), stats(_miner->getStats());
if (_client != nullptr) {
const Stats statsRecent(statManager.stats(false)), stats(statManager.stats(true));
const Job job(_client->getJob());
if (job.acceptedPatterns.size() > 0)
patternLength = job.acceptedPatterns[0].size();
Expand All @@ -115,10 +115,8 @@ void API::_process() {
bpd = statsRecent.estimatedAverageTimeToFindBlock(patternLength) == 0. ? 0. : (86400./statsRecent.estimatedAverageTimeToFindBlock(patternLength));
difficulty = job.difficulty;
miningPower = 150.*bpd*std::pow(difficulty/600., static_cast<double>(patternLength) + 2.3)/86400.;
if (std::dynamic_pointer_cast<StratumClient>(_client) != nullptr) {
shares = std::dynamic_pointer_cast<StratumClient>(_client)->shares();
sharesRejected = std::dynamic_pointer_cast<StratumClient>(_client)->sharesRejected();
}
shares = statManager.shares();
sharesRejected = statManager.rejectedShares();
}
if (method == "getstatsjson") {
oss << "{\"running\": " << (running ? "true" : "false") << ", ";
Expand Down
6 changes: 3 additions & 3 deletions API.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// (c) 2021 Pttn (https://riecoin.dev/en/rieMiner)
// (c) 2021-2022 Pttn (https://riecoin.dev/en/rieMiner)

#ifndef HEADER_API_hpp
#define HEADER_API_hpp
Expand All @@ -24,15 +24,15 @@ class API {
bool running() {return _running;}
void start() {
if (_running)
ERRORMSG("The API is already running");
logger.log("The API is already running\n"s, MessageType::ERROR);
else {
_running = true;
_thread = std::thread(&API::_process, this);
}
}
void stop() {
if (!_running)
ERRORMSG("The API is already not running");
logger.log("The API is already stopped\n"s, MessageType::ERROR);
else {
_running = false;
_thread.join();
Expand Down
20 changes: 10 additions & 10 deletions Client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ double decodeBits(const uint32_t nBits, const int32_t powVersion) {
if (powVersion == 1)
return static_cast<double>(nBits)/256.;
else
ERRORMSG("Unexpected PoW Version " << powVersion);
logger.log("Unexpected PoW Version "s + std::to_string(powVersion) + "\n"s, MessageType::ERROR);
return 1.;
}

Expand Down Expand Up @@ -38,7 +38,7 @@ mpz_class BlockHeader::target(const int32_t powVersion) const {
target <<= trailingZeros;
}
else
ERRORMSG("Unexpected PoW Version " << powVersion);
logger.log("Unexpected PoW Version "s + std::to_string(powVersion) + "\n"s, MessageType::ERROR);
return target;
}

Expand All @@ -52,35 +52,35 @@ std::array<uint8_t, 32> Job::encodedOffset() const {
*reinterpret_cast<uint16_t*>(&nOffset.data()[30]) = primorialNumber;
}
else
ERRORMSG("Unexpected PoW Version " << powVersion);
logger.log("Unexpected PoW Version "s + std::to_string(powVersion) + "\n"s, MessageType::ERROR);
return nOffset;
}

std::vector<uint64_t> Client::choosePatterns(const std::vector<std::vector<uint64_t>>& acceptedPatterns, const std::vector<uint64_t>& givenPattern) {
std::cout << "Accepted constellation pattern(s):" << std::endl;
logger.log("Accepted constellation pattern(s):\n"s);
if (acceptedPatterns.size() == 0) {
std::cout << " None - something went wrong :|" << std::endl;
logger.log("\tNone - something went wrong :|\n"s, MessageType::ERROR);
return {};
}
else {
bool accepted(false);
for (uint16_t i(0) ; i < acceptedPatterns.size() ; i++) {
std::cout << " " << i << " - " << formatContainer(acceptedPatterns[i]);
logger.log("\t"s + std::to_string(i) + " - "s + formatContainer(acceptedPatterns[i]));
bool compatible(true);
for (uint16_t j(0) ; j < acceptedPatterns[i].size() ; j++) {
const auto offset(acceptedPatterns[i][j]);
if (j >= givenPattern.size() ? true : offset != givenPattern[j])
compatible = false;
}
if (compatible) {
std::cout << " <- compatible";
logger.log(" <- compatible"s);
accepted = true;
}
std::cout << std::endl;
logger.log("\n"s);
}
if (!accepted) {
const uint16_t patternIndex(rand(0, acceptedPatterns.size() - 1));
std::cout << "None or not compatible one specified, choosing a random one: pattern " << patternIndex << std::endl;
logger.log("None or not compatible one specified, choosing a random one: pattern "s + std::to_string(patternIndex) + "\n");
return acceptedPatterns[patternIndex];
}
else
Expand Down Expand Up @@ -153,5 +153,5 @@ void SearchClient::handleResult(const Job& job) {
if (file)
file << job.resultPrimeCount << "-tuple: " << job.result << std::endl;
else
ERRORMSG("Unable to write tuple to file " << _tuplesFilename);
logger.log("Unable to write tuple to file "s + _tuplesFilename + "\n"s, MessageType::ERROR);
}
9 changes: 1 addition & 8 deletions Client.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,6 @@ class StratumClient : public NetworkedClient {
} _currentJobTemplate;
int _socket;
std::chrono::time_point<std::chrono::steady_clock> _lastPoolMessageTp; // Used to disconnect if the server sent nothing since a long time
uint32_t _shares, _rejectedShares;
enum State {UNSUBSCRIBED, SUBSCRIBED, AUTHORIZED} _state;
uint32_t _jsonId; // Counter for the Id field when sending requests to the pool

Expand All @@ -159,12 +158,6 @@ class StratumClient : public NetworkedClient {
}
uint32_t currentHeight() const {return _currentJobTemplate.job.height;}
double currentDifficulty() const {return _currentJobTemplate.job.difficulty;}
void printSharesStats() const { // Must be after a Stats::printStats()
std::cout << " ; Sh: " << _shares - _rejectedShares << "/" << _shares;
if (_shares > 0) std::cout << " (" << FIXED(1) << 100.*(static_cast<double>(_shares - _rejectedShares)/static_cast<double>(_shares)) << "%)";
}
uint32_t shares() const {return _shares;}
uint32_t sharesRejected() const {return _rejectedShares;}
};

// For BenchMarking, emulates a client to allow similar conditions to actual mining by providing
Expand Down Expand Up @@ -194,7 +187,7 @@ class SearchClient : public Client {
std::mutex _tupleFileMutex;
public:
SearchClient(const Options &options) : _pattern(options.minerParameters.pattern), _difficulty(options.difficulty), _tuplesFilename(options.tuplesFile) {
std::cout << "Tuples will be written to file " << _tuplesFilename << std::endl;
logger.log("Tuples will be written to file "s + _tuplesFilename + "\n"s);
}
Job getJob(const bool = false); // Work is generated here
void handleResult(const Job&); // Save tuple to file
Expand Down
30 changes: 15 additions & 15 deletions GBTClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ std::array<uint8_t, 32> coinbaseTxId(const std::vector<uint8_t> &coinbase) {
static std::array<uint8_t, 32> calculateMerkleRoot(const std::vector<std::array<uint8_t, 32>> &txHashes) {
std::array<uint8_t, 32> merkleRoot{};
if (txHashes.size() == 0)
ERRORMSG("No transaction to hash");
logger.log("No transaction to hash!\n"s, MessageType::ERROR);
else if (txHashes.size() == 1)
return txHashes[0];
else {
Expand Down Expand Up @@ -125,15 +125,15 @@ nlohmann::json GBTClient::_sendRequestToWallet(const std::string &method, const
curl_easy_setopt(_curl, CURLOPT_TIMEOUT, 10);
const CURLcode cc(curl_easy_perform(_curl));
if (cc != CURLE_OK)
ERRORMSG("Curl_easy_perform() failed: " << curl_easy_strerror(cc));
logger.log("Curl_easy_perform() failed: "s + curl_easy_strerror(cc) + "\n"s, MessageType::ERROR);
else {
try {jsonObj = nlohmann::json::parse(s);}
catch (nlohmann::json::parse_error &e) {
if (s.size() == 0)
std::cout << "Nothing was received from the server!" << std::endl;
logger.log("Nothing was received from the server!\n"s, MessageType::ERROR);
else {
std::cout << "Received bad JSON object!" << std::endl;
std::cout << "Server message was: " << s << std::endl;
logger.log("Received bad JSON object!\n"s
"Server message was: "s + s + "\n"s, MessageType::ERROR);
}
}
}
Expand All @@ -150,7 +150,7 @@ bool GBTClient::_fetchJob() {
getblocktemplateResult = getblocktemplate["result"];
}
catch (...) {
std::cout << "Could not get GetBlockTemplate Data!" << std::endl;
logger.log("Could not get GetBlockTemplate Data!\n"s, MessageType::ERROR);
return false;
}
JobTemplate newJobTemplate;
Expand All @@ -173,21 +173,21 @@ bool GBTClient::_fetchJob() {
newJobTemplate.job.height = getblocktemplateResult["height"];
newJobTemplate.job.powVersion = getblocktemplateResult["powversion"];
if (newJobTemplate.job.powVersion != 1) {
std::cout << "Unsupported PoW Version " << newJobTemplate.job.powVersion << ", your rieMiner version is likely outdated!" << std::endl;
logger.log("Unsupported PoW Version "s + std::to_string(newJobTemplate.job.powVersion) + ", your rieMiner version is likely outdated!\n"s, MessageType::ERROR);
return false;
}
newJobTemplate.job.acceptedPatterns = getblocktemplateResult["patterns"].get<decltype(newJobTemplate.job.acceptedPatterns)>();
if (newJobTemplate.job.acceptedPatterns.size() == 0) {
std::cout << "Empty or invalid accepted patterns list!" << std::endl;
logger.log("Empty or invalid accepted patterns list!\n"s, MessageType::ERROR);
return false;
}
newJobTemplate.job.primeCountTarget = newJobTemplate.job.acceptedPatterns[0].size();
newJobTemplate.job.primeCountMin = newJobTemplate.job.primeCountTarget;
newJobTemplate.job.difficulty = decodeBits(newJobTemplate.job.clientData.bh.bits, newJobTemplate.job.powVersion);
}
catch (...) {
std::cout << "Received GetBlockTemplate Data with invalid parameters!" << std::endl;
std::cout << "Json Object was: " << getblocktemplate.dump() << std::endl;
logger.log("Received GetBlockTemplate Data with invalid parameters!\n"s
"Json Object was: "s + getblocktemplate.dump() + "\n"s, MessageType::ERROR);
return false;
}
std::lock_guard<std::mutex> lock(_jobMutex);
Expand All @@ -196,7 +196,7 @@ bool GBTClient::_fetchJob() {
}

void GBTClient::_submit(const Job& job) {
std::cout << "Submitting block with " << job.clientData.txCount << " transaction(s) (including coinbase)..." << std::endl;
logger.log("Submitting block with "s + std::to_string(job.clientData.txCount) + " transaction(s) (including coinbase)...\n"s, MessageType::BOLD);
BlockHeader bh(job.clientData.bh);
bh.nOffset = job.encodedOffset();
std::ostringstream oss;
Expand All @@ -210,12 +210,12 @@ void GBTClient::_submit(const Job& job) {
try {
nlohmann::json submitblockResponse(_sendRequestToWallet("submitblock", {oss.str()}));
if (submitblockResponse["result"] == nullptr && submitblockResponse["error"] == nullptr)
std::cout << "Submission accepted :D !" << std::endl;
logger.log("Submission accepted :D !\n"s, MessageType::SUCCESS);
else
std::cout << "Submission rejected :| ! Received: " << submitblockResponse.dump() << std::endl;
logger.log("Submission rejected :| ! Received: " + submitblockResponse.dump() + "\n"s, MessageType::WARNING);
}
catch (std::exception &e) {
ERRORMSG("Failure submitting block");
logger.log("Failure submitting block :| !\n"s, MessageType::ERROR);
return;
}
}
Expand All @@ -226,7 +226,7 @@ void GBTClient::connect() {
_pendingSubmissions = {};
process();
if (_currentJobTemplate.job.height == 0) {
std::cout << "Could not get a first job from the server!" << std::endl;
logger.log("Could not get a first job from the server!\n"s, MessageType::ERROR);
return;
}
_connected = true;
Expand Down
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@ native: rieMiner
endif

debug: CFLAGS += -march=native -g
debug: LIBS := -pthread $(LIBS)
ifeq ($(shell uname -m),x86_64)
debug: rieMinerx64
else
debug: rieMiner
endif

Deb64: CFLAGS += -march=x86-64 -s -D CURL_STATICLIB -I incsDeb64/
Deb64AVX2: CFLAGS += -march=x86-64 -mavx2 -s -D CURL_STATICLIB -I incsDeb64/
Expand Down
Loading

0 comments on commit 434eab2

Please sign in to comment.