Wallet: added checks for FCMP++ compatibility
This commit is contained in:
+30
-4
@@ -73,12 +73,22 @@ Params::Params(int argc, char* const argv[])
|
||||
}
|
||||
|
||||
if ((strcmp(argv[i], "--wallet") == 0) && (i + 1 < argc)) {
|
||||
m_mainWallet.decode(argv[++i]);
|
||||
const char* s = argv[++i];
|
||||
|
||||
if (!m_mainWallet.decode(s)) {
|
||||
LOGERR(1, "Wallet " << s << " failed to decode");
|
||||
}
|
||||
|
||||
ok = true;
|
||||
}
|
||||
|
||||
if ((strcmp(argv[i], "--subaddress") == 0) && (i + 1 < argc)) {
|
||||
m_subaddress.decode(argv[++i]);
|
||||
const char* s = argv[++i];
|
||||
|
||||
if (!m_subaddress.decode(s)) {
|
||||
LOGERR(1, "Subaddress " << s << " failed to decode");
|
||||
}
|
||||
|
||||
ok = true;
|
||||
}
|
||||
|
||||
@@ -333,8 +343,14 @@ Params::Params(int argc, char* const argv[])
|
||||
char display_wallet_buf[Wallet::ADDRESS_LENGTH] = {};
|
||||
|
||||
if (m_mainWallet.valid() && m_subaddress.valid()) {
|
||||
m_miningWallet.assign(m_subaddress.spend_public_key(), m_mainWallet.view_public_key(), m_mainWallet.type(), false);
|
||||
m_subaddress.encode(display_wallet_buf);
|
||||
if (!m_miningWallet.assign(m_subaddress.spend_public_key(), m_mainWallet.view_public_key(), m_mainWallet.type(), false)) {
|
||||
LOGERR(1, "Failed to configure the mining wallet, falling back to " << m_mainWallet);
|
||||
m_miningWallet = m_mainWallet;
|
||||
m_mainWallet.encode(display_wallet_buf);
|
||||
}
|
||||
else {
|
||||
m_subaddress.encode(display_wallet_buf);
|
||||
}
|
||||
}
|
||||
else if (m_mainWallet.valid()) {
|
||||
m_miningWallet = m_mainWallet;
|
||||
@@ -367,6 +383,16 @@ bool Params::valid() const
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_mainWallet.torsion_check()) {
|
||||
LOGERR(1, m_mainWallet << " didn't pass the torsion check. It will be incompatible with FCMP++.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_subaddress.valid() && !m_subaddress.torsion_check()) {
|
||||
LOGERR(1, m_subaddress << " didn't pass the torsion check. It will be incompatible with FCMP++.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_mergeMiningHosts.size() > 10) {
|
||||
LOGERR(1, "Too many merge mining blockchains.");
|
||||
return false;
|
||||
|
||||
+3
-1
@@ -2486,7 +2486,9 @@ void SideChain::precalc_worker()
|
||||
for (const std::pair<size_t, const Wallet*>& w : wallets) {
|
||||
hash eph_public_key;
|
||||
uint8_t view_tag;
|
||||
w.second->get_eph_public_key(job->m_txkeySec, w.first, eph_public_key, view_tag);
|
||||
if (!w.second->get_eph_public_key(job->m_txkeySec, w.first, eph_public_key, view_tag)) {
|
||||
LOGWARN(6, "get_eph_public_key failed in precalc_worker");
|
||||
}
|
||||
}
|
||||
} while (true);
|
||||
}
|
||||
|
||||
+31
-1
@@ -27,6 +27,10 @@ extern "C" {
|
||||
#include "crypto-ops.h"
|
||||
}
|
||||
|
||||
#include "fcmp_pp_crypto.h"
|
||||
|
||||
LOG_CATEGORY(Wallet)
|
||||
|
||||
namespace {
|
||||
|
||||
// Allow only regular addresses (no integrated addresses, no subaddresses)
|
||||
@@ -81,7 +85,9 @@ namespace p2pool {
|
||||
|
||||
Wallet::Wallet(const char* address) : m_prefix(0), m_checksum(0), m_type(NetworkType::Invalid), m_subaddress(false)
|
||||
{
|
||||
decode(address);
|
||||
if (!decode(address) && address) {
|
||||
LOGWARN(1, address << " failed to decode");
|
||||
}
|
||||
}
|
||||
|
||||
Wallet::Wallet(const Wallet& w)
|
||||
@@ -179,6 +185,11 @@ bool Wallet::decode(const char* address)
|
||||
m_type = NetworkType::Invalid;
|
||||
}
|
||||
|
||||
if (!torsion_check()) {
|
||||
LOGWARN(1, "Torsion check failed for wallet " << *this << "! It will not be compatible with FCMP++.");
|
||||
// TODO: add "m_type = NetworkType::Invalid;" and return false in a later release, closer to FCMP++ hardfork
|
||||
}
|
||||
|
||||
return valid();
|
||||
}
|
||||
|
||||
@@ -213,6 +224,11 @@ bool Wallet::assign(const hash& spend_pub_key, const hash& view_pub_key, Network
|
||||
m_type = type;
|
||||
m_subaddress = subaddress;
|
||||
|
||||
if (!torsion_check()) {
|
||||
LOGWARN(1, "Torsion check failed for wallet " << *this << "! It will not be compatible with FCMP++.");
|
||||
// TODO: add "m_type = NetworkType::Invalid;" and return false in a later release, closer to FCMP++ hardfork
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -256,4 +272,18 @@ bool Wallet::get_eph_public_key(const hash& txkey_sec, size_t output_index, hash
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Wallet::torsion_check() const
|
||||
{
|
||||
ge_p3 p1, p2;
|
||||
if ((ge_frombytes_vartime(&p1, m_spendPublicKey.h) != 0) || (ge_frombytes_vartime(&p2, m_viewPublicKey.h) != 0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return
|
||||
!fcmp_pp::mul8_is_identity(p1) &&
|
||||
!fcmp_pp::mul8_is_identity(p2) &&
|
||||
fcmp_pp::torsion_check_vartime(p1) &&
|
||||
fcmp_pp::torsion_check_vartime(p2);
|
||||
}
|
||||
|
||||
} // namespace p2pool
|
||||
|
||||
+12
-11
@@ -34,31 +34,32 @@ public:
|
||||
Wallet(const Wallet& w);
|
||||
Wallet& operator=(const Wallet& w);
|
||||
|
||||
FORCEINLINE bool valid() const { return m_type != NetworkType::Invalid; }
|
||||
[[nodiscard]] FORCEINLINE bool valid() const { return m_type != NetworkType::Invalid; }
|
||||
|
||||
bool decode(const char* address);
|
||||
bool assign(const hash& spend_pub_key, const hash& view_pub_key, NetworkType type, bool subaddress);
|
||||
[[nodiscard]] bool decode(const char* address);
|
||||
[[nodiscard]] bool assign(const hash& spend_pub_key, const hash& view_pub_key, NetworkType type, bool subaddress);
|
||||
|
||||
void encode(char (&buf)[ADDRESS_LENGTH]) const;
|
||||
|
||||
FORCEINLINE std::string encode() const
|
||||
[[nodiscard]] FORCEINLINE std::string encode() const
|
||||
{
|
||||
char buf[ADDRESS_LENGTH];
|
||||
encode(buf);
|
||||
return std::string(buf, buf + ADDRESS_LENGTH);
|
||||
}
|
||||
|
||||
bool get_eph_public_key(const hash& txkey_sec, size_t output_index, hash& eph_public_key, uint8_t& view_tag, const uint8_t* expected_view_tag = nullptr) const;
|
||||
[[nodiscard]] bool get_eph_public_key(const hash& txkey_sec, size_t output_index, hash& eph_public_key, uint8_t& view_tag, const uint8_t* expected_view_tag = nullptr) const;
|
||||
|
||||
FORCEINLINE bool operator<(const Wallet& w) const { return (m_spendPublicKey < w.m_spendPublicKey) || ((m_spendPublicKey == w.m_spendPublicKey) && (m_viewPublicKey < w.m_viewPublicKey)); }
|
||||
FORCEINLINE bool operator==(const Wallet& w) const { return (m_spendPublicKey == w.m_spendPublicKey) && (m_viewPublicKey == w.m_viewPublicKey); }
|
||||
|
||||
FORCEINLINE uint64_t prefix() const { return m_prefix; }
|
||||
FORCEINLINE const hash& spend_public_key() const { return m_spendPublicKey; }
|
||||
FORCEINLINE const hash& view_public_key() const { return m_viewPublicKey; }
|
||||
FORCEINLINE uint32_t checksum() const { return m_checksum; }
|
||||
FORCEINLINE NetworkType type() const { return m_type; }
|
||||
FORCEINLINE bool is_subaddress() const { return m_subaddress; }
|
||||
[[nodiscard]] FORCEINLINE uint64_t prefix() const { return m_prefix; }
|
||||
[[nodiscard]] FORCEINLINE const hash& spend_public_key() const { return m_spendPublicKey; }
|
||||
[[nodiscard]] FORCEINLINE const hash& view_public_key() const { return m_viewPublicKey; }
|
||||
[[nodiscard]] FORCEINLINE uint32_t checksum() const { return m_checksum; }
|
||||
[[nodiscard]] FORCEINLINE NetworkType type() const { return m_type; }
|
||||
[[nodiscard]] FORCEINLINE bool is_subaddress() const { return m_subaddress; }
|
||||
[[nodiscard]] bool torsion_check() const;
|
||||
|
||||
private:
|
||||
uint64_t m_prefix;
|
||||
|
||||
Reference in New Issue
Block a user