mirror of
https://github.com/SChernykh/p2pool.git
synced 2025-03-29 18:38:45 +00:00
Check network type at startup
- Make network type part of consensus ID to avoid mixing p2pool nodes from mainnet and testnet/stagenet - Check that wallet address matches the network type of monerod
This commit is contained in:
parent
afca83d6c2
commit
27c2aab145
9 changed files with 110 additions and 30 deletions
|
@ -251,6 +251,13 @@ struct ChainMain
|
|||
hash id;
|
||||
};
|
||||
|
||||
enum class NetworkType {
|
||||
Invalid,
|
||||
Mainnet,
|
||||
Testnet,
|
||||
Stagenet,
|
||||
};
|
||||
|
||||
} // namespace p2pool
|
||||
|
||||
#include "util.h"
|
||||
|
|
|
@ -54,6 +54,7 @@ JSON_VALUE_PARSER(String, const char*)
|
|||
JSON_VALUE_PARSER(String, std::string)
|
||||
JSON_VALUE_PARSER(Uint, uint8_t)
|
||||
JSON_VALUE_PARSER(Uint64, uint64_t)
|
||||
JSON_VALUE_PARSER(Bool, bool)
|
||||
|
||||
#undef JSON_VALUE_PARSER
|
||||
|
||||
|
|
13
src/log.h
13
src/log.h
|
@ -359,6 +359,19 @@ template<> struct log::Stream::Entry<XMRAmount>
|
|||
}
|
||||
};
|
||||
|
||||
template<> struct log::Stream::Entry<NetworkType>
|
||||
{
|
||||
static NOINLINE void put(const NetworkType& value, Stream* wrapper)
|
||||
{
|
||||
switch (value) {
|
||||
case NetworkType::Invalid: *wrapper << "invalid"; break;
|
||||
case NetworkType::Mainnet: *wrapper << "mainnet"; break;
|
||||
case NetworkType::Testnet: *wrapper << "testnet"; break;
|
||||
case NetworkType::Stagenet: *wrapper << "stagenet"; break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
namespace {
|
||||
template<log::Severity severity> void apply_severity(log::Stream&);
|
||||
|
||||
|
|
|
@ -51,12 +51,12 @@ p2pool::p2pool(int argc, char* argv[])
|
|||
panic();
|
||||
}
|
||||
|
||||
const Wallet::Type type = m_params->m_wallet.type();
|
||||
const NetworkType type = m_params->m_wallet.type();
|
||||
|
||||
if (type == Wallet::Type::Testnet) {
|
||||
if (type == NetworkType::Testnet) {
|
||||
LOGWARN(1, "Mining to a testnet wallet address");
|
||||
}
|
||||
else if (type == Wallet::Type::Stagenet) {
|
||||
else if (type == NetworkType::Stagenet) {
|
||||
LOGWARN(1, "Mining to a stagenet wallet address");
|
||||
}
|
||||
|
||||
|
@ -86,7 +86,7 @@ p2pool::p2pool(int argc, char* argv[])
|
|||
|
||||
MinerData d;
|
||||
|
||||
m_sideChain = new SideChain(this);
|
||||
m_sideChain = new SideChain(this, type);
|
||||
m_hasher = new RandomX_Hasher(this);
|
||||
m_blockTemplate = new BlockTemplate(this);
|
||||
m_mempool = new Mempool();
|
||||
|
@ -530,6 +530,63 @@ void p2pool::stratum_on_block()
|
|||
#endif
|
||||
}
|
||||
|
||||
void p2pool::get_info()
|
||||
{
|
||||
JSONRPCRequest::call(m_params->m_host, m_params->m_rpcPort, "{\"jsonrpc\":\"2.0\",\"id\":\"0\",\"method\":\"get_info\"}",
|
||||
[this](const char* data, size_t size)
|
||||
{
|
||||
parse_get_info_rpc(data, size);
|
||||
});
|
||||
}
|
||||
|
||||
void p2pool::parse_get_info_rpc(const char* data, size_t size)
|
||||
{
|
||||
rapidjson::Document doc;
|
||||
doc.Parse(data, size);
|
||||
|
||||
if (!doc.IsObject() || !doc.HasMember("result")) {
|
||||
LOGWARN(1, "get_info RPC response is invalid (\"result\" not found), trying again in 1 second");
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||
get_info();
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& result = doc["result"];
|
||||
|
||||
struct {
|
||||
bool busy_syncing, mainnet, testnet, stagenet;
|
||||
} info;
|
||||
|
||||
if (!PARSE(result, info, busy_syncing) || !PARSE(result, info, mainnet) || !PARSE(result, info, testnet) || !PARSE(result, info, stagenet)) {
|
||||
LOGWARN(1, "get_info RPC response is invalid, trying again in 1 second");
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||
get_info();
|
||||
return;
|
||||
}
|
||||
|
||||
if (info.busy_syncing) {
|
||||
LOGINFO(1, "monerod is busy syncing, trying again in 1 second");
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||
get_info();
|
||||
return;
|
||||
}
|
||||
|
||||
NetworkType monero_network = NetworkType::Invalid;
|
||||
|
||||
if (info.mainnet) monero_network = NetworkType::Mainnet;
|
||||
if (info.testnet) monero_network = NetworkType::Testnet;
|
||||
if (info.stagenet) monero_network = NetworkType::Stagenet;
|
||||
|
||||
const NetworkType sidechain_network = m_sideChain->network_type();
|
||||
|
||||
if (monero_network != sidechain_network) {
|
||||
LOGERR(1, "monerod is on " << monero_network << ", but you're mining to a " << sidechain_network << " sidechain");
|
||||
panic();
|
||||
}
|
||||
|
||||
get_miner_data();
|
||||
}
|
||||
|
||||
void p2pool::get_miner_data()
|
||||
{
|
||||
JSONRPCRequest::call(m_params->m_host, m_params->m_rpcPort, "{\"jsonrpc\":\"2.0\",\"id\":\"0\",\"method\":\"get_miner_data\"}",
|
||||
|
@ -761,7 +818,7 @@ int p2pool::run()
|
|||
|
||||
{
|
||||
ZMQReader z(m_params->m_host, m_params->m_rpcPort, m_params->m_zmqPort, this);
|
||||
get_miner_data();
|
||||
get_info();
|
||||
const int rc = uv_run(uv_default_loop_checked(), UV_RUN_DEFAULT);
|
||||
LOGINFO(1, "uv_run exited, result = " << rc);
|
||||
}
|
||||
|
|
|
@ -102,6 +102,9 @@ private:
|
|||
|
||||
void stratum_on_block();
|
||||
|
||||
void get_info();
|
||||
void parse_get_info_rpc(const char* data, size_t size);
|
||||
|
||||
void get_miner_data();
|
||||
void parse_get_miner_data_rpc(const char* data, size_t size);
|
||||
|
||||
|
|
|
@ -51,8 +51,9 @@ static_assert(1 <= UNCLE_BLOCK_DEPTH && UNCLE_BLOCK_DEPTH <= 10, "Invalid UNCLE_
|
|||
|
||||
namespace p2pool {
|
||||
|
||||
SideChain::SideChain(p2pool* pool)
|
||||
SideChain::SideChain(p2pool* pool, NetworkType type)
|
||||
: m_pool(pool)
|
||||
, m_networkType(type)
|
||||
, m_chainTip(nullptr)
|
||||
, m_poolName("default")
|
||||
, m_targetBlockTime(1)
|
||||
|
@ -61,6 +62,8 @@ SideChain::SideChain(p2pool* pool)
|
|||
, m_unclePenalty(20)
|
||||
, m_curDifficulty(m_minDifficulty)
|
||||
{
|
||||
LOGINFO(1, log::LightCyan() << "network type = " << m_networkType);
|
||||
|
||||
if (!load_config(m_pool->params().m_config)) {
|
||||
panic();
|
||||
}
|
||||
|
@ -90,12 +93,13 @@ SideChain::SideChain(p2pool* pool)
|
|||
char consensus_str[log::Stream::BUF_SIZE + 1];
|
||||
log::Stream s(consensus_str);
|
||||
|
||||
s << m_poolName << '\0'
|
||||
<< m_poolPassword << '\0'
|
||||
<< m_targetBlockTime << '\0'
|
||||
<< m_minDifficulty << '\0'
|
||||
<< m_chainWindowSize << '\0'
|
||||
<< m_unclePenalty << '\0';
|
||||
s << m_networkType << '\0'
|
||||
<< m_poolName << '\0'
|
||||
<< m_poolPassword << '\0'
|
||||
<< m_targetBlockTime << '\0'
|
||||
<< m_minDifficulty << '\0'
|
||||
<< m_chainWindowSize << '\0'
|
||||
<< m_unclePenalty << '\0';
|
||||
|
||||
randomx_init_cache(cache, consensus_str, s.m_pos);
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ struct MinerShare
|
|||
class SideChain
|
||||
{
|
||||
public:
|
||||
explicit SideChain(p2pool* pool);
|
||||
SideChain(p2pool* pool, NetworkType type);
|
||||
~SideChain();
|
||||
|
||||
void fill_sidechain_data(PoolBlock& block, Wallet* w, const hash& txkeySec, std::vector<MinerShare>& shares);
|
||||
|
@ -62,11 +62,13 @@ public:
|
|||
// Consensus ID can therefore be used as a password to create private P2Pools
|
||||
const std::vector<uint8_t>& consensus_id() const { return m_consensusId; }
|
||||
uint64_t chain_window_size() const { return m_chainWindowSize; }
|
||||
NetworkType network_type() const { return m_networkType; }
|
||||
|
||||
static bool split_reward(uint64_t reward, const std::vector<MinerShare>& shares, std::vector<uint64_t>& rewards);
|
||||
|
||||
private:
|
||||
p2pool* m_pool;
|
||||
NetworkType m_networkType;
|
||||
|
||||
private:
|
||||
bool get_shares(PoolBlock* tip, std::vector<MinerShare>& shares) const;
|
||||
|
|
|
@ -123,7 +123,7 @@ Wallet& Wallet::operator=(const Wallet& w)
|
|||
|
||||
bool Wallet::decode(const char* address)
|
||||
{
|
||||
m_type = Type::Invalid;
|
||||
m_type = NetworkType::Invalid;
|
||||
|
||||
if (!address || (strlen(address) != ADDRESS_LENGTH)) {
|
||||
return false;
|
||||
|
@ -167,11 +167,11 @@ bool Wallet::decode(const char* address)
|
|||
|
||||
m_prefix = data[0];
|
||||
|
||||
if (m_prefix == valid_prefixes[0]) m_type = Type::Mainnet;
|
||||
if (m_prefix == valid_prefixes[1]) m_type = Type::Testnet;
|
||||
if (m_prefix == valid_prefixes[2]) m_type = Type::Stagenet;
|
||||
if (m_prefix == valid_prefixes[0]) m_type = NetworkType::Mainnet;
|
||||
if (m_prefix == valid_prefixes[1]) m_type = NetworkType::Testnet;
|
||||
if (m_prefix == valid_prefixes[2]) m_type = NetworkType::Stagenet;
|
||||
|
||||
if (m_type == Type::Invalid) {
|
||||
if (m_type == NetworkType::Invalid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -183,7 +183,7 @@ bool Wallet::decode(const char* address)
|
|||
keccak(data, sizeof(data) - sizeof(m_checksum), md);
|
||||
|
||||
if (memcmp(&m_checksum, md, sizeof(m_checksum)) != 0) {
|
||||
m_type = Type::Invalid;
|
||||
m_type = NetworkType::Invalid;
|
||||
}
|
||||
|
||||
return valid();
|
||||
|
@ -198,7 +198,7 @@ void Wallet::assign(const hash& spend_pub_key, const hash& view_pub_key)
|
|||
m_viewPublicKey = view_pub_key;
|
||||
m_checksum = 0;
|
||||
|
||||
m_type = Type::Mainnet;
|
||||
m_type = NetworkType::Mainnet;
|
||||
|
||||
m_txkeySec = {};
|
||||
m_outputIndex = std::numeric_limits<size_t>::max();
|
||||
|
|
13
src/wallet.h
13
src/wallet.h
|
@ -24,21 +24,14 @@ namespace p2pool {
|
|||
class Wallet
|
||||
{
|
||||
public:
|
||||
enum class Type {
|
||||
Invalid,
|
||||
Mainnet,
|
||||
Testnet,
|
||||
Stagenet,
|
||||
};
|
||||
|
||||
explicit Wallet(const char* address);
|
||||
~Wallet();
|
||||
|
||||
Wallet(const Wallet& w);
|
||||
Wallet& operator=(const Wallet& w);
|
||||
|
||||
FORCEINLINE bool valid() const { return m_type != Type::Invalid; }
|
||||
FORCEINLINE Type type() const { return m_type; }
|
||||
FORCEINLINE bool valid() const { return m_type != NetworkType::Invalid; }
|
||||
FORCEINLINE NetworkType type() const { return m_type; }
|
||||
|
||||
bool decode(const char* address);
|
||||
void assign(const hash& spend_pub_key, const hash& view_pub_key);
|
||||
|
@ -56,7 +49,7 @@ private:
|
|||
hash m_spendPublicKey;
|
||||
hash m_viewPublicKey;
|
||||
uint32_t m_checksum;
|
||||
Type m_type;
|
||||
NetworkType m_type;
|
||||
|
||||
mutable uv_mutex_t m_lock;
|
||||
hash m_txkeySec;
|
||||
|
|
Loading…
Reference in a new issue