nano-pow 4.0.5 → 4.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +105 -26
- package/dist/bin/nano-pow.sh +1 -1
- package/dist/bin/server.js +9 -14
- package/dist/main.min.js +13 -5
- package/docs/index.js +2 -2
- package/docs/nano-pow.1 +78 -7
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -17,8 +17,10 @@ https://docs.nano.org/integration-guides/work-generation/#work-calculation-detai
|
|
|
17
17
|
|
|
18
18
|
## Installation
|
|
19
19
|
```console
|
|
20
|
-
npm i nano-pow
|
|
20
|
+
$ npm i nano-pow
|
|
21
21
|
```
|
|
22
|
+
NanoPow can also be installed globally to add the `nano-pow` command to your
|
|
23
|
+
environment. To learn more, see [#Executables](#executables).
|
|
22
24
|
|
|
23
25
|
## Usage
|
|
24
26
|
### Import
|
|
@@ -46,17 +48,17 @@ Use it directly on a webpage with a script module:
|
|
|
46
48
|
<script type="module">
|
|
47
49
|
(async () => {
|
|
48
50
|
const { NanoPow } = await import('https://cdn.jsdelivr.net/npm/nano-pow@latest')
|
|
49
|
-
const work = await NanoPow.
|
|
51
|
+
const { work } = await NanoPow.work_generate(some_hash)
|
|
50
52
|
console.log(work)
|
|
51
53
|
})()
|
|
52
54
|
</script>
|
|
53
55
|
```
|
|
54
56
|
|
|
55
|
-
###
|
|
57
|
+
### Generate
|
|
56
58
|
```javascript
|
|
57
59
|
// `hash` is a 64-char hex string
|
|
58
60
|
const hash = '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'
|
|
59
|
-
const work = await NanoPow.
|
|
61
|
+
const { work } = await NanoPow.work_generate(hash)
|
|
60
62
|
// Result is a 16-char hex string
|
|
61
63
|
```
|
|
62
64
|
|
|
@@ -66,29 +68,112 @@ const work = await NanoPow.search(hash)
|
|
|
66
68
|
const work = 'fedcba0987654321'
|
|
67
69
|
// `hash` is a 64-char hex string
|
|
68
70
|
const hash = '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef'
|
|
69
|
-
const
|
|
71
|
+
const { valid } = await NanoPow.work_validate(work, hash)
|
|
70
72
|
// Result is a boolean
|
|
71
73
|
```
|
|
72
74
|
|
|
73
75
|
### Options
|
|
74
76
|
```javascript
|
|
75
77
|
const options = {
|
|
76
|
-
// default
|
|
78
|
+
// default 0xFFFFFFF800000000 for send/change blocks
|
|
77
79
|
threshold: number,
|
|
78
80
|
// default 8, valid range 1-32
|
|
79
81
|
effort: number,
|
|
80
82
|
// default false
|
|
81
83
|
debug: true
|
|
82
84
|
}
|
|
83
|
-
const work = await NanoPow.
|
|
85
|
+
const { work } = await NanoPow.work_generate(hash, options)
|
|
84
86
|
```
|
|
85
87
|
|
|
86
|
-
|
|
88
|
+
## Executables
|
|
87
89
|
NanoPow can be installed globally and executed from the command line. This is
|
|
88
90
|
useful for systems without a graphical interface.
|
|
89
91
|
```console
|
|
90
92
|
$ npm -g i nano-pow
|
|
91
|
-
$ nano-pow --help
|
|
93
|
+
$ nano-pow --help # view abbreviated CLI help
|
|
94
|
+
$ man nano-pow # view full manual
|
|
95
|
+
```
|
|
96
|
+
Ensure you have proper permissions on your
|
|
97
|
+
[npm `prefix`](https://docs.npmjs.com/cli/v11/commands/npm-prefix) directory and
|
|
98
|
+
have configured your `PATH` accordingly.
|
|
99
|
+
|
|
100
|
+
For example, this adds a user-specific directory for local binaries to `PATH`
|
|
101
|
+
upon login and configures `npm prefix` to use it for global installations:
|
|
102
|
+
```console
|
|
103
|
+
$ echo 'PATH="$HOME/.local/bin:$PATH"' >> .bashrc
|
|
104
|
+
$ npm config set prefix="$HOME/.local"
|
|
105
|
+
```
|
|
106
|
+
### Command Line
|
|
107
|
+
NanoPow provides a shell command—`nano-pow`—to accomodate systems
|
|
108
|
+
without a graphical user interface. It launches a headless Chrome browser using
|
|
109
|
+
`puppeteer` to access the required WebGPU or WebGL APIs. Use the `--global` flag
|
|
110
|
+
when installing to add the executable script to your system.
|
|
111
|
+
```console
|
|
112
|
+
$ npm i -g nano-pow
|
|
113
|
+
```
|
|
114
|
+
Some examples are provided below, and for full documentation, read the manual
|
|
115
|
+
with `man nano-pow`.
|
|
116
|
+
|
|
117
|
+
```console
|
|
118
|
+
$ # Generate a work value using default settings and debugging output enabled.
|
|
119
|
+
$ nano-pow --debug 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
|
|
120
|
+
```
|
|
121
|
+
```console
|
|
122
|
+
$ # Generate work using customized behavior with options.
|
|
123
|
+
$ nano-pow --effort 32 --threshold FFFFFFC000000000 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
|
|
124
|
+
```
|
|
125
|
+
```console
|
|
126
|
+
$ # Validate an existing work nonce against a blockhash.
|
|
127
|
+
nano-pow --validate fedcba9876543210 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
|
|
128
|
+
```
|
|
129
|
+
```console
|
|
130
|
+
$ # Process blockhashes in batches to reduce the initial startup overhead.
|
|
131
|
+
$ nano-pow 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef [...]
|
|
132
|
+
$ # OR
|
|
133
|
+
nano-pow $(cat /path/to/hashes/file)
|
|
134
|
+
$ # OR
|
|
135
|
+
$ cat /path/to/hashes/file | nano-pow
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Server
|
|
139
|
+
NanoPow also provides a basic work server similar to the one included in the
|
|
140
|
+
official Nano node software. The installed command will launch the server in a
|
|
141
|
+
detached process, and you can also start it yourself to customize behavior by
|
|
142
|
+
executing the server script directly.
|
|
143
|
+
|
|
144
|
+
`PORT` can be passed as an environment variable and defaults to 3000 if not
|
|
145
|
+
specified.
|
|
146
|
+
|
|
147
|
+
`NANO_POW_EFFORT` can also be passed as an environment variable to increase
|
|
148
|
+
or decrease the demand on the GPU and defaults to 8 if not specified.
|
|
149
|
+
|
|
150
|
+
```console
|
|
151
|
+
$ # Launch the server and detach from the current session
|
|
152
|
+
$ PORT=8080 nano-pow --server
|
|
153
|
+
$ # View process ID for "NanoPow Server"
|
|
154
|
+
$ cat ~/.nano-pow/server.pid
|
|
155
|
+
$ # Display list of server logs
|
|
156
|
+
$ ls ~/.nano-pow/logs/
|
|
157
|
+
$ # Find process ID manually
|
|
158
|
+
$ ps aux | grep NanoPow
|
|
159
|
+
```
|
|
160
|
+
Work is generated or validated by sending an HTTP `POST` request to the
|
|
161
|
+
configured hostname or IP address of the machine. Some basic help is available
|
|
162
|
+
via `GET` request.
|
|
163
|
+
```console
|
|
164
|
+
$ # Generate a work value
|
|
165
|
+
$ curl -d '{
|
|
166
|
+
"action": "work_generate",
|
|
167
|
+
"hash": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
168
|
+
}' localhost:3000
|
|
169
|
+
```
|
|
170
|
+
```console
|
|
171
|
+
$ # Validate a work value
|
|
172
|
+
$ curl -d '{
|
|
173
|
+
"action": "work_validate",
|
|
174
|
+
"work": "e45835c3b291c3d1",
|
|
175
|
+
"hash": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
176
|
+
}' localhost:3000
|
|
92
177
|
```
|
|
93
178
|
|
|
94
179
|
## Notes
|
|
@@ -106,21 +191,16 @@ for all other accounts.
|
|
|
106
191
|
* 𝘵𝘩𝘳𝘦𝘴𝘩𝘰𝘭𝘥 is 0xFFFFFFF800000000 for send/change blocks and 0xFFFFFE0000000000
|
|
107
192
|
for receive/open/epoch blocks.
|
|
108
193
|
|
|
109
|
-
The threshold is implemented in code as only the first 32 bits due to WGSL only
|
|
110
|
-
supporting u32 integer types, but the result is the same. For example, if
|
|
111
|
-
checking whether a two-digit number xx > 55, and it is known that the first
|
|
112
|
-
digit is 6, it is also automatically known that xx is greater than 55. The
|
|
113
|
-
default threshold used is the send/change difficulty. Any other threshold can be
|
|
114
|
-
specified in practice.
|
|
115
|
-
|
|
116
194
|
The BLAKE2b implementation has been optimized to the extreme for this package
|
|
117
|
-
due to the very narrow use case to which it is applied. The compute shader
|
|
118
|
-
consequently immense, but the goal is to squeeze
|
|
119
|
-
performance out of it.
|
|
195
|
+
due to the very narrow use case to which it is applied. The compute shader used
|
|
196
|
+
by the WebGPU implementation is consequently immense, but the goal is to squeeze
|
|
197
|
+
every last bit of speed and performance out of it.
|
|
120
198
|
|
|
121
199
|
## Tests
|
|
122
|
-
|
|
123
|
-
|
|
200
|
+
A few basic tests are availabe in the source repository.
|
|
201
|
+
* `test/index.html` in the source repository contains a web interface to change
|
|
202
|
+
execution options and compare results.
|
|
203
|
+
* `test/script.sh` starts the `nano-pow` server and sends some basic requests.
|
|
124
204
|
|
|
125
205
|
## Building
|
|
126
206
|
1. Clone source
|
|
@@ -128,11 +208,10 @@ speed of this tool. Feel free to check out how your system fares.
|
|
|
128
208
|
1. Install dev dependencies
|
|
129
209
|
1. Compile, minify, and bundle
|
|
130
210
|
|
|
131
|
-
```
|
|
132
|
-
git clone https://zoso.dev/nano-pow.git
|
|
133
|
-
cd nano-pow
|
|
134
|
-
npm i
|
|
135
|
-
npm run build
|
|
211
|
+
```console
|
|
212
|
+
$ git clone https://zoso.dev/nano-pow.git
|
|
213
|
+
$ cd nano-pow
|
|
214
|
+
$ npm i
|
|
136
215
|
```
|
|
137
216
|
|
|
138
217
|
## Reporting Bugs
|
package/dist/bin/nano-pow.sh
CHANGED
|
@@ -10,7 +10,7 @@ NANO_POW_LOGS="$NANO_POW_HOME"/logs;
|
|
|
10
10
|
mkdir -p "$NANO_POW_LOGS";
|
|
11
11
|
if [ "$1" = '--server' ]; then
|
|
12
12
|
shift;
|
|
13
|
-
node "$SCRIPT_DIR"/server.js
|
|
13
|
+
node "$SCRIPT_DIR"/server.js > "$NANO_POW_LOGS"/nano-pow-server-$(date +%s).log 2>&1 & echo "$!" > "$NANO_POW_HOME"/server.pid;
|
|
14
14
|
else
|
|
15
15
|
node "$SCRIPT_DIR"/cli.js "$@";
|
|
16
16
|
fi;
|
package/dist/bin/server.js
CHANGED
|
@@ -9,6 +9,7 @@ import * as os from "node:os";
|
|
|
9
9
|
import * as puppeteer from "puppeteer";
|
|
10
10
|
import { serverHelp } from "../../docs/index.js";
|
|
11
11
|
const PORT = process.env.PORT || 3e3;
|
|
12
|
+
const EFFORT = +(process.env.NANO_POW_EFFORT || 8);
|
|
12
13
|
function log(...args) {
|
|
13
14
|
console.log(new Date(Date.now()).toLocaleString(), "NanoPow", args);
|
|
14
15
|
}
|
|
@@ -28,13 +29,10 @@ async function work_generate(res, json) {
|
|
|
28
29
|
return;
|
|
29
30
|
}
|
|
30
31
|
try {
|
|
31
|
-
const result = await page.evaluate(async (
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
if (args.difficulty) options.threshold = BigInt(`0x${args.difficulty}`);
|
|
36
|
-
return await window.NanoPow.work_generate(args.hash, options);
|
|
37
|
-
}, json);
|
|
32
|
+
const result = await page.evaluate(async (json2, options) => {
|
|
33
|
+
if (json2.difficulty) options.threshold = BigInt(`0x${json2.difficulty}`);
|
|
34
|
+
return await window.NanoPow.work_generate(json2.hash, options);
|
|
35
|
+
}, json, { debug: true, effort: EFFORT });
|
|
38
36
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
39
37
|
res.end(JSON.stringify(result));
|
|
40
38
|
} catch (err) {
|
|
@@ -60,13 +58,10 @@ async function work_validate(res, json) {
|
|
|
60
58
|
return;
|
|
61
59
|
}
|
|
62
60
|
try {
|
|
63
|
-
const result = await page.evaluate(async (
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
if (args.difficulty) options.threshold = BigInt(`0x${args.difficulty}`);
|
|
68
|
-
return await window.NanoPow.work_validate(args.work, args.hash, options);
|
|
69
|
-
}, json);
|
|
61
|
+
const result = await page.evaluate(async (json2, options) => {
|
|
62
|
+
if (json2.difficulty) options.threshold = BigInt(`0x${json2.difficulty}`);
|
|
63
|
+
return await window.NanoPow.work_validate(json2.work, json2.hash, options);
|
|
64
|
+
}, json, { debug: true, effort: EFFORT });
|
|
70
65
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
71
66
|
res.end(JSON.stringify(result));
|
|
72
67
|
} catch (err) {
|
package/dist/main.min.js
CHANGED
|
@@ -43,6 +43,7 @@ layout(location=0)in vec4 position;void main(){gl_Position=position;}`;
|
|
|
43
43
|
var NanoPowGl = class _NanoPowGl {
|
|
44
44
|
static #SEND = 0xfffffff800000000n;
|
|
45
45
|
static #RECEIVE = 0xfffffe0000000000n;
|
|
46
|
+
static #isInitialized = false;
|
|
46
47
|
static #busy = false;
|
|
47
48
|
static #debug = false;
|
|
48
49
|
static #raf = 0;
|
|
@@ -187,12 +188,13 @@ var NanoPowGl = class _NanoPowGl {
|
|
|
187
188
|
this.#gl.bindBuffer(this.#gl.UNIFORM_BUFFER, null);
|
|
188
189
|
this.#query = this.#gl.createQuery();
|
|
189
190
|
this.#pixels = new Uint32Array(this.size * 4);
|
|
190
|
-
console.log(`NanoPow WebGL initialized at ${this.#gl.drawingBufferWidth}x${this.#gl.drawingBufferHeight}. Maximum nonces checked per frame: ${this.size}`);
|
|
191
191
|
} catch (err) {
|
|
192
192
|
throw new Error("WebGL initialization failed.", { cause: err });
|
|
193
193
|
} finally {
|
|
194
194
|
this.#busy = false;
|
|
195
195
|
}
|
|
196
|
+
this.#isInitialized = true;
|
|
197
|
+
console.log(`NanoPow WebGL initialized at ${this.#gl.drawingBufferWidth}x${this.#gl.drawingBufferHeight}. Maximum nonces checked per frame: ${this.size}`);
|
|
196
198
|
}
|
|
197
199
|
/**
|
|
198
200
|
* On WebGL context loss, attempts to clear all program variables and then
|
|
@@ -358,6 +360,7 @@ var NanoPowGl = class _NanoPowGl {
|
|
|
358
360
|
}, 100);
|
|
359
361
|
});
|
|
360
362
|
}
|
|
363
|
+
if (this.#isInitialized === false) this.init();
|
|
361
364
|
this.#busy = true;
|
|
362
365
|
if (typeof options?.threshold === "string") {
|
|
363
366
|
try {
|
|
@@ -442,6 +445,7 @@ var NanoPowGl = class _NanoPowGl {
|
|
|
442
445
|
}, 100);
|
|
443
446
|
});
|
|
444
447
|
}
|
|
448
|
+
if (this.#isInitialized === false) this.init();
|
|
445
449
|
this.#busy = true;
|
|
446
450
|
if (typeof options?.threshold === "string") {
|
|
447
451
|
try {
|
|
@@ -514,6 +518,7 @@ var NanoPowGpu = class _NanoPowGpu {
|
|
|
514
518
|
static #SEND = 0xfffffff800000000n;
|
|
515
519
|
static #RECEIVE = 0xfffffe0000000000n;
|
|
516
520
|
// Initialize WebGPU
|
|
521
|
+
static #isInitialized = false;
|
|
517
522
|
static #busy = false;
|
|
518
523
|
static #debug = false;
|
|
519
524
|
static #device = null;
|
|
@@ -543,6 +548,7 @@ var NanoPowGpu = class _NanoPowGpu {
|
|
|
543
548
|
} finally {
|
|
544
549
|
this.#busy = false;
|
|
545
550
|
}
|
|
551
|
+
this.#isInitialized = true;
|
|
546
552
|
}
|
|
547
553
|
static setup() {
|
|
548
554
|
if (this.#device == null) throw new Error(`WebGPU device failed to load.`);
|
|
@@ -704,6 +710,7 @@ var NanoPowGpu = class _NanoPowGpu {
|
|
|
704
710
|
}, 100);
|
|
705
711
|
});
|
|
706
712
|
}
|
|
713
|
+
if (this.#isInitialized === false) this.init();
|
|
707
714
|
this.#busy = true;
|
|
708
715
|
if (typeof options?.threshold === "string") {
|
|
709
716
|
try {
|
|
@@ -773,6 +780,7 @@ var NanoPowGpu = class _NanoPowGpu {
|
|
|
773
780
|
}, 100);
|
|
774
781
|
});
|
|
775
782
|
}
|
|
783
|
+
if (this.#isInitialized === false) this.init();
|
|
776
784
|
this.#busy = true;
|
|
777
785
|
if (typeof options?.threshold === "string") {
|
|
778
786
|
try {
|
|
@@ -824,15 +832,15 @@ var NanoPowGpu = class _NanoPowGpu {
|
|
|
824
832
|
var isGlSupported;
|
|
825
833
|
var isGpuSupported = false;
|
|
826
834
|
try {
|
|
827
|
-
await
|
|
828
|
-
isGpuSupported =
|
|
835
|
+
const adapter = await navigator?.gpu?.requestAdapter?.();
|
|
836
|
+
isGpuSupported = adapter instanceof GPUAdapter;
|
|
829
837
|
} catch (err) {
|
|
830
838
|
console.warn("WebGPU is not supported in this environment.\n", err);
|
|
831
839
|
isGpuSupported = false;
|
|
832
840
|
}
|
|
833
841
|
try {
|
|
834
|
-
|
|
835
|
-
isGlSupported =
|
|
842
|
+
const gl = new OffscreenCanvas(0, 0)?.getContext?.("webgl2");
|
|
843
|
+
isGlSupported = gl instanceof WebGL2RenderingContext;
|
|
836
844
|
} catch (err) {
|
|
837
845
|
console.warn("WebGL is not supported in this environment.\n", err);
|
|
838
846
|
isGlSupported = false;
|
package/docs/index.js
CHANGED
|
@@ -8,14 +8,14 @@ Prints a 16-character hexadecimal work value to standard output. If using --vali
|
|
|
8
8
|
|
|
9
9
|
-h, --help show this dialog
|
|
10
10
|
-d, --debug enable additional logging output
|
|
11
|
-
-j, --json
|
|
11
|
+
-j, --json gather all results and output them at once as JSON
|
|
12
12
|
-e, --effort=<value> increase demand on GPU processing
|
|
13
13
|
-t, --threshold=<value> override the minimum threshold value
|
|
14
14
|
-v, --validate=<value> check an existing work value instead of searching for one
|
|
15
15
|
|
|
16
16
|
If validating a nonce, it must be a 16-character hexadecimal value.
|
|
17
17
|
Effort must be a decimal number between 1-32.
|
|
18
|
-
Threshold must be a hexadecimal string between
|
|
18
|
+
Threshold must be a hexadecimal string between 1-FFFFFFFFFFFFFFFF.
|
|
19
19
|
|
|
20
20
|
Report bugs: <bug-nano-pow@zoso.dev>
|
|
21
21
|
Full documentation: <https://www.npmjs.com/package/nano-pow>
|
package/docs/nano-pow.1
CHANGED
|
@@ -12,12 +12,19 @@ nano-pow \- proof-of-work generation and validation for Nano cryptocurrency
|
|
|
12
12
|
.SH DESCRIPTION
|
|
13
13
|
Generate work for \fIBLOCKHASH\fR, or multiple work values for \fIBLOCKHASH\fR(es).
|
|
14
14
|
.PP
|
|
15
|
+
If the \fI--server\fR option is provided as the first argument, all other options are ignored and the NanoPow server is started.
|
|
16
|
+
.PP
|
|
15
17
|
\fIBLOCKHASH\fR is a 64-character hexadecimal string. Multiple blockhashes must be separated by whitespace or line breaks.
|
|
16
18
|
.PP
|
|
17
|
-
Prints a 16-character hexadecimal work value
|
|
19
|
+
Prints a 16-character hexadecimal work value, the BLAKE2b result, and the originating hash to standard output as a Javascript object.
|
|
20
|
+
.PP
|
|
21
|
+
If \fB--validate\fR is used, the original work value is returned instead along with validation flags.
|
|
18
22
|
|
|
19
23
|
.SH OPTIONS
|
|
20
24
|
.TP
|
|
25
|
+
\fB--server\fR
|
|
26
|
+
Start work server (see SERVER below). Must be the first argument in order to be recognized.
|
|
27
|
+
.TP
|
|
21
28
|
\fB\-h\fR, \fB\-\-help\fR
|
|
22
29
|
Show this help dialog and exit.
|
|
23
30
|
.TP
|
|
@@ -25,20 +32,64 @@ Show this help dialog and exit.
|
|
|
25
32
|
Enable additional logging output.
|
|
26
33
|
.TP
|
|
27
34
|
\fB\-j\fR, \fB\-\-json\fR
|
|
28
|
-
Format output as JSON.
|
|
35
|
+
Format final output of all hashes as a JSON array of stringified values instead of incrementally returning Javascript objects for each result.
|
|
29
36
|
.TP
|
|
30
37
|
\fB\-e\fR, \fB\-\-effort\fR=\fIEFFORT\fR
|
|
31
38
|
Increase demand on GPU processing. Must be between 1 and 32 inclusive.
|
|
32
39
|
.TP
|
|
33
40
|
\fB\-t\fR, \fB\-\-threshold\fR=\fITHRESHOLD\fR
|
|
34
|
-
Override the minimum threshold value. Higher values increase difficulty. Must be a hexadecimal string between
|
|
41
|
+
Override the minimum threshold value. Higher values increase difficulty. Must be a hexadecimal string between 1 and FFFFFFFFFFFFFFFF inclusive.
|
|
35
42
|
.TP
|
|
36
43
|
\fB\-v\fR, \fB\-\-validate\fR=\fIWORK\fR
|
|
37
|
-
Check an existing work value instead of searching for one.
|
|
44
|
+
Check an existing work value instead of searching for one. If you pass multiple blockhashes, the work value will be validated against each one.
|
|
45
|
+
|
|
46
|
+
.SH SERVER
|
|
47
|
+
Calling \fBnano-pow\fR with the \fI--server\fR option will start the NanoPow work server in a detached process.
|
|
48
|
+
.PP
|
|
49
|
+
It provides work generation and validation via HTTP requests in a similar, but not identical, fashion as the official Nano node.
|
|
50
|
+
.PP
|
|
51
|
+
More specifically, it does not support the \fIuse_peers\fR, \fImultiplier\fR, \fIaccount\fR, \fIversion\fR, \fIblock\fR, and \fIjson_block\fR options.
|
|
52
|
+
.PP
|
|
53
|
+
By default, the server listens on port 3000. To use a different port, set the \fBPORT\fR environment variable before starting the server.
|
|
54
|
+
|
|
55
|
+
.PP
|
|
56
|
+
.EX
|
|
57
|
+
$ PORT=8080 nano-pow --server
|
|
58
|
+
.EE
|
|
59
|
+
|
|
60
|
+
.PP
|
|
61
|
+
The server process ID (PID) is saved to \fB~/.nano-pow/server.pid\fR. Log files are stored in \fB~/.nano-pow/logs/\fR.
|
|
62
|
+
.TP
|
|
63
|
+
To stop the server, terminate it using its PID.
|
|
64
|
+
.EX
|
|
65
|
+
$ cat ~/.nano-pow/server.pid
|
|
66
|
+
12345
|
|
67
|
+
$ kill 12345
|
|
68
|
+
.EE
|
|
69
|
+
.TP
|
|
70
|
+
Alternatively, use \fBpgrep\fR to find the PID by process name:
|
|
71
|
+
.EX
|
|
72
|
+
$ pgrep "NanoPow Server"
|
|
73
|
+
12345
|
|
74
|
+
$ kill $(pgrep "NanoPow Server")
|
|
75
|
+
.EE
|
|
76
|
+
|
|
77
|
+
.PP
|
|
78
|
+
The server accepts HTTP \fBPOST\fR requests to the server's root path (\fB/\fR). Requests should be in JSON format and include an \fBaction\fR field to specify the desired operation.
|
|
79
|
+
.PP
|
|
80
|
+
The following actions are supported:
|
|
81
|
+
.TP
|
|
82
|
+
\fBwork_generate\fR
|
|
83
|
+
Generate a work value for a given blockhash. Requires a \fBhash\fR field containing the 64-character hexadecimal blockhash.
|
|
84
|
+
.TP
|
|
85
|
+
\fBwork_validate\fR
|
|
86
|
+
Validate an existing work value against a blockhash. Requires \fBwork\fR field containing the 16-character hexadecimal work value and a \fBhash\fR field containing the 64-character hexadecimal blockhash.
|
|
87
|
+
.PP
|
|
88
|
+
|
|
38
89
|
|
|
39
|
-
.SH EXAMPLES
|
|
90
|
+
.SH EXAMPLES - CLI
|
|
40
91
|
.PP
|
|
41
|
-
Search for a work nonce for a blockhash using the default threshold
|
|
92
|
+
Search for a work nonce for a blockhash using the default threshold 0xFFFFFFF800000000:
|
|
42
93
|
.EX
|
|
43
94
|
$ nano-pow \fB0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\fR
|
|
44
95
|
.EE
|
|
@@ -46,7 +97,7 @@ $ nano-pow \fB0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\f
|
|
|
46
97
|
.PP
|
|
47
98
|
Search for a work nonce using a custom threshold and increased effort:
|
|
48
99
|
.EX
|
|
49
|
-
$ nano-pow \fB\-t
|
|
100
|
+
$ nano-pow \fB\-t fffffe0000000000 \-e 32 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\fR
|
|
50
101
|
.EE
|
|
51
102
|
|
|
52
103
|
.PP
|
|
@@ -61,6 +112,26 @@ Validate an existing work nonce against a blockhash and show debugging output:
|
|
|
61
112
|
$ nano-pow \fB\-d \-v fedcba9876543210 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\fR
|
|
62
113
|
.EE
|
|
63
114
|
|
|
115
|
+
.SH EXAMPLES - SERVER
|
|
116
|
+
.PP
|
|
117
|
+
Generate a work value:
|
|
118
|
+
.EX
|
|
119
|
+
$ curl -d '{
|
|
120
|
+
"action": "work_generate",
|
|
121
|
+
"hash": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
122
|
+
}' localhost:3000
|
|
123
|
+
.EE
|
|
124
|
+
|
|
125
|
+
.PP
|
|
126
|
+
Validate a work value:
|
|
127
|
+
.EX
|
|
128
|
+
$ curl -d '{
|
|
129
|
+
"action": "work_validate",
|
|
130
|
+
"work": "e45835c3b291c3d1",
|
|
131
|
+
"hash": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
|
|
132
|
+
}' localhost:3000
|
|
133
|
+
.EE
|
|
134
|
+
|
|
64
135
|
.SH AUTHOR
|
|
65
136
|
Written by Chris Duncan.
|
|
66
137
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nano-pow",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.7",
|
|
4
4
|
"description": "Proof-of-work generation and validation with WebGPU/WebGL for Nano cryptocurrency.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"nemo",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"build": "rm -rf {dist,types} && tsc && node esbuild.mjs && cp -p src/bin/nano-pow.sh dist/bin",
|
|
49
49
|
"prepare": "npm run build",
|
|
50
50
|
"start": "./dist/bin/nano-pow.sh --server",
|
|
51
|
-
"test": "./test/script.sh"
|
|
51
|
+
"test": "npm run build && ./test/script.sh"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"@types/node": "^22.13.11",
|