bitmessage-js/src/worker.cc

98 lines
2.6 KiB
C++
Raw Permalink Normal View History

2015-01-09 21:36:42 +00:00
#include <node.h>
#include <nan.h>
#include "./pow.h"
2023-01-03 04:19:01 +00:00
// using v8::Handle;
2015-01-09 21:36:42 +00:00
using v8::Local;
using v8::FunctionTemplate;
using v8::Function;
using v8::Value;
using v8::Object;
using v8::String;
2015-01-14 22:07:03 +00:00
using v8::Number;
2015-01-09 21:36:42 +00:00
2015-01-14 21:37:23 +00:00
static const uint64_t MAX_SAFE_INTEGER = 9007199254740991ULL;
class PowWorker : public Nan::AsyncWorker {
2015-01-09 21:36:42 +00:00
public:
PowWorker(Nan::Callback* 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)
: Nan::AsyncWorker(callback),
2015-01-09 21:36:42 +00:00
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() {
2015-01-12 17:14:49 +00:00
delete[] initial_hash;
2015-01-09 21:36:42 +00:00
}
// 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 () {
if (error) {
2015-01-10 16:29:33 +00:00
Local<Value> argv[1];
if (error == -1) {
argv[0] = Nan::Error("Max safe integer overflow");
2015-01-10 16:29:33 +00:00
} else {
argv[0] = Nan::Error("Internal error");
2015-01-10 16:29:33 +00:00
}
2015-01-09 21:36:42 +00:00
callback->Call(1, argv);
} else {
Local<Value> argv[] = {Nan::Null(), Nan::New<Number>(nonce)};
2015-01-09 21:36:42 +00:00
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) {
if (info.Length() != 4 ||
!info[0]->IsNumber() || // pool_size
!info[1]->IsNumber() || // target
!node::Buffer::HasInstance(info[2]) || // initial_hash
!info[3]->IsFunction()) { // cb
return Nan::ThrowError("Bad input");
2015-01-11 02:59:32 +00:00
}
2023-01-03 04:19:01 +00:00
size_t pool_size = (size_t)Nan::To<uint32_t>(info[0]).FromJust();
uint64_t target = Nan::To<int64_t>(info[1]).FromJust();
char* buf = node::Buffer::Data(info[2]);
size_t length = node::Buffer::Length(info[2]);
2015-01-14 21:37:23 +00:00
if (pool_size < 1 ||
2015-01-12 18:27:14 +00:00
pool_size > MAX_POOL_SIZE ||
2015-01-14 21:37:23 +00:00
buf == NULL ||
length != HASH_SIZE) {
return Nan::ThrowError("Bad input");
2015-01-09 21:36:42 +00:00
}
2015-01-12 17:14:49 +00:00
uint8_t* initial_hash = new uint8_t[length];
2015-01-11 02:59:32 +00:00
memcpy(initial_hash, buf, length);
Nan::Callback* callback = new Nan::Callback(info[3].As<Function>());
Nan::AsyncQueueWorker(
new PowWorker(callback, pool_size, target, initial_hash));
2015-01-09 21:36:42 +00:00
}
NAN_MODULE_INIT(InitAll) {
Nan::Set(target, Nan::New<String>("powAsync").ToLocalChecked(),
Nan::GetFunction(Nan::New<FunctionTemplate>(PowAsync)).ToLocalChecked());
2015-01-09 21:36:42 +00:00
}
NODE_MODULE(worker, InitAll)