@cogcoin/client 1.1.16 → 1.2.0
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 +28 -11
- package/dist/bitcoind/indexer-daemon/lifecycle.js +98 -1
- package/dist/bitcoind/managed-bitcoind-service-config.js +2 -0
- package/dist/bitcoind/managed-bitcoind-service-lifecycle.js +4 -1
- package/dist/bitcoind/node.d.ts +3 -1
- package/dist/bitcoind/node.js +15 -3
- package/dist/bitcoind/types.d.ts +1 -0
- package/dist/sqlite/reindex-requirement.d.ts +8 -0
- package/dist/sqlite/reindex-requirement.js +100 -0
- package/dist/wallet/mining/competitiveness.d.ts +5 -0
- package/dist/wallet/mining/competitiveness.js +174 -35
- package/dist/wallet/mining/cycle.d.ts +2 -0
- package/dist/wallet/mining/cycle.js +1 -0
- package/dist/wallet/mining/mempool-index.d.ts +65 -0
- package/dist/wallet/mining/mempool-index.js +451 -0
- package/dist/wallet/mining/runner.js +24 -0
- package/dist/wallet/mining/types.d.ts +1 -1
- package/package.json +3 -3
|
@@ -2,9 +2,9 @@ import { createHash } from "node:crypto";
|
|
|
2
2
|
import { assaySentences, deriveBlendSeed } from "@cogcoin/scoring";
|
|
3
3
|
import { lookupDomain, lookupDomainById } from "@cogcoin/indexer/queries";
|
|
4
4
|
import { COG_OPCODES, COG_PREFIX } from "../cogop/constants.js";
|
|
5
|
-
import { extractOpReturnPayloadFromScriptHex } from "../tx/register.js";
|
|
6
5
|
import { compareLexicographically, numberToSats, resolveBip39WordsFromIndices, rootDomain, tieBreakHash, } from "./engine-utils.js";
|
|
7
6
|
import { getIndexerTruthKey } from "./candidate.js";
|
|
7
|
+
import { hydrateMiningMempoolIndex, } from "./mempool-index.js";
|
|
8
8
|
const MINING_MEMPOOL_COOPERATIVE_YIELD_EVERY = 25;
|
|
9
9
|
const MINING_MEMPOOL_RAW_TX_FETCH_CONCURRENCY = 8;
|
|
10
10
|
const MINING_MEMPOOL_PROGRESS_REPORT_EVERY = 25;
|
|
@@ -52,6 +52,41 @@ function resolveEffectiveFeeRate(mempoolEntry) {
|
|
|
52
52
|
: 0n,
|
|
53
53
|
].reduce((best, candidate) => (candidate > best ? candidate : best), 0n));
|
|
54
54
|
}
|
|
55
|
+
function createContextFromRawTransaction(txid, tx) {
|
|
56
|
+
const payloadHex = tx.vout.find((entry) => entry.scriptPubKey?.hex?.startsWith("6a") === true)?.scriptPubKey?.hex;
|
|
57
|
+
const payload = payloadHex === undefined ? null : Buffer.from(payloadHex, "hex");
|
|
58
|
+
const decodedPayload = payload === null || payload.length < 2 || payload[0] !== 0x6a
|
|
59
|
+
? null
|
|
60
|
+
: (() => {
|
|
61
|
+
const opcode = payload[1];
|
|
62
|
+
if (opcode === undefined) {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
if (opcode <= 75) {
|
|
66
|
+
const end = 2 + opcode;
|
|
67
|
+
return end === payload.length ? payload.subarray(2, end) : null;
|
|
68
|
+
}
|
|
69
|
+
if (opcode === 0x4c && payload.length >= 3) {
|
|
70
|
+
const length = payload[2];
|
|
71
|
+
const end = 3 + length;
|
|
72
|
+
return end === payload.length ? payload.subarray(3, end) : null;
|
|
73
|
+
}
|
|
74
|
+
return null;
|
|
75
|
+
})();
|
|
76
|
+
if (decodedPayload === null
|
|
77
|
+
|| decodedPayload.length < 3
|
|
78
|
+
|| decodedPayload[0] !== COG_PREFIX[0]
|
|
79
|
+
|| decodedPayload[1] !== COG_PREFIX[1]
|
|
80
|
+
|| decodedPayload[2] !== COG_PREFIX[2]) {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
return {
|
|
84
|
+
txid,
|
|
85
|
+
senderScriptHex: tx.vin[0]?.prevout?.scriptPubKey?.hex ?? null,
|
|
86
|
+
inputTxids: tx.vin.map((input) => input.txid).filter((inputTxid) => inputTxid !== undefined),
|
|
87
|
+
payload: decodedPayload,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
55
90
|
async function warmMissingRawTxContexts(options) {
|
|
56
91
|
const missingTxids = options.visibleTxids.filter((txid) => !options.rawTxContexts.has(txid));
|
|
57
92
|
if (missingTxids.length === 0) {
|
|
@@ -99,13 +134,10 @@ async function warmMissingRawTxContexts(options) {
|
|
|
99
134
|
const tx = await options.rpc.getRawTransaction(txid, true).catch(() => null);
|
|
100
135
|
options.throwIfStopping?.();
|
|
101
136
|
if (tx !== null) {
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
txid,
|
|
105
|
-
|
|
106
|
-
rawTransaction: tx,
|
|
107
|
-
payload: payloadHex === undefined ? null : extractOpReturnPayloadFromScriptHex(payloadHex),
|
|
108
|
-
});
|
|
137
|
+
const context = createContextFromRawTransaction(txid, tx);
|
|
138
|
+
if (context !== null) {
|
|
139
|
+
options.rawTxContexts.set(txid, context);
|
|
140
|
+
}
|
|
109
141
|
}
|
|
110
142
|
completed += 1;
|
|
111
143
|
await reportProgress(completed, completed === missingTxids.length);
|
|
@@ -217,9 +249,7 @@ function parseSupportedAncestorOperation(context) {
|
|
|
217
249
|
return "unsupported";
|
|
218
250
|
}
|
|
219
251
|
function getAncestorTxids(context, txContexts) {
|
|
220
|
-
return context.
|
|
221
|
-
.map((vin) => vin.txid ?? null)
|
|
222
|
-
.filter((txid) => txid !== null && txContexts.has(txid));
|
|
252
|
+
return context.inputTxids.filter((txid) => txContexts.has(txid));
|
|
223
253
|
}
|
|
224
254
|
function topologicallyOrderAncestorContexts(options) {
|
|
225
255
|
const visited = new Map();
|
|
@@ -281,9 +311,17 @@ function topologicallyOrderAncestorContexts(options) {
|
|
|
281
311
|
return ordered;
|
|
282
312
|
}
|
|
283
313
|
export function topologicallyOrderAncestorTxidsForTesting(options) {
|
|
314
|
+
const txContexts = new Map([...options.txContexts].map(([txid, context]) => [txid, {
|
|
315
|
+
txid: context.txid,
|
|
316
|
+
senderScriptHex: null,
|
|
317
|
+
inputTxids: context.rawTransaction.vin
|
|
318
|
+
.map((vin) => vin.txid)
|
|
319
|
+
.filter((inputTxid) => inputTxid !== undefined),
|
|
320
|
+
payload: null,
|
|
321
|
+
}]));
|
|
284
322
|
const ordered = topologicallyOrderAncestorContexts({
|
|
285
323
|
txid: options.txid,
|
|
286
|
-
txContexts
|
|
324
|
+
txContexts,
|
|
287
325
|
});
|
|
288
326
|
return ordered?.map((context) => context.txid) ?? null;
|
|
289
327
|
}
|
|
@@ -439,6 +477,35 @@ function toSentenceBoardEntries(entries) {
|
|
|
439
477
|
requiredWords: resolveBip39WordsFromIndices(entry.bip39WordIndices),
|
|
440
478
|
}));
|
|
441
479
|
}
|
|
480
|
+
async function fetchIndexedMempoolEntries(options) {
|
|
481
|
+
const entries = {};
|
|
482
|
+
let nextIndex = 0;
|
|
483
|
+
const workerCount = Math.min(MINING_MEMPOOL_RAW_TX_FETCH_CONCURRENCY, options.txids.length);
|
|
484
|
+
const workers = Array.from({ length: workerCount }, async () => {
|
|
485
|
+
while (true) {
|
|
486
|
+
const index = nextIndex;
|
|
487
|
+
if (index >= options.txids.length) {
|
|
488
|
+
return;
|
|
489
|
+
}
|
|
490
|
+
nextIndex += 1;
|
|
491
|
+
options.throwIfStopping?.();
|
|
492
|
+
const txid = options.txids[index];
|
|
493
|
+
const entry = await options.rpc.getMempoolEntry(txid).catch(() => null);
|
|
494
|
+
options.throwIfStopping?.();
|
|
495
|
+
if (entry === null) {
|
|
496
|
+
throw new Error("mining_mempool_index_entry_unavailable");
|
|
497
|
+
}
|
|
498
|
+
entries[txid] = entry;
|
|
499
|
+
}
|
|
500
|
+
});
|
|
501
|
+
try {
|
|
502
|
+
await Promise.all(workers);
|
|
503
|
+
return entries;
|
|
504
|
+
}
|
|
505
|
+
catch {
|
|
506
|
+
return null;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
442
509
|
export async function runCompetitivenessGate(options) {
|
|
443
510
|
const createDecision = (overrides) => ({
|
|
444
511
|
allowed: overrides.allowed ?? false,
|
|
@@ -475,12 +542,8 @@ export async function runCompetitivenessGate(options) {
|
|
|
475
542
|
};
|
|
476
543
|
};
|
|
477
544
|
let mempoolVerbose;
|
|
478
|
-
let mempoolEntries;
|
|
479
545
|
try {
|
|
480
|
-
|
|
481
|
-
options.rpc.getRawMempoolVerbose(),
|
|
482
|
-
options.rpc.getRawMempoolEntries(),
|
|
483
|
-
]);
|
|
546
|
+
mempoolVerbose = await options.rpc.getRawMempoolVerbose();
|
|
484
547
|
options.throwIfStopping?.();
|
|
485
548
|
}
|
|
486
549
|
catch {
|
|
@@ -512,19 +575,95 @@ export async function runCompetitivenessGate(options) {
|
|
|
512
575
|
}
|
|
513
576
|
const referencedPrefix = Buffer.from(options.candidate.referencedBlockHashInternal.subarray(0, 4)).toString("hex");
|
|
514
577
|
const visibleTxids = mempoolVerbose.txids.filter((txid) => !excludedTxids.includes(txid));
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
578
|
+
let rawTxContexts;
|
|
579
|
+
let mempoolEntries;
|
|
580
|
+
let gateCacheStatus = "refreshed";
|
|
581
|
+
if (options.mempoolIndex?.rawTxSupported === true) {
|
|
582
|
+
const indexed = await hydrateMiningMempoolIndex({
|
|
583
|
+
walletRootId,
|
|
584
|
+
serviceIdentity: options.mempoolIndex.serviceIdentity,
|
|
585
|
+
cachePath: options.mempoolIndex.cachePath,
|
|
586
|
+
rpc: options.rpc,
|
|
587
|
+
visibleTxids,
|
|
588
|
+
cooperativeYield: options.cooperativeYield,
|
|
589
|
+
cooperativeYieldEvery: options.cooperativeYieldEvery,
|
|
590
|
+
throwIfStopping: options.throwIfStopping,
|
|
591
|
+
onWarmupProgress: options.onWarmupProgress,
|
|
592
|
+
}).catch(() => null);
|
|
593
|
+
if (indexed !== null) {
|
|
594
|
+
rawTxContexts = indexed.contexts;
|
|
595
|
+
gateCacheStatus = indexed.cacheStatus;
|
|
596
|
+
const indexedTxids = visibleTxids.filter((txid) => rawTxContexts.has(txid));
|
|
597
|
+
const indexedEntries = await fetchIndexedMempoolEntries({
|
|
598
|
+
rpc: options.rpc,
|
|
599
|
+
txids: indexedTxids,
|
|
600
|
+
throwIfStopping: options.throwIfStopping,
|
|
601
|
+
});
|
|
602
|
+
if (indexedEntries === null) {
|
|
603
|
+
rawTxContexts = new Map();
|
|
604
|
+
mempoolEntries = {};
|
|
605
|
+
gateCacheStatus = "fallback-scan";
|
|
606
|
+
}
|
|
607
|
+
else {
|
|
608
|
+
mempoolEntries = indexedEntries;
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
else {
|
|
612
|
+
return createDecision({
|
|
613
|
+
competitivenessGateIndeterminate: true,
|
|
614
|
+
decision: "indeterminate-mempool-gate",
|
|
615
|
+
mempoolSequenceCacheStatus: "index-warming",
|
|
616
|
+
lastMempoolSequence: mempoolSequence,
|
|
617
|
+
});
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
else {
|
|
621
|
+
rawTxContexts = cacheState.rawTxContexts;
|
|
622
|
+
gateCacheStatus = options.mempoolIndex?.rawTxSupported === false ? "fallback-scan" : "refreshed";
|
|
623
|
+
const fallbackEntries = await options.rpc.getRawMempoolEntries().catch(() => null);
|
|
624
|
+
if (fallbackEntries === null) {
|
|
625
|
+
return createDecision({
|
|
626
|
+
competitivenessGateIndeterminate: true,
|
|
627
|
+
});
|
|
628
|
+
}
|
|
629
|
+
mempoolEntries = fallbackEntries;
|
|
630
|
+
pruneRawTxContextsToVisibleTxids({
|
|
631
|
+
rawTxContexts,
|
|
632
|
+
visibleTxids,
|
|
633
|
+
});
|
|
634
|
+
await warmMissingRawTxContexts({
|
|
635
|
+
rpc: options.rpc,
|
|
636
|
+
rawTxContexts,
|
|
637
|
+
visibleTxids,
|
|
638
|
+
cooperativeYield: options.cooperativeYield,
|
|
639
|
+
cooperativeYieldEvery: options.cooperativeYieldEvery,
|
|
640
|
+
throwIfStopping: options.throwIfStopping,
|
|
641
|
+
onWarmupProgress: options.onWarmupProgress,
|
|
642
|
+
});
|
|
643
|
+
}
|
|
644
|
+
if (gateCacheStatus === "fallback-scan" && rawTxContexts.size === 0 && Object.keys(mempoolEntries).length === 0) {
|
|
645
|
+
const fallbackEntries = await options.rpc.getRawMempoolEntries().catch(() => null);
|
|
646
|
+
if (fallbackEntries === null) {
|
|
647
|
+
return createDecision({
|
|
648
|
+
competitivenessGateIndeterminate: true,
|
|
649
|
+
});
|
|
650
|
+
}
|
|
651
|
+
mempoolEntries = fallbackEntries;
|
|
652
|
+
rawTxContexts = cacheState.rawTxContexts;
|
|
653
|
+
pruneRawTxContextsToVisibleTxids({
|
|
654
|
+
rawTxContexts,
|
|
655
|
+
visibleTxids,
|
|
656
|
+
});
|
|
657
|
+
await warmMissingRawTxContexts({
|
|
658
|
+
rpc: options.rpc,
|
|
659
|
+
rawTxContexts,
|
|
660
|
+
visibleTxids,
|
|
661
|
+
cooperativeYield: options.cooperativeYield,
|
|
662
|
+
cooperativeYieldEvery: options.cooperativeYieldEvery,
|
|
663
|
+
throwIfStopping: options.throwIfStopping,
|
|
664
|
+
onWarmupProgress: options.onWarmupProgress,
|
|
665
|
+
});
|
|
666
|
+
}
|
|
528
667
|
const entries = new Map();
|
|
529
668
|
for (let index = 0; index < visibleTxids.length; index += 1) {
|
|
530
669
|
await maybeYieldDuringMempoolScan({
|
|
@@ -555,7 +694,7 @@ export async function runCompetitivenessGate(options) {
|
|
|
555
694
|
const decision = createDecision({
|
|
556
695
|
competitivenessGateIndeterminate: true,
|
|
557
696
|
decision: "indeterminate-mempool-gate",
|
|
558
|
-
mempoolSequenceCacheStatus:
|
|
697
|
+
mempoolSequenceCacheStatus: gateCacheStatus,
|
|
559
698
|
lastMempoolSequence: mempoolSequence,
|
|
560
699
|
});
|
|
561
700
|
setDecisionReuse(decision);
|
|
@@ -625,7 +764,7 @@ export async function runCompetitivenessGate(options) {
|
|
|
625
764
|
higherRankedCompetitorDomainCount: 1,
|
|
626
765
|
dedupedCompetitorDomainCount: otherDomainBest.size,
|
|
627
766
|
competitivenessGateIndeterminate: false,
|
|
628
|
-
mempoolSequenceCacheStatus:
|
|
767
|
+
mempoolSequenceCacheStatus: gateCacheStatus,
|
|
629
768
|
lastMempoolSequence: mempoolSequence,
|
|
630
769
|
visibleBoardEntries: toSentenceBoardEntries(visibleRankedEntries),
|
|
631
770
|
});
|
|
@@ -669,7 +808,7 @@ export async function runCompetitivenessGate(options) {
|
|
|
669
808
|
higherRankedCompetitorDomainCount,
|
|
670
809
|
dedupedCompetitorDomainCount: otherDomainBest.size,
|
|
671
810
|
competitivenessGateIndeterminate: false,
|
|
672
|
-
mempoolSequenceCacheStatus:
|
|
811
|
+
mempoolSequenceCacheStatus: gateCacheStatus,
|
|
673
812
|
lastMempoolSequence: mempoolSequence,
|
|
674
813
|
visibleBoardEntries: toSentenceBoardEntries(visibleRankedEntries),
|
|
675
814
|
candidateRank,
|
|
@@ -683,7 +822,7 @@ export async function runCompetitivenessGate(options) {
|
|
|
683
822
|
higherRankedCompetitorDomainCount,
|
|
684
823
|
dedupedCompetitorDomainCount: otherDomainBest.size,
|
|
685
824
|
competitivenessGateIndeterminate: false,
|
|
686
|
-
mempoolSequenceCacheStatus:
|
|
825
|
+
mempoolSequenceCacheStatus: gateCacheStatus,
|
|
687
826
|
lastMempoolSequence: mempoolSequence,
|
|
688
827
|
visibleBoardEntries: toSentenceBoardEntries(visibleRankedEntries),
|
|
689
828
|
candidateRank,
|
|
@@ -698,7 +837,7 @@ export async function runCompetitivenessGate(options) {
|
|
|
698
837
|
higherRankedCompetitorDomainCount: 0,
|
|
699
838
|
dedupedCompetitorDomainCount: otherDomainBest.size,
|
|
700
839
|
competitivenessGateIndeterminate: true,
|
|
701
|
-
mempoolSequenceCacheStatus:
|
|
840
|
+
mempoolSequenceCacheStatus: gateCacheStatus,
|
|
702
841
|
lastMempoolSequence: mempoolSequence,
|
|
703
842
|
visibleBoardEntries: toSentenceBoardEntries(visibleRankedEntries),
|
|
704
843
|
});
|
|
@@ -10,6 +10,7 @@ import { type MiningRuntimeLoopState } from "./engine-state.js";
|
|
|
10
10
|
import { attachOrStartManagedBitcoindService } from "../../bitcoind/service.js";
|
|
11
11
|
import { createRpcClient } from "../../bitcoind/node.js";
|
|
12
12
|
import { type MiningRuntimeStatusOverrides } from "./projection.js";
|
|
13
|
+
import type { MiningMempoolIndexGateOptions } from "./mempool-index.js";
|
|
13
14
|
export declare function runMiningPhaseMachine(options: {
|
|
14
15
|
dataDir: string;
|
|
15
16
|
databasePath: string;
|
|
@@ -33,6 +34,7 @@ export declare function runMiningPhaseMachine(options: {
|
|
|
33
34
|
assaySentencesImpl?: typeof assaySentences;
|
|
34
35
|
cooperativeYieldImpl?: MiningCooperativeYield;
|
|
35
36
|
cooperativeYieldEvery?: number;
|
|
37
|
+
mempoolIndex?: MiningMempoolIndexGateOptions;
|
|
36
38
|
nowImpl?: () => number;
|
|
37
39
|
saveCycleStatus: (readContext: WalletReadContext, overrides: MiningRuntimeStatusOverrides) => Promise<MiningRuntimeStatusV1>;
|
|
38
40
|
appendEvent: (event: MiningEventRecord) => Promise<void>;
|
|
@@ -350,6 +350,7 @@ export async function runMiningPhaseMachine(options) {
|
|
|
350
350
|
assaySentencesImpl: options.assaySentencesImpl,
|
|
351
351
|
cooperativeYield: options.cooperativeYieldImpl,
|
|
352
352
|
cooperativeYieldEvery: options.cooperativeYieldEvery,
|
|
353
|
+
mempoolIndex: options.mempoolIndex,
|
|
353
354
|
throwIfStopping: options.throwIfStopping,
|
|
354
355
|
onWarmupProgress: async (progress) => {
|
|
355
356
|
if (progress.total <= 0) {
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { WalletRuntimePaths } from "../runtime.js";
|
|
2
|
+
import type { MiningCooperativeYield, MiningRpcClient } from "./engine-types.js";
|
|
3
|
+
export interface MiningMempoolTxContext {
|
|
4
|
+
txid: string;
|
|
5
|
+
senderScriptHex: string | null;
|
|
6
|
+
inputTxids: string[];
|
|
7
|
+
payload: Uint8Array | null;
|
|
8
|
+
}
|
|
9
|
+
export interface MiningMempoolIndexHydrationResult {
|
|
10
|
+
contexts: Map<string, MiningMempoolTxContext>;
|
|
11
|
+
cacheStatus: "indexed" | "index-warming";
|
|
12
|
+
hydratedCount: number;
|
|
13
|
+
}
|
|
14
|
+
export interface MiningMempoolIndexGateOptions {
|
|
15
|
+
rawTxSupported: boolean;
|
|
16
|
+
cachePath: string;
|
|
17
|
+
serviceIdentity: string;
|
|
18
|
+
}
|
|
19
|
+
interface RawTxSubscriberLike extends AsyncIterable<unknown> {
|
|
20
|
+
close(): void;
|
|
21
|
+
connect(endpoint: string): void;
|
|
22
|
+
subscribe(topic: string): void;
|
|
23
|
+
}
|
|
24
|
+
interface ZeroMqModuleLike {
|
|
25
|
+
Subscriber: new () => RawTxSubscriberLike;
|
|
26
|
+
}
|
|
27
|
+
interface ParsedRawTransactionIndexContext {
|
|
28
|
+
txid: string;
|
|
29
|
+
inputTxids: string[];
|
|
30
|
+
payload: Uint8Array | null;
|
|
31
|
+
}
|
|
32
|
+
export declare function resolveMiningMempoolIndexCachePath(paths: Pick<WalletRuntimePaths, "miningRoot">): string;
|
|
33
|
+
export declare function resolveMiningMempoolServiceIdentity(options: {
|
|
34
|
+
dataDir: string;
|
|
35
|
+
pid: number | null;
|
|
36
|
+
zmqEndpoint: string;
|
|
37
|
+
rawTxTopic?: "rawtx";
|
|
38
|
+
}): string;
|
|
39
|
+
export declare function hydrateMiningMempoolIndex(options: {
|
|
40
|
+
walletRootId: string;
|
|
41
|
+
serviceIdentity: string;
|
|
42
|
+
cachePath: string;
|
|
43
|
+
rpc: Pick<MiningRpcClient, "getRawTransaction">;
|
|
44
|
+
visibleTxids: readonly string[];
|
|
45
|
+
cooperativeYield?: MiningCooperativeYield;
|
|
46
|
+
cooperativeYieldEvery?: number;
|
|
47
|
+
throwIfStopping?: () => void;
|
|
48
|
+
onWarmupProgress?: (progress: {
|
|
49
|
+
processed: number;
|
|
50
|
+
total: number;
|
|
51
|
+
}) => Promise<void> | void;
|
|
52
|
+
}): Promise<MiningMempoolIndexHydrationResult>;
|
|
53
|
+
declare function parseRawTransactionForIndex(rawHex: string): ParsedRawTransactionIndexContext | null;
|
|
54
|
+
export declare function ensureMiningMempoolRawTxSubscriber(options: {
|
|
55
|
+
walletRootId: string;
|
|
56
|
+
serviceIdentity: string;
|
|
57
|
+
cachePath: string;
|
|
58
|
+
zmqEndpoint: string;
|
|
59
|
+
rawTxTopic?: "rawtx";
|
|
60
|
+
loadZeroMq?: () => Promise<ZeroMqModuleLike>;
|
|
61
|
+
}): Promise<boolean>;
|
|
62
|
+
export declare function closeMiningMempoolIndexSubscribersForTesting(): Promise<void>;
|
|
63
|
+
export declare function clearMiningMempoolIndexCacheForTesting(): void;
|
|
64
|
+
export declare const parseRawTransactionForMiningMempoolIndexTesting: typeof parseRawTransactionForIndex;
|
|
65
|
+
export {};
|