Success/Failure for work packages
Repeat working, send succ/fail msg for work package, added succ/fail facility
This commit is contained in:
parent
ceb8ce0b03
commit
f6ed227073
13 changed files with 166 additions and 51 deletions
3
bfclient/.gitignore
vendored
3
bfclient/.gitignore
vendored
|
@ -1,3 +1,4 @@
|
|||
/Debug/
|
||||
/Release/
|
||||
.clang-format
|
||||
.clang-format
|
||||
/RelOpt/
|
||||
|
|
|
@ -39,18 +39,26 @@ void Brainflyer::operator()() {
|
|||
|
||||
comm::Work work;
|
||||
|
||||
try {
|
||||
work = comm.getWork();
|
||||
} catch (runtime_error& e) {
|
||||
log("Failed to retrieve work: ", e.what());
|
||||
return;
|
||||
}
|
||||
while (true) {
|
||||
try {
|
||||
work = comm.getWork();
|
||||
} catch (runtime_error& e) {
|
||||
log("Failed to retrieve work: ", e.what());
|
||||
return;
|
||||
}
|
||||
|
||||
log("Got work", work.repr());
|
||||
performWork(work);
|
||||
if (work.isEmpty()) { // no more work available
|
||||
log("No more work available. Shutting down.");
|
||||
return;
|
||||
}
|
||||
|
||||
log("Got work", work.repr());
|
||||
performWork(work);
|
||||
comm.sendResult(work);
|
||||
}
|
||||
}
|
||||
|
||||
void Brainflyer::performWork(comm::Work work) {
|
||||
void Brainflyer::performWork(comm::Work& work) {
|
||||
// brainflayer compatibility args
|
||||
int nopt_mod = 1;
|
||||
|
||||
|
@ -72,25 +80,28 @@ void Brainflyer::performWork(comm::Work work) {
|
|||
long keys = 0;
|
||||
while (!work_end) {
|
||||
secp256k1_ec_pubkey_batch_incr(4096, nopt_mod, pub_batch, priv_batch, priv);
|
||||
|
||||
keys += 4096;
|
||||
memcpy(priv, priv_batch[4096 - 1], 32); // set next starting key
|
||||
|
||||
int i = checkBatch(pub_batch, 4096);
|
||||
size_t ch_batch_size =
|
||||
work.total >= keys ? 4096 : work.total - (keys - 4096);
|
||||
int i = checkBatch(pub_batch, ch_batch_size);
|
||||
if (i != -1) {
|
||||
util::bytestr b_priv(priv_batch[i], 32);
|
||||
work.key = util::bytestr(priv_batch[i], 32);
|
||||
log("Key found", util::bytestr(priv_batch[i], 32));
|
||||
}
|
||||
|
||||
work_end = true;
|
||||
for (int i = 0; i < 32; i++) {
|
||||
if (priv[i] > priv_to[i]) {
|
||||
work_end = true;
|
||||
break;
|
||||
} else if (priv[i] < priv_to[i]) {
|
||||
if (priv[i] < priv_to[i]) {
|
||||
work_end = false;
|
||||
break;
|
||||
} // equal: continue
|
||||
} else if (priv[i] > priv_to[i]) { // greater: work_end reached
|
||||
break;
|
||||
} // equal: work_end reached
|
||||
}
|
||||
keys += 4096;
|
||||
|
||||
log(keys, "checked");
|
||||
}
|
||||
|
||||
log(keys, "checked");
|
||||
|
|
|
@ -31,7 +31,7 @@ class Brainflyer {
|
|||
int checkBatch(unsigned char (*pub_batch)[65], size_t batch_size);
|
||||
void dumpBatch(unsigned char (*pub_batch)[65],
|
||||
unsigned char (*priv_batch)[32]);
|
||||
void performWork(comm::Work work);
|
||||
void performWork(comm::Work& work);
|
||||
|
||||
/*
|
||||
* Log facilities
|
||||
|
|
|
@ -17,10 +17,10 @@
|
|||
using namespace std;
|
||||
|
||||
#define BATCH_MAX 4096
|
||||
#define WIN_SIZE 16
|
||||
#define WIN_SIZE 21
|
||||
|
||||
int main() {
|
||||
util::bytestr key("b907c3a2a3b27789dfb509b730dd47703c272868");
|
||||
util::bytestr key("db53d9bbd1f3a83b094eeca7dd970bd85b492fa2");
|
||||
|
||||
cout << "Initializing precomputation table" << endl;
|
||||
// init with window size 16, not reading from file
|
||||
|
@ -35,7 +35,7 @@ int main() {
|
|||
thread* threads = new thread[numThreads];
|
||||
cout << "Starting " << numThreads << " threads" << endl;
|
||||
|
||||
// numThreads = 1;
|
||||
numThreads = 1;
|
||||
for (unsigned int i = 0; i < numThreads; i++) {
|
||||
threads[i] = thread{bf::Brainflyer(i, "127.0.0.1", 26765, key)};
|
||||
}
|
||||
|
|
|
@ -23,13 +23,7 @@ using namespace std;
|
|||
Comm::Comm(string host, int port) : port(port), host(host), sock(-1) {}
|
||||
|
||||
Work Comm::getWork(void) {
|
||||
if (sock < 0) {
|
||||
if (!conn()) {
|
||||
ostringstream o;
|
||||
o << "Connection to " << host << ":" << port << " failed";
|
||||
throw runtime_error(o.str());
|
||||
}
|
||||
}
|
||||
checkConn();
|
||||
|
||||
const char cmd[] = "WRK\n";
|
||||
if (send(sock, cmd, strlen(cmd), 0) < 0) {
|
||||
|
@ -42,12 +36,69 @@ Work Comm::getWork(void) {
|
|||
throw runtime_error("Receiving of work failed");
|
||||
}
|
||||
|
||||
buf[wrk_len] = '\0';
|
||||
|
||||
if (!strcmp(buf, "NIL\n")) return (Work());
|
||||
|
||||
string ws = string(buf, wrk_len - 1);
|
||||
Work wrk(ws);
|
||||
|
||||
return (wrk);
|
||||
}
|
||||
|
||||
void Comm::sendResult(Work work) {
|
||||
checkConn();
|
||||
|
||||
const char cmd[] = "RES\n";
|
||||
if (send(sock, cmd, strlen(cmd), 0) < 0) {
|
||||
throw runtime_error("Sending RES failed");
|
||||
}
|
||||
|
||||
string res = work.from.toHex() + " " + work.to.toHex() + " " + "\n";
|
||||
if (send(sock, res.c_str(), res.size(), 0) < 0) {
|
||||
throw runtime_error("Sending work result failed");
|
||||
}
|
||||
|
||||
char buf[1024];
|
||||
ssize_t ack_len;
|
||||
if ((ack_len = recv(sock, buf, 1024, 0)) < 0) {
|
||||
throw runtime_error("Receiving ACK failed");
|
||||
}
|
||||
|
||||
if (work.key.isEmpty()) {
|
||||
if (send(sock, "NIL\n", 4, 0) < 0) {
|
||||
throw runtime_error("Sending NIL ailed");
|
||||
}
|
||||
} else {
|
||||
if (send(sock, "SUC\n", 4, 0) < 0) {
|
||||
throw runtime_error("Sending SUC failed");
|
||||
}
|
||||
|
||||
if ((ack_len = recv(sock, buf, 1024, 0)) < 0) {
|
||||
throw runtime_error("Receiving ACK failed");
|
||||
}
|
||||
|
||||
string key = work.key.toHex() + "\n";
|
||||
if (send(sock, key.c_str(), key.length(), 0) < 0) {
|
||||
throw runtime_error("Sending key failed");
|
||||
}
|
||||
|
||||
if ((ack_len = recv(sock, buf, 1024, 0)) < 0) {
|
||||
throw runtime_error("Receiving ACK failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Comm::checkConn(void) {
|
||||
if (sock < 0) {
|
||||
if (!conn()) {
|
||||
ostringstream o;
|
||||
o << "Connection to " << host << ":" << port << " failed";
|
||||
throw runtime_error(o.str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects socket to server
|
||||
*
|
||||
|
|
|
@ -23,13 +23,14 @@ class Comm {
|
|||
int sock;
|
||||
|
||||
bool conn();
|
||||
std::string retrieve();
|
||||
void checkConn();
|
||||
void disconnect();
|
||||
|
||||
public:
|
||||
Comm(std::string host, int port);
|
||||
|
||||
comm::Work getWork();
|
||||
void sendResult(comm::Work work);
|
||||
|
||||
virtual ~Comm();
|
||||
};
|
||||
|
|
|
@ -15,6 +15,8 @@ namespace comm {
|
|||
|
||||
using namespace std;
|
||||
|
||||
Work::Work() : total(0) {}
|
||||
|
||||
Work::Work(string work_s) {
|
||||
vector<string> wrk_v = split(work_s, " ");
|
||||
assert(wrk_v.size() == 3);
|
||||
|
@ -24,6 +26,8 @@ Work::Work(string work_s) {
|
|||
total = strtol(wrk_v.at(2).c_str(), nullptr, 10);
|
||||
}
|
||||
|
||||
bool Work::isEmpty() { return (total <= 0); }
|
||||
|
||||
vector<string> Work::split(const string s, const string delimiter) {
|
||||
vector<string> split_str;
|
||||
|
||||
|
|
|
@ -20,9 +20,13 @@ class Work {
|
|||
util::bytestr to;
|
||||
long total;
|
||||
|
||||
Work() = default;
|
||||
util::bytestr key;
|
||||
|
||||
Work();
|
||||
Work(std::string work);
|
||||
|
||||
bool isEmpty();
|
||||
|
||||
std::string repr(void);
|
||||
std::vector<std::string> split(std::string s, std::string delimiter);
|
||||
|
||||
|
|
|
@ -59,6 +59,10 @@ void bytestr::set(const byte* fromBytes, int len) {
|
|||
}
|
||||
}
|
||||
|
||||
bool bytestr::isEmpty(void){
|
||||
return bytes.empty();
|
||||
}
|
||||
|
||||
const byte& bytestr::operator[](const int index) const {
|
||||
return (bytes[index]);
|
||||
}
|
||||
|
|
|
@ -31,6 +31,8 @@ class bytestr {
|
|||
void set(const string fromHex);
|
||||
void set(const byte* fromBytes, int len);
|
||||
|
||||
bool isEmpty();
|
||||
|
||||
const byte& operator[](const int index) const;
|
||||
|
||||
size_t size(void) const;
|
||||
|
|
|
@ -18,7 +18,7 @@ public class CnC {
|
|||
public static final int MAX_BITS = 62;
|
||||
|
||||
public static void main(String[] args) {
|
||||
KeyServer.init(19, 3, 1);
|
||||
KeyServer.init(54, 27, 18000000000l);
|
||||
CommServer server = new CommServer(PORT);
|
||||
try {
|
||||
server.listen();
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package org.btcollider.cnc.comm;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStreamWriter;
|
||||
|
@ -86,29 +88,57 @@ public class ClientWorker implements Runnable {
|
|||
ks.setInWork(kr);
|
||||
}
|
||||
|
||||
String work = Long.toHexString(kr.getStart()) + " " + Long.toHexString(kr.getEnd()) + " " + kr.getTotal();
|
||||
|
||||
out.println(work);
|
||||
|
||||
log.debug("Work <{}> sent to {}", work, clientSocket.getInetAddress());
|
||||
if (kr == null) {
|
||||
out.println("NIL");
|
||||
log.debug("Stop work sent to {}", clientSocket.getInetAddress());
|
||||
}
|
||||
else {
|
||||
String work = Long.toHexString(kr.getStart()) + " " + Long.toHexString(kr.getEnd()) + " " + kr.getTotal();
|
||||
out.println(work);
|
||||
log.debug("Work <{}> sent to {}", work, clientSocket.getInetAddress());
|
||||
}
|
||||
}
|
||||
|
||||
private void retrieveResult() {
|
||||
String[] result;
|
||||
try {
|
||||
result = in.readLine().split(" ");
|
||||
String[] result = in.readLine().split(" ");
|
||||
KeyRange kr = new KeyRange(Long.parseLong(result[0], 16), Long.parseLong(result[1], 16));
|
||||
|
||||
synchronized (KeyServer.getInstance()) {
|
||||
KeyServer.getInstance().setSearched(kr);
|
||||
}
|
||||
|
||||
log.debug("Got result for {}", kr);
|
||||
log.debug("Keyrange {} searched", kr);
|
||||
|
||||
out.println("ACK");
|
||||
|
||||
String suc = in.readLine();
|
||||
switch (suc) {
|
||||
case "NIL":
|
||||
log.debug("Keyrange {} unsuccessful", kr);
|
||||
break;
|
||||
case "SUC":
|
||||
log.info("Keyrange {} successful", kr);
|
||||
out.println("ACK");
|
||||
suc = in.readLine();
|
||||
log.info("Found private key {}", suc);
|
||||
writeKey(suc);
|
||||
out.println("ACK");
|
||||
break;
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
log.error("Couldn't read result", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeKey(String key) {
|
||||
try(BufferedWriter writer = new BufferedWriter(new FileWriter("/home/armin/Desktop/cwkey"))){
|
||||
writer.write(key);
|
||||
}catch(IOException e) {
|
||||
log.error("Couldn't write key {} to keyfile", key, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void shutDown() {
|
||||
closeCommChannel();
|
||||
|
|
|
@ -51,7 +51,7 @@ public class KeyServer {
|
|||
public KeyRange getRange() {
|
||||
BitSet keyStart = new BitSet(CnC.MAX_BITS);
|
||||
|
||||
recCollectKey(root, keyStart, index);
|
||||
if(!recCollectKey(root, keyStart, index)) return null;
|
||||
|
||||
BitSet keyEnd = new BitSet(CnC.MAX_BITS);
|
||||
keyEnd.or(keyStart); // set keyEnd to keyStart
|
||||
|
@ -78,6 +78,8 @@ public class KeyServer {
|
|||
}
|
||||
|
||||
public void setInWork(KeyRange keyRange) {
|
||||
if (keyRange == null) return;
|
||||
|
||||
markInWork(BitSet.valueOf(new long[] { keyRange.getStart() }));
|
||||
}
|
||||
|
||||
|
@ -201,7 +203,9 @@ public class KeyServer {
|
|||
assert depth > 0;
|
||||
|
||||
KeyTree root = new KeyTree(true, null);
|
||||
log.info("Starting recGenTree");
|
||||
recGenKeyTree(root, depth - 1);
|
||||
log.info("Ending recGenTree");
|
||||
|
||||
return root;
|
||||
}
|
||||
|
@ -222,7 +226,7 @@ public class KeyServer {
|
|||
recGenKeyTree(right, depth - 1);
|
||||
}
|
||||
|
||||
private void recCollectKey(KeyTree kt, BitSet keyStart, int curIndex) {
|
||||
private boolean recCollectKey(KeyTree kt, BitSet keyStart, int curIndex) {
|
||||
assert curIndex > 0;
|
||||
|
||||
keyStart.set(curIndex, kt.getValue());
|
||||
|
@ -234,33 +238,36 @@ public class KeyServer {
|
|||
if (left.isLeaf() || right.isLeaf()) {
|
||||
assert left.isLeaf() && right.isLeaf(); // fully balanced binary tree by construction
|
||||
|
||||
|
||||
if (!right.isFree() && ! left.isFree()) return false;
|
||||
|
||||
// No choice finish
|
||||
if (!right.isFree())
|
||||
keyStart.set(curIndex - 1, left.getValue());
|
||||
else if (!left.isFree())
|
||||
keyStart.set(curIndex - 1, right.getValue());
|
||||
else if (left.isLeaf() && right.isLeaf()) { // Randomized finish
|
||||
else if (left.isFree() && right.isFree()) { // Randomized finish
|
||||
Random r = new Random();
|
||||
boolean leftFirst = r.nextBoolean();
|
||||
if(leftFirst) keyStart.set(curIndex - 1, left.getValue());
|
||||
else keyStart.set(curIndex - 1, right.getValue());
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// No choice depth-first traversal
|
||||
if (!left.isFree())
|
||||
recCollectKey(right, keyStart, curIndex - 1);
|
||||
return recCollectKey(right, keyStart, curIndex - 1);
|
||||
else if (!right.isFree())
|
||||
recCollectKey(left, keyStart, curIndex - 1);
|
||||
return recCollectKey(left, keyStart, curIndex - 1);
|
||||
else { // Randomized depth-first traversal
|
||||
Random r = new Random();
|
||||
boolean leftFirst = r.nextBoolean();
|
||||
if (leftFirst)
|
||||
recCollectKey(left, keyStart, curIndex - 1);
|
||||
return recCollectKey(left, keyStart, curIndex - 1);
|
||||
else
|
||||
recCollectKey(right, keyStart, curIndex - 1);
|
||||
return recCollectKey(right, keyStart, curIndex - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue