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