@cogcoin/client 1.1.5 → 1.1.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 +2 -2
- package/dist/bitcoind/indexer-daemon.d.ts +3 -7
- package/dist/bitcoind/indexer-daemon.js +39 -204
- package/dist/bitcoind/managed-runtime/bitcoind-policy.d.ts +16 -0
- package/dist/bitcoind/managed-runtime/bitcoind-policy.js +177 -0
- package/dist/bitcoind/managed-runtime/bitcoind-runtime.d.ts +20 -0
- package/dist/bitcoind/managed-runtime/bitcoind-runtime.js +74 -0
- package/dist/bitcoind/managed-runtime/bitcoind-status.d.ts +11 -0
- package/dist/bitcoind/managed-runtime/bitcoind-status.js +44 -0
- package/dist/bitcoind/managed-runtime/indexer-policy.d.ts +34 -0
- package/dist/bitcoind/managed-runtime/indexer-policy.js +200 -0
- package/dist/bitcoind/managed-runtime/indexer-runtime.d.ts +15 -0
- package/dist/bitcoind/managed-runtime/indexer-runtime.js +82 -0
- package/dist/bitcoind/managed-runtime/status.d.ts +11 -0
- package/dist/bitcoind/managed-runtime/status.js +59 -0
- package/dist/bitcoind/managed-runtime/types.d.ts +77 -0
- package/dist/bitcoind/node.d.ts +2 -2
- package/dist/bitcoind/node.js +2 -2
- package/dist/bitcoind/rpc.d.ts +2 -1
- package/dist/bitcoind/rpc.js +53 -3
- package/dist/bitcoind/service.d.ts +2 -7
- package/dist/bitcoind/service.js +79 -207
- package/dist/cli/command-registry.d.ts +1 -1
- package/dist/cli/command-registry.js +2 -64
- package/dist/cli/commands/client-admin.js +3 -18
- package/dist/cli/commands/mining-runtime.js +4 -60
- package/dist/cli/commands/wallet-admin.js +6 -6
- package/dist/cli/context.js +1 -3
- package/dist/cli/mining-json.d.ts +1 -22
- package/dist/cli/mining-json.js +0 -23
- package/dist/cli/output.js +16 -2
- package/dist/cli/parse.js +0 -2
- package/dist/cli/preview-json.d.ts +1 -22
- package/dist/cli/preview-json.js +0 -19
- package/dist/cli/types.d.ts +1 -3
- package/dist/cli/wallet-format.js +1 -1
- package/dist/cli/workflow-hints.d.ts +1 -2
- package/dist/cli/workflow-hints.js +5 -8
- package/dist/wallet/lifecycle/access.d.ts +5 -0
- package/dist/wallet/lifecycle/access.js +79 -0
- package/dist/wallet/lifecycle/context.d.ts +26 -0
- package/dist/wallet/lifecycle/context.js +57 -0
- package/dist/wallet/lifecycle/managed-core.d.ts +1 -9
- package/dist/wallet/lifecycle/managed-core.js +3 -63
- package/dist/wallet/lifecycle/repair-bitcoind.d.ts +10 -0
- package/dist/wallet/lifecycle/repair-bitcoind.js +142 -0
- package/dist/wallet/lifecycle/repair-indexer.d.ts +8 -0
- package/dist/wallet/lifecycle/repair-indexer.js +117 -0
- package/dist/wallet/lifecycle/repair-mining.d.ts +1 -5
- package/dist/wallet/lifecycle/repair-mining.js +5 -39
- package/dist/wallet/lifecycle/repair.d.ts +2 -4
- package/dist/wallet/lifecycle/repair.js +74 -318
- package/dist/wallet/lifecycle/setup-prompts.d.ts +7 -0
- package/dist/wallet/lifecycle/setup-prompts.js +88 -0
- package/dist/wallet/lifecycle/setup-state.d.ts +26 -0
- package/dist/wallet/lifecycle/setup-state.js +159 -0
- package/dist/wallet/lifecycle/setup.d.ts +3 -4
- package/dist/wallet/lifecycle/setup.js +47 -351
- package/dist/wallet/lifecycle/types.d.ts +33 -5
- package/dist/wallet/managed-core-wallet.d.ts +2 -0
- package/dist/wallet/managed-core-wallet.js +27 -1
- package/dist/wallet/mining/candidate.d.ts +1 -0
- package/dist/wallet/mining/candidate.js +38 -6
- package/dist/wallet/mining/competitiveness.d.ts +1 -0
- package/dist/wallet/mining/competitiveness.js +6 -0
- package/dist/wallet/mining/cycle.d.ts +2 -0
- package/dist/wallet/mining/cycle.js +14 -4
- package/dist/wallet/mining/engine-types.d.ts +1 -0
- package/dist/wallet/mining/index.d.ts +1 -1
- package/dist/wallet/mining/index.js +1 -1
- package/dist/wallet/mining/publish.d.ts +3 -0
- package/dist/wallet/mining/publish.js +78 -6
- package/dist/wallet/mining/runner.d.ts +0 -32
- package/dist/wallet/mining/runner.js +59 -104
- package/dist/wallet/mining/stop.d.ts +7 -0
- package/dist/wallet/mining/stop.js +23 -0
- package/dist/wallet/mining/supervisor.d.ts +2 -36
- package/dist/wallet/mining/supervisor.js +139 -246
- package/dist/wallet/read/context.d.ts +1 -5
- package/dist/wallet/read/context.js +20 -379
- package/dist/wallet/read/managed-services.d.ts +33 -0
- package/dist/wallet/read/managed-services.js +222 -0
- package/dist/wallet/state/client-password/bootstrap.d.ts +2 -0
- package/dist/wallet/state/client-password/bootstrap.js +3 -0
- package/dist/wallet/state/client-password/context.d.ts +10 -0
- package/dist/wallet/state/client-password/context.js +46 -0
- package/dist/wallet/state/client-password/crypto.d.ts +34 -0
- package/dist/wallet/state/client-password/crypto.js +117 -0
- package/dist/wallet/state/client-password/files.d.ts +10 -0
- package/dist/wallet/state/client-password/files.js +109 -0
- package/dist/wallet/state/client-password/legacy-cleanup.d.ts +11 -0
- package/dist/wallet/state/client-password/legacy-cleanup.js +338 -0
- package/dist/wallet/state/client-password/messages.d.ts +3 -0
- package/dist/wallet/state/client-password/messages.js +9 -0
- package/dist/wallet/state/client-password/migration.d.ts +4 -0
- package/dist/wallet/state/client-password/migration.js +32 -0
- package/dist/wallet/state/client-password/prompts.d.ts +12 -0
- package/dist/wallet/state/client-password/prompts.js +79 -0
- package/dist/wallet/state/client-password/protected-secrets.d.ts +13 -0
- package/dist/wallet/state/client-password/protected-secrets.js +90 -0
- package/dist/wallet/state/client-password/readiness.d.ts +4 -0
- package/dist/wallet/state/client-password/readiness.js +48 -0
- package/dist/wallet/state/client-password/references.d.ts +1 -0
- package/dist/wallet/state/client-password/references.js +56 -0
- package/dist/wallet/state/client-password/rotation.d.ts +6 -0
- package/dist/wallet/state/client-password/rotation.js +98 -0
- package/dist/wallet/state/client-password/session-policy.d.ts +6 -0
- package/dist/wallet/state/client-password/session-policy.js +28 -0
- package/dist/wallet/state/client-password/session.d.ts +19 -0
- package/dist/wallet/state/client-password/session.js +170 -0
- package/dist/wallet/state/client-password/setup.d.ts +8 -0
- package/dist/wallet/state/client-password/setup.js +49 -0
- package/dist/wallet/state/client-password/types.d.ts +82 -0
- package/dist/wallet/state/client-password/types.js +5 -0
- package/dist/wallet/state/client-password.d.ts +7 -38
- package/dist/wallet/state/client-password.js +52 -937
- package/dist/wallet/tx/anchor.js +123 -216
- package/dist/wallet/tx/cog.js +294 -489
- package/dist/wallet/tx/common.d.ts +2 -0
- package/dist/wallet/tx/common.js +2 -0
- package/dist/wallet/tx/domain-admin.js +111 -220
- package/dist/wallet/tx/domain-market.js +401 -681
- package/dist/wallet/tx/executor.d.ts +176 -0
- package/dist/wallet/tx/executor.js +302 -0
- package/dist/wallet/tx/field.js +109 -215
- package/dist/wallet/tx/register.js +158 -269
- package/dist/wallet/tx/reputation.js +120 -227
- package/package.json +1 -1
- package/dist/wallet/mining/worker-main.js +0 -17
- package/dist/wallet/state/client-password-agent.d.ts +0 -1
- package/dist/wallet/state/client-password-agent.js +0 -211
- /package/dist/{wallet/mining/worker-main.d.ts → bitcoind/managed-runtime/types.js} +0 -0
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import type { ManagedBitcoindServiceProbeResult } from "./managed-runtime/types.js";
|
|
1
2
|
import { resolveManagedServicePaths } from "./service-paths.js";
|
|
2
3
|
import type { InternalManagedBitcoindOptions, ManagedBitcoindObservedStatus, ManagedBitcoindRuntimeConfig, ManagedBitcoindNodeHandle, ManagedCoreWalletReplicaStatus } from "./types.js";
|
|
4
|
+
export type { ManagedBitcoindServiceCompatibility, ManagedBitcoindServiceProbeResult, } from "./managed-runtime/types.js";
|
|
3
5
|
export declare function resolveManagedBitcoindDbcacheMiB(totalRamBytes: number): number;
|
|
4
6
|
interface ManagedWalletReplicaRpc {
|
|
5
7
|
listWallets(): Promise<string[]>;
|
|
@@ -26,12 +28,6 @@ type ManagedBitcoindServiceOptions = Pick<InternalManagedBitcoindOptions, "dataD
|
|
|
26
28
|
getblockArchiveSha256?: string | null;
|
|
27
29
|
serviceLifetime?: "persistent" | "ephemeral";
|
|
28
30
|
};
|
|
29
|
-
export type ManagedBitcoindServiceCompatibility = "compatible" | "service-version-mismatch" | "wallet-root-mismatch" | "runtime-mismatch" | "unreachable" | "protocol-error";
|
|
30
|
-
export interface ManagedBitcoindServiceProbeResult {
|
|
31
|
-
compatibility: ManagedBitcoindServiceCompatibility;
|
|
32
|
-
status: ManagedBitcoindObservedStatus | null;
|
|
33
|
-
error: string | null;
|
|
34
|
-
}
|
|
35
31
|
export interface ManagedBitcoindServiceStopResult {
|
|
36
32
|
status: "stopped" | "not-running";
|
|
37
33
|
walletRootId: string;
|
|
@@ -66,4 +62,3 @@ export declare function shutdownManagedBitcoindServiceForTesting(options: {
|
|
|
66
62
|
walletRootId?: string;
|
|
67
63
|
shutdownTimeoutMs?: number;
|
|
68
64
|
}): Promise<void>;
|
|
69
|
-
export {};
|
package/dist/bitcoind/service.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { randomBytes } from "node:crypto";
|
|
2
2
|
import { execFile, spawn } from "node:child_process";
|
|
3
|
-
import { access, constants, mkdir, readFile,
|
|
3
|
+
import { access, constants, mkdir, readFile, rm } from "node:fs/promises";
|
|
4
|
+
import { totalmem } from "node:os";
|
|
4
5
|
import { dirname, join } from "node:path";
|
|
5
6
|
import { promisify } from "node:util";
|
|
6
7
|
import net from "node:net";
|
|
@@ -9,6 +10,10 @@ import { acquireFileLock, FileLockBusyError } from "../wallet/fs/lock.js";
|
|
|
9
10
|
import { writeFileAtomic } from "../wallet/fs/atomic.js";
|
|
10
11
|
import { writeRuntimeStatusFile } from "../wallet/fs/status-file.js";
|
|
11
12
|
import { stopIndexerDaemonServiceWithLockHeld } from "./indexer-daemon.js";
|
|
13
|
+
import { mapManagedBitcoindRuntimeProbeFailure, mapManagedBitcoindValidationError, validateManagedBitcoindObservedStatus, } from "./managed-runtime/bitcoind-policy.js";
|
|
14
|
+
import { listManagedBitcoindStatusCandidates, readManagedBitcoindObservedStatus, } from "./managed-runtime/bitcoind-status.js";
|
|
15
|
+
import { attachOrStartManagedBitcoindRuntime, probeManagedBitcoindRuntime, } from "./managed-runtime/bitcoind-runtime.js";
|
|
16
|
+
import { readJsonFileIfPresent } from "./managed-runtime/status.js";
|
|
12
17
|
import { createRpcClient, validateNodeConfigForTesting } from "./node.js";
|
|
13
18
|
import { resolveManagedServicePaths, UNINITIALIZED_WALLET_ROOT_ID } from "./service-paths.js";
|
|
14
19
|
import { DEFAULT_MANAGED_BITCOIND_FOLLOW_POLL_INTERVAL_MS, MANAGED_BITCOIND_SERVICE_API_VERSION as MANAGED_BITCOIND_SERVICE_API_VERSION_VALUE, } from "./types.js";
|
|
@@ -17,14 +22,31 @@ const LOCAL_HOST = "127.0.0.1";
|
|
|
17
22
|
const SUPPORTED_BITCOIND_VERSION = "30.2.0";
|
|
18
23
|
const DEFAULT_STARTUP_TIMEOUT_MS = 30_000;
|
|
19
24
|
const DEFAULT_SHUTDOWN_TIMEOUT_MS = 15_000;
|
|
20
|
-
const DEFAULT_DBCACHE_MIB =
|
|
25
|
+
const DEFAULT_DBCACHE_MIB = 450;
|
|
21
26
|
const claimedUninitializedRuntimeKeys = new Set();
|
|
27
|
+
const GIB = 1024 ** 3;
|
|
22
28
|
export function resolveManagedBitcoindDbcacheMiB(totalRamBytes) {
|
|
23
|
-
|
|
24
|
-
|
|
29
|
+
if (!Number.isFinite(totalRamBytes) || totalRamBytes <= 0) {
|
|
30
|
+
return DEFAULT_DBCACHE_MIB;
|
|
31
|
+
}
|
|
32
|
+
if (totalRamBytes < 8 * GIB) {
|
|
33
|
+
return 450;
|
|
34
|
+
}
|
|
35
|
+
if (totalRamBytes < 16 * GIB) {
|
|
36
|
+
return 768;
|
|
37
|
+
}
|
|
38
|
+
if (totalRamBytes < 32 * GIB) {
|
|
39
|
+
return 1024;
|
|
40
|
+
}
|
|
41
|
+
return 2048;
|
|
25
42
|
}
|
|
26
43
|
function detectManagedBitcoindDbcacheMiB() {
|
|
27
|
-
|
|
44
|
+
try {
|
|
45
|
+
return resolveManagedBitcoindDbcacheMiB(totalmem());
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return DEFAULT_DBCACHE_MIB;
|
|
49
|
+
}
|
|
28
50
|
}
|
|
29
51
|
function sleep(ms) {
|
|
30
52
|
return new Promise((resolve) => {
|
|
@@ -58,53 +80,6 @@ async function acquireFileLockWithRetry(lockPath, metadata, timeoutMs) {
|
|
|
58
80
|
function getWalletReplicaName(walletRootId) {
|
|
59
81
|
return `cogcoin-${walletRootId}`.replace(/[^a-zA-Z0-9._-]+/g, "-").slice(0, 63);
|
|
60
82
|
}
|
|
61
|
-
async function readJsonFile(filePath) {
|
|
62
|
-
try {
|
|
63
|
-
return JSON.parse(await readFile(filePath, "utf8"));
|
|
64
|
-
}
|
|
65
|
-
catch (error) {
|
|
66
|
-
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
67
|
-
return null;
|
|
68
|
-
}
|
|
69
|
-
throw error;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
async function listManagedBitcoindStatusCandidates(options) {
|
|
73
|
-
const candidates = new Map();
|
|
74
|
-
const addCandidate = async (statusPath, allowDataDirMismatch = false) => {
|
|
75
|
-
const status = await readJsonFile(statusPath);
|
|
76
|
-
if (status === null) {
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
if (!allowDataDirMismatch && status.dataDir !== options.dataDir) {
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
candidates.set(statusPath, status);
|
|
83
|
-
};
|
|
84
|
-
await addCandidate(options.expectedStatusPath, true);
|
|
85
|
-
try {
|
|
86
|
-
const entries = await readdir(options.runtimeRoot, {
|
|
87
|
-
withFileTypes: true,
|
|
88
|
-
});
|
|
89
|
-
for (const entry of entries) {
|
|
90
|
-
if (!entry.isDirectory()) {
|
|
91
|
-
continue;
|
|
92
|
-
}
|
|
93
|
-
const statusPath = join(options.runtimeRoot, entry.name, "bitcoind-status.json");
|
|
94
|
-
if (statusPath === options.expectedStatusPath) {
|
|
95
|
-
continue;
|
|
96
|
-
}
|
|
97
|
-
await addCandidate(statusPath);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
catch {
|
|
101
|
-
// Missing runtime roots are handled by returning no candidates.
|
|
102
|
-
}
|
|
103
|
-
return [...candidates.entries()].map(([statusPath, status]) => ({
|
|
104
|
-
statusPath,
|
|
105
|
-
status,
|
|
106
|
-
}));
|
|
107
|
-
}
|
|
108
83
|
async function allocatePort() {
|
|
109
84
|
return new Promise((resolve, reject) => {
|
|
110
85
|
const server = net.createServer();
|
|
@@ -207,38 +182,6 @@ async function waitForRpcReady(rpc, cookieFile, expectedChain, timeoutMs) {
|
|
|
207
182
|
}
|
|
208
183
|
throw lastError instanceof Error ? lastError : new Error("bitcoind_rpc_timeout");
|
|
209
184
|
}
|
|
210
|
-
function validateManagedBitcoindStatus(status, options, runtimeRoot) {
|
|
211
|
-
const legacyRuntimeRoot = join(resolveManagedServicePaths(options.dataDir ?? "", options.walletRootId ?? UNINITIALIZED_WALLET_ROOT_ID).runtimeRoot, status.walletRootId);
|
|
212
|
-
if (status.serviceApiVersion !== MANAGED_BITCOIND_SERVICE_API_VERSION_VALUE) {
|
|
213
|
-
throw new Error("managed_bitcoind_service_version_mismatch");
|
|
214
|
-
}
|
|
215
|
-
if (status.chain !== options.chain
|
|
216
|
-
|| status.dataDir !== (options.dataDir ?? "")
|
|
217
|
-
|| (status.runtimeRoot !== runtimeRoot && status.runtimeRoot !== legacyRuntimeRoot)) {
|
|
218
|
-
throw new Error("managed_bitcoind_runtime_mismatch");
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
function isRuntimeMismatchError(error) {
|
|
222
|
-
if (!(error instanceof Error)) {
|
|
223
|
-
return false;
|
|
224
|
-
}
|
|
225
|
-
return error.message.startsWith("bitcoind_chain_expected_")
|
|
226
|
-
|| error.message === "managed_bitcoind_runtime_mismatch";
|
|
227
|
-
}
|
|
228
|
-
function isUnreachableManagedBitcoindError(error) {
|
|
229
|
-
if (error instanceof Error) {
|
|
230
|
-
if ("code" in error) {
|
|
231
|
-
const code = error.code;
|
|
232
|
-
return code === "ENOENT" || code === "ECONNREFUSED" || code === "ECONNRESET";
|
|
233
|
-
}
|
|
234
|
-
return error.message === "bitcoind_cookie_timeout"
|
|
235
|
-
|| error.message.includes("cookie file is unavailable")
|
|
236
|
-
|| error.message.includes("ECONNREFUSED")
|
|
237
|
-
|| error.message.includes("ECONNRESET")
|
|
238
|
-
|| error.message.includes("socket hang up");
|
|
239
|
-
}
|
|
240
|
-
return false;
|
|
241
|
-
}
|
|
242
185
|
function createBitcoindServiceStatus(options) {
|
|
243
186
|
return {
|
|
244
187
|
serviceApiVersion: MANAGED_BITCOIND_SERVICE_API_VERSION_VALUE,
|
|
@@ -264,27 +207,16 @@ function createBitcoindServiceStatus(options) {
|
|
|
264
207
|
lastError: options.lastError,
|
|
265
208
|
};
|
|
266
209
|
}
|
|
267
|
-
function mapManagedBitcoindValidationError(error) {
|
|
268
|
-
return {
|
|
269
|
-
compatibility: error instanceof Error
|
|
270
|
-
? error.message === "managed_bitcoind_service_version_mismatch"
|
|
271
|
-
? "service-version-mismatch"
|
|
272
|
-
: "runtime-mismatch"
|
|
273
|
-
: "protocol-error",
|
|
274
|
-
status: null,
|
|
275
|
-
error: error instanceof Error ? error.message : "managed_bitcoind_protocol_error",
|
|
276
|
-
};
|
|
277
|
-
}
|
|
278
210
|
async function probeManagedBitcoindStatusCandidate(status, options, runtimeRoot) {
|
|
279
211
|
try {
|
|
280
|
-
|
|
212
|
+
validateManagedBitcoindObservedStatus(status, {
|
|
213
|
+
chain: options.chain,
|
|
214
|
+
dataDir: options.dataDir ?? "",
|
|
215
|
+
runtimeRoot,
|
|
216
|
+
});
|
|
281
217
|
}
|
|
282
218
|
catch (error) {
|
|
283
|
-
|
|
284
|
-
return {
|
|
285
|
-
...mapped,
|
|
286
|
-
status,
|
|
287
|
-
};
|
|
219
|
+
return mapManagedBitcoindValidationError(error, status);
|
|
288
220
|
}
|
|
289
221
|
const rpc = createRpcClient(status.rpc);
|
|
290
222
|
try {
|
|
@@ -297,30 +229,12 @@ async function probeManagedBitcoindStatusCandidate(status, options, runtimeRoot)
|
|
|
297
229
|
};
|
|
298
230
|
}
|
|
299
231
|
catch (error) {
|
|
300
|
-
|
|
301
|
-
return {
|
|
302
|
-
compatibility: "runtime-mismatch",
|
|
303
|
-
status,
|
|
304
|
-
error: "managed_bitcoind_runtime_mismatch",
|
|
305
|
-
};
|
|
306
|
-
}
|
|
307
|
-
if (isUnreachableManagedBitcoindError(error)) {
|
|
308
|
-
return {
|
|
309
|
-
compatibility: "unreachable",
|
|
310
|
-
status,
|
|
311
|
-
error: null,
|
|
312
|
-
};
|
|
313
|
-
}
|
|
314
|
-
return {
|
|
315
|
-
compatibility: "protocol-error",
|
|
316
|
-
status,
|
|
317
|
-
error: "managed_bitcoind_protocol_error",
|
|
318
|
-
};
|
|
232
|
+
return mapManagedBitcoindRuntimeProbeFailure(error, status);
|
|
319
233
|
}
|
|
320
234
|
}
|
|
321
235
|
async function resolveRuntimeConfig(statusPath, configPath, options) {
|
|
322
|
-
const previousStatus = await
|
|
323
|
-
const previousConfig = await
|
|
236
|
+
const previousStatus = await readJsonFileIfPresent(statusPath);
|
|
237
|
+
const previousConfig = await readJsonFileIfPresent(configPath);
|
|
324
238
|
const reserved = new Set();
|
|
325
239
|
const rpcPort = options.rpcPort
|
|
326
240
|
?? previousStatus?.rpc.port
|
|
@@ -545,7 +459,7 @@ async function clearManagedBitcoindRuntimeArtifacts(paths) {
|
|
|
545
459
|
export async function stopManagedBitcoindServiceWithLockHeld(options) {
|
|
546
460
|
const walletRootId = options.walletRootId ?? UNINITIALIZED_WALLET_ROOT_ID;
|
|
547
461
|
const paths = options.paths ?? resolveManagedServicePaths(options.dataDir, walletRootId);
|
|
548
|
-
const status = await
|
|
462
|
+
const status = await readJsonFileIfPresent(paths.bitcoindStatusPath);
|
|
549
463
|
const processId = status?.processId ?? null;
|
|
550
464
|
if (status === null || processId === null || !await isProcessAlive(processId)) {
|
|
551
465
|
await clearManagedBitcoindRuntimeArtifacts(paths);
|
|
@@ -716,44 +630,19 @@ async function tryAttachExistingManagedBitcoindService(options) {
|
|
|
716
630
|
const refreshed = await refreshManagedBitcoindStatus(probe.status, paths, options);
|
|
717
631
|
return createNodeHandle(refreshed, paths, options, "attached");
|
|
718
632
|
}
|
|
719
|
-
async function waitForManagedBitcoindService(options, timeoutMs) {
|
|
720
|
-
const deadline = Date.now() + timeoutMs;
|
|
721
|
-
while (Date.now() < deadline) {
|
|
722
|
-
const attached = await tryAttachExistingManagedBitcoindService(options).catch(() => null);
|
|
723
|
-
if (attached !== null) {
|
|
724
|
-
return attached;
|
|
725
|
-
}
|
|
726
|
-
await sleep(250);
|
|
727
|
-
}
|
|
728
|
-
throw new Error("managed_bitcoind_service_start_timeout");
|
|
729
|
-
}
|
|
730
633
|
export async function probeManagedBitcoindService(options) {
|
|
731
|
-
const
|
|
732
|
-
|
|
733
|
-
const candidates = await listManagedBitcoindStatusCandidates({
|
|
634
|
+
const resolvedOptions = {
|
|
635
|
+
...options,
|
|
734
636
|
dataDir: options.dataDir ?? "",
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
});
|
|
738
|
-
const expectedCandidate = candidates.find((candidate) => candidate.statusPath === paths.bitcoindStatusPath) ?? null;
|
|
739
|
-
for (const candidate of candidates) {
|
|
740
|
-
if (!await isProcessAlive(candidate.status.processId)) {
|
|
741
|
-
continue;
|
|
742
|
-
}
|
|
743
|
-
return probeManagedBitcoindStatusCandidate(candidate.status, options, paths.walletRuntimeRoot);
|
|
744
|
-
}
|
|
745
|
-
if (expectedCandidate !== null) {
|
|
746
|
-
return {
|
|
747
|
-
compatibility: "unreachable",
|
|
748
|
-
status: expectedCandidate.status,
|
|
749
|
-
error: null,
|
|
750
|
-
};
|
|
751
|
-
}
|
|
752
|
-
return {
|
|
753
|
-
compatibility: "unreachable",
|
|
754
|
-
status: candidates[0]?.status ?? null,
|
|
755
|
-
error: null,
|
|
637
|
+
walletRootId: options.walletRootId ?? UNINITIALIZED_WALLET_ROOT_ID,
|
|
638
|
+
startupTimeoutMs: options.startupTimeoutMs ?? DEFAULT_STARTUP_TIMEOUT_MS,
|
|
756
639
|
};
|
|
640
|
+
return probeManagedBitcoindRuntime(resolvedOptions, {
|
|
641
|
+
getPaths: (runtimeOptions) => resolveManagedServicePaths(runtimeOptions.dataDir, runtimeOptions.walletRootId),
|
|
642
|
+
listStatusCandidates: listManagedBitcoindStatusCandidates,
|
|
643
|
+
isProcessAlive,
|
|
644
|
+
probeStatusCandidate: probeManagedBitcoindStatusCandidate,
|
|
645
|
+
});
|
|
757
646
|
}
|
|
758
647
|
export async function attachOrStartManagedBitcoindService(options) {
|
|
759
648
|
const resolvedOptions = {
|
|
@@ -768,38 +657,27 @@ export async function attachOrStartManagedBitcoindService(options) {
|
|
|
768
657
|
walletRootId: resolvedOptions.walletRootId,
|
|
769
658
|
shutdownTimeoutMs: resolvedOptions.shutdownTimeoutMs,
|
|
770
659
|
}, async () => {
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
const lock = await acquireFileLock(paths.bitcoindLockPath, {
|
|
660
|
+
return attachOrStartManagedBitcoindRuntime({
|
|
661
|
+
...resolvedOptions,
|
|
662
|
+
dataDir: resolvedOptions.dataDir ?? "",
|
|
663
|
+
walletRootId: resolvedOptions.walletRootId ?? UNINITIALIZED_WALLET_ROOT_ID,
|
|
664
|
+
startupTimeoutMs,
|
|
665
|
+
}, {
|
|
666
|
+
getPaths: (runtimeOptions) => resolveManagedServicePaths(runtimeOptions.dataDir, runtimeOptions.walletRootId),
|
|
667
|
+
listStatusCandidates: listManagedBitcoindStatusCandidates,
|
|
668
|
+
isProcessAlive,
|
|
669
|
+
probeStatusCandidate: probeManagedBitcoindStatusCandidate,
|
|
670
|
+
attachExisting: tryAttachExistingManagedBitcoindService,
|
|
671
|
+
acquireStartLock: async (runtimeOptions, paths) => acquireFileLock(paths.bitcoindLockPath, {
|
|
784
672
|
purpose: "managed-bitcoind-start",
|
|
785
|
-
walletRootId:
|
|
786
|
-
dataDir:
|
|
787
|
-
})
|
|
788
|
-
|
|
789
|
-
const liveProbe = await probeManagedBitcoindService(resolvedOptions);
|
|
790
|
-
if (liveProbe.compatibility === "compatible") {
|
|
791
|
-
const reattached = await tryAttachExistingManagedBitcoindService(resolvedOptions);
|
|
792
|
-
if (reattached !== null) {
|
|
793
|
-
return reattached;
|
|
794
|
-
}
|
|
795
|
-
}
|
|
796
|
-
if (liveProbe.compatibility !== "unreachable") {
|
|
797
|
-
throw new Error(liveProbe.error ?? "managed_bitcoind_protocol_error");
|
|
798
|
-
}
|
|
673
|
+
walletRootId: runtimeOptions.walletRootId,
|
|
674
|
+
dataDir: runtimeOptions.dataDir,
|
|
675
|
+
}),
|
|
676
|
+
startService: async (runtimeOptions, paths) => {
|
|
799
677
|
const bitcoindPath = await getBitcoindPath();
|
|
800
678
|
await verifyBitcoindVersion(bitcoindPath);
|
|
801
679
|
const binaryVersion = SUPPORTED_BITCOIND_VERSION;
|
|
802
|
-
await mkdir(
|
|
680
|
+
await mkdir(runtimeOptions.dataDir, { recursive: true });
|
|
803
681
|
const startManagedProcess = async (startOptions) => {
|
|
804
682
|
const runtimeConfig = await resolveRuntimeConfig(paths.bitcoindStatusPath, paths.bitcoindRuntimeConfigPath, startOptions);
|
|
805
683
|
await writeBitcoinConf(paths.bitcoinConfPath, startOptions, runtimeConfig);
|
|
@@ -841,16 +719,15 @@ export async function attachOrStartManagedBitcoindService(options) {
|
|
|
841
719
|
throw error;
|
|
842
720
|
}
|
|
843
721
|
const nowUnixMs = Date.now();
|
|
844
|
-
const
|
|
845
|
-
const walletReplica = await loadManagedWalletReplicaIfPresent(rpc, walletRootId, startOptions.dataDir ?? "");
|
|
722
|
+
const walletReplica = await loadManagedWalletReplicaIfPresent(rpc, startOptions.walletRootId, startOptions.dataDir);
|
|
846
723
|
return createBitcoindServiceStatus({
|
|
847
724
|
binaryVersion,
|
|
848
725
|
serviceInstanceId: randomBytes(16).toString("hex"),
|
|
849
726
|
state: "ready",
|
|
850
727
|
processId: child.pid ?? null,
|
|
851
|
-
walletRootId,
|
|
728
|
+
walletRootId: startOptions.walletRootId,
|
|
852
729
|
chain: startOptions.chain,
|
|
853
|
-
dataDir: startOptions.dataDir
|
|
730
|
+
dataDir: startOptions.dataDir,
|
|
854
731
|
runtimeRoot: paths.walletRuntimeRoot,
|
|
855
732
|
startHeight: startOptions.startHeight,
|
|
856
733
|
rpc: rpcConfig,
|
|
@@ -866,32 +743,25 @@ export async function attachOrStartManagedBitcoindService(options) {
|
|
|
866
743
|
};
|
|
867
744
|
let status;
|
|
868
745
|
try {
|
|
869
|
-
status = await startManagedProcess(
|
|
746
|
+
status = await startManagedProcess(runtimeOptions);
|
|
870
747
|
}
|
|
871
748
|
catch (error) {
|
|
872
|
-
if (
|
|
749
|
+
if (runtimeOptions.getblockArchivePath === undefined || runtimeOptions.getblockArchivePath === null) {
|
|
873
750
|
throw error;
|
|
874
751
|
}
|
|
875
752
|
status = await startManagedProcess({
|
|
876
|
-
...
|
|
753
|
+
...runtimeOptions,
|
|
877
754
|
getblockArchivePath: null,
|
|
878
755
|
getblockArchiveEndHeight: null,
|
|
879
756
|
getblockArchiveSha256: null,
|
|
880
757
|
});
|
|
881
758
|
}
|
|
882
759
|
await writeBitcoindStatus(paths, status);
|
|
883
|
-
return createNodeHandle(status,
|
|
884
|
-
}
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
}
|
|
889
|
-
catch (error) {
|
|
890
|
-
if (error instanceof FileLockBusyError) {
|
|
891
|
-
return waitForManagedBitcoindService(resolvedOptions, startupTimeoutMs);
|
|
892
|
-
}
|
|
893
|
-
throw error;
|
|
894
|
-
}
|
|
760
|
+
return createNodeHandle(status, resolveManagedServicePaths(runtimeOptions.dataDir, runtimeOptions.walletRootId), runtimeOptions, "started");
|
|
761
|
+
},
|
|
762
|
+
isLockBusyError: (error) => error instanceof FileLockBusyError,
|
|
763
|
+
sleep,
|
|
764
|
+
});
|
|
895
765
|
});
|
|
896
766
|
}
|
|
897
767
|
export async function stopManagedBitcoindService(options) {
|
|
@@ -914,8 +784,10 @@ export async function stopManagedBitcoindService(options) {
|
|
|
914
784
|
}
|
|
915
785
|
}
|
|
916
786
|
export async function readManagedBitcoindServiceStatusForTesting(dataDir, walletRootId = UNINITIALIZED_WALLET_ROOT_ID) {
|
|
917
|
-
|
|
918
|
-
|
|
787
|
+
return readManagedBitcoindObservedStatus({
|
|
788
|
+
dataDir,
|
|
789
|
+
walletRootId,
|
|
790
|
+
});
|
|
919
791
|
}
|
|
920
792
|
export async function shutdownManagedBitcoindServiceForTesting(options) {
|
|
921
793
|
await stopManagedBitcoindService({
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export type CommandHandlerFamily = "status" | "update" | "sync" | "follow" | "client-admin" | "service-runtime" | "wallet-admin" | "wallet-read" | "wallet-mutation" | "mining-admin" | "mining-runtime" | "mining-read";
|
|
2
|
-
export type CommandName = "init" | "reset" | "repair" | "update" | "sync" | "status" | "client-
|
|
2
|
+
export type CommandName = "init" | "reset" | "repair" | "update" | "sync" | "status" | "client-change-password" | "follow" | "bitcoin-start" | "bitcoin-stop" | "bitcoin-status" | "bitcoin-transfer" | "indexer-start" | "indexer-stop" | "indexer-status" | "anchor" | "register" | "transfer" | "sell" | "unsell" | "buy" | "domain-endpoint-set" | "domain-endpoint-clear" | "domain-delegate-set" | "domain-delegate-clear" | "domain-miner-set" | "domain-miner-clear" | "domain-canonical" | "fields" | "field" | "field-create" | "field-set" | "field-clear" | "send" | "claim" | "reclaim" | "cog-lock" | "rep-give" | "rep-revoke" | "mine" | "mine-setup" | "mine-prompt" | "mine-prompt-list" | "mine-status" | "mine-log" | "wallet-show-mnemonic" | "wallet-status" | "address" | "ids" | "balance" | "locks" | "domains" | "show";
|
|
3
3
|
type AliasMatchMode = "always" | "requires-arg" | "end-or-flag";
|
|
4
4
|
interface HelpEntry {
|
|
5
5
|
usage: string;
|
|
@@ -31,38 +31,6 @@ const commandSpecs = [
|
|
|
31
31
|
return "cogcoin update";
|
|
32
32
|
},
|
|
33
33
|
},
|
|
34
|
-
{
|
|
35
|
-
id: "client-unlock",
|
|
36
|
-
handlerFamily: "client-admin",
|
|
37
|
-
supportsYes: false,
|
|
38
|
-
supportsSatvb: false,
|
|
39
|
-
aliases: [{ tokens: ["client", "unlock"] }],
|
|
40
|
-
helpEntries: [
|
|
41
|
-
{
|
|
42
|
-
usage: "client unlock",
|
|
43
|
-
description: "Unlock password-protected local wallet secrets for a limited time",
|
|
44
|
-
},
|
|
45
|
-
],
|
|
46
|
-
describeCommand() {
|
|
47
|
-
return "cogcoin client unlock";
|
|
48
|
-
},
|
|
49
|
-
},
|
|
50
|
-
{
|
|
51
|
-
id: "client-lock",
|
|
52
|
-
handlerFamily: "client-admin",
|
|
53
|
-
supportsYes: false,
|
|
54
|
-
supportsSatvb: false,
|
|
55
|
-
aliases: [{ tokens: ["client", "lock"] }],
|
|
56
|
-
helpEntries: [
|
|
57
|
-
{
|
|
58
|
-
usage: "client lock",
|
|
59
|
-
description: "Flush the cached client password unlock session",
|
|
60
|
-
},
|
|
61
|
-
],
|
|
62
|
-
describeCommand() {
|
|
63
|
-
return "cogcoin client lock";
|
|
64
|
-
},
|
|
65
|
-
},
|
|
66
34
|
{
|
|
67
35
|
id: "client-change-password",
|
|
68
36
|
handlerFamily: "client-admin",
|
|
@@ -308,38 +276,6 @@ const commandSpecs = [
|
|
|
308
276
|
return "cogcoin mine";
|
|
309
277
|
},
|
|
310
278
|
},
|
|
311
|
-
{
|
|
312
|
-
id: "mine-start",
|
|
313
|
-
handlerFamily: "mining-runtime",
|
|
314
|
-
supportsYes: false,
|
|
315
|
-
supportsSatvb: false,
|
|
316
|
-
aliases: [{ tokens: ["mine", "start"] }],
|
|
317
|
-
helpEntries: [
|
|
318
|
-
{
|
|
319
|
-
usage: "mine start",
|
|
320
|
-
description: "Start the miner as a background worker",
|
|
321
|
-
},
|
|
322
|
-
],
|
|
323
|
-
describeCommand() {
|
|
324
|
-
return "cogcoin mine start";
|
|
325
|
-
},
|
|
326
|
-
},
|
|
327
|
-
{
|
|
328
|
-
id: "mine-stop",
|
|
329
|
-
handlerFamily: "mining-runtime",
|
|
330
|
-
supportsYes: false,
|
|
331
|
-
supportsSatvb: false,
|
|
332
|
-
aliases: [{ tokens: ["mine", "stop"] }],
|
|
333
|
-
helpEntries: [
|
|
334
|
-
{
|
|
335
|
-
usage: "mine stop",
|
|
336
|
-
description: "Stop the active background miner",
|
|
337
|
-
},
|
|
338
|
-
],
|
|
339
|
-
describeCommand() {
|
|
340
|
-
return "cogcoin mine stop";
|
|
341
|
-
},
|
|
342
|
-
},
|
|
343
279
|
{
|
|
344
280
|
id: "mine-setup",
|
|
345
281
|
handlerFamily: "mining-admin",
|
|
@@ -949,6 +885,8 @@ const commandSpecs = [
|
|
|
949
885
|
},
|
|
950
886
|
];
|
|
951
887
|
const removedPathSpecs = [
|
|
888
|
+
{ tokens: ["client", "unlock"], errorCode: "cli_client_unlock_removed" },
|
|
889
|
+
{ tokens: ["client", "lock"], errorCode: "cli_client_lock_removed" },
|
|
952
890
|
{ tokens: ["restore"], errorCode: "cli_restore_removed" },
|
|
953
891
|
{ tokens: ["wallet", "delete"], errorCode: "cli_wallet_delete_removed" },
|
|
954
892
|
{ tokens: ["wallet", "restore"], errorCode: "cli_wallet_restore_removed" },
|
|
@@ -1,30 +1,15 @@
|
|
|
1
1
|
import { writeLine } from "../io.js";
|
|
2
2
|
import { writeHandledCliError } from "../output.js";
|
|
3
|
-
import { changeClientPassword,
|
|
3
|
+
import { changeClientPassword, } from "../../wallet/state/provider.js";
|
|
4
4
|
function createCommandPrompter(context) {
|
|
5
5
|
return context.createPrompter();
|
|
6
6
|
}
|
|
7
7
|
export async function runClientAdminCommand(parsed, context) {
|
|
8
8
|
try {
|
|
9
|
-
if (parsed.command === "client-lock") {
|
|
10
|
-
await lockClientPassword(context.walletSecretProvider);
|
|
11
|
-
writeLine(context.stdout, "Client locked.");
|
|
12
|
-
return 0;
|
|
13
|
-
}
|
|
14
|
-
if (parsed.command === "client-unlock") {
|
|
15
|
-
const prompter = createCommandPrompter(context);
|
|
16
|
-
const status = await unlockClientPassword(context.walletSecretProvider, prompter);
|
|
17
|
-
writeLine(context.stdout, status.unlockUntilUnixMs === null
|
|
18
|
-
? "Client unlocked."
|
|
19
|
-
: `Client unlocked until ${new Date(status.unlockUntilUnixMs).toISOString()}.`);
|
|
20
|
-
return 0;
|
|
21
|
-
}
|
|
22
9
|
if (parsed.command === "client-change-password") {
|
|
23
10
|
const prompter = createCommandPrompter(context);
|
|
24
|
-
|
|
25
|
-
writeLine(context.stdout,
|
|
26
|
-
? "Client password changed."
|
|
27
|
-
: `Client password changed. Client unlocked until ${new Date(status.unlockUntilUnixMs).toISOString()}.`);
|
|
11
|
+
await changeClientPassword(context.walletSecretProvider, prompter);
|
|
12
|
+
writeLine(context.stdout, "Client password changed.");
|
|
28
13
|
return 0;
|
|
29
14
|
}
|
|
30
15
|
writeLine(context.stderr, `client admin command not implemented: ${parsed.command}`);
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { dirname } from "node:path";
|
|
2
2
|
import { DEFAULT_SNAPSHOT_METADATA, resolveBootstrapPathsForTesting } from "../../bitcoind/bootstrap.js";
|
|
3
3
|
import { createEmptyMiningFollowVisualizerState, MiningFollowVisualizer, } from "../../wallet/mining/visualizer.js";
|
|
4
|
+
import { createMiningStopRequestedError } from "../../wallet/mining/stop.js";
|
|
4
5
|
import { resolveWalletRootIdFromLocalArtifacts } from "../../wallet/root-resolution.js";
|
|
5
6
|
import { withInteractiveWalletSecretProvider } from "../../wallet/state/provider.js";
|
|
7
|
+
import { bindClientPasswordPromptSessionPolicy } from "../../wallet/state/client-password/session-policy.js";
|
|
6
8
|
import { ManagedIndexerProgressObserver, assertManagedIndexerStatusRecoverable, isManagedIndexerCaughtUp, pollManagedIndexerUntilCaughtUp, } from "../managed-indexer-observer.js";
|
|
7
9
|
import { usesTtyProgress, writeLine } from "../io.js";
|
|
8
10
|
import { writeHandledCliError } from "../output.js";
|
|
9
|
-
import { formatNextStepLines, getMineStopNextSteps, } from "../workflow-hints.js";
|
|
10
11
|
import { createCloseSignalWatcher, waitForCompletionOrStop } from "../signals.js";
|
|
11
12
|
import { createSyncProgressReporter } from "../sync-progress.js";
|
|
12
13
|
import { PASSIVE_UPDATE_CHECK_TIMEOUT_MS, applyUpdateCheckResult, compareSemver, createEmptyUpdateCheckCache, fetchLatestPublishedVersion, isUpdateCheckDisabled, loadUpdateCheckCache, persistUpdateCheckCache, shouldRefreshUpdateCheck, } from "../update-service.js";
|
|
@@ -317,7 +318,7 @@ export async function runMiningRuntimeCommand(parsed, context) {
|
|
|
317
318
|
const packageVersion = await context.readPackageVersion();
|
|
318
319
|
const runtimePaths = context.resolveWalletRuntimePaths();
|
|
319
320
|
if (parsed.command === "mine") {
|
|
320
|
-
const prompter = context.createPrompter();
|
|
321
|
+
const prompter = bindClientPasswordPromptSessionPolicy(context.createPrompter(), "mining-indefinite");
|
|
321
322
|
const provider = withInteractiveWalletSecretProvider(context.walletSecretProvider, prompter);
|
|
322
323
|
const ttyProgressActive = usesTtyProgress(parsed.progressOutput, context.stderr);
|
|
323
324
|
await ensureMiningProviderSetup({
|
|
@@ -368,7 +369,7 @@ export async function runMiningRuntimeCommand(parsed, context) {
|
|
|
368
369
|
: false;
|
|
369
370
|
abortController = new AbortController();
|
|
370
371
|
onStop = () => {
|
|
371
|
-
abortController?.abort();
|
|
372
|
+
abortController?.abort(createMiningStopRequestedError());
|
|
372
373
|
};
|
|
373
374
|
context.signalSource.on("SIGINT", onStop);
|
|
374
375
|
context.signalSource.on("SIGTERM", onStop);
|
|
@@ -397,63 +398,6 @@ export async function runMiningRuntimeCommand(parsed, context) {
|
|
|
397
398
|
}
|
|
398
399
|
return 0;
|
|
399
400
|
}
|
|
400
|
-
if (parsed.command === "mine-start") {
|
|
401
|
-
const prompter = createCommandPrompter(context);
|
|
402
|
-
const provider = withInteractiveWalletSecretProvider(context.walletSecretProvider, prompter);
|
|
403
|
-
await ensureMiningProviderSetup({
|
|
404
|
-
context,
|
|
405
|
-
provider,
|
|
406
|
-
prompter,
|
|
407
|
-
runtimePaths,
|
|
408
|
-
});
|
|
409
|
-
const preflightCode = await syncManagedMiningReadiness({
|
|
410
|
-
parsed,
|
|
411
|
-
context,
|
|
412
|
-
dataDir,
|
|
413
|
-
databasePath: dbPath,
|
|
414
|
-
expectedBinaryVersion: packageVersion,
|
|
415
|
-
provider,
|
|
416
|
-
runtimePaths,
|
|
417
|
-
});
|
|
418
|
-
if (preflightCode !== null) {
|
|
419
|
-
return preflightCode;
|
|
420
|
-
}
|
|
421
|
-
const result = await context.startBackgroundMining({
|
|
422
|
-
dataDir,
|
|
423
|
-
databasePath: dbPath,
|
|
424
|
-
provider,
|
|
425
|
-
prompter,
|
|
426
|
-
builtInSetupEnsured: true,
|
|
427
|
-
paths: runtimePaths,
|
|
428
|
-
});
|
|
429
|
-
if (!result.started) {
|
|
430
|
-
writeLine(context.stdout, "Background mining is already active.");
|
|
431
|
-
if (result.snapshot?.backgroundWorkerPid !== null && result.snapshot?.backgroundWorkerPid !== undefined) {
|
|
432
|
-
writeLine(context.stdout, `Worker pid: ${result.snapshot.backgroundWorkerPid}`);
|
|
433
|
-
}
|
|
434
|
-
return 0;
|
|
435
|
-
}
|
|
436
|
-
writeLine(context.stdout, "Started background mining.");
|
|
437
|
-
if (result.snapshot?.backgroundWorkerPid !== null && result.snapshot?.backgroundWorkerPid !== undefined) {
|
|
438
|
-
writeLine(context.stdout, `Worker pid: ${result.snapshot.backgroundWorkerPid}`);
|
|
439
|
-
}
|
|
440
|
-
return 0;
|
|
441
|
-
}
|
|
442
|
-
if (parsed.command === "mine-stop") {
|
|
443
|
-
const provider = withInteractiveWalletSecretProvider(context.walletSecretProvider, context.createPrompter());
|
|
444
|
-
const snapshot = await context.stopBackgroundMining({
|
|
445
|
-
dataDir,
|
|
446
|
-
databasePath: dbPath,
|
|
447
|
-
provider,
|
|
448
|
-
paths: runtimePaths,
|
|
449
|
-
});
|
|
450
|
-
const nextSteps = getMineStopNextSteps();
|
|
451
|
-
writeLine(context.stdout, snapshot?.note ?? "Background mining was not active.");
|
|
452
|
-
for (const line of formatNextStepLines(nextSteps)) {
|
|
453
|
-
writeLine(context.stdout, line);
|
|
454
|
-
}
|
|
455
|
-
return 0;
|
|
456
|
-
}
|
|
457
401
|
writeLine(context.stderr, `mining runtime command not implemented: ${parsed.command}`);
|
|
458
402
|
return 1;
|
|
459
403
|
}
|