smoldot 2.0.6 → 2.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/internals/bytecode/wasm0.js +1 -1
- package/dist/cjs/internals/bytecode/wasm1.js +1 -1
- package/dist/cjs/internals/bytecode/wasm2.js +1 -1
- package/dist/cjs/internals/client.d.ts +18 -22
- package/dist/cjs/internals/client.js +4 -4
- package/dist/cjs/internals/local-instance.d.ts +2 -7
- package/dist/cjs/internals/local-instance.js +10 -19
- package/dist/cjs/internals/remote-instance.js +7 -7
- package/dist/cjs/no-auto-bytecode-browser.js +24 -98
- package/dist/cjs/no-auto-bytecode-deno.js +2 -2
- package/dist/cjs/no-auto-bytecode-nodejs.js +2 -5
- package/dist/cjs/public-types.d.ts +14 -13
- package/dist/mjs/internals/bytecode/wasm0.js +1 -1
- package/dist/mjs/internals/bytecode/wasm1.js +1 -1
- package/dist/mjs/internals/bytecode/wasm2.js +1 -1
- package/dist/mjs/internals/client.d.ts +18 -22
- package/dist/mjs/internals/client.js +4 -4
- package/dist/mjs/internals/local-instance.d.ts +2 -7
- package/dist/mjs/internals/local-instance.js +10 -19
- package/dist/mjs/internals/remote-instance.js +7 -7
- package/dist/mjs/no-auto-bytecode-browser.js +24 -98
- package/dist/mjs/no-auto-bytecode-deno.js +2 -2
- package/dist/mjs/no-auto-bytecode-nodejs.js +2 -5
- package/dist/mjs/public-types.d.ts +14 -13
- package/package.json +1 -1
|
@@ -7,6 +7,9 @@ export interface PlatformBindings {
|
|
|
7
7
|
/**
|
|
8
8
|
* Tries to open a new connection using the given configuration.
|
|
9
9
|
*
|
|
10
|
+
* In case of a multistream connection, `onMultistreamHandshakeInfo` should be called as soon
|
|
11
|
+
* as possible.
|
|
12
|
+
*
|
|
10
13
|
* @see Connection
|
|
11
14
|
*/
|
|
12
15
|
connect(config: ConnectionConfig): Connection;
|
|
@@ -22,19 +25,14 @@ export interface PlatformBindings {
|
|
|
22
25
|
/**
|
|
23
26
|
* Connection to a remote node.
|
|
24
27
|
*
|
|
25
|
-
* At any time, a connection can be in one of the
|
|
28
|
+
* At any time, a connection can be in one of the following states:
|
|
26
29
|
*
|
|
27
|
-
* - `
|
|
28
|
-
* - `Open`
|
|
30
|
+
* - `Open` (initial state)
|
|
29
31
|
* - `Reset`
|
|
30
32
|
*
|
|
31
|
-
* When in the `
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
* transition back to another state.
|
|
35
|
-
*
|
|
36
|
-
* Initially in the `Opening` state, the connection can transition to the `Open` state if the
|
|
37
|
-
* remote accepts the connection. When that happens, `config.onOpen` is called.
|
|
33
|
+
* When in the `Open` state, the connection can transition to the `Reset` state if the remote
|
|
34
|
+
* closes the connection or refuses the connection altogether. When that happens, `config.onReset`
|
|
35
|
+
* is called. Once in the `Reset` state, the connection cannot transition back to `Open`.
|
|
38
36
|
*
|
|
39
37
|
* When in the `Open` state, the connection can receive messages. When a message is received,
|
|
40
38
|
* `config.onMessage` is called.
|
|
@@ -112,16 +110,14 @@ export interface ConnectionConfig {
|
|
|
112
110
|
*/
|
|
113
111
|
address: instance.ParsedMultiaddr;
|
|
114
112
|
/**
|
|
115
|
-
* Callback called when
|
|
113
|
+
* Callback called when a multistream connection knows information about its handshake. Should
|
|
114
|
+
* be called as soon as possible.
|
|
115
|
+
*
|
|
116
|
+
* Can only happen while the connection is in the `Open` state.
|
|
116
117
|
*
|
|
117
118
|
* Must only be called once per connection.
|
|
118
119
|
*/
|
|
119
|
-
|
|
120
|
-
type: 'single-stream';
|
|
121
|
-
handshake: 'multistream-select-noise-yamux';
|
|
122
|
-
initialWritableBytes: number;
|
|
123
|
-
} | {
|
|
124
|
-
type: 'multi-stream';
|
|
120
|
+
onMultistreamHandshakeInfo: (info: {
|
|
125
121
|
handshake: 'webrtc';
|
|
126
122
|
localTlsCertificateSha256: Uint8Array;
|
|
127
123
|
remoteTlsCertificateSha256: Uint8Array;
|
|
@@ -137,7 +133,7 @@ export interface ConnectionConfig {
|
|
|
137
133
|
*
|
|
138
134
|
* This function must only be called for connections of type "multi-stream".
|
|
139
135
|
*/
|
|
140
|
-
onStreamOpened: (streamId: number, direction: 'inbound' | 'outbound'
|
|
136
|
+
onStreamOpened: (streamId: number, direction: 'inbound' | 'outbound') => void;
|
|
141
137
|
/**
|
|
142
138
|
* Callback called when a stream transitions to the `Reset` state.
|
|
143
139
|
*
|
|
@@ -151,14 +147,14 @@ export interface ConnectionConfig {
|
|
|
151
147
|
* written on the stream, meaning that some buffer space is now free.
|
|
152
148
|
*
|
|
153
149
|
* Can only happen while the connection is in the `Open` state.
|
|
154
|
-
*
|
|
155
150
|
* This callback must not be called after `closeSend` has been called.
|
|
156
151
|
*
|
|
152
|
+
* The total of writable bytes must not go beyond reasonable values (e.g. a few megabytes). It
|
|
153
|
+
* is not legal to provide a dummy implementation that simply passes an exceedingly large
|
|
154
|
+
* value.
|
|
155
|
+
*
|
|
157
156
|
* The `streamId` parameter must be provided if and only if the connection is of type
|
|
158
157
|
* "multi-stream".
|
|
159
|
-
*
|
|
160
|
-
* Only a number of bytes equal to the size of the data provided to {@link Connection.send}
|
|
161
|
-
* must be reported. In other words, the `initialWritableBytes` must never be exceeded.
|
|
162
158
|
*/
|
|
163
159
|
onWritableBytes: (numExtra: number, streamId?: number) => void;
|
|
164
160
|
/**
|
|
@@ -135,15 +135,15 @@ export function start(options, wasmModule, platformBindings) {
|
|
|
135
135
|
throw new Error();
|
|
136
136
|
state.instance.instance.streamMessage(connectionId, message, streamId);
|
|
137
137
|
},
|
|
138
|
-
onStreamOpened(streamId, direction
|
|
138
|
+
onStreamOpened(streamId, direction) {
|
|
139
139
|
if (state.instance.status !== "ready")
|
|
140
140
|
throw new Error();
|
|
141
|
-
state.instance.instance.streamOpened(connectionId, streamId, direction
|
|
141
|
+
state.instance.instance.streamOpened(connectionId, streamId, direction);
|
|
142
142
|
},
|
|
143
|
-
|
|
143
|
+
onMultistreamHandshakeInfo(info) {
|
|
144
144
|
if (state.instance.status !== "ready")
|
|
145
145
|
throw new Error();
|
|
146
|
-
state.instance.instance.
|
|
146
|
+
state.instance.instance.connectionMultiStreamSetHandshakeInfo(connectionId, info);
|
|
147
147
|
},
|
|
148
148
|
onWritableBytes(numExtra, streamId) {
|
|
149
149
|
if (state.instance.status !== "ready")
|
|
@@ -103,12 +103,7 @@ export interface Instance {
|
|
|
103
103
|
* all connections.
|
|
104
104
|
*/
|
|
105
105
|
shutdownExecutor: () => void;
|
|
106
|
-
|
|
107
|
-
type: 'single-stream';
|
|
108
|
-
handshake: 'multistream-select-noise-yamux';
|
|
109
|
-
initialWritableBytes: number;
|
|
110
|
-
} | {
|
|
111
|
-
type: 'multi-stream';
|
|
106
|
+
connectionMultiStreamSetHandshakeInfo: (connectionId: number, info: {
|
|
112
107
|
handshake: 'webrtc';
|
|
113
108
|
localTlsCertificateSha256: Uint8Array;
|
|
114
109
|
remoteTlsCertificateSha256: Uint8Array;
|
|
@@ -116,7 +111,7 @@ export interface Instance {
|
|
|
116
111
|
connectionReset: (connectionId: number, message: string) => void;
|
|
117
112
|
streamWritableBytes: (connectionId: number, numExtra: number, streamId?: number) => void;
|
|
118
113
|
streamMessage: (connectionId: number, message: Uint8Array, streamId?: number) => void;
|
|
119
|
-
streamOpened: (connectionId: number, streamId: number, direction: 'inbound' | 'outbound'
|
|
114
|
+
streamOpened: (connectionId: number, streamId: number, direction: 'inbound' | 'outbound') => void;
|
|
120
115
|
streamReset: (connectionId: number, streamId: number) => void;
|
|
121
116
|
}
|
|
122
117
|
/**
|
|
@@ -401,25 +401,16 @@ export function startLocalInstance(config, wasmModule, eventCallback) {
|
|
|
401
401
|
state.onShutdownExecutorOrWasmPanic = () => { };
|
|
402
402
|
cb();
|
|
403
403
|
},
|
|
404
|
-
|
|
404
|
+
connectionMultiStreamSetHandshakeInfo: (connectionId, info) => {
|
|
405
405
|
if (!state.instance)
|
|
406
406
|
return;
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
buffer.writeUInt8(handshakeTy, 0, 0);
|
|
415
|
-
handshakeTy.set(info.localTlsCertificateSha256, 1);
|
|
416
|
-
handshakeTy.set(info.remoteTlsCertificateSha256, 1 + info.localTlsCertificateSha256.length);
|
|
417
|
-
state.bufferIndices[0] = handshakeTy;
|
|
418
|
-
state.instance.exports.connection_open_multi_stream(connectionId, 0);
|
|
419
|
-
delete state.bufferIndices[0];
|
|
420
|
-
break;
|
|
421
|
-
}
|
|
422
|
-
}
|
|
407
|
+
const handshakeTy = new Uint8Array(1 + info.localTlsCertificateSha256.length + info.remoteTlsCertificateSha256.length);
|
|
408
|
+
buffer.writeUInt8(handshakeTy, 0, 0);
|
|
409
|
+
handshakeTy.set(info.localTlsCertificateSha256, 1);
|
|
410
|
+
handshakeTy.set(info.remoteTlsCertificateSha256, 1 + info.localTlsCertificateSha256.length);
|
|
411
|
+
state.bufferIndices[0] = handshakeTy;
|
|
412
|
+
state.instance.exports.connection_multi_stream_set_handshake_info(connectionId, 0);
|
|
413
|
+
delete state.bufferIndices[0];
|
|
423
414
|
},
|
|
424
415
|
connectionReset: (connectionId, message) => {
|
|
425
416
|
if (!state.instance)
|
|
@@ -440,10 +431,10 @@ export function startLocalInstance(config, wasmModule, eventCallback) {
|
|
|
440
431
|
state.instance.exports.stream_message(connectionId, streamId || 0, 0);
|
|
441
432
|
delete state.bufferIndices[0];
|
|
442
433
|
},
|
|
443
|
-
streamOpened: (connectionId, streamId, direction
|
|
434
|
+
streamOpened: (connectionId, streamId, direction) => {
|
|
444
435
|
if (!state.instance)
|
|
445
436
|
return;
|
|
446
|
-
state.instance.exports.connection_stream_opened(connectionId, streamId, direction === 'outbound' ? 1 : 0
|
|
437
|
+
state.instance.exports.connection_stream_opened(connectionId, streamId, direction === 'outbound' ? 1 : 0);
|
|
447
438
|
},
|
|
448
439
|
streamReset: (connectionId, streamId) => {
|
|
449
440
|
if (!state.instance)
|
|
@@ -176,17 +176,17 @@ export function connectToInstanceServer(config) {
|
|
|
176
176
|
const msg = { ty: "connection-reset", connectionId, message };
|
|
177
177
|
portToServer.postMessage(msg);
|
|
178
178
|
},
|
|
179
|
-
|
|
180
|
-
const msg = { ty: "connection-
|
|
179
|
+
connectionMultiStreamSetHandshakeInfo(connectionId, info) {
|
|
180
|
+
const msg = { ty: "connection-multistream-set-info", connectionId, info };
|
|
181
181
|
portToServer.postMessage(msg);
|
|
182
182
|
},
|
|
183
183
|
streamMessage(connectionId, message, streamId) {
|
|
184
184
|
const msg = { ty: "stream-message", connectionId, message, streamId };
|
|
185
185
|
portToServer.postMessage(msg);
|
|
186
186
|
},
|
|
187
|
-
streamOpened(connectionId, streamId, direction
|
|
187
|
+
streamOpened(connectionId, streamId, direction) {
|
|
188
188
|
state.connections.get(connectionId).add(streamId);
|
|
189
|
-
const msg = { ty: "stream-opened", connectionId, streamId, direction
|
|
189
|
+
const msg = { ty: "stream-opened", connectionId, streamId, direction };
|
|
190
190
|
portToServer.postMessage(msg);
|
|
191
191
|
},
|
|
192
192
|
streamWritableBytes(connectionId, numExtra, streamId) {
|
|
@@ -317,11 +317,11 @@ export function startInstanceServer(config, initPortToClient) {
|
|
|
317
317
|
state.instance.connectionReset(message.connectionId, message.message);
|
|
318
318
|
break;
|
|
319
319
|
}
|
|
320
|
-
case "connection-
|
|
320
|
+
case "connection-multistream-set-info": {
|
|
321
321
|
// The connection might have been reset locally in the past.
|
|
322
322
|
if (!state.connections.has(message.connectionId))
|
|
323
323
|
return;
|
|
324
|
-
state.instance.
|
|
324
|
+
state.instance.connectionMultiStreamSetHandshakeInfo(message.connectionId, message.info);
|
|
325
325
|
break;
|
|
326
326
|
}
|
|
327
327
|
case "stream-message": {
|
|
@@ -339,7 +339,7 @@ export function startInstanceServer(config, initPortToClient) {
|
|
|
339
339
|
if (!state.connections.has(message.connectionId))
|
|
340
340
|
return;
|
|
341
341
|
state.connections.get(message.connectionId).add(message.streamId);
|
|
342
|
-
state.instance.streamOpened(message.connectionId, message.streamId, message.direction
|
|
342
|
+
state.instance.streamOpened(message.connectionId, message.streamId, message.direction);
|
|
343
343
|
break;
|
|
344
344
|
}
|
|
345
345
|
case "stream-writable-bytes": {
|
|
@@ -49,7 +49,7 @@ export function startWithBytecode(options) {
|
|
|
49
49
|
* Tries to open a new connection using the given configuration.
|
|
50
50
|
*
|
|
51
51
|
* @see Connection
|
|
52
|
-
* @throws
|
|
52
|
+
* @throws any If the multiaddress couldn't be parsed or contains an invalid protocol.
|
|
53
53
|
*/
|
|
54
54
|
function connect(config) {
|
|
55
55
|
if (config.address.ty === "websocket") {
|
|
@@ -94,10 +94,7 @@ function connect(config) {
|
|
|
94
94
|
if (connection instanceof WebSocket) {
|
|
95
95
|
connection.binaryType = 'arraybuffer';
|
|
96
96
|
connection.onopen = () => {
|
|
97
|
-
config.
|
|
98
|
-
type: 'single-stream', handshake: 'multistream-select-noise-yamux',
|
|
99
|
-
initialWritableBytes: 1024 * 1024
|
|
100
|
-
});
|
|
97
|
+
config.onWritableBytes(1024 * 1024);
|
|
101
98
|
};
|
|
102
99
|
connection.onclose = (event) => {
|
|
103
100
|
const message = "Error code " + event.code + (!!event.reason ? (": " + event.reason) : "");
|
|
@@ -158,10 +155,6 @@ function connect(config) {
|
|
|
158
155
|
let pc = undefined;
|
|
159
156
|
// Contains the data channels that are open and have been reported to smoldot.
|
|
160
157
|
const dataChannels = new Map();
|
|
161
|
-
// For various reasons explained below, we open a data channel in advance without reporting it
|
|
162
|
-
// to smoldot. This data channel is stored in this variable. Once it is reported to smoldot,
|
|
163
|
-
// it is inserted in `dataChannels`.
|
|
164
|
-
let handshakeDataChannel;
|
|
165
158
|
// SHA256 hash of the DTLS certificate of the local node. Unknown as long as it hasn't been
|
|
166
159
|
// generated.
|
|
167
160
|
// TODO: could be merged with `pc` in one variable, and maybe even the other fields as well
|
|
@@ -173,7 +166,7 @@ function connect(config) {
|
|
|
173
166
|
// The `RTCPeerConnection` is created pretty quickly. It is however still possible for
|
|
174
167
|
// smoldot to cancel the opening, in which case `pc` will still be undefined.
|
|
175
168
|
if (!pc) {
|
|
176
|
-
console.assert(dataChannels.size === 0
|
|
169
|
+
console.assert(dataChannels.size === 0, "substreams exist while pc is undef");
|
|
177
170
|
pc = null;
|
|
178
171
|
return;
|
|
179
172
|
}
|
|
@@ -188,14 +181,6 @@ function connect(config) {
|
|
|
188
181
|
channel.channel.onmessage = null;
|
|
189
182
|
}
|
|
190
183
|
dataChannels.clear();
|
|
191
|
-
if (handshakeDataChannel) {
|
|
192
|
-
handshakeDataChannel.onopen = null;
|
|
193
|
-
handshakeDataChannel.onerror = null;
|
|
194
|
-
handshakeDataChannel.onclose = null;
|
|
195
|
-
handshakeDataChannel.onbufferedamountlow = null;
|
|
196
|
-
handshakeDataChannel.onmessage = null;
|
|
197
|
-
}
|
|
198
|
-
handshakeDataChannel = undefined;
|
|
199
184
|
pc.close(); // Not necessarily necessary, but it doesn't hurt to do so.
|
|
200
185
|
};
|
|
201
186
|
// Function that configures a newly-opened channel and adds it to the map. Used for both
|
|
@@ -203,54 +188,19 @@ function connect(config) {
|
|
|
203
188
|
const addChannel = (dataChannel, direction) => {
|
|
204
189
|
const dataChannelId = dataChannel.id;
|
|
205
190
|
dataChannel.binaryType = 'arraybuffer';
|
|
206
|
-
let isOpen = false;
|
|
191
|
+
let isOpen = { value: false };
|
|
207
192
|
dataChannel.onopen = () => {
|
|
208
|
-
console.assert(!isOpen, "substream opened twice");
|
|
209
|
-
isOpen = true;
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
console.assert(handshakeDataChannel === dataChannel, "handshake substream mismatch");
|
|
213
|
-
config.onOpen({
|
|
214
|
-
type: 'multi-stream',
|
|
215
|
-
handshake: 'webrtc',
|
|
216
|
-
// `addChannel` can never be called before the local certificate is generated, so this
|
|
217
|
-
// value is always defined.
|
|
218
|
-
localTlsCertificateSha256: localTlsCertificateSha256,
|
|
219
|
-
remoteTlsCertificateSha256,
|
|
220
|
-
});
|
|
221
|
-
}
|
|
222
|
-
else {
|
|
223
|
-
console.assert(direction !== 'outbound' || !handshakeDataChannel, "handshakeDataChannel still defined");
|
|
224
|
-
config.onStreamOpened(dataChannelId, direction, 65536);
|
|
225
|
-
}
|
|
193
|
+
console.assert(!isOpen.value, "substream opened twice");
|
|
194
|
+
isOpen.value = true;
|
|
195
|
+
config.onStreamOpened(dataChannelId, direction);
|
|
196
|
+
config.onWritableBytes(65536, dataChannelId);
|
|
226
197
|
};
|
|
227
198
|
dataChannel.onerror = dataChannel.onclose = (_error) => {
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
//
|
|
231
|
-
//
|
|
232
|
-
//
|
|
233
|
-
killAllJs();
|
|
234
|
-
// Note that the event doesn't give any additional reason for the failure.
|
|
235
|
-
config.onConnectionReset("handshake data channel failed to open");
|
|
236
|
-
}
|
|
237
|
-
else if (handshakeDataChannel === dataChannel) {
|
|
238
|
-
// The handshake data channel has been closed before we reported it to smoldot. This
|
|
239
|
-
// isn't really a problem. We just update the state and continue running. If smoldot
|
|
240
|
-
// requests a substream, another one will be opened. It could be a valid implementation
|
|
241
|
-
// to also just kill the entire connection, however doing so is a bit too intrusive and
|
|
242
|
-
// punches through abstraction layers.
|
|
243
|
-
handshakeDataChannel.onopen = null;
|
|
244
|
-
handshakeDataChannel.onerror = null;
|
|
245
|
-
handshakeDataChannel.onclose = null;
|
|
246
|
-
handshakeDataChannel.onbufferedamountlow = null;
|
|
247
|
-
handshakeDataChannel.onmessage = null;
|
|
248
|
-
handshakeDataChannel = undefined;
|
|
249
|
-
}
|
|
250
|
-
else if (!isOpen) {
|
|
251
|
-
// Substream wasn't opened yet and thus has failed to open. The API has no mechanism to
|
|
252
|
-
// report substream openings failures. We could try opening it again, but given that
|
|
253
|
-
// it's unlikely to succeed, we simply opt to kill the entire connection.
|
|
199
|
+
if (!isOpen.value) {
|
|
200
|
+
// Substream wasn't opened yet and thus has failed to open. The API has no
|
|
201
|
+
// mechanism to report substream openings failures. We could try opening it
|
|
202
|
+
// again, but given that it's unlikely to succeed, we simply opt to kill the
|
|
203
|
+
// entire connection.
|
|
254
204
|
killAllJs();
|
|
255
205
|
// Note that the event doesn't give any additional reason for the failure.
|
|
256
206
|
config.onConnectionReset("data channel failed to open");
|
|
@@ -270,10 +220,7 @@ function connect(config) {
|
|
|
270
220
|
// The `data` field is an `ArrayBuffer`.
|
|
271
221
|
config.onMessage(new Uint8Array(m.data), dataChannelId);
|
|
272
222
|
};
|
|
273
|
-
|
|
274
|
-
dataChannels.set(dataChannelId, { channel: dataChannel, bufferedBytes: 0 });
|
|
275
|
-
else
|
|
276
|
-
handshakeDataChannel = dataChannel;
|
|
223
|
+
dataChannels.set(dataChannelId, { channel: dataChannel, bufferedBytes: 0 });
|
|
277
224
|
};
|
|
278
225
|
// It is possible for the browser to use multiple different certificates.
|
|
279
226
|
// In order for our local certificate to be deterministic, we need to generate it manually and
|
|
@@ -423,16 +370,11 @@ function connect(config) {
|
|
|
423
370
|
// TODO: is the substream maybe already open? according to the Internet it seems that no but it's unclear
|
|
424
371
|
addChannel(channel, 'inbound');
|
|
425
372
|
};
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
// Instead of following this API, we open this substream in advance, and will notify smoldot
|
|
432
|
-
// that the connection is open when the substream is open.
|
|
433
|
-
// Note that the label passed to `createDataChannel` is required to be empty as per the
|
|
434
|
-
// libp2p WebRTC specification.
|
|
435
|
-
addChannel(pc.createDataChannel("", { id: 0, negotiated: true }), 'first-outbound');
|
|
373
|
+
config.onMultistreamHandshakeInfo({
|
|
374
|
+
handshake: 'webrtc',
|
|
375
|
+
localTlsCertificateSha256,
|
|
376
|
+
remoteTlsCertificateSha256,
|
|
377
|
+
});
|
|
436
378
|
}));
|
|
437
379
|
return {
|
|
438
380
|
reset: (streamId) => {
|
|
@@ -458,27 +400,11 @@ function connect(config) {
|
|
|
458
400
|
},
|
|
459
401
|
closeSend: () => { throw new Error('Wrong connection type'); },
|
|
460
402
|
openOutSubstream: () => {
|
|
461
|
-
// `openOutSubstream` can only be called after we have called `config.onOpen`,
|
|
462
|
-
// `pc` is guaranteed to be non-null.
|
|
463
|
-
//
|
|
464
|
-
//
|
|
465
|
-
|
|
466
|
-
// Do this asynchronously because calling callbacks within callbacks is error-prone.
|
|
467
|
-
(() => __awaiter(this, void 0, void 0, function* () {
|
|
468
|
-
// We need to check again if `handshakeDataChannel` is still defined, as the
|
|
469
|
-
// connection might have been closed.
|
|
470
|
-
if (handshakeDataChannel) {
|
|
471
|
-
config.onStreamOpened(handshakeDataChannel.id, 'outbound', 1024 * 1024);
|
|
472
|
-
dataChannels.set(handshakeDataChannel.id, { channel: handshakeDataChannel, bufferedBytes: 0 });
|
|
473
|
-
handshakeDataChannel = undefined;
|
|
474
|
-
}
|
|
475
|
-
}))();
|
|
476
|
-
}
|
|
477
|
-
else {
|
|
478
|
-
// Note that the label passed to `createDataChannel` is required to be empty as per the
|
|
479
|
-
// libp2p WebRTC specification.
|
|
480
|
-
addChannel(pc.createDataChannel(""), 'outbound');
|
|
481
|
-
}
|
|
403
|
+
// `openOutSubstream` can only be called after we have called `config.onOpen`,
|
|
404
|
+
// therefore `pc` is guaranteed to be non-null.
|
|
405
|
+
// Note that the label passed to `createDataChannel` is required to be empty as
|
|
406
|
+
// per the libp2p WebRTC specification.
|
|
407
|
+
addChannel(pc.createDataChannel(""), 'outbound');
|
|
482
408
|
}
|
|
483
409
|
};
|
|
484
410
|
}
|
|
@@ -70,7 +70,7 @@ function connect(config) {
|
|
|
70
70
|
config.onWritableBytes(wasSent);
|
|
71
71
|
};
|
|
72
72
|
socket.onopen = () => {
|
|
73
|
-
config.
|
|
73
|
+
config.onWritableBytes(1024 * 1024);
|
|
74
74
|
};
|
|
75
75
|
socket.onclose = (event) => {
|
|
76
76
|
const message = "Error code " + event.code + (!!event.reason ? (": " + event.reason) : "");
|
|
@@ -125,7 +125,7 @@ function connect(config) {
|
|
|
125
125
|
if (socket.destroyed)
|
|
126
126
|
return established;
|
|
127
127
|
established === null || established === void 0 ? void 0 : established.setNoDelay();
|
|
128
|
-
config.
|
|
128
|
+
config.onWritableBytes(1024 * 1024);
|
|
129
129
|
// Spawns an asynchronous task that continuously reads from the socket.
|
|
130
130
|
// Every time data is read, the task re-executes itself in order to continue reading.
|
|
131
131
|
// The task ends automatically if an EOF or error is detected, which should also happen
|
|
@@ -66,7 +66,7 @@ function connect(config) {
|
|
|
66
66
|
config.onWritableBytes(wasSent);
|
|
67
67
|
};
|
|
68
68
|
socket.onopen = () => {
|
|
69
|
-
config.
|
|
69
|
+
config.onWritableBytes(1024 * 1024);
|
|
70
70
|
};
|
|
71
71
|
socket.onclose = (event) => {
|
|
72
72
|
const message = "Error code " + event.code + (!!event.reason ? (": " + event.reason) : "");
|
|
@@ -119,10 +119,7 @@ function connect(config) {
|
|
|
119
119
|
socket.on('connect', () => {
|
|
120
120
|
if (socket.destroyed)
|
|
121
121
|
return;
|
|
122
|
-
config.
|
|
123
|
-
type: 'single-stream', handshake: 'multistream-select-noise-yamux',
|
|
124
|
-
initialWritableBytes: socket.writableHighWaterMark
|
|
125
|
-
});
|
|
122
|
+
config.onWritableBytes(socket.writableHighWaterMark);
|
|
126
123
|
});
|
|
127
124
|
socket.on('close', (hasError) => {
|
|
128
125
|
if (socket.destroyed)
|
|
@@ -90,19 +90,19 @@ export interface Chain {
|
|
|
90
90
|
/**
|
|
91
91
|
* Enqueues a JSON-RPC request that the client will process as soon as possible.
|
|
92
92
|
*
|
|
93
|
-
* The response
|
|
93
|
+
* The response can be pulled by calling {@link Chain.nextJsonRpcResponse}.
|
|
94
94
|
*
|
|
95
95
|
* See <https://www.jsonrpc.org/specification> for a specification of the JSON-RPC format. Only
|
|
96
96
|
* version 2 is supported.
|
|
97
|
-
* Be aware that some requests will cause notifications to be sent back
|
|
98
|
-
*
|
|
97
|
+
* Be aware that some requests will cause notifications to be sent back through
|
|
98
|
+
* {@link Chain.nextJsonRpcResponse}.
|
|
99
99
|
*
|
|
100
100
|
* If the request is not a valid JSON-RPC request, then a JSON-RPC error response is later
|
|
101
101
|
* generated with an `id` equal to `null`, in accordance with the JSON-RPC 2.0 specification.
|
|
102
102
|
*
|
|
103
103
|
* If, however, the request is a valid JSON-RPC request but that concerns an unknown method, or
|
|
104
104
|
* if for example some parameters are missing, an error response is properly generated and
|
|
105
|
-
* yielded through
|
|
105
|
+
* yielded through {@link Chain.nextJsonRpcResponse}.
|
|
106
106
|
*
|
|
107
107
|
* Two JSON-RPC APIs are supported by smoldot:
|
|
108
108
|
*
|
|
@@ -121,9 +121,10 @@ export interface Chain {
|
|
|
121
121
|
* Waits for a JSON-RPC response or notification to be generated.
|
|
122
122
|
*
|
|
123
123
|
* Each chain contains a buffer of the responses waiting to be sent out. Calling this function
|
|
124
|
-
* pulls one element from the buffer. If this function is called at a slower rate than
|
|
125
|
-
* are generated, then the buffer will eventually become full, at which point calling
|
|
126
|
-
* {@link Chain.sendJsonRpc} will throw an exception.
|
|
124
|
+
* pulls one element from the buffer. If this function is called at a slower rate than
|
|
125
|
+
* responses are generated, then the buffer will eventually become full, at which point calling
|
|
126
|
+
* {@link Chain.sendJsonRpc} will throw an exception. The size of this buffer can be configured
|
|
127
|
+
* through {@link AddChainOptions.jsonRpcMaxPendingRequests}.
|
|
127
128
|
*
|
|
128
129
|
* If this function is called multiple times "simultaneously" (generating multiple different
|
|
129
130
|
* `Promise`s), each `Promise` will return a different JSON-RPC response or notification. In
|
|
@@ -139,11 +140,11 @@ export interface Chain {
|
|
|
139
140
|
/**
|
|
140
141
|
* Disconnects from the blockchain.
|
|
141
142
|
*
|
|
142
|
-
*
|
|
143
|
-
*
|
|
143
|
+
* Any on-going call to {@link Chain.nextJsonRpcResponse} is instantaneously aborted and will
|
|
144
|
+
* throw a {@link AlreadyDestroyedError}.
|
|
144
145
|
*
|
|
145
|
-
* Trying to use the chain again will lead to a
|
|
146
|
-
* being thrown.
|
|
146
|
+
* Trying to use the chain again after this function has returned will lead to a
|
|
147
|
+
* {@link AlreadyDestroyedError} exception being thrown.
|
|
147
148
|
*
|
|
148
149
|
* While the chain instantaneously disappears from the public API as soon as this function is
|
|
149
150
|
* called, its shutdown process actually happens asynchronously in the background. This means
|
|
@@ -369,7 +370,7 @@ export interface AddChainOptions {
|
|
|
369
370
|
*
|
|
370
371
|
* This field is ignored if {@link AddChainOptions.disableJsonRpc} is `true`.
|
|
371
372
|
*
|
|
372
|
-
* A zero, negative or NaN value is invalid.
|
|
373
|
+
* A zero, negative or NaN value is invalid and will generate a {@link AddChainError}.
|
|
373
374
|
*
|
|
374
375
|
* If this value is not set, it means that there is no maximum.
|
|
375
376
|
*/
|
|
@@ -379,7 +380,7 @@ export interface AddChainOptions {
|
|
|
379
380
|
*
|
|
380
381
|
* This field is ignored if {@link AddChainOptions.disableJsonRpc} is `true`.
|
|
381
382
|
*
|
|
382
|
-
* A negative or NaN value is invalid.
|
|
383
|
+
* A negative or NaN value is invalid and will generate a {@link AddChainError}.
|
|
383
384
|
*
|
|
384
385
|
* If this value is not set, it means that there is no maximum.
|
|
385
386
|
*/
|