@bsv/sdk 1.7.1 → 1.7.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/package.json +1 -1
- package/dist/cjs/src/overlay-tools/LookupResolver.js +156 -76
- package/dist/cjs/src/overlay-tools/LookupResolver.js.map +1 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/src/overlay-tools/LookupResolver.js +163 -76
- package/dist/esm/src/overlay-tools/LookupResolver.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/types/src/overlay-tools/LookupResolver.d.ts +30 -2
- package/dist/types/src/overlay-tools/LookupResolver.d.ts.map +1 -1
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/dist/umd/bundle.js +3 -3
- package/dist/umd/bundle.js.map +1 -1
- package/docs/reference/overlay-tools.md +11 -2
- package/package.json +1 -1
- package/src/overlay-tools/LookupResolver.ts +172 -82
- package/src/overlay-tools/__tests/LookupResolver.test.ts +0 -47
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { Transaction } from '../transaction/index.js';
|
|
2
2
|
import OverlayAdminTokenTemplate from './OverlayAdminTokenTemplate.js';
|
|
3
|
+
// Only bind window.fetch in the browser
|
|
4
|
+
const defaultFetch = typeof window !== 'undefined' ? fetch.bind(window) : fetch;
|
|
3
5
|
/** Default SLAP trackers */
|
|
4
6
|
export const DEFAULT_SLAP_TRACKERS = [
|
|
5
7
|
// BSVA clusters
|
|
@@ -23,7 +25,7 @@ const MAX_TRACKER_WAIT_TIME = 5000;
|
|
|
23
25
|
export class HTTPSOverlayLookupFacilitator {
|
|
24
26
|
fetchClient;
|
|
25
27
|
allowHTTP;
|
|
26
|
-
constructor(httpClient =
|
|
28
|
+
constructor(httpClient = defaultFetch, allowHTTP = false) {
|
|
27
29
|
this.fetchClient = httpClient;
|
|
28
30
|
this.allowHTTP = allowHTTP;
|
|
29
31
|
}
|
|
@@ -31,31 +33,38 @@ export class HTTPSOverlayLookupFacilitator {
|
|
|
31
33
|
if (!url.startsWith('https:') && !this.allowHTTP) {
|
|
32
34
|
throw new Error('HTTPS facilitator can only use URLs that start with "https:"');
|
|
33
35
|
}
|
|
34
|
-
const
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
36
|
+
const controller = typeof AbortController !== 'undefined' ? new AbortController() : undefined;
|
|
37
|
+
const timer = setTimeout(() => {
|
|
38
|
+
try {
|
|
39
|
+
controller?.abort();
|
|
40
|
+
}
|
|
41
|
+
catch { /* noop */ }
|
|
42
|
+
}, timeout);
|
|
43
|
+
try {
|
|
44
|
+
const fco = {
|
|
45
|
+
method: 'POST',
|
|
46
|
+
headers: { 'Content-Type': 'application/json' },
|
|
47
|
+
body: JSON.stringify({ service: question.service, query: question.query }),
|
|
48
|
+
signal: controller?.signal
|
|
49
|
+
};
|
|
50
|
+
const response = await this.fetchClient(`${url}/lookup`, fco);
|
|
51
|
+
if (!response.ok)
|
|
52
|
+
throw new Error(`Failed to facilitate lookup (HTTP ${response.status})`);
|
|
50
53
|
return await response.json();
|
|
51
54
|
}
|
|
52
|
-
|
|
53
|
-
|
|
55
|
+
catch (e) {
|
|
56
|
+
// Normalize timeouts to a consistent error message
|
|
57
|
+
if (e?.name === 'AbortError')
|
|
58
|
+
throw new Error('Request timed out');
|
|
59
|
+
throw e;
|
|
60
|
+
}
|
|
61
|
+
finally {
|
|
62
|
+
clearTimeout(timer);
|
|
54
63
|
}
|
|
55
64
|
}
|
|
56
65
|
}
|
|
57
66
|
/**
|
|
58
|
-
* Represents
|
|
67
|
+
* Represents a Lookup Resolver.
|
|
59
68
|
*/
|
|
60
69
|
export default class LookupResolver {
|
|
61
70
|
facilitator;
|
|
@@ -63,12 +72,26 @@ export default class LookupResolver {
|
|
|
63
72
|
hostOverrides;
|
|
64
73
|
additionalHosts;
|
|
65
74
|
networkPreset;
|
|
75
|
+
// ---- Caches / memoization ----
|
|
76
|
+
hostsCache;
|
|
77
|
+
hostsInFlight;
|
|
78
|
+
hostsTtlMs;
|
|
79
|
+
hostsMaxEntries;
|
|
80
|
+
txMemo;
|
|
81
|
+
txMemoTtlMs;
|
|
66
82
|
constructor(config = {}) {
|
|
67
83
|
this.networkPreset = config.networkPreset ?? 'mainnet';
|
|
68
84
|
this.facilitator = config.facilitator ?? new HTTPSOverlayLookupFacilitator(undefined, this.networkPreset === 'local');
|
|
69
85
|
this.slapTrackers = config.slapTrackers ?? (this.networkPreset === 'mainnet' ? DEFAULT_SLAP_TRACKERS : DEFAULT_TESTNET_SLAP_TRACKERS);
|
|
70
86
|
this.hostOverrides = config.hostOverrides ?? {};
|
|
71
87
|
this.additionalHosts = config.additionalHosts ?? {};
|
|
88
|
+
// cache tuning
|
|
89
|
+
this.hostsTtlMs = config.cache?.hostsTtlMs ?? 5 * 60 * 1000; // 5 min
|
|
90
|
+
this.hostsMaxEntries = config.cache?.hostsMaxEntries ?? 128;
|
|
91
|
+
this.txMemoTtlMs = config.cache?.txMemoTtlMs ?? 10 * 60 * 1000; // 10 min
|
|
92
|
+
this.hostsCache = new Map();
|
|
93
|
+
this.hostsInFlight = new Map();
|
|
94
|
+
this.txMemo = new Map();
|
|
72
95
|
}
|
|
73
96
|
/**
|
|
74
97
|
* Given a LookupQuestion, returns a LookupAnswer. Aggregates across multiple services and supports resiliency.
|
|
@@ -85,53 +108,119 @@ export default class LookupResolver {
|
|
|
85
108
|
competentHosts = ['http://localhost:8080'];
|
|
86
109
|
}
|
|
87
110
|
else {
|
|
88
|
-
competentHosts = await this.
|
|
111
|
+
competentHosts = await this.getCompetentHostsCached(question.service);
|
|
89
112
|
}
|
|
90
113
|
if (this.additionalHosts[question.service]?.length > 0) {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
114
|
+
// preserve order: resolved hosts first, then additional (unique)
|
|
115
|
+
const extra = this.additionalHosts[question.service];
|
|
116
|
+
const seen = new Set(competentHosts);
|
|
117
|
+
for (const h of extra)
|
|
118
|
+
if (!seen.has(h))
|
|
119
|
+
competentHosts.push(h);
|
|
95
120
|
}
|
|
96
121
|
if (competentHosts.length < 1) {
|
|
97
122
|
throw new Error(`No competent ${this.networkPreset} hosts found by the SLAP trackers for lookup service: ${question.service}`);
|
|
98
123
|
}
|
|
99
|
-
//
|
|
100
|
-
const hostResponses = await Promise.allSettled(competentHosts.map(async (host) =>
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
124
|
+
// Fire all hosts with per-host timeout, harvest successful output-list responses
|
|
125
|
+
const hostResponses = await Promise.allSettled(competentHosts.map(async (host) => {
|
|
126
|
+
return await this.facilitator.lookup(host, question, timeout);
|
|
127
|
+
}));
|
|
128
|
+
const outputsMap = new Map();
|
|
129
|
+
// Memo key helper for tx parsing
|
|
130
|
+
const beefKey = (beef) => {
|
|
131
|
+
if (typeof beef !== 'object')
|
|
132
|
+
return ''; // The invalid BEEF has an empty key.
|
|
133
|
+
// A fast and deterministic key for memoization; avoids large JSON strings
|
|
134
|
+
// since beef is an array of integers, join is safe and compact.
|
|
135
|
+
return beef.join(',');
|
|
136
|
+
};
|
|
137
|
+
for (const result of hostResponses) {
|
|
138
|
+
if (result.status !== 'fulfilled')
|
|
112
139
|
continue;
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
140
|
+
const response = result.value;
|
|
141
|
+
if (response?.type !== 'output-list' || !Array.isArray(response.outputs))
|
|
142
|
+
continue;
|
|
143
|
+
for (const output of response.outputs) {
|
|
144
|
+
const keyForBeef = beefKey(output.beef);
|
|
145
|
+
let memo = this.txMemo.get(keyForBeef);
|
|
146
|
+
const now = Date.now();
|
|
147
|
+
if (typeof memo !== 'object' || memo === null || memo.expiresAt <= now) {
|
|
116
148
|
try {
|
|
117
|
-
const txId = Transaction.fromBEEF(output.beef).id('hex');
|
|
118
|
-
|
|
119
|
-
|
|
149
|
+
const txId = Transaction.fromBEEF(output.beef).id('hex');
|
|
150
|
+
memo = { txId, expiresAt: now + this.txMemoTtlMs };
|
|
151
|
+
// prune opportunistically if the map gets too large (cheap heuristic)
|
|
152
|
+
if (this.txMemo.size > 4096)
|
|
153
|
+
this.evictOldest(this.txMemo);
|
|
154
|
+
this.txMemo.set(keyForBeef, memo);
|
|
120
155
|
}
|
|
121
156
|
catch {
|
|
122
157
|
continue;
|
|
123
158
|
}
|
|
124
159
|
}
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
160
|
+
const uniqKey = `${memo.txId}.${output.outputIndex}`;
|
|
161
|
+
// last-writer wins is fine here; outputs are identical if uniqKey matches
|
|
162
|
+
outputsMap.set(uniqKey, output);
|
|
128
163
|
}
|
|
129
164
|
}
|
|
130
165
|
return {
|
|
131
166
|
type: 'output-list',
|
|
132
|
-
outputs: Array.from(
|
|
167
|
+
outputs: Array.from(outputsMap.values())
|
|
133
168
|
};
|
|
134
169
|
}
|
|
170
|
+
/**
|
|
171
|
+
* Cached wrapper for competent host discovery with stale-while-revalidate.
|
|
172
|
+
*/
|
|
173
|
+
async getCompetentHostsCached(service) {
|
|
174
|
+
const now = Date.now();
|
|
175
|
+
const cached = this.hostsCache.get(service);
|
|
176
|
+
// if fresh, return immediately
|
|
177
|
+
if (typeof cached === 'object' && cached.expiresAt > now) {
|
|
178
|
+
return cached.hosts.slice();
|
|
179
|
+
}
|
|
180
|
+
// if stale but present, kick off a refresh if not already in-flight and return stale
|
|
181
|
+
if (typeof cached === 'object' && cached.expiresAt <= now) {
|
|
182
|
+
if (!this.hostsInFlight.has(service)) {
|
|
183
|
+
this.hostsInFlight.set(service, this.refreshHosts(service).finally(() => {
|
|
184
|
+
this.hostsInFlight.delete(service);
|
|
185
|
+
}));
|
|
186
|
+
}
|
|
187
|
+
return cached.hosts.slice();
|
|
188
|
+
}
|
|
189
|
+
// no cache: coalesce concurrent requests
|
|
190
|
+
if (this.hostsInFlight.has(service)) {
|
|
191
|
+
try {
|
|
192
|
+
const hosts = await this.hostsInFlight.get(service);
|
|
193
|
+
if (typeof hosts !== 'object') {
|
|
194
|
+
throw new Error('Hosts is not defined.');
|
|
195
|
+
}
|
|
196
|
+
return hosts.slice();
|
|
197
|
+
}
|
|
198
|
+
catch {
|
|
199
|
+
// fall through to a fresh attempt below
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
const promise = this.refreshHosts(service).finally(() => {
|
|
203
|
+
this.hostsInFlight.delete(service);
|
|
204
|
+
});
|
|
205
|
+
this.hostsInFlight.set(service, promise);
|
|
206
|
+
const hosts = await promise;
|
|
207
|
+
return hosts.slice();
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Actually resolves competent hosts from SLAP trackers and updates cache.
|
|
211
|
+
*/
|
|
212
|
+
async refreshHosts(service) {
|
|
213
|
+
const hosts = await this.findCompetentHosts(service);
|
|
214
|
+
const expiresAt = Date.now() + this.hostsTtlMs;
|
|
215
|
+
// bounded cache with simple FIFO eviction
|
|
216
|
+
if (!this.hostsCache.has(service) && this.hostsCache.size >= this.hostsMaxEntries) {
|
|
217
|
+
const oldestKey = this.hostsCache.keys().next().value;
|
|
218
|
+
if (oldestKey !== undefined)
|
|
219
|
+
this.hostsCache.delete(oldestKey);
|
|
220
|
+
}
|
|
221
|
+
this.hostsCache.set(service, { hosts, expiresAt });
|
|
222
|
+
return hosts;
|
|
223
|
+
}
|
|
135
224
|
/**
|
|
136
225
|
* Returns a list of competent hosts for a given lookup service.
|
|
137
226
|
* @param service Service for which competent hosts are to be returned
|
|
@@ -140,44 +229,42 @@ export default class LookupResolver {
|
|
|
140
229
|
async findCompetentHosts(service) {
|
|
141
230
|
const query = {
|
|
142
231
|
service: 'ls_slap',
|
|
143
|
-
query: {
|
|
144
|
-
service
|
|
145
|
-
}
|
|
232
|
+
query: { service }
|
|
146
233
|
};
|
|
147
|
-
//
|
|
234
|
+
// Query all SLAP trackers; tolerate failures.
|
|
148
235
|
const trackerResponses = await Promise.allSettled(this.slapTrackers.map(async (tracker) => await this.facilitator.lookup(tracker, query, MAX_TRACKER_WAIT_TIME)));
|
|
149
236
|
const hosts = new Set();
|
|
150
237
|
for (const result of trackerResponses) {
|
|
151
|
-
if (result.status
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
const parsed = OverlayAdminTokenTemplate.decode(script);
|
|
162
|
-
if (parsed.topicOrService !== service ||
|
|
163
|
-
parsed.protocol !== 'SLAP') {
|
|
164
|
-
// Invalid advertisement, skip
|
|
165
|
-
continue;
|
|
166
|
-
}
|
|
167
|
-
hosts.add(parsed.domain);
|
|
168
|
-
}
|
|
169
|
-
catch {
|
|
170
|
-
// Invalid output, skip
|
|
238
|
+
if (result.status !== 'fulfilled')
|
|
239
|
+
continue;
|
|
240
|
+
const answer = result.value;
|
|
241
|
+
if (answer.type !== 'output-list')
|
|
242
|
+
continue;
|
|
243
|
+
for (const output of answer.outputs) {
|
|
244
|
+
try {
|
|
245
|
+
const tx = Transaction.fromBEEF(output.beef);
|
|
246
|
+
const script = tx.outputs[output.outputIndex]?.lockingScript;
|
|
247
|
+
if (typeof script !== 'object' || script === null)
|
|
171
248
|
continue;
|
|
249
|
+
const parsed = OverlayAdminTokenTemplate.decode(script);
|
|
250
|
+
if (parsed.topicOrService !== service || parsed.protocol !== 'SLAP')
|
|
251
|
+
continue;
|
|
252
|
+
if (typeof parsed.domain === 'string' && parsed.domain.length > 0) {
|
|
253
|
+
hosts.add(parsed.domain);
|
|
172
254
|
}
|
|
173
255
|
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
continue;
|
|
256
|
+
catch {
|
|
257
|
+
continue;
|
|
258
|
+
}
|
|
178
259
|
}
|
|
179
260
|
}
|
|
180
261
|
return [...hosts];
|
|
181
262
|
}
|
|
263
|
+
/** Evict an arbitrary “oldest” entry from a Map (iteration order). */
|
|
264
|
+
evictOldest(m) {
|
|
265
|
+
const firstKey = m.keys().next().value;
|
|
266
|
+
if (firstKey !== undefined)
|
|
267
|
+
m.delete(firstKey);
|
|
268
|
+
}
|
|
182
269
|
}
|
|
183
270
|
//# sourceMappingURL=LookupResolver.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LookupResolver.js","sourceRoot":"","sources":["../../../../src/overlay-tools/LookupResolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AACrD,OAAO,yBAAyB,MAAM,gCAAgC,CAAA;
|
|
1
|
+
{"version":3,"file":"LookupResolver.js","sourceRoot":"","sources":["../../../../src/overlay-tools/LookupResolver.ts"],"names":[],"mappings":"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"}
|