@spirobel/monero-wallet-api 0.4.0 → 0.4.1
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/dist/io/atomicWrite.js +2 -1
- package/dist/io/logging.d.ts +40 -0
- package/dist/io/logging.js +172 -0
- package/dist/scanning-syncing/backgroundWorker.d.ts +1 -0
- package/dist/scanning-syncing/backgroundWorker.js +19 -7
- package/dist/scanning-syncing/blocksbuffer/blocksBufferFetchLoop.js +9 -7
- package/dist/scanning-syncing/blocksbuffer/blocksbufferCoordination.js +2 -1
- package/dist/scanning-syncing/scanSettings.d.ts +10 -0
- package/dist/scanning-syncing/scanSettings.js +9 -0
- package/dist/scanning-syncing/scanresult/scanCache.js +7 -3
- package/dist/scanning-syncing/scanresult/scanCoordination.js +63 -72
- package/dist/scanning-syncing/scanresult/scanResult.d.ts +1 -1
- package/dist/scanning-syncing/scanresult/scanResult.js +12 -3
- package/dist/scanning-syncing/worker-entrypoints/worker.js +1 -1
- package/dist/scanning-syncing/worker-mains/coordinator-main.js +3 -2
- package/dist/scanning-syncing/worker-mains/cpubound-main.js +24 -14
- package/dist/scanning-syncing/worker-mains/worker.js +11 -7
- package/package.json +1 -1
package/dist/io/atomicWrite.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { log } from "./logging";
|
|
1
2
|
export async function atomicWrite(targetPath, data) {
|
|
2
|
-
|
|
3
|
+
log("atomicWrite", ["writing to", targetPath]);
|
|
3
4
|
// in the browser we don't have rename + indexedDB writes are atomic in any case
|
|
4
5
|
if (areWeInTheBrowser)
|
|
5
6
|
return await Bun.write(targetPath, data);
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* logging function names registry.
|
|
3
|
+
*
|
|
4
|
+
* useful filter combinations for `scanSettings.json`:
|
|
5
|
+
*
|
|
6
|
+
* "logs": "console",
|
|
7
|
+
* "logs_include": ["handleCpuboundScan", "logBufStatus"]
|
|
8
|
+
* -> cpu worker progress + buffer/work status.
|
|
9
|
+
*
|
|
10
|
+
* "logs_include": ["coordinatorMainMultithreaded", "scheduleWorkOnCpuPorts", "workToBeDoneForBatch"]
|
|
11
|
+
* -> coordinator events: race count, work dispatch, batch decisions.
|
|
12
|
+
*
|
|
13
|
+
* "logs_include": ["blocksBufferFetchLoop", "makeWorkItemsFromBlocksBuffer", "logBufStatus"]
|
|
14
|
+
* -> block fetching, reconciliation, buffer state.
|
|
15
|
+
*
|
|
16
|
+
* "logs_include": ["processScanResult", "processWorkItem", "processScanResultForWorkItem"]
|
|
17
|
+
* -> result processing, cache updates, reorg detection.
|
|
18
|
+
*
|
|
19
|
+
* "logs_include": ["handleConnectionStatusChanges", "handleScanError"]
|
|
20
|
+
* -> connection events and scan errors.
|
|
21
|
+
*
|
|
22
|
+
* "logs": "off" disables all logging.
|
|
23
|
+
* "logs": "file" writes to `<coordinator|cpubound|mainthread>-<id>-<timestamp>.log`.
|
|
24
|
+
* "logs": "console-and-file" writes to file and console.
|
|
25
|
+
*/
|
|
26
|
+
export declare const LOGGING_FUNCTIONS: readonly ["findWorkToBeDone", "workToBeDoneForBatch", "makeWorkItemsFromBlocksBuffer", "reconcileWorkItemDone", "processScanResultForWorkItem", "processWorkItem", "logBufStatus", "coordinatorMain", "coordinatorMainMultithreaded", "scheduleWorkOnCpuPorts", "processScanResult", "handleScanError", "createWebworker", "startWebworker", "blocksBufferFetchLoop", "reduceStartHeightToTip", "handleConnectionStatusChanges", "handleCpuboundScan", "coordinatorMainWorker", "CPU_PORT_HANDLER", "atomicWrite"];
|
|
27
|
+
export type PossibleLogs = (typeof LOGGING_FUNCTIONS)[number];
|
|
28
|
+
export type LogSetting = "console" | "file" | "console-and-file" | "off";
|
|
29
|
+
export type FileLogMessage = {
|
|
30
|
+
timestamp: string;
|
|
31
|
+
message: any;
|
|
32
|
+
};
|
|
33
|
+
export declare function setupLoggingPath(scan_settings_path: string, path_prefix: string, role: "coordinator" | "cpubound" | "mainthread", cpu_worker_id?: number): Promise<{
|
|
34
|
+
logs: LogSetting | undefined;
|
|
35
|
+
logs_include: ("findWorkToBeDone" | "workToBeDoneForBatch" | "makeWorkItemsFromBlocksBuffer" | "reconcileWorkItemDone" | "processScanResultForWorkItem" | "processWorkItem" | "logBufStatus" | "coordinatorMain" | "coordinatorMainMultithreaded" | "scheduleWorkOnCpuPorts" | "processScanResult" | "handleScanError" | "createWebworker" | "startWebworker" | "blocksBufferFetchLoop" | "reduceStartHeightToTip" | "handleConnectionStatusChanges" | "handleCpuboundScan" | "coordinatorMainWorker" | "CPU_PORT_HANDLER" | "atomicWrite")[] | undefined;
|
|
36
|
+
logs_exclude: ("findWorkToBeDone" | "workToBeDoneForBatch" | "makeWorkItemsFromBlocksBuffer" | "reconcileWorkItemDone" | "processScanResultForWorkItem" | "processWorkItem" | "logBufStatus" | "coordinatorMain" | "coordinatorMainMultithreaded" | "scheduleWorkOnCpuPorts" | "processScanResult" | "handleScanError" | "createWebworker" | "startWebworker" | "blocksBufferFetchLoop" | "reduceStartHeightToTip" | "handleConnectionStatusChanges" | "handleCpuboundScan" | "coordinatorMainWorker" | "CPU_PORT_HANDLER" | "atomicWrite")[] | undefined;
|
|
37
|
+
file_logbuffer: FileLogMessage[];
|
|
38
|
+
global_logging_path: string;
|
|
39
|
+
}>;
|
|
40
|
+
export declare function log(fnname: string, message: any): void;
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { getPathPrefix, openScanSettingsFile } from "../api";
|
|
2
|
+
import { atomicWrite } from "./atomicWrite";
|
|
3
|
+
/**
|
|
4
|
+
* logging function names registry.
|
|
5
|
+
*
|
|
6
|
+
* useful filter combinations for `scanSettings.json`:
|
|
7
|
+
*
|
|
8
|
+
* "logs": "console",
|
|
9
|
+
* "logs_include": ["handleCpuboundScan", "logBufStatus"]
|
|
10
|
+
* -> cpu worker progress + buffer/work status.
|
|
11
|
+
*
|
|
12
|
+
* "logs_include": ["coordinatorMainMultithreaded", "scheduleWorkOnCpuPorts", "workToBeDoneForBatch"]
|
|
13
|
+
* -> coordinator events: race count, work dispatch, batch decisions.
|
|
14
|
+
*
|
|
15
|
+
* "logs_include": ["blocksBufferFetchLoop", "makeWorkItemsFromBlocksBuffer", "logBufStatus"]
|
|
16
|
+
* -> block fetching, reconciliation, buffer state.
|
|
17
|
+
*
|
|
18
|
+
* "logs_include": ["processScanResult", "processWorkItem", "processScanResultForWorkItem"]
|
|
19
|
+
* -> result processing, cache updates, reorg detection.
|
|
20
|
+
*
|
|
21
|
+
* "logs_include": ["handleConnectionStatusChanges", "handleScanError"]
|
|
22
|
+
* -> connection events and scan errors.
|
|
23
|
+
*
|
|
24
|
+
* "logs": "off" disables all logging.
|
|
25
|
+
* "logs": "file" writes to `<coordinator|cpubound|mainthread>-<id>-<timestamp>.log`.
|
|
26
|
+
* "logs": "console-and-file" writes to file and console.
|
|
27
|
+
*/
|
|
28
|
+
export const LOGGING_FUNCTIONS = [
|
|
29
|
+
// scanCoordination.ts
|
|
30
|
+
"findWorkToBeDone",
|
|
31
|
+
"workToBeDoneForBatch",
|
|
32
|
+
"makeWorkItemsFromBlocksBuffer",
|
|
33
|
+
"reconcileWorkItemDone",
|
|
34
|
+
"processScanResultForWorkItem",
|
|
35
|
+
"processWorkItem",
|
|
36
|
+
"logBufStatus",
|
|
37
|
+
"coordinatorMain",
|
|
38
|
+
"coordinatorMainMultithreaded",
|
|
39
|
+
"scheduleWorkOnCpuPorts",
|
|
40
|
+
// scanResult.ts
|
|
41
|
+
"processScanResult",
|
|
42
|
+
// scanCache.ts
|
|
43
|
+
"handleScanError",
|
|
44
|
+
// backgroundWorker.ts
|
|
45
|
+
"createWebworker",
|
|
46
|
+
"startWebworker",
|
|
47
|
+
// blocksBufferFetchLoop.ts
|
|
48
|
+
"blocksBufferFetchLoop",
|
|
49
|
+
"reduceStartHeightToTip",
|
|
50
|
+
// blocksbufferCoordination.ts
|
|
51
|
+
"handleConnectionStatusChanges",
|
|
52
|
+
// cpubound-main.ts
|
|
53
|
+
"handleCpuboundScan",
|
|
54
|
+
// coordinator-main.ts
|
|
55
|
+
"coordinatorMainWorker",
|
|
56
|
+
// worker.ts
|
|
57
|
+
"CPU_PORT_HANDLER",
|
|
58
|
+
// io/atomicWrite.ts
|
|
59
|
+
"atomicWrite",
|
|
60
|
+
];
|
|
61
|
+
export async function setupLoggingPath(scan_settings_path, path_prefix, role, cpu_worker_id) {
|
|
62
|
+
const scanSettings = await openScanSettingsFile(scan_settings_path);
|
|
63
|
+
const logs = scanSettings?.logs;
|
|
64
|
+
const logs_include = scanSettings?.logs_include;
|
|
65
|
+
const logs_exclude = scanSettings?.logs_exclude;
|
|
66
|
+
const file_logbuffer = [];
|
|
67
|
+
const logging_path_prefix = getPathPrefix(scan_settings_path, path_prefix);
|
|
68
|
+
const timestamp = new Date().toISOString().slice(0, 19).replace("T", " ");
|
|
69
|
+
const global_logging_path = `${logging_path_prefix}${role}-${cpu_worker_id ?? ""}-${timestamp}.log`;
|
|
70
|
+
const global_log_setup = {
|
|
71
|
+
logs,
|
|
72
|
+
logs_include,
|
|
73
|
+
logs_exclude,
|
|
74
|
+
file_logbuffer,
|
|
75
|
+
global_logging_path,
|
|
76
|
+
};
|
|
77
|
+
globalThis.__global_log_setup = global_log_setup;
|
|
78
|
+
startLogFlusher(global_log_setup);
|
|
79
|
+
return global_log_setup;
|
|
80
|
+
}
|
|
81
|
+
function safeStringify(value) {
|
|
82
|
+
try {
|
|
83
|
+
return JSON.stringify(value, (_key, v) => {
|
|
84
|
+
if (typeof v === "bigint")
|
|
85
|
+
return v.toString();
|
|
86
|
+
if (typeof v === "function")
|
|
87
|
+
return `fn ${v.name || "anon"}`;
|
|
88
|
+
if (v !== null && typeof v === "object") {
|
|
89
|
+
// promise or thenable
|
|
90
|
+
if (typeof v.then === "function") {
|
|
91
|
+
try {
|
|
92
|
+
return typeof Bun !== "undefined" && Bun.inspect
|
|
93
|
+
? Bun.inspect(v)
|
|
94
|
+
: "Promise";
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
return "Promise";
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
// message port
|
|
101
|
+
const ctor = v.constructor;
|
|
102
|
+
if (ctor?.name === "MessagePort")
|
|
103
|
+
return "MessagePort";
|
|
104
|
+
}
|
|
105
|
+
return v;
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
return String(value);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
const flusherRef = new WeakMap();
|
|
113
|
+
function startLogFlusher(setup) {
|
|
114
|
+
if (setup.logs !== "file" && setup.logs !== "console-and-file")
|
|
115
|
+
return;
|
|
116
|
+
if (flusherRef.has(setup))
|
|
117
|
+
return; // already running
|
|
118
|
+
let writtenIndex = 0;
|
|
119
|
+
const id = setInterval(async () => {
|
|
120
|
+
const buffer = setup.file_logbuffer;
|
|
121
|
+
if (buffer.length <= writtenIndex)
|
|
122
|
+
return; // nothing new
|
|
123
|
+
const newEntries = buffer.slice(writtenIndex);
|
|
124
|
+
writtenIndex = buffer.length;
|
|
125
|
+
if (newEntries.length === 0)
|
|
126
|
+
return;
|
|
127
|
+
const lines = newEntries
|
|
128
|
+
.map((e) => `[${e.timestamp}] ${safeStringify(e.message)}`)
|
|
129
|
+
.join("\n");
|
|
130
|
+
try {
|
|
131
|
+
const existing = await Bun.file(setup.global_logging_path)
|
|
132
|
+
.text()
|
|
133
|
+
.catch(() => "");
|
|
134
|
+
const newContent = existing ? existing + "\n" + lines : lines;
|
|
135
|
+
await atomicWrite(setup.global_logging_path, newContent);
|
|
136
|
+
}
|
|
137
|
+
catch (err) {
|
|
138
|
+
console.error("[logFlusher] write failed:", err);
|
|
139
|
+
}
|
|
140
|
+
}, 2000);
|
|
141
|
+
flusherRef.set(setup, id);
|
|
142
|
+
}
|
|
143
|
+
export function log(fnname, message) {
|
|
144
|
+
const setup = globalThis.__global_log_setup;
|
|
145
|
+
if (!setup)
|
|
146
|
+
return;
|
|
147
|
+
const { logs, logs_include, logs_exclude, file_logbuffer } = setup;
|
|
148
|
+
if (logs === "off")
|
|
149
|
+
return;
|
|
150
|
+
// Apply include/exclude filters
|
|
151
|
+
if (logs_include && logs_include.length > 0 && !logs_include.includes(fnname))
|
|
152
|
+
return;
|
|
153
|
+
if (logs_exclude && logs_exclude.includes(fnname))
|
|
154
|
+
return;
|
|
155
|
+
// skip messages that are about writing to the log file itself
|
|
156
|
+
// (prevents atomicWrite calls inside the flusher from feeding back)
|
|
157
|
+
const logPath = setup.global_logging_path;
|
|
158
|
+
if (logPath) {
|
|
159
|
+
const msg = message;
|
|
160
|
+
if ((typeof msg === "string" && msg.includes(logPath)) ||
|
|
161
|
+
(Array.isArray(msg) &&
|
|
162
|
+
msg.some((m) => typeof m === "string" && m.includes(logPath))))
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
const timestamp = new Date().toISOString().slice(0, 19).replace("T", " ");
|
|
166
|
+
if (logs === "console" || logs === "console-and-file") {
|
|
167
|
+
console.log(`[${fnname}]`, ...(Array.isArray(message) ? message : [message]));
|
|
168
|
+
}
|
|
169
|
+
if (logs === "file" || logs === "console-and-file") {
|
|
170
|
+
file_logbuffer.push({ timestamp, message });
|
|
171
|
+
}
|
|
172
|
+
}
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { LOCAL_NODE_DEFAULT_URL } from "../node-interaction/nodeUrl";
|
|
2
2
|
import {} from "./scanresult/scanCache";
|
|
3
|
-
import { openScanSettingsFile } from "./scanSettings";
|
|
3
|
+
import { openScanSettingsFile, SCAN_SETTINGS_STORE_NAME_DEFAULT, } from "./scanSettings";
|
|
4
|
+
import { log, setupLoggingPath } from "../io/logging";
|
|
4
5
|
import { workerMainCode } from "./worker-entrypoints/worker";
|
|
5
|
-
const CPU_POOL_SIZE = 4;
|
|
6
|
+
export const CPU_POOL_SIZE = 4;
|
|
6
7
|
export async function createWebworker(handle_result, scan_settings_path, pathPrefix, handle_error) {
|
|
7
8
|
try {
|
|
8
|
-
const
|
|
9
|
+
const resolvedPath = scan_settings_path || SCAN_SETTINGS_STORE_NAME_DEFAULT;
|
|
10
|
+
const scanSettings = await openScanSettingsFile(resolvedPath);
|
|
11
|
+
await setupLoggingPath(resolvedPath, pathPrefix ?? "", "mainthread");
|
|
9
12
|
const node_url = scanSettings?.node_url || LOCAL_NODE_DEFAULT_URL;
|
|
10
13
|
const cpu_worker_count = typeof scanSettings?.cpu_worker_count !== "undefined"
|
|
11
14
|
? scanSettings?.cpu_worker_count
|
|
@@ -16,7 +19,13 @@ export async function createWebworker(handle_result, scan_settings_path, pathPre
|
|
|
16
19
|
for (let i = 0; i < cpu_worker_count; i++) {
|
|
17
20
|
const channel = new MessageChannel();
|
|
18
21
|
const cpuWorker = await startWebworkerReady();
|
|
19
|
-
cpuWorker.postMessage({
|
|
22
|
+
cpuWorker.postMessage({
|
|
23
|
+
type: "setup",
|
|
24
|
+
role: "cpubound",
|
|
25
|
+
cpu_worker_id: i,
|
|
26
|
+
scan_settings_path: resolvedPath,
|
|
27
|
+
pathPrefix,
|
|
28
|
+
}, [channel.port1]);
|
|
20
29
|
cpuWorker.onerror = (e) => {
|
|
21
30
|
if (handle_error)
|
|
22
31
|
handle_error("cpu worker " + i + " error: " + (e.message ?? String(e)));
|
|
@@ -27,13 +36,16 @@ export async function createWebworker(handle_result, scan_settings_path, pathPre
|
|
|
27
36
|
const coordinationWorker = await startWebworkerReady();
|
|
28
37
|
coordinationWorker.postMessage({
|
|
29
38
|
type: "setup",
|
|
30
|
-
scan_settings_path,
|
|
39
|
+
scan_settings_path: resolvedPath,
|
|
31
40
|
pathPrefix,
|
|
32
41
|
role: "coordinator",
|
|
33
42
|
node_url,
|
|
34
43
|
start_height: 0,
|
|
35
44
|
}, cpuPorts); // transfer CPU port2s to coordination worker
|
|
36
|
-
|
|
45
|
+
log("createWebworker", [
|
|
46
|
+
"coordinator worker started, node_url=" + node_url,
|
|
47
|
+
", cpuPorts=" + cpuPorts.length,
|
|
48
|
+
]);
|
|
37
49
|
coordinationWorker.onmessage = (event) => {
|
|
38
50
|
if (event.data.type === "ERROR") {
|
|
39
51
|
if (handle_error)
|
|
@@ -79,7 +91,7 @@ export function startWebworker(handle_result, handle_error) {
|
|
|
79
91
|
handle_error(event.data.payload ?? event.data.error);
|
|
80
92
|
break;
|
|
81
93
|
case "DEBUG":
|
|
82
|
-
|
|
94
|
+
log("startWebworker", ["worker debug:", event.data.payload]);
|
|
83
95
|
break;
|
|
84
96
|
}
|
|
85
97
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { findRange, get_block_headers_range, get_info, mergeRanges, NodeUrl, sleep, } from "../../api";
|
|
2
2
|
import {} from "../connectionStatus";
|
|
3
|
+
import { log } from "../../io/logging";
|
|
3
4
|
export const MAX_BLOCKS_BUFFER_SIZE = 10;
|
|
4
5
|
// runs forever, fetching blocks from the node.
|
|
5
6
|
// handles scan level reorg detection and catastrophic reorg
|
|
@@ -8,7 +9,7 @@ connection_status, // we make a local copy of this and pass last_packet and sync
|
|
|
8
9
|
max_blocks_buffer_size = MAX_BLOCKS_BUFFER_SIZE, anchor_range, stopSync) {
|
|
9
10
|
connection_status = structuredClone(connection_status);
|
|
10
11
|
const nodeUrl = await NodeUrl.create(node_url);
|
|
11
|
-
|
|
12
|
+
log("blocksBufferFetchLoop", ["NodeUrl:", nodeUrl.node_url, "start:", start_height]);
|
|
12
13
|
start_height = await reduceStartHeightToTip(start_height, nodeUrl.node_url);
|
|
13
14
|
// initialise ranges on first call
|
|
14
15
|
let { current_range, scanned_ranges } = await initScannedRanges(nodeUrl.node_url, start_height, anchor_range ? [anchor_range] : []);
|
|
@@ -38,12 +39,10 @@ max_blocks_buffer_size = MAX_BLOCKS_BUFFER_SIZE, anchor_range, stopSync) {
|
|
|
38
39
|
await sleep(5000);
|
|
39
40
|
continue;
|
|
40
41
|
}
|
|
41
|
-
|
|
42
|
+
log("blocksBufferFetchLoop", ["fetching", nodeUrl.node_url, current_range.start, "->", current_range.end]);
|
|
42
43
|
const get_blocks_bin = await doRPCrequest(nodeUrl, current_range, stopSync);
|
|
43
44
|
const result_meta = await nodeUrl.loadGetBlocksBinResponse(get_blocks_bin);
|
|
44
|
-
|
|
45
|
-
result_meta.block_infos.length +
|
|
46
|
-
" blocks");
|
|
45
|
+
log("blocksBufferFetchLoop", "response: " + result_meta.block_infos.length + " blocks");
|
|
47
46
|
connection_status.last_packet = {
|
|
48
47
|
status: "OK",
|
|
49
48
|
bytes_read: get_blocks_bin.length,
|
|
@@ -343,8 +342,11 @@ export async function reduceStartHeightToTip(start_height, node_url) {
|
|
|
343
342
|
if (start_height > getInfo.height - 1) {
|
|
344
343
|
const oldStartHeight = start_height;
|
|
345
344
|
start_height = getInfo.height - 1;
|
|
346
|
-
|
|
347
|
-
|
|
345
|
+
log("reduceStartHeightToTip", [
|
|
346
|
+
"start height was larger than daemon height, setting start_height=" +
|
|
347
|
+
start_height,
|
|
348
|
+
" oldStartHeight=" + oldStartHeight,
|
|
349
|
+
]);
|
|
348
350
|
}
|
|
349
351
|
return start_height;
|
|
350
352
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { blocksBufferFetchLoop, readWriteConnectionStatusFile, CatastrophicReorgError, readOrInitConnectionStatus, } from "../../api";
|
|
2
|
+
import { log } from "../../io/logging";
|
|
2
3
|
export async function setupBlocksBufferGenerator(params) {
|
|
3
4
|
const blocksBuffer = [];
|
|
4
5
|
const connection_status = await readOrInitConnectionStatus(params.scanSettingsPath);
|
|
@@ -13,7 +14,7 @@ export async function handleConnectionStatusChanges(event, scanSettingsPath) {
|
|
|
13
14
|
cs2.last_packet = event;
|
|
14
15
|
}, scanSettingsPath);
|
|
15
16
|
if (event.status === "catastrophic_reorg") {
|
|
16
|
-
|
|
17
|
+
log("handleConnectionStatusChanges", "catastrophic reorg, stopping");
|
|
17
18
|
throw new CatastrophicReorgError("[blocksbufferCoordinator] catastrophic reorg, stopping");
|
|
18
19
|
}
|
|
19
20
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { LogSetting, PossibleLogs } from "../io/logging";
|
|
1
2
|
export declare const SCAN_SETTINGS_STORE_NAME_DEFAULT = "ScanSettings.json";
|
|
2
3
|
export type ScanSetting = {
|
|
3
4
|
primary_address: string;
|
|
@@ -17,6 +18,9 @@ export type WriteScanSettingParams = {
|
|
|
17
18
|
wallet_route?: string;
|
|
18
19
|
wallet_name?: string;
|
|
19
20
|
wallet_slot?: number;
|
|
21
|
+
logs?: LogSetting;
|
|
22
|
+
logs_include?: PossibleLogs[];
|
|
23
|
+
logs_exclude?: PossibleLogs[];
|
|
20
24
|
};
|
|
21
25
|
export type ScanSettingOpened = {
|
|
22
26
|
primary_address: string;
|
|
@@ -36,6 +40,9 @@ export type ScanSettings = {
|
|
|
36
40
|
start_height: number | null;
|
|
37
41
|
merchant_confirmations?: number | null;
|
|
38
42
|
cpu_worker_count?: number;
|
|
43
|
+
logs?: LogSetting;
|
|
44
|
+
logs_include?: PossibleLogs[];
|
|
45
|
+
logs_exclude?: PossibleLogs[];
|
|
39
46
|
};
|
|
40
47
|
export type ScanSettingsOpened = {
|
|
41
48
|
wallets: (ScanSettingOpened | undefined)[];
|
|
@@ -43,6 +50,9 @@ export type ScanSettingsOpened = {
|
|
|
43
50
|
start_height: number | null;
|
|
44
51
|
merchant_confirmations?: number | null;
|
|
45
52
|
cpu_worker_count?: number;
|
|
53
|
+
logs?: LogSetting;
|
|
54
|
+
logs_include?: PossibleLogs[];
|
|
55
|
+
logs_exclude?: PossibleLogs[];
|
|
46
56
|
};
|
|
47
57
|
/**
|
|
48
58
|
* Writes scan settings to the default or specified storage file in json.
|
|
@@ -239,10 +239,19 @@ export async function writeWalletToScanSettings(params) {
|
|
|
239
239
|
},
|
|
240
240
|
],
|
|
241
241
|
node_url: params.node_url,
|
|
242
|
+
logs: params.logs,
|
|
243
|
+
logs_include: params.logs_include,
|
|
244
|
+
logs_exclude: params.logs_exclude,
|
|
242
245
|
start_height: params.start_height || null,
|
|
243
246
|
}, params.scan_settings_path);
|
|
244
247
|
}
|
|
245
248
|
scanSettings.node_url = params.node_url || scanSettings.node_url;
|
|
249
|
+
if (params.logs)
|
|
250
|
+
scanSettings.logs = params.logs;
|
|
251
|
+
if (params.logs_include)
|
|
252
|
+
scanSettings.logs_include = params.logs_include;
|
|
253
|
+
if (params.logs_exclude)
|
|
254
|
+
scanSettings.logs_exclude = params.logs_exclude;
|
|
246
255
|
scanSettings.start_height =
|
|
247
256
|
params.start_height === undefined
|
|
248
257
|
? scanSettings.start_height
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {} from "./computeKeyImage";
|
|
2
2
|
import { get_block_headers_range, } from "../../api";
|
|
3
3
|
import { atomicWrite } from "../../io/atomicWrite";
|
|
4
|
+
import { log } from "../../io/logging";
|
|
4
5
|
export async function initScanCache(viewpair, start_height, scan_settings_path, pathPrefix) {
|
|
5
6
|
const initialCache = await readCacheFileDefaultLocation(viewpair.primary_address, pathPrefix);
|
|
6
7
|
let cache = {
|
|
@@ -161,7 +162,7 @@ export function handleScanError(error) {
|
|
|
161
162
|
// treat errno 0 code "ConnectionRefused" as non fatal outcome, and rethrow,
|
|
162
163
|
// so that UI can be informed after catching it higher up
|
|
163
164
|
if (isConnectionError(error)) {
|
|
164
|
-
|
|
165
|
+
log("handleScanError", "Scan stopped. node might be offline. Connection Refused");
|
|
165
166
|
throw error;
|
|
166
167
|
}
|
|
167
168
|
// Treat AbortError as a normal, non-fatal outcome
|
|
@@ -169,11 +170,14 @@ export function handleScanError(error) {
|
|
|
169
170
|
typeof error === "object" &&
|
|
170
171
|
(("name" in error && error.name === "AbortError") ||
|
|
171
172
|
("code" in error && error.code === 20))) {
|
|
172
|
-
|
|
173
|
+
log("handleScanError", "Scan was aborted.");
|
|
173
174
|
return;
|
|
174
175
|
}
|
|
175
176
|
else {
|
|
176
|
-
|
|
177
|
+
log("handleScanError", [
|
|
178
|
+
error,
|
|
179
|
+
"\n, scanWithCache in scanning-syncing/scanWithCache.ts`",
|
|
180
|
+
]);
|
|
177
181
|
throw error;
|
|
178
182
|
}
|
|
179
183
|
}
|