Success/Failure for work packages

Repeat working, send succ/fail msg for work package, added succ/fail
facility
This commit is contained in:
armin 2018-04-25 23:37:19 +02:00
parent ceb8ce0b03
commit f6ed227073
13 changed files with 166 additions and 51 deletions

1
bfclient/.gitignore vendored
View file

@ -1,3 +1,4 @@
/Debug/
/Release/
.clang-format
/RelOpt/

View file

@ -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");

View file

@ -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

View file

@ -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)};
}

View file

@ -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
*

View file

@ -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();
};

View file

@ -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;

View file

@ -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);

View file

@ -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]);
}

View file

@ -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;

View file

@ -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();

View file

@ -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,30 +88,58 @@ 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();
if (!clientSocket.isClosed()) {

View file

@ -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);
}
}