forked from gridcoin-community/Gridcoin-Research
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcpid.cpp
138 lines (110 loc) · 3.41 KB
/
cpid.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// Copyright (c) 2014-2021 The Gridcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "gridcoin/cpid.h"
#include "util.h"
#include <algorithm>
#include <openssl/md5.h>
using namespace GRC;
namespace {
//!
//! \brief Gets the string representation of a mining ID object.
//!
struct MiningIdToStringVisitor
{
//!
//! \brief Call the mining ID variant type's \c ToString() method directly.
//!
//! \param variant The object to create a string for.
//!
//! \return The string representation of the mining ID.
//!
template<typename T>
std::string operator()(const T& variant) const
{
return variant.ToString();
}
};
} // anonymous namespace
// -----------------------------------------------------------------------------
// Class: Cpid
// -----------------------------------------------------------------------------
Cpid::Cpid(const std::vector<unsigned char>& bytes)
{
if (bytes.size() == 16) {
std::copy_n(bytes.begin(), 16, m_bytes.begin());
} else {
m_bytes.fill(0x00);
}
}
Cpid Cpid::Parse(const std::string& hex)
{
if (hex.size() != 32) {
return Cpid();
}
return Cpid(ParseHex(hex));
}
Cpid Cpid::Hash(const std::string& internal, const std::string& email)
{
if (internal.empty() || email.empty()) {
return Cpid();
}
Cpid cpid;
// Even though the internal CPID is hex-encoded, BOINC creates the external
// CPID hash from the hex string, not from the encoded bytes:
//
std::vector<unsigned char> input(internal.begin(), internal.end());
input.insert(input.end(), email.begin(), email.end());
MD5(input.data(), input.size(), cpid.m_bytes.data());
return cpid;
}
bool Cpid::IsZero() const
{
const auto zero = [](const unsigned char& i) { return i == 0; };
return std::all_of(m_bytes.begin(), m_bytes.end(), zero);
}
bool Cpid::Matches(const std::string& internal, const std::string& email) const
{
return m_bytes == Cpid::Hash(internal, email).m_bytes;
}
std::string Cpid::ToString() const
{
return HexStr(m_bytes.begin(), m_bytes.end());
}
// -----------------------------------------------------------------------------
// Class: MiningId
// -----------------------------------------------------------------------------
MiningId MiningId::Parse(const std::string& input)
{
if (input.empty()) {
return MiningId();
}
if (input == "INVESTOR" || input == "investor") {
return MiningId::ForInvestor();
}
if (input.size() == 32) {
std::vector<unsigned char> bytes = ParseHex(input);
if (bytes.size() == 16) {
return MiningId(Cpid(bytes));
}
}
return MiningId();
}
std::string MiningId::ToString() const
{
return std::visit(MiningIdToStringVisitor(), m_variant);
}
// -----------------------------------------------------------------------------
// Class: MiningId::Invalid
// -----------------------------------------------------------------------------
std::string MiningId::Invalid::ToString() const
{
return std::string();
}
// -----------------------------------------------------------------------------
// Class: MiningId::Investor
// -----------------------------------------------------------------------------
std::string MiningId::Investor::ToString() const
{
return "INVESTOR";
}