mirror of
https://github.com/SChernykh/p2pool.git
synced 2024-12-22 11:29:23 +00:00
Added command line for merge mining
Start a merge mining client for each of the aux chains
This commit is contained in:
parent
abd9c80e4d
commit
e6b8292d5b
13 changed files with 77 additions and 25 deletions
|
@ -29,6 +29,7 @@
|
||||||
--no-upnp Disable UPnP port forwarding
|
--no-upnp Disable UPnP port forwarding
|
||||||
--no-igd An alias for --no-upnp
|
--no-igd An alias for --no-upnp
|
||||||
--upnp-stratum Port forward Stratum port (it's not forwarded by default)
|
--upnp-stratum Port forward Stratum port (it's not forwarded by default)
|
||||||
|
--merge-mine IP:port and wallet address for another blockchain to merge mine with
|
||||||
--version Print p2pool's version and build details
|
--version Print p2pool's version and build details
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -50,3 +51,9 @@ In this example, you have local Monero host running on ports 18081/18083 (RPC/zm
|
||||||
```
|
```
|
||||||
p2pool.exe --host 127.0.0.1 --host xmr1.rs.me --rpc-port 18089 --zmq-port 18084 --host xmr2.rs.me --host xmr3.rs.me --wallet YOUR_WALLET_ADDRESS
|
p2pool.exe --host 127.0.0.1 --host xmr1.rs.me --rpc-port 18089 --zmq-port 18084 --host xmr2.rs.me --host xmr3.rs.me --wallet YOUR_WALLET_ADDRESS
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Merge mining
|
||||||
|
|
||||||
|
```
|
||||||
|
p2pool.exe --wallet YOUR_WALLET_ADDRESS --merge-mine IP:port YOUR_WALLET_ADDRESS_ON_ANOTHER_BLOCKCHAIN
|
||||||
|
```
|
||||||
|
|
|
@ -86,6 +86,8 @@ Example response 2: `{"jsonrpc":"2.0","id":"0","result":{}}`
|
||||||
|
|
||||||
### merge_mining_submit_solution
|
### merge_mining_submit_solution
|
||||||
|
|
||||||
|
Example request: `{"jsonrpc":"2.0","id":"0","method":"merge_mining_submit_solution","params":{"aux_blob":"4c6f72656d20697073756d","aux_hash":"f6952d6eef555ddd87aca66e56b91530222d6e318414816f3ba7cf5bf694bf0f","blob":"...","merkle_proof":["hash1","hash2","hash3"]}}`
|
||||||
|
|
||||||
Request: a JSON containing these fields:
|
Request: a JSON containing these fields:
|
||||||
Field|Description
|
Field|Description
|
||||||
-|-
|
-|-
|
||||||
|
|
|
@ -385,6 +385,8 @@ struct TxMempoolData
|
||||||
|
|
||||||
struct AuxChainData
|
struct AuxChainData
|
||||||
{
|
{
|
||||||
|
FORCEINLINE AuxChainData(const hash& _id, const hash& _data, const difficulty_type& _difficulty) : unique_id(_id), data(_data), difficulty(_difficulty) {}
|
||||||
|
|
||||||
hash unique_id;
|
hash unique_id;
|
||||||
hash data;
|
hash data;
|
||||||
difficulty_type difficulty;
|
difficulty_type difficulty;
|
||||||
|
|
12
src/keccak.h
12
src/keccak.h
|
@ -42,18 +42,6 @@ FORCEINLINE void keccak(const uint8_t* in, int inlen, uint8_t (&md)[N])
|
||||||
template<typename T>
|
template<typename T>
|
||||||
FORCEINLINE void keccak_custom(T&& in, int inlen, uint8_t* md, int mdlen)
|
FORCEINLINE void keccak_custom(T&& in, int inlen, uint8_t* md, int mdlen)
|
||||||
{
|
{
|
||||||
// TODO: remove after testing
|
|
||||||
#if 0
|
|
||||||
if (inlen > 100) {
|
|
||||||
printf("\nkeccak_custom %d", inlen);
|
|
||||||
for (int i = 0; i < inlen; ++i) {
|
|
||||||
if ((i & 31) == 0) printf("\n");
|
|
||||||
printf("%02X ", static_cast<uint8_t>(in(i)));
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uint64_t st[25] = {};
|
uint64_t st[25] = {};
|
||||||
|
|
||||||
const int rsiz = sizeof(st) == mdlen ? KeccakParams::HASH_DATA_AREA : 200 - 2 * mdlen;
|
const int rsiz = sizeof(st) == mdlen ? KeccakParams::HASH_DATA_AREA : 200 - 2 * mdlen;
|
||||||
|
|
|
@ -62,6 +62,7 @@ void p2pool_usage()
|
||||||
"--no-igd An alias for --no-upnp\n"
|
"--no-igd An alias for --no-upnp\n"
|
||||||
"--upnp-stratum Port forward Stratum port (it's not forwarded by default)\n"
|
"--upnp-stratum Port forward Stratum port (it's not forwarded by default)\n"
|
||||||
#endif
|
#endif
|
||||||
|
"--merge-mine IP:port and wallet address for another blockchain to merge mine with"
|
||||||
"--version Print p2pool's version and build details\n"
|
"--version Print p2pool's version and build details\n"
|
||||||
"--help Show this help message\n\n"
|
"--help Show this help message\n\n"
|
||||||
"Example command line:\n\n"
|
"Example command line:\n\n"
|
||||||
|
|
|
@ -27,10 +27,10 @@ LOG_CATEGORY(MergeMiningClient)
|
||||||
|
|
||||||
namespace p2pool {
|
namespace p2pool {
|
||||||
|
|
||||||
MergeMiningClient::MergeMiningClient(p2pool* pool, const std::string& host, const std::string& address)
|
MergeMiningClient::MergeMiningClient(p2pool* pool, const std::string& host, const std::string& wallet)
|
||||||
: m_host(host)
|
: m_host(host)
|
||||||
, m_port(80)
|
, m_port(80)
|
||||||
, m_auxAddress(address)
|
, m_auxWallet(wallet)
|
||||||
, m_ping(0.0)
|
, m_ping(0.0)
|
||||||
, m_pool(pool)
|
, m_pool(pool)
|
||||||
, m_loop{}
|
, m_loop{}
|
||||||
|
@ -42,7 +42,7 @@ MergeMiningClient::MergeMiningClient(p2pool* pool, const std::string& host, cons
|
||||||
const size_t k = host.find_last_of(':');
|
const size_t k = host.find_last_of(':');
|
||||||
if (k != std::string::npos) {
|
if (k != std::string::npos) {
|
||||||
m_host = host.substr(0, k);
|
m_host = host.substr(0, k);
|
||||||
m_port = strtoul(host.substr(k + 1).c_str(), nullptr, 10);
|
m_port = std::stoul(host.substr(k + 1), nullptr, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_host.empty() || (m_port == 0) || (m_port >= 65536)) {
|
if (m_host.empty() || (m_port == 0) || (m_port >= 65536)) {
|
||||||
|
@ -95,7 +95,7 @@ MergeMiningClient::~MergeMiningClient()
|
||||||
void MergeMiningClient::on_timer()
|
void MergeMiningClient::on_timer()
|
||||||
{
|
{
|
||||||
MinerData data = m_pool->miner_data();
|
MinerData data = m_pool->miner_data();
|
||||||
merge_mining_get_job(data.height, data.prev_id, m_auxAddress, m_auxHash);
|
merge_mining_get_job(data.height, data.prev_id, m_auxWallet, m_auxHash);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MergeMiningClient::merge_mining_get_chain_id()
|
void MergeMiningClient::merge_mining_get_chain_id()
|
||||||
|
@ -157,7 +157,7 @@ bool MergeMiningClient::parse_merge_mining_get_chain_id(const char* data, size_t
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MergeMiningClient::merge_mining_get_job(uint64_t height, const hash& prev_id, const std::string& address, const hash& aux_hash)
|
void MergeMiningClient::merge_mining_get_job(uint64_t height, const hash& prev_id, const std::string& wallet, const hash& aux_hash)
|
||||||
{
|
{
|
||||||
if (m_getJobRunning) {
|
if (m_getJobRunning) {
|
||||||
return;
|
return;
|
||||||
|
@ -169,7 +169,7 @@ void MergeMiningClient::merge_mining_get_job(uint64_t height, const hash& prev_i
|
||||||
log::Stream s(buf);
|
log::Stream s(buf);
|
||||||
|
|
||||||
s << "{\"jsonrpc\":\"2.0\",\"id\":\"0\",\"method\":\"merge_mining_get_job\",\"params\":{"
|
s << "{\"jsonrpc\":\"2.0\",\"id\":\"0\",\"method\":\"merge_mining_get_job\",\"params\":{"
|
||||||
<< "\"address\":\"" << address << '"'
|
<< "\"address\":\"" << wallet << '"'
|
||||||
<< ",\"aux_hash\":\"" << aux_hash << '"'
|
<< ",\"aux_hash\":\"" << aux_hash << '"'
|
||||||
<< ",\"height\":" << height
|
<< ",\"height\":" << height
|
||||||
<< ",\"prev_id\":\"" << prev_id << '"'
|
<< ",\"prev_id\":\"" << prev_id << '"'
|
||||||
|
|
|
@ -26,11 +26,15 @@ class p2pool;
|
||||||
class MergeMiningClient
|
class MergeMiningClient
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MergeMiningClient(p2pool* pool, const std::string& host, const std::string& address);
|
MergeMiningClient(p2pool* pool, const std::string& host, const std::string& wallet);
|
||||||
~MergeMiningClient();
|
~MergeMiningClient();
|
||||||
|
|
||||||
void merge_mining_submit_solution(const std::vector<uint8_t>& blob, const std::vector<hash>& merkle_proof);
|
void merge_mining_submit_solution(const std::vector<uint8_t>& blob, const std::vector<hash>& merkle_proof);
|
||||||
|
|
||||||
|
FORCEINLINE const hash& aux_id() const { return m_chainID; }
|
||||||
|
FORCEINLINE const hash& aux_data() const { return m_auxHash; }
|
||||||
|
FORCEINLINE const difficulty_type& aux_diff() const { return m_auxDiff; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void loop(void* data);
|
static void loop(void* data);
|
||||||
|
|
||||||
|
@ -40,7 +44,7 @@ private:
|
||||||
void merge_mining_get_chain_id();
|
void merge_mining_get_chain_id();
|
||||||
bool parse_merge_mining_get_chain_id(const char* data, size_t size);
|
bool parse_merge_mining_get_chain_id(const char* data, size_t size);
|
||||||
|
|
||||||
void merge_mining_get_job(uint64_t height, const hash& prev_id, const std::string& address, const hash& aux_hash);
|
void merge_mining_get_job(uint64_t height, const hash& prev_id, const std::string& wallet, const hash& aux_hash);
|
||||||
bool parse_merge_mining_get_job(const char* data, size_t size);
|
bool parse_merge_mining_get_job(const char* data, size_t size);
|
||||||
|
|
||||||
bool parse_merge_mining_submit_solution(const char* data, size_t size);
|
bool parse_merge_mining_submit_solution(const char* data, size_t size);
|
||||||
|
@ -48,7 +52,7 @@ private:
|
||||||
std::string m_host;
|
std::string m_host;
|
||||||
uint32_t m_port;
|
uint32_t m_port;
|
||||||
|
|
||||||
std::string m_auxAddress;
|
std::string m_auxWallet;
|
||||||
std::vector<uint8_t> m_auxBlob;
|
std::vector<uint8_t> m_auxBlob;
|
||||||
hash m_auxHash;
|
hash m_auxHash;
|
||||||
difficulty_type m_auxDiff;
|
difficulty_type m_auxDiff;
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include "pool_block.h"
|
#include "pool_block.h"
|
||||||
#include "keccak.h"
|
#include "keccak.h"
|
||||||
#include "merkle.h"
|
#include "merkle.h"
|
||||||
|
#include "merge_mining_client.h"
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
|
@ -186,6 +187,11 @@ p2pool::~p2pool()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
for (const MergeMiningClient* c : m_mergeMiningClients) {
|
||||||
|
delete c;
|
||||||
|
}
|
||||||
|
m_mergeMiningClients.clear();
|
||||||
|
|
||||||
uv_rwlock_destroy(&m_mainchainLock);
|
uv_rwlock_destroy(&m_mainchainLock);
|
||||||
uv_rwlock_destroy(&m_minerDataLock);
|
uv_rwlock_destroy(&m_minerDataLock);
|
||||||
uv_rwlock_destroy(&m_ZMQReaderLock);
|
uv_rwlock_destroy(&m_ZMQReaderLock);
|
||||||
|
@ -334,6 +340,25 @@ void p2pool::handle_miner_data(MinerData& data)
|
||||||
cleanup_mainchain_data(data.height);
|
cleanup_mainchain_data(data.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data.aux_chains.clear();
|
||||||
|
|
||||||
|
if (!m_mergeMiningClients.empty()) {
|
||||||
|
data.aux_chains.reserve(m_mergeMiningClients.size());
|
||||||
|
|
||||||
|
std::vector<hash> tmp;
|
||||||
|
tmp.reserve(m_mergeMiningClients.size());
|
||||||
|
|
||||||
|
for (const MergeMiningClient* c : m_mergeMiningClients) {
|
||||||
|
data.aux_chains.emplace_back(c->aux_id(), c->aux_data(), c->aux_diff());
|
||||||
|
tmp.emplace_back(c->aux_data());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!find_aux_nonce(tmp, data.aux_nonce)) {
|
||||||
|
LOGERR(1, "Failed to find the aux nonce for merge mining. Merge mining will be off this round.");
|
||||||
|
data.aux_chains.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: remove after testing
|
// TODO: remove after testing
|
||||||
#if 0
|
#if 0
|
||||||
{
|
{
|
||||||
|
@ -840,6 +865,10 @@ void p2pool::download_block_headers(uint64_t current_height)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (const auto& h : m_params->m_mergeMiningHosts) {
|
||||||
|
m_mergeMiningClients.push_back(new MergeMiningClient(this, h.m_host, h.m_wallet));
|
||||||
|
}
|
||||||
|
|
||||||
m_startupFinished = true;
|
m_startupFinished = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1136,11 +1165,10 @@ void p2pool::get_miner_data(bool retry)
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||||
m_getMinerDataPending = false;
|
m_getMinerDataPending = false;
|
||||||
get_miner_data();
|
get_miner_data();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
m_getMinerDataPending = false;
|
||||||
m_getMinerDataPending = false;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ class Miner;
|
||||||
class ConsoleCommands;
|
class ConsoleCommands;
|
||||||
class p2pool_api;
|
class p2pool_api;
|
||||||
class ZMQReader;
|
class ZMQReader;
|
||||||
|
class MergeMiningClient;
|
||||||
struct PoolBlock;
|
struct PoolBlock;
|
||||||
|
|
||||||
class p2pool : public MinerCallbackHandler, public nocopy_nomove
|
class p2pool : public MinerCallbackHandler, public nocopy_nomove
|
||||||
|
@ -226,6 +227,8 @@ private:
|
||||||
mutable uv_rwlock_t m_ZMQReaderLock;
|
mutable uv_rwlock_t m_ZMQReaderLock;
|
||||||
ZMQReader* m_ZMQReader = nullptr;
|
ZMQReader* m_ZMQReader = nullptr;
|
||||||
|
|
||||||
|
std::vector<MergeMiningClient*> m_mergeMiningClients;
|
||||||
|
|
||||||
hash m_getMinerDataHash;
|
hash m_getMinerDataHash;
|
||||||
bool m_getMinerDataPending = false;
|
bool m_getMinerDataPending = false;
|
||||||
|
|
||||||
|
|
|
@ -189,6 +189,12 @@ Params::Params(int argc, char* const argv[])
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if ((strcmp(argv[i], "--merge-mine") == 0) && (i + 2 < argc)) {
|
||||||
|
m_mergeMiningHosts.emplace_back(argv[i + 1], argv[i + 2]);
|
||||||
|
i += 2;
|
||||||
|
ok = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
fprintf(stderr, "Unknown command line parameter %s\n\n", argv[i]);
|
fprintf(stderr, "Unknown command line parameter %s\n\n", argv[i]);
|
||||||
p2pool_usage();
|
p2pool_usage();
|
||||||
|
|
10
src/params.h
10
src/params.h
|
@ -53,6 +53,16 @@ struct Params
|
||||||
|
|
||||||
std::vector<Host> m_hosts;
|
std::vector<Host> m_hosts;
|
||||||
|
|
||||||
|
struct MergeMiningHost
|
||||||
|
{
|
||||||
|
MergeMiningHost(const char* host, const char* wallet) : m_host(host), m_wallet(wallet) {}
|
||||||
|
|
||||||
|
std::string m_host;
|
||||||
|
std::string m_wallet;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<MergeMiningHost> m_mergeMiningHosts;
|
||||||
|
|
||||||
bool m_lightMode = false;
|
bool m_lightMode = false;
|
||||||
Wallet m_wallet{ nullptr };
|
Wallet m_wallet{ nullptr };
|
||||||
std::string m_stratumAddresses;
|
std::string m_stratumAddresses;
|
||||||
|
|
|
@ -113,7 +113,7 @@ void TCPServer::parse_address_list_internal(const std::string& address_list, Cal
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const int port = strtol(address.substr(k2 + 1).c_str(), nullptr, 10);
|
const uint32_t port = std::stoul(address.substr(k2 + 1), nullptr, 10);
|
||||||
if ((port > 0) && (port < 65536)) {
|
if ((port > 0) && (port < 65536)) {
|
||||||
callback(is_v6, address, ip, port);
|
callback(is_v6, address, ip, port);
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,7 @@ set(SOURCES
|
||||||
../src/log.cpp
|
../src/log.cpp
|
||||||
../src/memory_leak_debug.cpp
|
../src/memory_leak_debug.cpp
|
||||||
../src/mempool.cpp
|
../src/mempool.cpp
|
||||||
|
../src/merge_mining_client.cpp
|
||||||
../src/merkle.cpp
|
../src/merkle.cpp
|
||||||
../src/miner.cpp
|
../src/miner.cpp
|
||||||
../src/p2p_server.cpp
|
../src/p2p_server.cpp
|
||||||
|
|
Loading…
Reference in a new issue