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