-
Notifications
You must be signed in to change notification settings - Fork 39
/
miner.cpp
115 lines (108 loc) · 4.41 KB
/
miner.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
#include "../core/crypto.hpp"
#include "../core/helpers.hpp"
#include "../core/api.hpp"
#include "../core/crypto.hpp"
#include "../core/merkle_tree.hpp"
#include "../core/host_manager.hpp"
#include "../core/logger.hpp"
#include "../core/user.hpp"
#include <iostream>
#include <mutex>
#include <set>
#include <thread>
using namespace std;
#define SERVER
void run_mining(PublicWalletAddress wallet, HostManager& hosts) {
TransactionAmount allEarnings = 0;
BloomFilter bf;
while(true) {
try {
std::pair<string,int> bestHost = hosts.getLongestChainHost();
if (bestHost.first == "") {
Logger::logStatus("no host found");
} else {
Logger::logStatus("fetching problem from " + bestHost.first);
}
int bestCount = bestHost.second;
string host = bestHost.first;
int nextBlock = bestCount + 1;
json problem = getMiningProblem(host);
Logger::logStatus("Got problem. Difficulty=" + to_string(problem["challengeSize"]));
// download transactions
int count = 0;
vector<Transaction> transactions;
readRawTransactionsForBlock(host, nextBlock, [&nextBlock, &count, &transactions](Transaction t) {
transactions.push_back(t);
count++;
});
stringstream s;
s<<"Read "<<count<<" transactions from "<<host;
Logger::logStatus(s.str());
string lastHashStr = problem["lastHash"];
SHA256Hash lastHash = stringToSHA256(lastHashStr);
int challengeSize = problem["challengeSize"];
// create fee to our wallet:
Transaction fee(wallet, nextBlock);
Block newBlock;
newBlock.setId(nextBlock);
newBlock.addTransaction(fee);
set<string> nonces;
TransactionAmount total = MINING_FEE;
if (newBlock.getId() >= MINING_PAYMENTS_UNTIL) {
total = 0;
}
for(auto t : transactions) {
if (nonces.find(t.getNonce()) != nonces.end()) continue;
newBlock.addTransaction(t);
total += t.getTransactionFee();
nonces.insert(t.getNonce());
}
allEarnings += total;
MerkleTree m;
m.setItems(newBlock.getTransactions());
newBlock.setMerkleRoot(m.getRootHash());
newBlock.setDifficulty(challengeSize);
newBlock.setLastBlockHash(lastHash);
SHA256Hash hash = newBlock.getHash();
SHA256Hash solution = mineHash(hash, challengeSize);
newBlock.setNonce(solution);
auto result = submitBlock(host, newBlock);
Logger::logStatus(result.dump(4));
if (string(result["status"]) == "SUCCESS") {
Logger::logStatus("================BLOCK ACCEPTED=================");
Logger::logStatus("Earned:" + std::to_string(total/DECIMAL_SCALE_FACTOR));
Logger::logStatus("Total:" + std::to_string(allEarnings/DECIMAL_SCALE_FACTOR));
}
// std::this_thread::sleep_for(std::chrono::milliseconds(15000));
} catch (const std::exception& e) {
Logger::logError("run_mining", string(e.what()));
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
}
}
int main(int argc, char **argv) {
#ifdef SERVER
string configFile = DEFAULT_CONFIG_FILE_PATH;
if (argc > 1 ) {
configFile = string(argv[1]);
}
json config = readJsonFromFile(configFile);
int port = config["port"];
HostManager hosts(config);
Logger::logStatus("Running miner");
string file = "./keys/miner2.json";
json info = readJsonFromFile(file);
PublicWalletAddress wallet = stringToWalletAddress(info["wallet"]);
Logger::logStatus("Mining to wallet: " + walletAddressToString(wallet));
#else
json config;
config["hostSources"] = json::array();
config["hostSources"].push_back("http://ec2-34-218-176-84.us-west-2.compute.amazonaws.com/hosts");
HostManager hosts(config);
json keys = readJsonFromFile("./keys.json");
PublicWalletAddress wallet = stringToWalletAddress(keys["wallet"]);
Logger::logStatus("Running miner. Coins stored in : " + string(keys["wallet"]));
#endif
std::thread mining_thread(run_mining, wallet, ref(hosts));
mining_thread.join();
}