@mem-cash/storage 0.0.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/README.md +46 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/memoryStorage.d.ts +26 -0
- package/dist/memoryStorage.d.ts.map +1 -0
- package/dist/memoryStorage.js +531 -0
- package/dist/memoryStorage.js.map +1 -0
- package/dist/testHelpers.d.ts +92 -0
- package/dist/testHelpers.d.ts.map +1 -0
- package/dist/testHelpers.js +205 -0
- package/dist/testHelpers.js.map +1 -0
- package/package.json +43 -0
package/README.md
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# @mem-cash/storage
|
|
2
|
+
|
|
3
|
+
In-memory implementation of the `Storage` interface from `@mem-cash/types`.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
import { createMemoryStorage } from "@mem-cash/storage";
|
|
9
|
+
|
|
10
|
+
const storage = createMemoryStorage();
|
|
11
|
+
|
|
12
|
+
// StorageReader methods
|
|
13
|
+
storage.getHeader(height);
|
|
14
|
+
storage.getHistory(scriptHash);
|
|
15
|
+
storage.getBalance(scriptHash);
|
|
16
|
+
storage.getUtxos(scriptHash);
|
|
17
|
+
storage.getScriptHashStatus(scriptHash);
|
|
18
|
+
|
|
19
|
+
// StorageWriter methods
|
|
20
|
+
storage.applyBlock(block);
|
|
21
|
+
storage.undoBlock(height);
|
|
22
|
+
storage.addMempoolTx(tx);
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Defensive Copies
|
|
26
|
+
|
|
27
|
+
All reader methods that return `UtxoEntry` objects (`getUtxos`, `getUtxoByOutpoint`, `getMempoolUtxo`) return cloned entries with copied `lockingBytecode` buffers. This prevents external code from mutating internal storage state. `getTxidsAtHeight` also returns a shallow copy.
|
|
28
|
+
|
|
29
|
+
Undo snapshots created during `applyBlock` clone spent UTXOs so that reorgs restore clean data even if callers mutated returned entries.
|
|
30
|
+
|
|
31
|
+
## Mempool Child Removal
|
|
32
|
+
|
|
33
|
+
`removeMempoolTx` uses iterative traversal (not recursion) to cascade-delete descendant transactions, preventing stack overflow on deep chains.
|
|
34
|
+
|
|
35
|
+
## Test Helpers
|
|
36
|
+
|
|
37
|
+
`createMemoryStorage()` returns a `TestableStorage` with a `_test` namespace for direct state manipulation:
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
storage._test.utxo.add({ txid, vout, satoshis, scriptHash, height });
|
|
41
|
+
storage._test.header.add({ hash, height, timestamp });
|
|
42
|
+
storage._test.mempool.add({ txid, fee, size, inputs, outputs });
|
|
43
|
+
storage._test.tx.add({ txid, height, rawHex });
|
|
44
|
+
storage._test.history.add({ scriptHash, entries });
|
|
45
|
+
storage._test.reset();
|
|
46
|
+
```
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { createMemoryStorage, type StorageInternals, type TestableStorage, } from "./memoryStorage.js";
|
|
2
|
+
export type { AddHeaderParams, AddHistoryParams, AddMempoolTxParams, AddTxParams, AddUtxoParams, RemoveUtxoParams, TestHelpers, TestMempoolInput, TestMempoolOutput, } from "./testHelpers.js";
|
|
3
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,mBAAmB,EACnB,KAAK,gBAAgB,EACrB,KAAK,eAAe,GACpB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACX,eAAe,EACf,gBAAgB,EAChB,kBAAkB,EAClB,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,gBAAgB,EAChB,iBAAiB,GACjB,MAAM,kBAAkB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,mBAAmB,GAGnB,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { BlockHeader, HistoryEntry, MempoolTx, OutpointKey, ScriptHash, Storage, TransactionRecord, Txid, UndoInfo, UtxoEntry } from "@mem-cash/types";
|
|
2
|
+
import { type TestHelpers } from "./testHelpers.js";
|
|
3
|
+
/** Storage extended with direct test manipulation. */
|
|
4
|
+
export type TestableStorage = Storage & {
|
|
5
|
+
readonly _test: TestHelpers;
|
|
6
|
+
};
|
|
7
|
+
/** Internal state shared between storage and test helpers. */
|
|
8
|
+
export interface StorageInternals {
|
|
9
|
+
headers: (BlockHeader | undefined)[];
|
|
10
|
+
headersByHash: Map<string, BlockHeader>;
|
|
11
|
+
utxos: Map<OutpointKey, UtxoEntry>;
|
|
12
|
+
utxosByScriptHash: Map<ScriptHash, Set<OutpointKey>>;
|
|
13
|
+
history: Map<ScriptHash, HistoryEntry[]>;
|
|
14
|
+
txIndex: Map<Txid, TransactionRecord>;
|
|
15
|
+
rawTxs: Map<Txid, string>;
|
|
16
|
+
undoInfos: Map<number, UndoInfo>;
|
|
17
|
+
blockTxids: Map<number, Txid[]>;
|
|
18
|
+
mempoolTxs: Map<Txid, MempoolTx>;
|
|
19
|
+
mempoolUtxos: Map<OutpointKey, UtxoEntry>;
|
|
20
|
+
mempoolUtxosByScriptHash: Map<ScriptHash, Set<OutpointKey>>;
|
|
21
|
+
mempoolSpends: Map<OutpointKey, Txid>;
|
|
22
|
+
mempoolHistory: Map<ScriptHash, HistoryEntry[]>;
|
|
23
|
+
}
|
|
24
|
+
/** Create a new in-memory storage instance with test helpers. */
|
|
25
|
+
export declare function createMemoryStorage(): TestableStorage;
|
|
26
|
+
//# sourceMappingURL=memoryStorage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memoryStorage.d.ts","sourceRoot":"","sources":["../src/memoryStorage.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEX,WAAW,EACX,YAAY,EACZ,SAAS,EACT,WAAW,EAEX,UAAU,EACV,OAAO,EACP,iBAAiB,EACjB,IAAI,EACJ,QAAQ,EACR,SAAS,EACT,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAqB,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEvE,sDAAsD;AACtD,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAA;CAAE,CAAC;AAExE,8DAA8D;AAC9D,MAAM,WAAW,gBAAgB;IAEhC,OAAO,EAAE,CAAC,WAAW,GAAG,SAAS,CAAC,EAAE,CAAC;IACrC,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACxC,KAAK,EAAE,GAAG,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IACnC,iBAAiB,EAAE,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC;IACrD,OAAO,EAAE,GAAG,CAAC,UAAU,EAAE,YAAY,EAAE,CAAC,CAAC;IACzC,OAAO,EAAE,GAAG,CAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC;IACtC,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC1B,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAGjC,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IAGhC,UAAU,EAAE,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IACjC,YAAY,EAAE,GAAG,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IAC1C,wBAAwB,EAAE,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC;IAC5D,aAAa,EAAE,GAAG,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;IACtC,cAAc,EAAE,GAAG,CAAC,UAAU,EAAE,YAAY,EAAE,CAAC,CAAC;CAChD;AA8ED,iEAAiE;AACjE,wBAAgB,mBAAmB,IAAI,eAAe,CAqfrD"}
|
|
@@ -0,0 +1,531 @@
|
|
|
1
|
+
import { binToHex, sha256, utf8ToBin } from "@bitauth/libauth";
|
|
2
|
+
import { makeOutpointKey } from "@mem-cash/types";
|
|
3
|
+
import { createTestHelpers } from "./testHelpers.js";
|
|
4
|
+
/** Clone a UtxoEntry, copying the mutable lockingBytecode. */
|
|
5
|
+
function cloneUtxo(utxo) {
|
|
6
|
+
return { ...utxo, lockingBytecode: utxo.lockingBytecode.slice() };
|
|
7
|
+
}
|
|
8
|
+
/** Create empty internals. */
|
|
9
|
+
function createInternals() {
|
|
10
|
+
return {
|
|
11
|
+
headers: [],
|
|
12
|
+
headersByHash: new Map(),
|
|
13
|
+
utxos: new Map(),
|
|
14
|
+
utxosByScriptHash: new Map(),
|
|
15
|
+
history: new Map(),
|
|
16
|
+
txIndex: new Map(),
|
|
17
|
+
rawTxs: new Map(),
|
|
18
|
+
undoInfos: new Map(),
|
|
19
|
+
blockTxids: new Map(),
|
|
20
|
+
mempoolTxs: new Map(),
|
|
21
|
+
mempoolUtxos: new Map(),
|
|
22
|
+
mempoolUtxosByScriptHash: new Map(),
|
|
23
|
+
mempoolSpends: new Map(),
|
|
24
|
+
mempoolHistory: new Map(),
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/** Compute Electrum-style status hash: SHA256 of concatenated `"txHash:height:"` strings. */
|
|
28
|
+
function computeStatusHash(entries) {
|
|
29
|
+
if (entries.length === 0)
|
|
30
|
+
return null;
|
|
31
|
+
let concatenated = "";
|
|
32
|
+
for (const entry of entries) {
|
|
33
|
+
concatenated += `${entry.txHash}:${entry.height}:`;
|
|
34
|
+
}
|
|
35
|
+
return binToHex(sha256.hash(utf8ToBin(concatenated)));
|
|
36
|
+
}
|
|
37
|
+
/** Get or create a set in a map. */
|
|
38
|
+
function getOrCreateSet(map, key) {
|
|
39
|
+
let set = map.get(key);
|
|
40
|
+
if (!set) {
|
|
41
|
+
set = new Set();
|
|
42
|
+
map.set(key, set);
|
|
43
|
+
}
|
|
44
|
+
return set;
|
|
45
|
+
}
|
|
46
|
+
/** Insert a confirmed history entry maintaining sort by (height ascending, txHash ascending). */
|
|
47
|
+
function insertHistorySorted(entries, entry) {
|
|
48
|
+
let i = entries.length;
|
|
49
|
+
while (i > 0) {
|
|
50
|
+
const prev = entries[i - 1];
|
|
51
|
+
if (!prev || prev.height < entry.height)
|
|
52
|
+
break;
|
|
53
|
+
if (prev.height === entry.height && prev.txHash <= entry.txHash)
|
|
54
|
+
break;
|
|
55
|
+
i--;
|
|
56
|
+
}
|
|
57
|
+
entries.splice(i, 0, entry);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Insert a mempool history entry maintaining Fulcrum's mempool sort order:
|
|
61
|
+
* height 0 (confirmed parents) before height -1 (unconfirmed parents),
|
|
62
|
+
* within same height sorted by txHash ascending.
|
|
63
|
+
* This is equivalent to (height descending, txHash ascending).
|
|
64
|
+
*/
|
|
65
|
+
function insertMempoolHistorySorted(entries, entry) {
|
|
66
|
+
let i = entries.length;
|
|
67
|
+
while (i > 0) {
|
|
68
|
+
const prev = entries[i - 1];
|
|
69
|
+
if (!prev || prev.height > entry.height)
|
|
70
|
+
break;
|
|
71
|
+
if (prev.height === entry.height && prev.txHash <= entry.txHash)
|
|
72
|
+
break;
|
|
73
|
+
i--;
|
|
74
|
+
}
|
|
75
|
+
entries.splice(i, 0, entry);
|
|
76
|
+
}
|
|
77
|
+
/** Create a new in-memory storage instance with test helpers. */
|
|
78
|
+
export function createMemoryStorage() {
|
|
79
|
+
const s = createInternals();
|
|
80
|
+
// --- StorageReader ---
|
|
81
|
+
function getHeader(height) {
|
|
82
|
+
return s.headers[height];
|
|
83
|
+
}
|
|
84
|
+
function getHeaderByHash(hash) {
|
|
85
|
+
return s.headersByHash.get(hash);
|
|
86
|
+
}
|
|
87
|
+
function getTip() {
|
|
88
|
+
for (let i = s.headers.length - 1; i >= 0; i--) {
|
|
89
|
+
const h = s.headers[i];
|
|
90
|
+
if (h)
|
|
91
|
+
return h;
|
|
92
|
+
}
|
|
93
|
+
return undefined;
|
|
94
|
+
}
|
|
95
|
+
function getHistory(scriptHash, fromHeight, toHeight) {
|
|
96
|
+
const all = s.history.get(scriptHash);
|
|
97
|
+
if (!all)
|
|
98
|
+
return [];
|
|
99
|
+
if (fromHeight === undefined && toHeight === undefined)
|
|
100
|
+
return [...all];
|
|
101
|
+
return all.filter((e) => {
|
|
102
|
+
if (fromHeight !== undefined && e.height < fromHeight)
|
|
103
|
+
return false;
|
|
104
|
+
if (toHeight !== undefined && e.height > toHeight)
|
|
105
|
+
return false;
|
|
106
|
+
return true;
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
function getMempoolHistory(scriptHash) {
|
|
110
|
+
return [...(s.mempoolHistory.get(scriptHash) ?? [])];
|
|
111
|
+
}
|
|
112
|
+
function getBalance(scriptHash) {
|
|
113
|
+
// Confirmed balance: sum of confirmed UTXOs
|
|
114
|
+
let confirmed = 0n;
|
|
115
|
+
const confirmedKeys = s.utxosByScriptHash.get(scriptHash);
|
|
116
|
+
if (confirmedKeys) {
|
|
117
|
+
for (const key of confirmedKeys) {
|
|
118
|
+
const utxo = s.utxos.get(key);
|
|
119
|
+
if (utxo)
|
|
120
|
+
confirmed += utxo.satoshis;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// Unconfirmed delta:
|
|
124
|
+
// + mempool outputs to this scripthash
|
|
125
|
+
// - confirmed UTXOs spent in mempool (confirmedSpends only, not unconfirmedSpends)
|
|
126
|
+
let unconfirmed = 0n;
|
|
127
|
+
// Add mempool UTXO values
|
|
128
|
+
const mempoolKeys = s.mempoolUtxosByScriptHash.get(scriptHash);
|
|
129
|
+
if (mempoolKeys) {
|
|
130
|
+
for (const key of mempoolKeys) {
|
|
131
|
+
const utxo = s.mempoolUtxos.get(key);
|
|
132
|
+
if (utxo)
|
|
133
|
+
unconfirmed += utxo.satoshis;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
// Subtract confirmed UTXOs spent in mempool
|
|
137
|
+
for (const mempoolTx of s.mempoolTxs.values()) {
|
|
138
|
+
const entry = mempoolTx.entries.get(scriptHash);
|
|
139
|
+
if (!entry)
|
|
140
|
+
continue;
|
|
141
|
+
for (const spentKey of entry.confirmedSpends) {
|
|
142
|
+
const utxo = s.utxos.get(spentKey);
|
|
143
|
+
if (utxo)
|
|
144
|
+
unconfirmed -= utxo.satoshis;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return { confirmed, unconfirmed };
|
|
148
|
+
}
|
|
149
|
+
function getUtxos(scriptHash) {
|
|
150
|
+
const result = [];
|
|
151
|
+
// Confirmed UTXOs not spent in mempool
|
|
152
|
+
const confirmedKeys = s.utxosByScriptHash.get(scriptHash);
|
|
153
|
+
if (confirmedKeys) {
|
|
154
|
+
for (const key of confirmedKeys) {
|
|
155
|
+
if (s.mempoolSpends.has(key))
|
|
156
|
+
continue;
|
|
157
|
+
const utxo = s.utxos.get(key);
|
|
158
|
+
if (utxo)
|
|
159
|
+
result.push(cloneUtxo(utxo));
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
// Mempool UTXOs (unconfirmed outputs)
|
|
163
|
+
const mempoolKeys = s.mempoolUtxosByScriptHash.get(scriptHash);
|
|
164
|
+
if (mempoolKeys) {
|
|
165
|
+
for (const key of mempoolKeys) {
|
|
166
|
+
if (s.mempoolSpends.has(key))
|
|
167
|
+
continue;
|
|
168
|
+
const utxo = s.mempoolUtxos.get(key);
|
|
169
|
+
if (utxo)
|
|
170
|
+
result.push(cloneUtxo(utxo));
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return result;
|
|
174
|
+
}
|
|
175
|
+
function getTx(txid) {
|
|
176
|
+
return s.txIndex.get(txid);
|
|
177
|
+
}
|
|
178
|
+
function getRawTx(txid) {
|
|
179
|
+
return s.rawTxs.get(txid);
|
|
180
|
+
}
|
|
181
|
+
function getScriptHashStatus(scriptHash) {
|
|
182
|
+
const confirmed = s.history.get(scriptHash) ?? [];
|
|
183
|
+
const mempool = s.mempoolHistory.get(scriptHash) ?? [];
|
|
184
|
+
return computeStatusHash([...confirmed, ...mempool]);
|
|
185
|
+
}
|
|
186
|
+
function getMempoolTx(txid) {
|
|
187
|
+
return s.mempoolTxs.get(txid);
|
|
188
|
+
}
|
|
189
|
+
function getTxidsAtHeight(height) {
|
|
190
|
+
const txids = s.blockTxids.get(height);
|
|
191
|
+
return txids ? [...txids] : undefined;
|
|
192
|
+
}
|
|
193
|
+
function getUtxoByOutpoint(key) {
|
|
194
|
+
if (s.mempoolSpends.has(key))
|
|
195
|
+
return undefined;
|
|
196
|
+
const utxo = s.utxos.get(key) ?? s.mempoolUtxos.get(key);
|
|
197
|
+
return utxo ? cloneUtxo(utxo) : undefined;
|
|
198
|
+
}
|
|
199
|
+
function getMempoolTxids() {
|
|
200
|
+
return [...s.mempoolTxs.keys()];
|
|
201
|
+
}
|
|
202
|
+
function getMempoolUtxo(key) {
|
|
203
|
+
const utxo = s.mempoolUtxos.get(key);
|
|
204
|
+
return utxo ? cloneUtxo(utxo) : undefined;
|
|
205
|
+
}
|
|
206
|
+
// --- StorageWriter ---
|
|
207
|
+
function applyBlock(block) {
|
|
208
|
+
const affected = new Set();
|
|
209
|
+
const addedUtxoKeys = [];
|
|
210
|
+
const removedUtxos = [];
|
|
211
|
+
for (const tx of block.transactions) {
|
|
212
|
+
// Process inputs (spend UTXOs)
|
|
213
|
+
for (const input of tx.inputs) {
|
|
214
|
+
const key = makeOutpointKey(input.prevOutpoint.txid, input.prevOutpoint.vout);
|
|
215
|
+
const existing = s.utxos.get(key);
|
|
216
|
+
if (existing) {
|
|
217
|
+
removedUtxos.push(cloneUtxo(existing));
|
|
218
|
+
affected.add(existing.scriptHash);
|
|
219
|
+
s.utxos.delete(key);
|
|
220
|
+
const shSet = s.utxosByScriptHash.get(existing.scriptHash);
|
|
221
|
+
if (shSet) {
|
|
222
|
+
shSet.delete(key);
|
|
223
|
+
if (shSet.size === 0)
|
|
224
|
+
s.utxosByScriptHash.delete(existing.scriptHash);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
// Process outputs (create UTXOs)
|
|
229
|
+
for (const output of tx.outputs) {
|
|
230
|
+
s.utxos.set(output.outpointKey, output.utxo);
|
|
231
|
+
getOrCreateSet(s.utxosByScriptHash, output.utxo.scriptHash).add(output.outpointKey);
|
|
232
|
+
addedUtxoKeys.push(output.outpointKey);
|
|
233
|
+
affected.add(output.utxo.scriptHash);
|
|
234
|
+
}
|
|
235
|
+
// Store transaction record
|
|
236
|
+
const txRecord = {
|
|
237
|
+
txid: tx.txid,
|
|
238
|
+
height: block.height,
|
|
239
|
+
};
|
|
240
|
+
if (tx.rawHex !== undefined) {
|
|
241
|
+
txRecord.rawHex = tx.rawHex;
|
|
242
|
+
}
|
|
243
|
+
if (tx.fee !== undefined) {
|
|
244
|
+
txRecord.fee = tx.fee;
|
|
245
|
+
}
|
|
246
|
+
s.txIndex.set(tx.txid, txRecord);
|
|
247
|
+
if (tx.rawHex) {
|
|
248
|
+
s.rawTxs.set(tx.txid, tx.rawHex);
|
|
249
|
+
}
|
|
250
|
+
// Remove from mempool if present
|
|
251
|
+
if (s.mempoolTxs.has(tx.txid)) {
|
|
252
|
+
removeMempoolTxInternal(tx.txid, affected);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
// Update history for all affected scripthashes
|
|
256
|
+
for (const tx of block.transactions) {
|
|
257
|
+
const txScriptHashes = new Set();
|
|
258
|
+
for (const input of tx.inputs) {
|
|
259
|
+
const key = makeOutpointKey(input.prevOutpoint.txid, input.prevOutpoint.vout);
|
|
260
|
+
const removed = removedUtxos.find((u) => makeOutpointKey(u.outpoint.txid, u.outpoint.vout) === key);
|
|
261
|
+
if (removed)
|
|
262
|
+
txScriptHashes.add(removed.scriptHash);
|
|
263
|
+
}
|
|
264
|
+
for (const output of tx.outputs) {
|
|
265
|
+
txScriptHashes.add(output.utxo.scriptHash);
|
|
266
|
+
}
|
|
267
|
+
for (const sh of txScriptHashes) {
|
|
268
|
+
const entries = getOrCreateArray(s.history, sh);
|
|
269
|
+
insertHistorySorted(entries, { txHash: tx.txid, height: block.height });
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
// Store block txid ordering (for merkle proofs)
|
|
273
|
+
s.blockTxids.set(block.height, block.transactions.map((tx) => tx.txid));
|
|
274
|
+
// Store header
|
|
275
|
+
s.headers[block.height] = block.header;
|
|
276
|
+
s.headersByHash.set(block.hash, block.header);
|
|
277
|
+
// Store undo info
|
|
278
|
+
s.undoInfos.set(block.height, {
|
|
279
|
+
height: block.height,
|
|
280
|
+
hash: block.hash,
|
|
281
|
+
addedUtxos: addedUtxoKeys,
|
|
282
|
+
removedUtxos,
|
|
283
|
+
affectedScriptHashes: affected,
|
|
284
|
+
});
|
|
285
|
+
return affected;
|
|
286
|
+
}
|
|
287
|
+
function undoBlock(height) {
|
|
288
|
+
const undo = s.undoInfos.get(height);
|
|
289
|
+
if (!undo)
|
|
290
|
+
return new Set();
|
|
291
|
+
const affected = new Set(undo.affectedScriptHashes);
|
|
292
|
+
// Remove UTXOs added by this block
|
|
293
|
+
for (const key of undo.addedUtxos) {
|
|
294
|
+
const utxo = s.utxos.get(key);
|
|
295
|
+
if (utxo) {
|
|
296
|
+
s.utxos.delete(key);
|
|
297
|
+
const shSet = s.utxosByScriptHash.get(utxo.scriptHash);
|
|
298
|
+
if (shSet) {
|
|
299
|
+
shSet.delete(key);
|
|
300
|
+
if (shSet.size === 0)
|
|
301
|
+
s.utxosByScriptHash.delete(utxo.scriptHash);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
// Restore UTXOs spent by this block
|
|
306
|
+
for (const utxo of undo.removedUtxos) {
|
|
307
|
+
const key = makeOutpointKey(utxo.outpoint.txid, utxo.outpoint.vout);
|
|
308
|
+
s.utxos.set(key, utxo);
|
|
309
|
+
getOrCreateSet(s.utxosByScriptHash, utxo.scriptHash).add(key);
|
|
310
|
+
}
|
|
311
|
+
// Remove history entries at this height
|
|
312
|
+
for (const sh of affected) {
|
|
313
|
+
const entries = s.history.get(sh);
|
|
314
|
+
if (entries) {
|
|
315
|
+
const filtered = entries.filter((e) => e.height !== height);
|
|
316
|
+
if (filtered.length === 0) {
|
|
317
|
+
s.history.delete(sh);
|
|
318
|
+
}
|
|
319
|
+
else {
|
|
320
|
+
s.history.set(sh, filtered);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
// Remove tx records for transactions in this block
|
|
325
|
+
const undoBlockData = s.undoInfos.get(height);
|
|
326
|
+
if (undoBlockData) {
|
|
327
|
+
// Remove txids that were added at this height
|
|
328
|
+
for (const [txid, record] of s.txIndex) {
|
|
329
|
+
if (record.height === height) {
|
|
330
|
+
s.txIndex.delete(txid);
|
|
331
|
+
s.rawTxs.delete(txid);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
// Remove block txids
|
|
336
|
+
s.blockTxids.delete(height);
|
|
337
|
+
// Remove header
|
|
338
|
+
const header = s.headers[height];
|
|
339
|
+
if (header) {
|
|
340
|
+
s.headersByHash.delete(header.hash);
|
|
341
|
+
s.headers[height] = undefined;
|
|
342
|
+
}
|
|
343
|
+
// Trim trailing undefineds
|
|
344
|
+
while (s.headers.length > 0 && s.headers[s.headers.length - 1] === undefined) {
|
|
345
|
+
s.headers.pop();
|
|
346
|
+
}
|
|
347
|
+
// Clear mempool (after reorg, mempool is invalidated)
|
|
348
|
+
clearMempoolInternal(affected);
|
|
349
|
+
s.undoInfos.delete(height);
|
|
350
|
+
return affected;
|
|
351
|
+
}
|
|
352
|
+
function addMempoolTx(tx) {
|
|
353
|
+
const affected = new Set();
|
|
354
|
+
s.mempoolTxs.set(tx.txid, tx);
|
|
355
|
+
for (const [scriptHash, entry] of tx.entries) {
|
|
356
|
+
affected.add(scriptHash);
|
|
357
|
+
// Track confirmed spends
|
|
358
|
+
for (const key of entry.confirmedSpends) {
|
|
359
|
+
s.mempoolSpends.set(key, tx.txid);
|
|
360
|
+
}
|
|
361
|
+
// Track unconfirmed spends
|
|
362
|
+
for (const key of entry.unconfirmedSpends) {
|
|
363
|
+
s.mempoolSpends.set(key, tx.txid);
|
|
364
|
+
}
|
|
365
|
+
// Add mempool UTXOs
|
|
366
|
+
for (const key of entry.outputs) {
|
|
367
|
+
const utxo = s.mempoolUtxos.get(key);
|
|
368
|
+
// The UTXO must be provided via mempoolUtxos already, or we create a placeholder
|
|
369
|
+
// In practice, the caller builds the full MempoolTx with UTXOs set up via test helpers
|
|
370
|
+
if (!utxo)
|
|
371
|
+
continue;
|
|
372
|
+
getOrCreateSet(s.mempoolUtxosByScriptHash, scriptHash).add(key);
|
|
373
|
+
}
|
|
374
|
+
// Add mempool history (sorted: height 0 before -1, then by txHash)
|
|
375
|
+
const hasUnconfirmedParent = tx.parents.size > 0;
|
|
376
|
+
const historyEntry = {
|
|
377
|
+
txHash: tx.txid,
|
|
378
|
+
height: hasUnconfirmedParent ? -1 : 0,
|
|
379
|
+
fee: tx.fee,
|
|
380
|
+
};
|
|
381
|
+
const mempoolEntries = getOrCreateArray(s.mempoolHistory, scriptHash);
|
|
382
|
+
insertMempoolHistorySorted(mempoolEntries, historyEntry);
|
|
383
|
+
}
|
|
384
|
+
// Update parent→child linkage
|
|
385
|
+
for (const parentTxid of tx.parents) {
|
|
386
|
+
const parentTx = s.mempoolTxs.get(parentTxid);
|
|
387
|
+
if (parentTx) {
|
|
388
|
+
parentTx.children.add(tx.txid);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
return affected;
|
|
392
|
+
}
|
|
393
|
+
function removeMempoolTx(txid) {
|
|
394
|
+
const affected = new Set();
|
|
395
|
+
removeMempoolTxInternal(txid, affected);
|
|
396
|
+
return affected;
|
|
397
|
+
}
|
|
398
|
+
function removeMempoolTxInternal(txid, affected) {
|
|
399
|
+
// Iterative traversal to avoid stack overflow on deep chains
|
|
400
|
+
const stack = [txid];
|
|
401
|
+
const toRemove = [];
|
|
402
|
+
const visited = new Set();
|
|
403
|
+
// Collect all descendants depth-first (children before parents)
|
|
404
|
+
while (stack.length > 0) {
|
|
405
|
+
const current = stack.pop();
|
|
406
|
+
if (visited.has(current))
|
|
407
|
+
continue;
|
|
408
|
+
visited.add(current);
|
|
409
|
+
toRemove.push(current);
|
|
410
|
+
const tx = s.mempoolTxs.get(current);
|
|
411
|
+
if (tx) {
|
|
412
|
+
for (const childTxid of tx.children) {
|
|
413
|
+
if (!visited.has(childTxid))
|
|
414
|
+
stack.push(childTxid);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
// Remove in reverse order (children first)
|
|
419
|
+
for (let i = toRemove.length - 1; i >= 0; i--) {
|
|
420
|
+
const removeTxid = toRemove[i];
|
|
421
|
+
const tx = s.mempoolTxs.get(removeTxid);
|
|
422
|
+
if (!tx)
|
|
423
|
+
continue;
|
|
424
|
+
for (const [scriptHash, entry] of tx.entries) {
|
|
425
|
+
affected.add(scriptHash);
|
|
426
|
+
// Remove spend tracking
|
|
427
|
+
for (const key of entry.confirmedSpends) {
|
|
428
|
+
s.mempoolSpends.delete(key);
|
|
429
|
+
}
|
|
430
|
+
for (const key of entry.unconfirmedSpends) {
|
|
431
|
+
s.mempoolSpends.delete(key);
|
|
432
|
+
}
|
|
433
|
+
// Remove mempool UTXOs
|
|
434
|
+
for (const key of entry.outputs) {
|
|
435
|
+
s.mempoolUtxos.delete(key);
|
|
436
|
+
const shSet = s.mempoolUtxosByScriptHash.get(scriptHash);
|
|
437
|
+
if (shSet) {
|
|
438
|
+
shSet.delete(key);
|
|
439
|
+
if (shSet.size === 0)
|
|
440
|
+
s.mempoolUtxosByScriptHash.delete(scriptHash);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
// Remove mempool history
|
|
444
|
+
const mempoolEntries = s.mempoolHistory.get(scriptHash);
|
|
445
|
+
if (mempoolEntries) {
|
|
446
|
+
const filtered = mempoolEntries.filter((e) => e.txHash !== removeTxid);
|
|
447
|
+
if (filtered.length === 0) {
|
|
448
|
+
s.mempoolHistory.delete(scriptHash);
|
|
449
|
+
}
|
|
450
|
+
else {
|
|
451
|
+
s.mempoolHistory.set(scriptHash, filtered);
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
// Remove parent→child reference
|
|
456
|
+
for (const parentTxid of tx.parents) {
|
|
457
|
+
const parentTx = s.mempoolTxs.get(parentTxid);
|
|
458
|
+
if (parentTx) {
|
|
459
|
+
parentTx.children.delete(removeTxid);
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
s.mempoolTxs.delete(removeTxid);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
function clearMempool() {
|
|
466
|
+
const affected = new Set();
|
|
467
|
+
clearMempoolInternal(affected);
|
|
468
|
+
return affected;
|
|
469
|
+
}
|
|
470
|
+
function clearMempoolInternal(affected) {
|
|
471
|
+
for (const scriptHash of s.mempoolHistory.keys()) {
|
|
472
|
+
affected.add(scriptHash);
|
|
473
|
+
}
|
|
474
|
+
for (const [, tx] of s.mempoolTxs) {
|
|
475
|
+
for (const scriptHash of tx.entries.keys()) {
|
|
476
|
+
affected.add(scriptHash);
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
s.mempoolTxs.clear();
|
|
480
|
+
s.mempoolUtxos.clear();
|
|
481
|
+
s.mempoolUtxosByScriptHash.clear();
|
|
482
|
+
s.mempoolSpends.clear();
|
|
483
|
+
s.mempoolHistory.clear();
|
|
484
|
+
}
|
|
485
|
+
function addMempoolUtxo(key, utxo) {
|
|
486
|
+
s.mempoolUtxos.set(key, utxo);
|
|
487
|
+
}
|
|
488
|
+
function storeRawTx(txid, rawHex) {
|
|
489
|
+
s.rawTxs.set(txid, rawHex);
|
|
490
|
+
}
|
|
491
|
+
// --- Build test helpers ---
|
|
492
|
+
const testHelpers = createTestHelpers(s, { removeMempoolTx, clearMempool });
|
|
493
|
+
return {
|
|
494
|
+
// StorageReader
|
|
495
|
+
getHeader,
|
|
496
|
+
getHeaderByHash,
|
|
497
|
+
getTip,
|
|
498
|
+
getHistory,
|
|
499
|
+
getMempoolHistory,
|
|
500
|
+
getBalance,
|
|
501
|
+
getUtxos,
|
|
502
|
+
getTx,
|
|
503
|
+
getRawTx,
|
|
504
|
+
getScriptHashStatus,
|
|
505
|
+
getMempoolTx,
|
|
506
|
+
getTxidsAtHeight,
|
|
507
|
+
getUtxoByOutpoint,
|
|
508
|
+
getMempoolTxids,
|
|
509
|
+
getMempoolUtxo,
|
|
510
|
+
// StorageWriter
|
|
511
|
+
applyBlock,
|
|
512
|
+
undoBlock,
|
|
513
|
+
addMempoolTx,
|
|
514
|
+
removeMempoolTx,
|
|
515
|
+
clearMempool,
|
|
516
|
+
addMempoolUtxo,
|
|
517
|
+
storeRawTx,
|
|
518
|
+
// Test
|
|
519
|
+
_test: testHelpers,
|
|
520
|
+
};
|
|
521
|
+
}
|
|
522
|
+
/** Get or create an array in a map. */
|
|
523
|
+
function getOrCreateArray(map, key) {
|
|
524
|
+
let arr = map.get(key);
|
|
525
|
+
if (!arr) {
|
|
526
|
+
arr = [];
|
|
527
|
+
map.set(key, arr);
|
|
528
|
+
}
|
|
529
|
+
return arr;
|
|
530
|
+
}
|
|
531
|
+
//# sourceMappingURL=memoryStorage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memoryStorage.js","sourceRoot":"","sources":["../src/memoryStorage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import type { BlockHash, BlockHeight, HistoryEntry, ScriptHash, TokenData, Txid } from "@mem-cash/types";
|
|
2
|
+
import type { StorageInternals } from "./memoryStorage.js";
|
|
3
|
+
/** Parameters for adding a test UTXO. */
|
|
4
|
+
export interface AddUtxoParams {
|
|
5
|
+
txid: Txid;
|
|
6
|
+
vout: number;
|
|
7
|
+
satoshis: bigint;
|
|
8
|
+
scriptHash: ScriptHash;
|
|
9
|
+
height: BlockHeight;
|
|
10
|
+
lockingBytecode?: Uint8Array;
|
|
11
|
+
isCoinbase?: boolean;
|
|
12
|
+
tokenData?: TokenData;
|
|
13
|
+
}
|
|
14
|
+
/** Parameters for removing a test UTXO. */
|
|
15
|
+
export interface RemoveUtxoParams {
|
|
16
|
+
txid: Txid;
|
|
17
|
+
vout: number;
|
|
18
|
+
}
|
|
19
|
+
/** Parameters for adding a test header. */
|
|
20
|
+
export interface AddHeaderParams {
|
|
21
|
+
hash: BlockHash;
|
|
22
|
+
height: BlockHeight;
|
|
23
|
+
version?: number;
|
|
24
|
+
prevHash?: BlockHash;
|
|
25
|
+
merkleRoot?: string;
|
|
26
|
+
timestamp?: number;
|
|
27
|
+
bits?: number;
|
|
28
|
+
nonce?: number;
|
|
29
|
+
hex?: string;
|
|
30
|
+
}
|
|
31
|
+
/** Simplified mempool input for test helpers. */
|
|
32
|
+
export interface TestMempoolInput {
|
|
33
|
+
txid: Txid;
|
|
34
|
+
vout: number;
|
|
35
|
+
}
|
|
36
|
+
/** Simplified mempool output for test helpers. */
|
|
37
|
+
export interface TestMempoolOutput {
|
|
38
|
+
satoshis: bigint;
|
|
39
|
+
scriptHash: ScriptHash;
|
|
40
|
+
lockingBytecode?: Uint8Array;
|
|
41
|
+
tokenData?: TokenData;
|
|
42
|
+
}
|
|
43
|
+
/** Parameters for adding a test mempool transaction. */
|
|
44
|
+
export interface AddMempoolTxParams {
|
|
45
|
+
txid: Txid;
|
|
46
|
+
fee: bigint;
|
|
47
|
+
size: number;
|
|
48
|
+
inputs: TestMempoolInput[];
|
|
49
|
+
outputs: TestMempoolOutput[];
|
|
50
|
+
}
|
|
51
|
+
/** Parameters for adding a transaction record. */
|
|
52
|
+
export interface AddTxParams {
|
|
53
|
+
txid: Txid;
|
|
54
|
+
height: BlockHeight;
|
|
55
|
+
rawHex?: string;
|
|
56
|
+
fee?: bigint;
|
|
57
|
+
}
|
|
58
|
+
/** Parameters for adding history entries. */
|
|
59
|
+
export interface AddHistoryParams {
|
|
60
|
+
scriptHash: ScriptHash;
|
|
61
|
+
entries: HistoryEntry[];
|
|
62
|
+
}
|
|
63
|
+
/** Storage write ops needed by test helpers. */
|
|
64
|
+
export interface StorageWriteOps {
|
|
65
|
+
removeMempoolTx(txid: Txid): Set<ScriptHash>;
|
|
66
|
+
clearMempool(): Set<ScriptHash>;
|
|
67
|
+
}
|
|
68
|
+
/** Direct manipulation helpers for testing. */
|
|
69
|
+
export interface TestHelpers {
|
|
70
|
+
readonly utxo: {
|
|
71
|
+
add(params: AddUtxoParams): void;
|
|
72
|
+
remove(params: RemoveUtxoParams): void;
|
|
73
|
+
};
|
|
74
|
+
readonly header: {
|
|
75
|
+
add(params: AddHeaderParams): void;
|
|
76
|
+
};
|
|
77
|
+
readonly mempool: {
|
|
78
|
+
add(params: AddMempoolTxParams): void;
|
|
79
|
+
remove(txid: Txid): Set<ScriptHash>;
|
|
80
|
+
clear(): Set<ScriptHash>;
|
|
81
|
+
};
|
|
82
|
+
readonly tx: {
|
|
83
|
+
add(params: AddTxParams): void;
|
|
84
|
+
};
|
|
85
|
+
readonly history: {
|
|
86
|
+
add(params: AddHistoryParams): void;
|
|
87
|
+
};
|
|
88
|
+
reset(): void;
|
|
89
|
+
}
|
|
90
|
+
/** Create test helpers that manipulate storage internals directly. */
|
|
91
|
+
export declare function createTestHelpers(s: StorageInternals, ops: StorageWriteOps): TestHelpers;
|
|
92
|
+
//# sourceMappingURL=testHelpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testHelpers.d.ts","sourceRoot":"","sources":["../src/testHelpers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import { makeOutpointKey } from "@mem-cash/types";
|
|
2
|
+
/** Get or create a set in a map. */
|
|
3
|
+
function getOrCreateSet(map, key) {
|
|
4
|
+
let set = map.get(key);
|
|
5
|
+
if (!set) {
|
|
6
|
+
set = new Set();
|
|
7
|
+
map.set(key, set);
|
|
8
|
+
}
|
|
9
|
+
return set;
|
|
10
|
+
}
|
|
11
|
+
/** Insert a history entry maintaining sort by (height, txHash). */
|
|
12
|
+
function insertHistorySorted(entries, entry) {
|
|
13
|
+
let i = entries.length;
|
|
14
|
+
while (i > 0) {
|
|
15
|
+
const prev = entries[i - 1];
|
|
16
|
+
if (!prev || prev.height < entry.height)
|
|
17
|
+
break;
|
|
18
|
+
if (prev.height === entry.height && prev.txHash <= entry.txHash)
|
|
19
|
+
break;
|
|
20
|
+
i--;
|
|
21
|
+
}
|
|
22
|
+
entries.splice(i, 0, entry);
|
|
23
|
+
}
|
|
24
|
+
/** Create test helpers that manipulate storage internals directly. */
|
|
25
|
+
export function createTestHelpers(s, ops) {
|
|
26
|
+
return {
|
|
27
|
+
utxo: {
|
|
28
|
+
add(params) {
|
|
29
|
+
const key = makeOutpointKey(params.txid, params.vout);
|
|
30
|
+
const utxo = Object.assign({
|
|
31
|
+
outpoint: { txid: params.txid, vout: params.vout },
|
|
32
|
+
satoshis: params.satoshis,
|
|
33
|
+
scriptHash: params.scriptHash,
|
|
34
|
+
height: params.height,
|
|
35
|
+
lockingBytecode: params.lockingBytecode ?? new Uint8Array(0),
|
|
36
|
+
}, params.isCoinbase ? { isCoinbase: true } : {}, params.tokenData !== undefined ? { tokenData: params.tokenData } : {});
|
|
37
|
+
s.utxos.set(key, utxo);
|
|
38
|
+
getOrCreateSet(s.utxosByScriptHash, params.scriptHash).add(key);
|
|
39
|
+
},
|
|
40
|
+
remove(params) {
|
|
41
|
+
const key = makeOutpointKey(params.txid, params.vout);
|
|
42
|
+
const utxo = s.utxos.get(key);
|
|
43
|
+
if (utxo) {
|
|
44
|
+
s.utxos.delete(key);
|
|
45
|
+
const shSet = s.utxosByScriptHash.get(utxo.scriptHash);
|
|
46
|
+
if (shSet) {
|
|
47
|
+
shSet.delete(key);
|
|
48
|
+
if (shSet.size === 0)
|
|
49
|
+
s.utxosByScriptHash.delete(utxo.scriptHash);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
header: {
|
|
55
|
+
add(params) {
|
|
56
|
+
const header = {
|
|
57
|
+
hash: params.hash,
|
|
58
|
+
height: params.height,
|
|
59
|
+
version: params.version ?? 1,
|
|
60
|
+
prevHash: params.prevHash ?? "0".repeat(64),
|
|
61
|
+
merkleRoot: params.merkleRoot ?? "0".repeat(64),
|
|
62
|
+
timestamp: params.timestamp ?? Math.floor(Date.now() / 1000),
|
|
63
|
+
bits: params.bits ?? 0x1d00ffff,
|
|
64
|
+
nonce: params.nonce ?? 0,
|
|
65
|
+
hex: params.hex ?? "0".repeat(160),
|
|
66
|
+
};
|
|
67
|
+
s.headers[params.height] = header;
|
|
68
|
+
s.headersByHash.set(params.hash, header);
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
mempool: {
|
|
72
|
+
add(params) {
|
|
73
|
+
const entriesMap = new Map();
|
|
74
|
+
const parents = new Set();
|
|
75
|
+
// Process inputs
|
|
76
|
+
for (const input of params.inputs) {
|
|
77
|
+
const key = makeOutpointKey(input.txid, input.vout);
|
|
78
|
+
// Check if this is spending a confirmed UTXO
|
|
79
|
+
const confirmedUtxo = s.utxos.get(key);
|
|
80
|
+
if (confirmedUtxo) {
|
|
81
|
+
const entry = getOrCreateEntry(entriesMap, confirmedUtxo.scriptHash);
|
|
82
|
+
entry.confirmedSpends.push(key);
|
|
83
|
+
s.mempoolSpends.set(key, params.txid);
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
// Check if spending a mempool UTXO
|
|
87
|
+
const mempoolUtxo = s.mempoolUtxos.get(key);
|
|
88
|
+
if (mempoolUtxo) {
|
|
89
|
+
const entry = getOrCreateEntry(entriesMap, mempoolUtxo.scriptHash);
|
|
90
|
+
entry.unconfirmedSpends.push(key);
|
|
91
|
+
s.mempoolSpends.set(key, params.txid);
|
|
92
|
+
parents.add(input.txid);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// Process outputs
|
|
96
|
+
for (let vout = 0; vout < params.outputs.length; vout++) {
|
|
97
|
+
const output = params.outputs[vout];
|
|
98
|
+
if (!output)
|
|
99
|
+
continue;
|
|
100
|
+
const key = makeOutpointKey(params.txid, vout);
|
|
101
|
+
const utxo = Object.assign({
|
|
102
|
+
outpoint: { txid: params.txid, vout },
|
|
103
|
+
satoshis: output.satoshis,
|
|
104
|
+
scriptHash: output.scriptHash,
|
|
105
|
+
height: 0,
|
|
106
|
+
lockingBytecode: output.lockingBytecode ?? new Uint8Array(0),
|
|
107
|
+
}, output.tokenData !== undefined ? { tokenData: output.tokenData } : {});
|
|
108
|
+
s.mempoolUtxos.set(key, utxo);
|
|
109
|
+
getOrCreateSet(s.mempoolUtxosByScriptHash, output.scriptHash).add(key);
|
|
110
|
+
const entry = getOrCreateEntry(entriesMap, output.scriptHash);
|
|
111
|
+
entry.outputs.push(key);
|
|
112
|
+
}
|
|
113
|
+
// Build mempool history
|
|
114
|
+
const hasUnconfirmedParent = parents.size > 0;
|
|
115
|
+
for (const scriptHash of entriesMap.keys()) {
|
|
116
|
+
const historyEntry = {
|
|
117
|
+
txHash: params.txid,
|
|
118
|
+
height: hasUnconfirmedParent ? -1 : 0,
|
|
119
|
+
fee: params.fee,
|
|
120
|
+
};
|
|
121
|
+
const mempoolEntries = getOrCreateArray(s.mempoolHistory, scriptHash);
|
|
122
|
+
mempoolEntries.push(historyEntry);
|
|
123
|
+
}
|
|
124
|
+
const mempoolTx = {
|
|
125
|
+
txid: params.txid,
|
|
126
|
+
fee: params.fee,
|
|
127
|
+
size: params.size,
|
|
128
|
+
entries: entriesMap,
|
|
129
|
+
parents,
|
|
130
|
+
children: new Set(),
|
|
131
|
+
};
|
|
132
|
+
s.mempoolTxs.set(params.txid, mempoolTx);
|
|
133
|
+
// Update parent→child links
|
|
134
|
+
for (const parentTxid of parents) {
|
|
135
|
+
const parentTx = s.mempoolTxs.get(parentTxid);
|
|
136
|
+
if (parentTx) {
|
|
137
|
+
parentTx.children.add(params.txid);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
},
|
|
141
|
+
remove(txid) {
|
|
142
|
+
return ops.removeMempoolTx(txid);
|
|
143
|
+
},
|
|
144
|
+
clear() {
|
|
145
|
+
return ops.clearMempool();
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
tx: {
|
|
149
|
+
add(params) {
|
|
150
|
+
const record = Object.assign({ txid: params.txid, height: params.height }, params.rawHex !== undefined ? { rawHex: params.rawHex } : {}, params.fee !== undefined ? { fee: params.fee } : {});
|
|
151
|
+
s.txIndex.set(params.txid, record);
|
|
152
|
+
if (params.rawHex) {
|
|
153
|
+
s.rawTxs.set(params.txid, params.rawHex);
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
history: {
|
|
158
|
+
add(params) {
|
|
159
|
+
let entries = s.history.get(params.scriptHash);
|
|
160
|
+
if (!entries) {
|
|
161
|
+
entries = [];
|
|
162
|
+
s.history.set(params.scriptHash, entries);
|
|
163
|
+
}
|
|
164
|
+
for (const entry of params.entries) {
|
|
165
|
+
insertHistorySorted(entries, entry);
|
|
166
|
+
}
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
reset() {
|
|
170
|
+
s.headers.length = 0;
|
|
171
|
+
s.headersByHash.clear();
|
|
172
|
+
s.utxos.clear();
|
|
173
|
+
s.utxosByScriptHash.clear();
|
|
174
|
+
s.history.clear();
|
|
175
|
+
s.txIndex.clear();
|
|
176
|
+
s.rawTxs.clear();
|
|
177
|
+
s.undoInfos.clear();
|
|
178
|
+
s.blockTxids.clear();
|
|
179
|
+
s.mempoolTxs.clear();
|
|
180
|
+
s.mempoolUtxos.clear();
|
|
181
|
+
s.mempoolUtxosByScriptHash.clear();
|
|
182
|
+
s.mempoolSpends.clear();
|
|
183
|
+
s.mempoolHistory.clear();
|
|
184
|
+
},
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
/** Get or create a MempoolTxScriptHashEntry in the map. */
|
|
188
|
+
function getOrCreateEntry(map, scriptHash) {
|
|
189
|
+
let entry = map.get(scriptHash);
|
|
190
|
+
if (!entry) {
|
|
191
|
+
entry = { confirmedSpends: [], unconfirmedSpends: [], outputs: [] };
|
|
192
|
+
map.set(scriptHash, entry);
|
|
193
|
+
}
|
|
194
|
+
return entry;
|
|
195
|
+
}
|
|
196
|
+
/** Get or create an array in a map. */
|
|
197
|
+
function getOrCreateArray(map, key) {
|
|
198
|
+
let arr = map.get(key);
|
|
199
|
+
if (!arr) {
|
|
200
|
+
arr = [];
|
|
201
|
+
map.set(key, arr);
|
|
202
|
+
}
|
|
203
|
+
return arr;
|
|
204
|
+
}
|
|
205
|
+
//# sourceMappingURL=testHelpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testHelpers.js","sourceRoot":"","sources":["../src/testHelpers.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAoGlD,oCAAoC;AACpC,SAAS,cAAc,CAAO,GAAmB,EAAE,GAAM;IACxD,IAAI,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACvB,IAAI,CAAC,GAAG,EAAE,CAAC;QACV,GAAG,GAAG,IAAI,GAAG,EAAE,CAAC;QAChB,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACnB,CAAC;IACD,OAAO,GAAG,CAAC;AACZ,CAAC;AAED,mEAAmE;AACnE,SAAS,mBAAmB,CAAC,OAAuB,EAAE,KAAmB;IACxE,IAAI,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IACvB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACd,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC5B,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM;YAAE,MAAM;QAC/C,IAAI,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM;YAAE,MAAM;QACvE,CAAC,EAAE,CAAC;IACL,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;AAC7B,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,iBAAiB,CAAC,CAAmB,EAAE,GAAoB;IAC1E,OAAO;QACN,IAAI,EAAE;YACL,GAAG,CAAC,MAAqB;gBACxB,MAAM,GAAG,GAAG,eAAe,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;gBACtD,MAAM,IAAI,GAAc,MAAM,CAAC,MAAM,CACpC;oBACC,QAAQ,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE;oBAClD,QAAQ,EAAE,MAAM,CAAC,QAAQ;oBACzB,UAAU,EAAE,MAAM,CAAC,UAAU;oBAC7B,MAAM,EAAE,MAAM,CAAC,MAAM;oBACrB,eAAe,EAAE,MAAM,CAAC,eAAe,IAAI,IAAI,UAAU,CAAC,CAAC,CAAC;iBAC5D,EACD,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAC7C,MAAM,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CACrE,CAAC;gBACF,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;gBACvB,cAAc,CAAC,CAAC,CAAC,iBAAiB,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACjE,CAAC;YACD,MAAM,CAAC,MAAwB;gBAC9B,MAAM,GAAG,GAAG,eAAe,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;gBACtD,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBAC9B,IAAI,IAAI,EAAE,CAAC;oBACV,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;oBACpB,MAAM,KAAK,GAAG,CAAC,CAAC,iBAAiB,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;oBACvD,IAAI,KAAK,EAAE,CAAC;wBACX,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;wBAClB,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC;4BAAE,CAAC,CAAC,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;oBACnE,CAAC;gBACF,CAAC;YACF,CAAC;SACD;QACD,MAAM,EAAE;YACP,GAAG,CAAC,MAAuB;gBAC1B,MAAM,MAAM,GAAgB;oBAC3B,IAAI,EAAE,MAAM,CAAC,IAAI;oBACjB,MAAM,EAAE,MAAM,CAAC,MAAM;oBACrB,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,CAAC;oBAC5B,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;oBAC3C,UAAU,EAAE,MAAM,CAAC,UAAU,IAAI,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;oBAC/C,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;oBAC5D,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,UAAU;oBAC/B,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;oBACxB,GAAG,EAAE,MAAM,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC;iBAClC,CAAC;gBACF,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;gBAClC,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAC1C,CAAC;SACD;QACD,OAAO,EAAE;YACR,GAAG,CAAC,MAA0B;gBAC7B,MAAM,UAAU,GAAG,IAAI,GAAG,EAAwC,CAAC;gBACnE,MAAM,OAAO,GAAG,IAAI,GAAG,EAAQ,CAAC;gBAEhC,iBAAiB;gBACjB,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;oBACnC,MAAM,GAAG,GAAG,eAAe,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;oBAEpD,6CAA6C;oBAC7C,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;oBACvC,IAAI,aAAa,EAAE,CAAC;wBACnB,MAAM,KAAK,GAAG,gBAAgB,CAAC,UAAU,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC;wBACpE,KAAK,CAAC,eAAiC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;wBACnD,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;wBACtC,SAAS;oBACV,CAAC;oBAED,mCAAmC;oBACnC,MAAM,WAAW,GAAG,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;oBAC5C,IAAI,WAAW,EAAE,CAAC;wBACjB,MAAM,KAAK,GAAG,gBAAgB,CAAC,UAAU,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC;wBAClE,KAAK,CAAC,iBAAmC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;wBACrD,CAAC,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;wBACtC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBACzB,CAAC;gBACF,CAAC;gBAED,kBAAkB;gBAClB,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC;oBACzD,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;oBACpC,IAAI,CAAC,MAAM;wBAAE,SAAS;oBACtB,MAAM,GAAG,GAAG,eAAe,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;oBAC/C,MAAM,IAAI,GAAc,MAAM,CAAC,MAAM,CACpC;wBACC,QAAQ,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE;wBACrC,QAAQ,EAAE,MAAM,CAAC,QAAQ;wBACzB,UAAU,EAAE,MAAM,CAAC,UAAU;wBAC7B,MAAM,EAAE,CAAC;wBACT,eAAe,EAAE,MAAM,CAAC,eAAe,IAAI,IAAI,UAAU,CAAC,CAAC,CAAC;qBAC5D,EACD,MAAM,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CACrE,CAAC;oBACF,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;oBAC9B,cAAc,CAAC,CAAC,CAAC,wBAAwB,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;oBAEvE,MAAM,KAAK,GAAG,gBAAgB,CAAC,UAAU,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;oBAC7D,KAAK,CAAC,OAAyB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBAC5C,CAAC;gBAED,wBAAwB;gBACxB,MAAM,oBAAoB,GAAG,OAAO,CAAC,IAAI,GAAG,CAAC,CAAC;gBAC9C,KAAK,MAAM,UAAU,IAAI,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC;oBAC5C,MAAM,YAAY,GAAiB;wBAClC,MAAM,EAAE,MAAM,CAAC,IAAI;wBACnB,MAAM,EAAE,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;wBACrC,GAAG,EAAE,MAAM,CAAC,GAAG;qBACf,CAAC;oBACF,MAAM,cAAc,GAAG,gBAAgB,CAAC,CAAC,CAAC,cAAc,EAAE,UAAU,CAAC,CAAC;oBACtE,cAAc,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;gBACnC,CAAC;gBAED,MAAM,SAAS,GAAc;oBAC5B,IAAI,EAAE,MAAM,CAAC,IAAI;oBACjB,GAAG,EAAE,MAAM,CAAC,GAAG;oBACf,IAAI,EAAE,MAAM,CAAC,IAAI;oBACjB,OAAO,EAAE,UAAU;oBACnB,OAAO;oBACP,QAAQ,EAAE,IAAI,GAAG,EAAE;iBACnB,CAAC;gBAEF,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;gBAEzC,4BAA4B;gBAC5B,KAAK,MAAM,UAAU,IAAI,OAAO,EAAE,CAAC;oBAClC,MAAM,QAAQ,GAAG,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;oBAC9C,IAAI,QAAQ,EAAE,CAAC;wBACb,QAAQ,CAAC,QAAsB,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;oBACnD,CAAC;gBACF,CAAC;YACF,CAAC;YACD,MAAM,CAAC,IAAU;gBAChB,OAAO,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;YAClC,CAAC;YACD,KAAK;gBACJ,OAAO,GAAG,CAAC,YAAY,EAAE,CAAC;YAC3B,CAAC;SACD;QACD,EAAE,EAAE;YACH,GAAG,CAAC,MAAmB;gBACtB,MAAM,MAAM,GAAsB,MAAM,CAAC,MAAM,CAC9C,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,EAC5C,MAAM,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,EAC5D,MAAM,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,CACnD,CAAC;gBACF,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;gBACnC,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;oBACnB,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;gBAC1C,CAAC;YACF,CAAC;SACD;QACD,OAAO,EAAE;YACR,GAAG,CAAC,MAAwB;gBAC3B,IAAI,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;gBAC/C,IAAI,CAAC,OAAO,EAAE,CAAC;oBACd,OAAO,GAAG,EAAE,CAAC;oBACb,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;gBAC3C,CAAC;gBACD,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;oBACpC,mBAAmB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;gBACrC,CAAC;YACF,CAAC;SACD;QACD,KAAK;YACJ,CAAC,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;YACrB,CAAC,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;YACxB,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YAChB,CAAC,CAAC,iBAAiB,CAAC,KAAK,EAAE,CAAC;YAC5B,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YAClB,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YAClB,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YACjB,CAAC,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;YACpB,CAAC,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;YACrB,CAAC,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;YACrB,CAAC,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;YACvB,CAAC,CAAC,wBAAwB,CAAC,KAAK,EAAE,CAAC;YACnC,CAAC,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;YACxB,CAAC,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC;QAC1B,CAAC;KACD,CAAC;AACH,CAAC;AAED,2DAA2D;AAC3D,SAAS,gBAAgB,CACxB,GAA8C,EAC9C,UAAsB;IAEtB,IAAI,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAChC,IAAI,CAAC,KAAK,EAAE,CAAC;QACZ,KAAK,GAAG,EAAE,eAAe,EAAE,EAAE,EAAE,iBAAiB,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;QACpE,GAAG,CAAC,GAAG,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IAC5B,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED,uCAAuC;AACvC,SAAS,gBAAgB,CAAO,GAAgB,EAAE,GAAM;IACvD,IAAI,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACvB,IAAI,CAAC,GAAG,EAAE,CAAC;QACV,GAAG,GAAG,EAAE,CAAC;QACT,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACnB,CAAC;IACD,OAAO,GAAG,CAAC;AACZ,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mem-cash/storage",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "In-memory storage implementation for mem-cash",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"sideEffects": false,
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist/",
|
|
17
|
+
"README.md",
|
|
18
|
+
"LICENSE"
|
|
19
|
+
],
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "https://github.com/mainnet-pat/mem-cash.git",
|
|
24
|
+
"directory": "packages/storage"
|
|
25
|
+
},
|
|
26
|
+
"keywords": [
|
|
27
|
+
"bitcoin-cash",
|
|
28
|
+
"electrum",
|
|
29
|
+
"storage",
|
|
30
|
+
"utxo",
|
|
31
|
+
"mempool"
|
|
32
|
+
],
|
|
33
|
+
"engines": {
|
|
34
|
+
"node": ">=20"
|
|
35
|
+
},
|
|
36
|
+
"scripts": {
|
|
37
|
+
"prepublishOnly": "tsc -b"
|
|
38
|
+
},
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"@bitauth/libauth": "^3.1.0-next.8",
|
|
41
|
+
"@mem-cash/types": "0.0.1"
|
|
42
|
+
}
|
|
43
|
+
}
|