bitmessage-js/src/worker.cc

97 lines
2.3 KiB
C++
Raw Normal View History

2015-01-09 21:36:42 +00:00
#include <node.h>
#include <nan.h>
#include <stdlib.h>
#include "./pow.h"
2015-01-10 13:03:14 +00:00
#define MAX_SAFE_INTEGER 9007199254740991
2015-01-09 22:44:03 +00:00
2015-01-09 21:36:42 +00:00
using node::Buffer;
using v8::Handle;
using v8::Local;
using v8::FunctionTemplate;
using v8::Function;
using v8::Value;
using v8::Object;
using v8::String;
using v8::Integer;
class PowWorker : public NanAsyncWorker {
public:
PowWorker(NanCallback* callback,
2015-01-09 22:09:01 +00:00
size_t pool_size,
uint64_t target,
2015-01-09 21:36:42 +00:00
uint8_t* initial_hash)
: NanAsyncWorker(callback),
pool_size(pool_size),
target(target),
initial_hash(initial_hash) {}
2015-01-10 22:33:30 +00:00
2015-01-09 21:36:42 +00:00
~PowWorker() {
free(initial_hash);
}
// Executed inside the worker-thread.
// It is not safe to access V8, or V8 data structures
// here, so everything we need for input and output
// should go on `this`.
void Execute () {
2015-01-10 13:03:14 +00:00
error = pow(pool_size, target, initial_hash, MAX_SAFE_INTEGER, &nonce);
2015-01-09 21:36:42 +00:00
}
// Executed when the async work is complete
// this function will be run inside the main event loop
// so it is safe to use V8 again
void HandleOKCallback () {
NanScope();
if (error) {
2015-01-10 16:29:33 +00:00
Local<Value> argv[1];
if (error == -1) {
argv[0] = NanError("Max safe integer overflow");
} else {
argv[0] = NanError("Internal error");
}
2015-01-09 21:36:42 +00:00
callback->Call(1, argv);
} else {
Local<Value> argv[] = {NanNull(), NanNew<Integer>(nonce)};
callback->Call(2, argv);
}
}
private:
2015-01-09 22:09:01 +00:00
size_t pool_size;
uint64_t target;
2015-01-09 21:36:42 +00:00
uint8_t* initial_hash;
2015-01-09 22:09:01 +00:00
uint64_t nonce;
2015-01-09 21:36:42 +00:00
int error;
};
NAN_METHOD(PowAsync) {
NanScope();
NanCallback *callback = new NanCallback(args[3].As<Function>());
2015-01-09 22:09:01 +00:00
size_t pool_size = args[0]->Uint32Value();
uint64_t target = args[1]->IntegerValue();
2015-01-09 21:36:42 +00:00
size_t length = Buffer::Length(args[2]->ToObject());
char* buf = Buffer::Data(args[2]->ToObject());
uint8_t* initial_hash = (uint8_t *)malloc(length);
if (initial_hash == NULL) {
2015-01-10 16:29:33 +00:00
Local<Value> argv[] = {NanError("Internal error")};
2015-01-09 21:36:42 +00:00
callback->Call(1, argv);
} else {
memcpy(initial_hash, buf, length);
NanAsyncQueueWorker(
new PowWorker(callback, pool_size, target, initial_hash));
}
NanReturnUndefined();
}
void InitAll(Handle<Object> exports) {
exports->Set(
NanNew<String>("powAsync"),
NanNew<FunctionTemplate>(PowAsync)->GetFunction());
}
NODE_MODULE(worker, InitAll)