@antseed/node 0.2.3 → 0.2.5
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 +15 -1
- package/dist/discovery/bootstrap.d.ts.map +1 -1
- package/dist/discovery/bootstrap.js +2 -6
- package/dist/discovery/bootstrap.js.map +1 -1
- package/dist/discovery/http-metadata-resolver.d.ts +3 -0
- package/dist/discovery/http-metadata-resolver.d.ts.map +1 -1
- package/dist/discovery/http-metadata-resolver.js +13 -5
- package/dist/discovery/http-metadata-resolver.js.map +1 -1
- package/dist/node.d.ts +7 -3
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +80 -38
- package/dist/node.js.map +1 -1
- package/dist/p2p/connection-manager.d.ts.map +1 -1
- package/dist/p2p/connection-manager.js +11 -5
- package/dist/p2p/connection-manager.js.map +1 -1
- package/dist/proxy/proxy-mux.d.ts.map +1 -1
- package/dist/proxy/proxy-mux.js +11 -1
- package/dist/proxy/proxy-mux.js.map +1 -1
- package/dist/types/http.d.ts +5 -1
- package/dist/types/http.d.ts.map +1 -1
- package/dist/types/http.js +6 -2
- package/dist/types/http.js.map +1 -1
- package/package.json +10 -10
- package/LICENSE +0 -674
package/README.md
CHANGED
|
@@ -104,6 +104,20 @@ Discovery topics are normalized to improve lookup consistency:
|
|
|
104
104
|
|
|
105
105
|
Canonical and search model topics are both used when their keys differ, so variants like `kimi 2.5`, `kimi-2.5`, and `kimi_2.5` can converge in discovery while keeping exact canonical topics.
|
|
106
106
|
|
|
107
|
+
## Security Overview
|
|
108
|
+
|
|
109
|
+
For a full buyer-seller threat model and hardening guide, see:
|
|
110
|
+
|
|
111
|
+
- [`docs/protocol/spec/06-security-overview.md`](../../docs/protocol/spec/06-security-overview.md)
|
|
112
|
+
|
|
113
|
+
At a high level, `@antseed/node` currently enforces:
|
|
114
|
+
|
|
115
|
+
- Signed discovery metadata verification and staleness checks
|
|
116
|
+
- Signed connection intro envelopes with replay protection
|
|
117
|
+
- Frame, stream, and upload limits to reduce DoS exposure
|
|
118
|
+
- Escrow-aware request gating (`402` if lock is not committed when escrow is enabled)
|
|
119
|
+
- Signed bilateral receipts (Ed25519) plus on-chain payment authorization (ECDSA)
|
|
120
|
+
|
|
107
121
|
## Node Configuration
|
|
108
122
|
|
|
109
123
|
```ts
|
|
@@ -133,7 +147,7 @@ interface NodeConfig {
|
|
|
133
147
|
| `dataDir` | `~/.antseed` | Directory for identity keys, metering DB, and config |
|
|
134
148
|
| `dhtPort` | `6881` / `0` | UDP port for DHT. Seller defaults to 6881, buyer uses OS-assigned |
|
|
135
149
|
| `signalingPort` | `6882` | TCP port for P2P signaling and incoming connections (seller only) |
|
|
136
|
-
| `bootstrapNodes` |
|
|
150
|
+
| `bootstrapNodes` | AntSeed nodes | Additional DHT bootstrap nodes merged with the official AntSeed infrastructure |
|
|
137
151
|
| `payments` | disabled | Optional seller-side payment channel + settlement lifecycle wiring |
|
|
138
152
|
|
|
139
153
|
## On-Chain Settlement Flow
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../src/discovery/bootstrap.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,wBAAwB,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../src/discovery/bootstrap.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,wBAAwB,EAAE,aAAa,EAGnD,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,aAAa,EAAE,CAiBrE;AAED,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,aAAa,EAAE,EACzB,cAAc,EAAE,aAAa,EAAE,GAC9B,aAAa,EAAE,CAajB;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,aAAa,EAAE,GACrB,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAEvC"}
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
export const OFFICIAL_BOOTSTRAP_NODES = [
|
|
2
|
-
{ host: "
|
|
3
|
-
{ host: "
|
|
4
|
-
{ host: "router.utorrent.com", port: 6881, label: "uTorrent" },
|
|
5
|
-
{ host: "dht.libtorrent.org", port: 25401, label: "libtorrent" },
|
|
6
|
-
{ host: "router.silotis.us", port: 6881, label: "Silotis" },
|
|
7
|
-
{ host: "dht.aelitis.com", port: 6881, label: "Vuze" },
|
|
2
|
+
{ host: "dht1.antseed.com", port: 6881, label: "AntSeed-1" },
|
|
3
|
+
{ host: "dht2.antseed.com", port: 6881, label: "AntSeed-2" },
|
|
8
4
|
];
|
|
9
5
|
export function parseBootstrapList(entries) {
|
|
10
6
|
return entries.map((entry) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../src/discovery/bootstrap.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,MAAM,wBAAwB,GAAoB;IACvD,EAAE,IAAI,EAAE,
|
|
1
|
+
{"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../src/discovery/bootstrap.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,MAAM,wBAAwB,GAAoB;IACvD,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE;IAC5D,EAAE,IAAI,EAAE,kBAAkB,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE;CAC7D,CAAC;AAEF,MAAM,UAAU,kBAAkB,CAAC,OAAiB;IAClD,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QAC3B,MAAM,SAAS,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACzC,IAAI,SAAS,KAAK,CAAC,CAAC,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CAAC,2CAA2C,KAAK,GAAG,CAAC,CAAC;QACvE,CAAC;QAED,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;QACvC,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;QAC3C,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAEnC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,KAAK,EAAE,CAAC;YACvD,MAAM,IAAI,KAAK,CAAC,qCAAqC,KAAK,GAAG,CAAC,CAAC;QACjE,CAAC;QAED,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACxB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,QAAyB,EACzB,cAA+B;IAE/B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,MAAM,GAAoB,EAAE,CAAC;IAEnC,KAAK,MAAM,IAAI,IAAI,CAAC,GAAG,QAAQ,EAAE,GAAG,cAAc,CAAC,EAAE,CAAC;QACpD,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACxC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACnB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACd,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpB,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,KAAsB;IAEtB,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;AAC5D,CAAC"}
|
|
@@ -7,11 +7,14 @@ export interface HttpMetadataResolverConfig {
|
|
|
7
7
|
metadataPortOffset?: number;
|
|
8
8
|
/** Cooldown in ms before retrying an endpoint that recently failed. Default: 30000 */
|
|
9
9
|
failureCooldownMs?: number;
|
|
10
|
+
/** Upper bound for failure cooldown backoff. Default: 1800000 (30 minutes) */
|
|
11
|
+
maxFailureCooldownMs?: number;
|
|
10
12
|
}
|
|
11
13
|
export declare class HttpMetadataResolver implements MetadataResolver {
|
|
12
14
|
private readonly timeoutMs;
|
|
13
15
|
private readonly metadataPortOffset;
|
|
14
16
|
private readonly failureCooldownMs;
|
|
17
|
+
private readonly maxFailureCooldownMs;
|
|
15
18
|
private readonly failedEndpoints;
|
|
16
19
|
constructor(config?: HttpMetadataResolverConfig);
|
|
17
20
|
resolve(peer: PeerEndpoint): Promise<PeerMetadata | null>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-metadata-resolver.d.ts","sourceRoot":"","sources":["../../src/discovery/http-metadata-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC7E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGvD,MAAM,WAAW,0BAA0B;IACzC,2DAA2D;IAC3D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4FAA4F;IAC5F,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,sFAAsF;IACtF,iBAAiB,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"http-metadata-resolver.d.ts","sourceRoot":"","sources":["../../src/discovery/http-metadata-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC7E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGvD,MAAM,WAAW,0BAA0B;IACzC,2DAA2D;IAC3D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,4FAA4F;IAC5F,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,sFAAsF;IACtF,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,8EAA8E;IAC9E,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAOD,qBAAa,oBAAqB,YAAW,gBAAgB;IAC3D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAS;IAC5C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAC3C,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAS;IAC9C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAmC;gBAEvD,MAAM,CAAC,EAAE,0BAA0B;IAWzC,OAAO,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IA2C/D,OAAO,CAAC,mBAAmB;IAc3B,OAAO,CAAC,cAAc;CAGvB"}
|
|
@@ -3,11 +3,13 @@ export class HttpMetadataResolver {
|
|
|
3
3
|
timeoutMs;
|
|
4
4
|
metadataPortOffset;
|
|
5
5
|
failureCooldownMs;
|
|
6
|
+
maxFailureCooldownMs;
|
|
6
7
|
failedEndpoints;
|
|
7
8
|
constructor(config) {
|
|
8
9
|
this.timeoutMs = config?.timeoutMs ?? 2000;
|
|
9
10
|
this.metadataPortOffset = config?.metadataPortOffset ?? 0;
|
|
10
11
|
this.failureCooldownMs = Math.max(0, config?.failureCooldownMs ?? 30_000);
|
|
12
|
+
this.maxFailureCooldownMs = Math.max(this.failureCooldownMs, config?.maxFailureCooldownMs ?? 30 * 60_000);
|
|
11
13
|
this.failedEndpoints = new Map();
|
|
12
14
|
}
|
|
13
15
|
async resolve(peer) {
|
|
@@ -15,9 +17,9 @@ export class HttpMetadataResolver {
|
|
|
15
17
|
const host = peer.host.toLowerCase();
|
|
16
18
|
const endpointKey = this.getEndpointKey(host, metadataPort);
|
|
17
19
|
const now = Date.now();
|
|
18
|
-
const
|
|
19
|
-
if (
|
|
20
|
-
if (
|
|
20
|
+
const failedState = this.failedEndpoints.get(endpointKey);
|
|
21
|
+
if (failedState !== undefined) {
|
|
22
|
+
if (failedState.nextRetryAt > now) {
|
|
21
23
|
return null;
|
|
22
24
|
}
|
|
23
25
|
this.failedEndpoints.delete(endpointKey);
|
|
@@ -53,8 +55,14 @@ export class HttpMetadataResolver {
|
|
|
53
55
|
if (this.failureCooldownMs <= 0) {
|
|
54
56
|
return;
|
|
55
57
|
}
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
+
const previous = this.failedEndpoints.get(endpointKey);
|
|
59
|
+
const consecutiveFailures = Math.max(1, (previous?.consecutiveFailures ?? 0) + 1);
|
|
60
|
+
const multiplier = 2 ** Math.max(0, consecutiveFailures - 1);
|
|
61
|
+
const backoffMs = Math.min(this.maxFailureCooldownMs, this.failureCooldownMs * multiplier);
|
|
62
|
+
this.failedEndpoints.set(endpointKey, {
|
|
63
|
+
nextRetryAt: Date.now() + backoffMs,
|
|
64
|
+
consecutiveFailures,
|
|
65
|
+
});
|
|
58
66
|
}
|
|
59
67
|
getEndpointKey(host, port) {
|
|
60
68
|
return `${host}:${port}`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-metadata-resolver.js","sourceRoot":"","sources":["../../src/discovery/http-metadata-resolver.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"http-metadata-resolver.js","sourceRoot":"","sources":["../../src/discovery/http-metadata-resolver.ts"],"names":[],"mappings":"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"}
|
package/dist/node.d.ts
CHANGED
|
@@ -51,6 +51,8 @@ export interface NodeConfig {
|
|
|
51
51
|
/** Use only the provided bootstrapNodes and skip the official public DHT nodes. Default: false.
|
|
52
52
|
* Set true for isolated local testing where official nodes must not be contacted. */
|
|
53
53
|
noOfficialBootstrap?: boolean;
|
|
54
|
+
/** Override the DHT operation timeout in ms. Defaults to DEFAULT_DHT_CONFIG.operationTimeoutMs (10 000). */
|
|
55
|
+
dhtOperationTimeoutMs?: number;
|
|
54
56
|
/** Optional seller-side payment runtime wiring. */
|
|
55
57
|
payments?: NodePaymentsConfig;
|
|
56
58
|
}
|
|
@@ -76,6 +78,9 @@ export interface RequestStreamCallbacks {
|
|
|
76
78
|
onResponseStart?: (response: SerializedHttpResponse, metadata: RequestStreamResponseMetadata) => void;
|
|
77
79
|
onResponseChunk?: (chunk: SerializedHttpResponseChunk) => void;
|
|
78
80
|
}
|
|
81
|
+
export interface RequestExecutionOptions {
|
|
82
|
+
signal?: AbortSignal;
|
|
83
|
+
}
|
|
79
84
|
export declare class AntseedNode extends EventEmitter {
|
|
80
85
|
private static readonly _METADATA_REFRESH_DEBOUNCE_MS;
|
|
81
86
|
private _config;
|
|
@@ -87,7 +92,6 @@ export declare class AntseedNode extends EventEmitter {
|
|
|
87
92
|
private _started;
|
|
88
93
|
private _announcer;
|
|
89
94
|
private _peerLookup;
|
|
90
|
-
private _metadataResolver;
|
|
91
95
|
private _muxes;
|
|
92
96
|
private _decoders;
|
|
93
97
|
private _nat;
|
|
@@ -127,8 +131,8 @@ export declare class AntseedNode extends EventEmitter {
|
|
|
127
131
|
start(): Promise<void>;
|
|
128
132
|
stop(): Promise<void>;
|
|
129
133
|
discoverPeers(model?: string): Promise<PeerInfo[]>;
|
|
130
|
-
sendRequest(peer: PeerInfo, req: SerializedHttpRequest): Promise<SerializedHttpResponse>;
|
|
131
|
-
sendRequestStream(peer: PeerInfo, req: SerializedHttpRequest, callbacks: RequestStreamCallbacks): Promise<SerializedHttpResponse>;
|
|
134
|
+
sendRequest(peer: PeerInfo, req: SerializedHttpRequest, options?: RequestExecutionOptions): Promise<SerializedHttpResponse>;
|
|
135
|
+
sendRequestStream(peer: PeerInfo, req: SerializedHttpRequest, callbacks: RequestStreamCallbacks, options?: RequestExecutionOptions): Promise<SerializedHttpResponse>;
|
|
132
136
|
private _sendRequestInternal;
|
|
133
137
|
private _createDHTConfig;
|
|
134
138
|
private _wireConnection;
|
package/dist/node.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"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"}
|
package/dist/node.js
CHANGED
|
@@ -35,7 +35,6 @@ export class AntseedNode extends EventEmitter {
|
|
|
35
35
|
_started = false;
|
|
36
36
|
_announcer = null;
|
|
37
37
|
_peerLookup = null;
|
|
38
|
-
_metadataResolver = null;
|
|
39
38
|
_muxes = new Map();
|
|
40
39
|
_decoders = new Map();
|
|
41
40
|
_nat = null;
|
|
@@ -202,7 +201,6 @@ export class AntseedNode extends EventEmitter {
|
|
|
202
201
|
this._metering = null;
|
|
203
202
|
}
|
|
204
203
|
this._peerLookup = null;
|
|
205
|
-
this._metadataResolver = null;
|
|
206
204
|
this._receiptGenerator = null;
|
|
207
205
|
this._balanceManager = null;
|
|
208
206
|
this._escrowClient = null;
|
|
@@ -236,33 +234,6 @@ export class AntseedNode extends EventEmitter {
|
|
|
236
234
|
peers.push(p);
|
|
237
235
|
}
|
|
238
236
|
}
|
|
239
|
-
// Also probe bootstrap nodes' signaling ports (DHT port + 1 by convention).
|
|
240
|
-
// This ensures AntSeed bootstrap nodes are always discoverable even when DHT
|
|
241
|
-
// announcement propagation is unreliable.
|
|
242
|
-
if (this._config.bootstrapNodes && this._config.bootstrapNodes.length > 0 && this._metadataResolver && this._peerLookup) {
|
|
243
|
-
const bootstrapProbes = await Promise.allSettled(this._config.bootstrapNodes.map(async (n) => {
|
|
244
|
-
const signalingPort = n.port + 1;
|
|
245
|
-
const metadata = await this._metadataResolver.resolve({ host: n.host, port: signalingPort });
|
|
246
|
-
if (!metadata)
|
|
247
|
-
return null;
|
|
248
|
-
const valid = await this._peerLookup.verifyMetadataSignature(metadata);
|
|
249
|
-
if (!valid)
|
|
250
|
-
return null;
|
|
251
|
-
if (this._peerLookup.isStale(metadata))
|
|
252
|
-
return null;
|
|
253
|
-
return { metadata, host: n.host, port: signalingPort };
|
|
254
|
-
}));
|
|
255
|
-
for (const r of bootstrapProbes) {
|
|
256
|
-
if (r.status === "fulfilled" && r.value !== null) {
|
|
257
|
-
const p = this._lookupResultToPeerInfo(r.value);
|
|
258
|
-
if (!seen.has(p.peerId)) {
|
|
259
|
-
seen.add(p.peerId);
|
|
260
|
-
peers.push(p);
|
|
261
|
-
debugLog(`[Node] bootstrap-probe peer ${p.peerId.slice(0, 12)}... providers=[${p.providers.join(",")}]`);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
237
|
// Optional reputation verification: replace claimed data with verified on-chain data
|
|
267
238
|
if (this._escrowClient) {
|
|
268
239
|
for (const p of peers) {
|
|
@@ -285,13 +256,13 @@ export class AntseedNode extends EventEmitter {
|
|
|
285
256
|
}
|
|
286
257
|
return peers;
|
|
287
258
|
}
|
|
288
|
-
async sendRequest(peer, req) {
|
|
289
|
-
return this._sendRequestInternal(peer, req);
|
|
259
|
+
async sendRequest(peer, req, options) {
|
|
260
|
+
return this._sendRequestInternal(peer, req, undefined, options);
|
|
290
261
|
}
|
|
291
|
-
async sendRequestStream(peer, req, callbacks) {
|
|
292
|
-
return this._sendRequestInternal(peer, req, callbacks);
|
|
262
|
+
async sendRequestStream(peer, req, callbacks, options) {
|
|
263
|
+
return this._sendRequestInternal(peer, req, callbacks, options);
|
|
293
264
|
}
|
|
294
|
-
async _sendRequestInternal(peer, req, callbacks) {
|
|
265
|
+
async _sendRequestInternal(peer, req, callbacks, options) {
|
|
295
266
|
if (!req.requestId || typeof req.requestId !== "string") {
|
|
296
267
|
throw new Error("requestId must be a non-empty string");
|
|
297
268
|
}
|
|
@@ -312,6 +283,7 @@ export class AntseedNode extends EventEmitter {
|
|
|
312
283
|
const timeoutMs = this._config.requestTimeoutMs ?? 30_000;
|
|
313
284
|
const maxStreamBufferBytes = Math.max(1, this._config.maxStreamBufferBytes ?? 16 * 1024 * 1024);
|
|
314
285
|
const maxStreamDurationMs = Math.max(1, this._config.maxStreamDurationMs ?? 5 * 60_000);
|
|
286
|
+
const streamInitialResponseTimeoutMs = callbacks ? Math.max(timeoutMs, 90_000) : timeoutMs;
|
|
315
287
|
// Idle timeout for streaming: resets on each chunk so long-running
|
|
316
288
|
// streams (thinking models, large outputs) stay alive as long as
|
|
317
289
|
// data keeps flowing.
|
|
@@ -323,26 +295,88 @@ export class AntseedNode extends EventEmitter {
|
|
|
323
295
|
let streamStartResponse = null;
|
|
324
296
|
const streamChunks = [];
|
|
325
297
|
let activeTimeout = null;
|
|
298
|
+
let activeTimeoutMs = streamInitialResponseTimeoutMs;
|
|
299
|
+
const abortSignal = options?.signal;
|
|
300
|
+
let abortListenerAttached = false;
|
|
301
|
+
let connectionStateListenerAttached = false;
|
|
302
|
+
const hasConnectionStateEvents = typeof conn.on === "function"
|
|
303
|
+
&& typeof conn.off === "function";
|
|
304
|
+
const cleanupAbortListener = () => {
|
|
305
|
+
if (abortSignal && abortListenerAttached) {
|
|
306
|
+
abortSignal.removeEventListener("abort", onAbort);
|
|
307
|
+
abortListenerAttached = false;
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
const onConnectionStateChange = (state) => {
|
|
311
|
+
if (settled)
|
|
312
|
+
return;
|
|
313
|
+
if (state !== ConnectionState.Closed && state !== ConnectionState.Failed) {
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
settled = true;
|
|
317
|
+
if (activeTimeout)
|
|
318
|
+
clearTimeout(activeTimeout);
|
|
319
|
+
cleanupAbortListener();
|
|
320
|
+
cleanupConnectionListener();
|
|
321
|
+
mux.cancelProxyRequest(req.requestId);
|
|
322
|
+
reject(new Error(`Connection to ${peer.peerId} ${state.toLowerCase()} during request ${req.requestId}`));
|
|
323
|
+
};
|
|
324
|
+
const cleanupConnectionListener = () => {
|
|
325
|
+
if (!connectionStateListenerAttached)
|
|
326
|
+
return;
|
|
327
|
+
conn.off("stateChange", onConnectionStateChange);
|
|
328
|
+
connectionStateListenerAttached = false;
|
|
329
|
+
};
|
|
330
|
+
const onAbort = () => {
|
|
331
|
+
if (settled)
|
|
332
|
+
return;
|
|
333
|
+
settled = true;
|
|
334
|
+
if (activeTimeout)
|
|
335
|
+
clearTimeout(activeTimeout);
|
|
336
|
+
cleanupAbortListener();
|
|
337
|
+
cleanupConnectionListener();
|
|
338
|
+
debugWarn(`[Node] Request ${req.requestId.slice(0, 8)} aborted by caller`);
|
|
339
|
+
mux.cancelProxyRequest(req.requestId);
|
|
340
|
+
reject(new Error(`Request ${req.requestId} aborted`));
|
|
341
|
+
};
|
|
342
|
+
if (abortSignal) {
|
|
343
|
+
if (abortSignal.aborted) {
|
|
344
|
+
onAbort();
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
abortSignal.addEventListener("abort", onAbort, { once: true });
|
|
348
|
+
abortListenerAttached = true;
|
|
349
|
+
}
|
|
350
|
+
if (hasConnectionStateEvents) {
|
|
351
|
+
conn.on("stateChange", onConnectionStateChange);
|
|
352
|
+
connectionStateListenerAttached = true;
|
|
353
|
+
}
|
|
326
354
|
const resetTimeout = (ms) => {
|
|
327
355
|
if (activeTimeout)
|
|
328
356
|
clearTimeout(activeTimeout);
|
|
357
|
+
activeTimeoutMs = ms;
|
|
329
358
|
activeTimeout = setTimeout(() => {
|
|
330
359
|
if (settled)
|
|
331
360
|
return;
|
|
332
361
|
settled = true;
|
|
333
|
-
|
|
362
|
+
cleanupAbortListener();
|
|
363
|
+
cleanupConnectionListener();
|
|
364
|
+
debugWarn(`[Node] Request ${req.requestId.slice(0, 8)} timed out after ${Date.now() - startTime}ms `
|
|
365
|
+
+ `(timeout=${activeTimeoutMs}ms, stream=${callbacks ? "true" : "false"}, streamStarted=${streamStarted ? "true" : "false"}, buffered=${streamBufferedBytes}b)`);
|
|
334
366
|
mux.cancelProxyRequest(req.requestId);
|
|
335
367
|
reject(new Error(`Request ${req.requestId} timed out`));
|
|
336
368
|
}, ms);
|
|
337
369
|
};
|
|
338
370
|
// Initial timeout: wait for the first response frame.
|
|
339
|
-
resetTimeout(
|
|
371
|
+
resetTimeout(streamInitialResponseTimeoutMs);
|
|
340
372
|
const finish = (response) => {
|
|
341
373
|
if (settled)
|
|
342
374
|
return;
|
|
343
375
|
settled = true;
|
|
344
376
|
if (activeTimeout)
|
|
345
377
|
clearTimeout(activeTimeout);
|
|
378
|
+
cleanupAbortListener();
|
|
379
|
+
cleanupConnectionListener();
|
|
346
380
|
const cleaned = this._stripStreamingHeader(response);
|
|
347
381
|
debugLog(`[Node] Response for ${req.requestId.slice(0, 8)}: status=${cleaned.statusCode} (${Date.now() - startTime}ms, ${cleaned.body.length}b)`);
|
|
348
382
|
resolve(cleaned);
|
|
@@ -353,6 +387,8 @@ export class AntseedNode extends EventEmitter {
|
|
|
353
387
|
settled = true;
|
|
354
388
|
if (activeTimeout)
|
|
355
389
|
clearTimeout(activeTimeout);
|
|
390
|
+
cleanupAbortListener();
|
|
391
|
+
cleanupConnectionListener();
|
|
356
392
|
reject(error);
|
|
357
393
|
};
|
|
358
394
|
mux.sendProxyRequest(req, (response, metadata) => {
|
|
@@ -363,6 +399,7 @@ export class AntseedNode extends EventEmitter {
|
|
|
363
399
|
streamStartedAtMs = Date.now();
|
|
364
400
|
streamBufferedBytes = 0;
|
|
365
401
|
streamStartResponse = this._stripStreamingHeader(response);
|
|
402
|
+
debugLog(`[Node] Stream started for ${req.requestId.slice(0, 8)}; idle-timeout=${streamIdleTimeoutMs}ms`);
|
|
366
403
|
// Switch to streaming idle timeout: resets on each chunk.
|
|
367
404
|
resetTimeout(streamIdleTimeoutMs);
|
|
368
405
|
callbacks?.onResponseStart?.(streamStartResponse, { streaming: true });
|
|
@@ -414,7 +451,7 @@ export class AntseedNode extends EventEmitter {
|
|
|
414
451
|
port,
|
|
415
452
|
bootstrapNodes,
|
|
416
453
|
reannounceIntervalMs: DEFAULT_DHT_CONFIG.reannounceIntervalMs,
|
|
417
|
-
operationTimeoutMs: DEFAULT_DHT_CONFIG.operationTimeoutMs,
|
|
454
|
+
operationTimeoutMs: this._config.dhtOperationTimeoutMs ?? DEFAULT_DHT_CONFIG.operationTimeoutMs,
|
|
418
455
|
allowPrivateIPs: this._config.allowPrivateIPs,
|
|
419
456
|
};
|
|
420
457
|
}
|
|
@@ -489,6 +526,9 @@ export class AntseedNode extends EventEmitter {
|
|
|
489
526
|
// Create ConnectionManager and start listening
|
|
490
527
|
this._connectionManager = new ConnectionManager();
|
|
491
528
|
this._connectionManager.setLocalIdentity(identity);
|
|
529
|
+
this._connectionManager.on("error", (err) => {
|
|
530
|
+
debugWarn(`[ConnectionManager] ${err.message}`);
|
|
531
|
+
});
|
|
492
532
|
await this._connectionManager.startListening({
|
|
493
533
|
peerId: identity.peerId,
|
|
494
534
|
port: signalingPort,
|
|
@@ -559,9 +599,11 @@ export class AntseedNode extends EventEmitter {
|
|
|
559
599
|
// Create ConnectionManager for outbound connections
|
|
560
600
|
this._connectionManager = new ConnectionManager();
|
|
561
601
|
this._connectionManager.setLocalIdentity(identity);
|
|
602
|
+
this._connectionManager.on("error", (err) => {
|
|
603
|
+
debugWarn(`[ConnectionManager] ${err.message}`);
|
|
604
|
+
});
|
|
562
605
|
// Create PeerLookup with HttpMetadataResolver
|
|
563
606
|
const metadataResolver = new HttpMetadataResolver();
|
|
564
|
-
this._metadataResolver = metadataResolver;
|
|
565
607
|
const lookupConfig = {
|
|
566
608
|
dht: this._dht,
|
|
567
609
|
metadataResolver,
|