smoldot 2.0.6 → 2.0.8
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 -23
- package/dist/cjs/internals/client.js +4 -4
- package/dist/cjs/internals/local-instance.d.ts +2 -8
- package/dist/cjs/internals/local-instance.js +9 -19
- package/dist/cjs/internals/remote-instance.js +7 -7
- package/dist/cjs/no-auto-bytecode-browser.js +23 -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 -23
- package/dist/mjs/internals/client.js +4 -4
- package/dist/mjs/internals/local-instance.d.ts +2 -8
- package/dist/mjs/internals/local-instance.js +9 -19
- package/dist/mjs/internals/remote-instance.js +7 -7
- package/dist/mjs/no-auto-bytecode-browser.js +23 -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,19 +110,16 @@ 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
|
-
remoteTlsCertificateSha256: Uint8Array;
|
|
128
123
|
}) => void;
|
|
129
124
|
/**
|
|
130
125
|
* Callback called when the connection transitions to the `Reset` state.
|
|
@@ -137,7 +132,7 @@ export interface ConnectionConfig {
|
|
|
137
132
|
*
|
|
138
133
|
* This function must only be called for connections of type "multi-stream".
|
|
139
134
|
*/
|
|
140
|
-
onStreamOpened: (streamId: number, direction: 'inbound' | 'outbound'
|
|
135
|
+
onStreamOpened: (streamId: number, direction: 'inbound' | 'outbound') => void;
|
|
141
136
|
/**
|
|
142
137
|
* Callback called when a stream transitions to the `Reset` state.
|
|
143
138
|
*
|
|
@@ -151,14 +146,14 @@ export interface ConnectionConfig {
|
|
|
151
146
|
* written on the stream, meaning that some buffer space is now free.
|
|
152
147
|
*
|
|
153
148
|
* Can only happen while the connection is in the `Open` state.
|
|
154
|
-
*
|
|
155
149
|
* This callback must not be called after `closeSend` has been called.
|
|
156
150
|
*
|
|
151
|
+
* The total of writable bytes must not go beyond reasonable values (e.g. a few megabytes). It
|
|
152
|
+
* is not legal to provide a dummy implementation that simply passes an exceedingly large
|
|
153
|
+
* value.
|
|
154
|
+
*
|
|
157
155
|
* The `streamId` parameter must be provided if and only if the connection is of type
|
|
158
156
|
* "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
157
|
*/
|
|
163
158
|
onWritableBytes: (numExtra: number, streamId?: number) => void;
|
|
164
159
|
/**
|
|
@@ -138,15 +138,15 @@ function start(options, wasmModule, platformBindings) {
|
|
|
138
138
|
throw new Error();
|
|
139
139
|
state.instance.instance.streamMessage(connectionId, message, streamId);
|
|
140
140
|
},
|
|
141
|
-
onStreamOpened(streamId, direction
|
|
141
|
+
onStreamOpened(streamId, direction) {
|
|
142
142
|
if (state.instance.status !== "ready")
|
|
143
143
|
throw new Error();
|
|
144
|
-
state.instance.instance.streamOpened(connectionId, streamId, direction
|
|
144
|
+
state.instance.instance.streamOpened(connectionId, streamId, direction);
|
|
145
145
|
},
|
|
146
|
-
|
|
146
|
+
onMultistreamHandshakeInfo(info) {
|
|
147
147
|
if (state.instance.status !== "ready")
|
|
148
148
|
throw new Error();
|
|
149
|
-
state.instance.instance.
|
|
149
|
+
state.instance.instance.connectionMultiStreamSetHandshakeInfo(connectionId, info);
|
|
150
150
|
},
|
|
151
151
|
onWritableBytes(numExtra, streamId) {
|
|
152
152
|
if (state.instance.status !== "ready")
|
|
@@ -103,20 +103,14 @@ 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
|
-
remoteTlsCertificateSha256: Uint8Array;
|
|
115
109
|
}) => void;
|
|
116
110
|
connectionReset: (connectionId: number, message: string) => void;
|
|
117
111
|
streamWritableBytes: (connectionId: number, numExtra: number, streamId?: number) => void;
|
|
118
112
|
streamMessage: (connectionId: number, message: Uint8Array, streamId?: number) => void;
|
|
119
|
-
streamOpened: (connectionId: number, streamId: number, direction: 'inbound' | 'outbound'
|
|
113
|
+
streamOpened: (connectionId: number, streamId: number, direction: 'inbound' | 'outbound') => void;
|
|
120
114
|
streamReset: (connectionId: number, streamId: number) => void;
|
|
121
115
|
}
|
|
122
116
|
/**
|
|
@@ -404,25 +404,15 @@ function startLocalInstance(config, wasmModule, eventCallback) {
|
|
|
404
404
|
state.onShutdownExecutorOrWasmPanic = () => { };
|
|
405
405
|
cb();
|
|
406
406
|
},
|
|
407
|
-
|
|
407
|
+
connectionMultiStreamSetHandshakeInfo: (connectionId, info) => {
|
|
408
408
|
if (!state.instance)
|
|
409
409
|
return;
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
const handshakeTy = new Uint8Array(1 + info.localTlsCertificateSha256.length + info.remoteTlsCertificateSha256.length);
|
|
417
|
-
buffer.writeUInt8(handshakeTy, 0, 0);
|
|
418
|
-
handshakeTy.set(info.localTlsCertificateSha256, 1);
|
|
419
|
-
handshakeTy.set(info.remoteTlsCertificateSha256, 1 + info.localTlsCertificateSha256.length);
|
|
420
|
-
state.bufferIndices[0] = handshakeTy;
|
|
421
|
-
state.instance.exports.connection_open_multi_stream(connectionId, 0);
|
|
422
|
-
delete state.bufferIndices[0];
|
|
423
|
-
break;
|
|
424
|
-
}
|
|
425
|
-
}
|
|
410
|
+
const handshakeTy = new Uint8Array(1 + info.localTlsCertificateSha256.length);
|
|
411
|
+
buffer.writeUInt8(handshakeTy, 0, 0);
|
|
412
|
+
handshakeTy.set(info.localTlsCertificateSha256, 1);
|
|
413
|
+
state.bufferIndices[0] = handshakeTy;
|
|
414
|
+
state.instance.exports.connection_multi_stream_set_handshake_info(connectionId, 0);
|
|
415
|
+
delete state.bufferIndices[0];
|
|
426
416
|
},
|
|
427
417
|
connectionReset: (connectionId, message) => {
|
|
428
418
|
if (!state.instance)
|
|
@@ -443,10 +433,10 @@ function startLocalInstance(config, wasmModule, eventCallback) {
|
|
|
443
433
|
state.instance.exports.stream_message(connectionId, streamId || 0, 0);
|
|
444
434
|
delete state.bufferIndices[0];
|
|
445
435
|
},
|
|
446
|
-
streamOpened: (connectionId, streamId, direction
|
|
436
|
+
streamOpened: (connectionId, streamId, direction) => {
|
|
447
437
|
if (!state.instance)
|
|
448
438
|
return;
|
|
449
|
-
state.instance.exports.connection_stream_opened(connectionId, streamId, direction === 'outbound' ? 1 : 0
|
|
439
|
+
state.instance.exports.connection_stream_opened(connectionId, streamId, direction === 'outbound' ? 1 : 0);
|
|
450
440
|
},
|
|
451
441
|
streamReset: (connectionId, streamId) => {
|
|
452
442
|
if (!state.instance)
|
|
@@ -179,17 +179,17 @@ function connectToInstanceServer(config) {
|
|
|
179
179
|
const msg = { ty: "connection-reset", connectionId, message };
|
|
180
180
|
portToServer.postMessage(msg);
|
|
181
181
|
},
|
|
182
|
-
|
|
183
|
-
const msg = { ty: "connection-
|
|
182
|
+
connectionMultiStreamSetHandshakeInfo(connectionId, info) {
|
|
183
|
+
const msg = { ty: "connection-multistream-set-info", connectionId, info };
|
|
184
184
|
portToServer.postMessage(msg);
|
|
185
185
|
},
|
|
186
186
|
streamMessage(connectionId, message, streamId) {
|
|
187
187
|
const msg = { ty: "stream-message", connectionId, message, streamId };
|
|
188
188
|
portToServer.postMessage(msg);
|
|
189
189
|
},
|
|
190
|
-
streamOpened(connectionId, streamId, direction
|
|
190
|
+
streamOpened(connectionId, streamId, direction) {
|
|
191
191
|
state.connections.get(connectionId).add(streamId);
|
|
192
|
-
const msg = { ty: "stream-opened", connectionId, streamId, direction
|
|
192
|
+
const msg = { ty: "stream-opened", connectionId, streamId, direction };
|
|
193
193
|
portToServer.postMessage(msg);
|
|
194
194
|
},
|
|
195
195
|
streamWritableBytes(connectionId, numExtra, streamId) {
|
|
@@ -321,11 +321,11 @@ function startInstanceServer(config, initPortToClient) {
|
|
|
321
321
|
state.instance.connectionReset(message.connectionId, message.message);
|
|
322
322
|
break;
|
|
323
323
|
}
|
|
324
|
-
case "connection-
|
|
324
|
+
case "connection-multistream-set-info": {
|
|
325
325
|
// The connection might have been reset locally in the past.
|
|
326
326
|
if (!state.connections.has(message.connectionId))
|
|
327
327
|
return;
|
|
328
|
-
state.instance.
|
|
328
|
+
state.instance.connectionMultiStreamSetHandshakeInfo(message.connectionId, message.info);
|
|
329
329
|
break;
|
|
330
330
|
}
|
|
331
331
|
case "stream-message": {
|
|
@@ -343,7 +343,7 @@ function startInstanceServer(config, initPortToClient) {
|
|
|
343
343
|
if (!state.connections.has(message.connectionId))
|
|
344
344
|
return;
|
|
345
345
|
state.connections.get(message.connectionId).add(message.streamId);
|
|
346
|
-
state.instance.streamOpened(message.connectionId, message.streamId, message.direction
|
|
346
|
+
state.instance.streamOpened(message.connectionId, message.streamId, message.direction);
|
|
347
347
|
break;
|
|
348
348
|
}
|
|
349
349
|
case "stream-writable-bytes": {
|
|
@@ -58,7 +58,7 @@ exports.startWithBytecode = startWithBytecode;
|
|
|
58
58
|
* Tries to open a new connection using the given configuration.
|
|
59
59
|
*
|
|
60
60
|
* @see Connection
|
|
61
|
-
* @throws
|
|
61
|
+
* @throws any If the multiaddress couldn't be parsed or contains an invalid protocol.
|
|
62
62
|
*/
|
|
63
63
|
function connect(config) {
|
|
64
64
|
if (config.address.ty === "websocket") {
|
|
@@ -103,10 +103,7 @@ function connect(config) {
|
|
|
103
103
|
if (connection instanceof WebSocket) {
|
|
104
104
|
connection.binaryType = 'arraybuffer';
|
|
105
105
|
connection.onopen = () => {
|
|
106
|
-
config.
|
|
107
|
-
type: 'single-stream', handshake: 'multistream-select-noise-yamux',
|
|
108
|
-
initialWritableBytes: 1024 * 1024
|
|
109
|
-
});
|
|
106
|
+
config.onWritableBytes(1024 * 1024);
|
|
110
107
|
};
|
|
111
108
|
connection.onclose = (event) => {
|
|
112
109
|
const message = "Error code " + event.code + (!!event.reason ? (": " + event.reason) : "");
|
|
@@ -167,10 +164,6 @@ function connect(config) {
|
|
|
167
164
|
let pc = undefined;
|
|
168
165
|
// Contains the data channels that are open and have been reported to smoldot.
|
|
169
166
|
const dataChannels = new Map();
|
|
170
|
-
// For various reasons explained below, we open a data channel in advance without reporting it
|
|
171
|
-
// to smoldot. This data channel is stored in this variable. Once it is reported to smoldot,
|
|
172
|
-
// it is inserted in `dataChannels`.
|
|
173
|
-
let handshakeDataChannel;
|
|
174
167
|
// SHA256 hash of the DTLS certificate of the local node. Unknown as long as it hasn't been
|
|
175
168
|
// generated.
|
|
176
169
|
// TODO: could be merged with `pc` in one variable, and maybe even the other fields as well
|
|
@@ -182,7 +175,7 @@ function connect(config) {
|
|
|
182
175
|
// The `RTCPeerConnection` is created pretty quickly. It is however still possible for
|
|
183
176
|
// smoldot to cancel the opening, in which case `pc` will still be undefined.
|
|
184
177
|
if (!pc) {
|
|
185
|
-
console.assert(dataChannels.size === 0
|
|
178
|
+
console.assert(dataChannels.size === 0, "substreams exist while pc is undef");
|
|
186
179
|
pc = null;
|
|
187
180
|
return;
|
|
188
181
|
}
|
|
@@ -197,14 +190,6 @@ function connect(config) {
|
|
|
197
190
|
channel.channel.onmessage = null;
|
|
198
191
|
}
|
|
199
192
|
dataChannels.clear();
|
|
200
|
-
if (handshakeDataChannel) {
|
|
201
|
-
handshakeDataChannel.onopen = null;
|
|
202
|
-
handshakeDataChannel.onerror = null;
|
|
203
|
-
handshakeDataChannel.onclose = null;
|
|
204
|
-
handshakeDataChannel.onbufferedamountlow = null;
|
|
205
|
-
handshakeDataChannel.onmessage = null;
|
|
206
|
-
}
|
|
207
|
-
handshakeDataChannel = undefined;
|
|
208
193
|
pc.close(); // Not necessarily necessary, but it doesn't hurt to do so.
|
|
209
194
|
};
|
|
210
195
|
// Function that configures a newly-opened channel and adds it to the map. Used for both
|
|
@@ -212,54 +197,19 @@ function connect(config) {
|
|
|
212
197
|
const addChannel = (dataChannel, direction) => {
|
|
213
198
|
const dataChannelId = dataChannel.id;
|
|
214
199
|
dataChannel.binaryType = 'arraybuffer';
|
|
215
|
-
let isOpen = false;
|
|
200
|
+
let isOpen = { value: false };
|
|
216
201
|
dataChannel.onopen = () => {
|
|
217
|
-
console.assert(!isOpen, "substream opened twice");
|
|
218
|
-
isOpen = true;
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
console.assert(handshakeDataChannel === dataChannel, "handshake substream mismatch");
|
|
222
|
-
config.onOpen({
|
|
223
|
-
type: 'multi-stream',
|
|
224
|
-
handshake: 'webrtc',
|
|
225
|
-
// `addChannel` can never be called before the local certificate is generated, so this
|
|
226
|
-
// value is always defined.
|
|
227
|
-
localTlsCertificateSha256: localTlsCertificateSha256,
|
|
228
|
-
remoteTlsCertificateSha256,
|
|
229
|
-
});
|
|
230
|
-
}
|
|
231
|
-
else {
|
|
232
|
-
console.assert(direction !== 'outbound' || !handshakeDataChannel, "handshakeDataChannel still defined");
|
|
233
|
-
config.onStreamOpened(dataChannelId, direction, 65536);
|
|
234
|
-
}
|
|
202
|
+
console.assert(!isOpen.value, "substream opened twice");
|
|
203
|
+
isOpen.value = true;
|
|
204
|
+
config.onStreamOpened(dataChannelId, direction);
|
|
205
|
+
config.onWritableBytes(65536, dataChannelId);
|
|
235
206
|
};
|
|
236
207
|
dataChannel.onerror = dataChannel.onclose = (_error) => {
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
//
|
|
240
|
-
//
|
|
241
|
-
//
|
|
242
|
-
killAllJs();
|
|
243
|
-
// Note that the event doesn't give any additional reason for the failure.
|
|
244
|
-
config.onConnectionReset("handshake data channel failed to open");
|
|
245
|
-
}
|
|
246
|
-
else if (handshakeDataChannel === dataChannel) {
|
|
247
|
-
// The handshake data channel has been closed before we reported it to smoldot. This
|
|
248
|
-
// isn't really a problem. We just update the state and continue running. If smoldot
|
|
249
|
-
// requests a substream, another one will be opened. It could be a valid implementation
|
|
250
|
-
// to also just kill the entire connection, however doing so is a bit too intrusive and
|
|
251
|
-
// punches through abstraction layers.
|
|
252
|
-
handshakeDataChannel.onopen = null;
|
|
253
|
-
handshakeDataChannel.onerror = null;
|
|
254
|
-
handshakeDataChannel.onclose = null;
|
|
255
|
-
handshakeDataChannel.onbufferedamountlow = null;
|
|
256
|
-
handshakeDataChannel.onmessage = null;
|
|
257
|
-
handshakeDataChannel = undefined;
|
|
258
|
-
}
|
|
259
|
-
else if (!isOpen) {
|
|
260
|
-
// Substream wasn't opened yet and thus has failed to open. The API has no mechanism to
|
|
261
|
-
// report substream openings failures. We could try opening it again, but given that
|
|
262
|
-
// it's unlikely to succeed, we simply opt to kill the entire connection.
|
|
208
|
+
if (!isOpen.value) {
|
|
209
|
+
// Substream wasn't opened yet and thus has failed to open. The API has no
|
|
210
|
+
// mechanism to report substream openings failures. We could try opening it
|
|
211
|
+
// again, but given that it's unlikely to succeed, we simply opt to kill the
|
|
212
|
+
// entire connection.
|
|
263
213
|
killAllJs();
|
|
264
214
|
// Note that the event doesn't give any additional reason for the failure.
|
|
265
215
|
config.onConnectionReset("data channel failed to open");
|
|
@@ -279,10 +229,7 @@ function connect(config) {
|
|
|
279
229
|
// The `data` field is an `ArrayBuffer`.
|
|
280
230
|
config.onMessage(new Uint8Array(m.data), dataChannelId);
|
|
281
231
|
};
|
|
282
|
-
|
|
283
|
-
dataChannels.set(dataChannelId, { channel: dataChannel, bufferedBytes: 0 });
|
|
284
|
-
else
|
|
285
|
-
handshakeDataChannel = dataChannel;
|
|
232
|
+
dataChannels.set(dataChannelId, { channel: dataChannel, bufferedBytes: 0 });
|
|
286
233
|
};
|
|
287
234
|
// It is possible for the browser to use multiple different certificates.
|
|
288
235
|
// In order for our local certificate to be deterministic, we need to generate it manually and
|
|
@@ -432,16 +379,10 @@ function connect(config) {
|
|
|
432
379
|
// TODO: is the substream maybe already open? according to the Internet it seems that no but it's unclear
|
|
433
380
|
addChannel(channel, 'inbound');
|
|
434
381
|
};
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
// the connection is open, smoldot will open a substream in order to perform the handshake.
|
|
440
|
-
// Instead of following this API, we open this substream in advance, and will notify smoldot
|
|
441
|
-
// that the connection is open when the substream is open.
|
|
442
|
-
// Note that the label passed to `createDataChannel` is required to be empty as per the
|
|
443
|
-
// libp2p WebRTC specification.
|
|
444
|
-
addChannel(pc.createDataChannel("", { id: 0, negotiated: true }), 'first-outbound');
|
|
382
|
+
config.onMultistreamHandshakeInfo({
|
|
383
|
+
handshake: 'webrtc',
|
|
384
|
+
localTlsCertificateSha256,
|
|
385
|
+
});
|
|
445
386
|
}));
|
|
446
387
|
return {
|
|
447
388
|
reset: (streamId) => {
|
|
@@ -467,27 +408,11 @@ function connect(config) {
|
|
|
467
408
|
},
|
|
468
409
|
closeSend: () => { throw new Error('Wrong connection type'); },
|
|
469
410
|
openOutSubstream: () => {
|
|
470
|
-
// `openOutSubstream` can only be called after we have called `config.onOpen`,
|
|
471
|
-
// `pc` is guaranteed to be non-null.
|
|
472
|
-
//
|
|
473
|
-
//
|
|
474
|
-
|
|
475
|
-
// Do this asynchronously because calling callbacks within callbacks is error-prone.
|
|
476
|
-
(() => __awaiter(this, void 0, void 0, function* () {
|
|
477
|
-
// We need to check again if `handshakeDataChannel` is still defined, as the
|
|
478
|
-
// connection might have been closed.
|
|
479
|
-
if (handshakeDataChannel) {
|
|
480
|
-
config.onStreamOpened(handshakeDataChannel.id, 'outbound', 1024 * 1024);
|
|
481
|
-
dataChannels.set(handshakeDataChannel.id, { channel: handshakeDataChannel, bufferedBytes: 0 });
|
|
482
|
-
handshakeDataChannel = undefined;
|
|
483
|
-
}
|
|
484
|
-
}))();
|
|
485
|
-
}
|
|
486
|
-
else {
|
|
487
|
-
// Note that the label passed to `createDataChannel` is required to be empty as per the
|
|
488
|
-
// libp2p WebRTC specification.
|
|
489
|
-
addChannel(pc.createDataChannel(""), 'outbound');
|
|
490
|
-
}
|
|
411
|
+
// `openOutSubstream` can only be called after we have called `config.onOpen`,
|
|
412
|
+
// therefore `pc` is guaranteed to be non-null.
|
|
413
|
+
// Note that the label passed to `createDataChannel` is required to be empty as
|
|
414
|
+
// per the libp2p WebRTC specification.
|
|
415
|
+
addChannel(pc.createDataChannel(""), 'outbound');
|
|
491
416
|
}
|
|
492
417
|
};
|
|
493
418
|
}
|
|
@@ -79,7 +79,7 @@ function connect(config) {
|
|
|
79
79
|
config.onWritableBytes(wasSent);
|
|
80
80
|
};
|
|
81
81
|
socket.onopen = () => {
|
|
82
|
-
config.
|
|
82
|
+
config.onWritableBytes(1024 * 1024);
|
|
83
83
|
};
|
|
84
84
|
socket.onclose = (event) => {
|
|
85
85
|
const message = "Error code " + event.code + (!!event.reason ? (": " + event.reason) : "");
|
|
@@ -134,7 +134,7 @@ function connect(config) {
|
|
|
134
134
|
if (socket.destroyed)
|
|
135
135
|
return established;
|
|
136
136
|
established === null || established === void 0 ? void 0 : established.setNoDelay();
|
|
137
|
-
config.
|
|
137
|
+
config.onWritableBytes(1024 * 1024);
|
|
138
138
|
// Spawns an asynchronous task that continuously reads from the socket.
|
|
139
139
|
// Every time data is read, the task re-executes itself in order to continue reading.
|
|
140
140
|
// The task ends automatically if an EOF or error is detected, which should also happen
|
|
@@ -75,7 +75,7 @@ function connect(config) {
|
|
|
75
75
|
config.onWritableBytes(wasSent);
|
|
76
76
|
};
|
|
77
77
|
socket.onopen = () => {
|
|
78
|
-
config.
|
|
78
|
+
config.onWritableBytes(1024 * 1024);
|
|
79
79
|
};
|
|
80
80
|
socket.onclose = (event) => {
|
|
81
81
|
const message = "Error code " + event.code + (!!event.reason ? (": " + event.reason) : "");
|
|
@@ -128,10 +128,7 @@ function connect(config) {
|
|
|
128
128
|
socket.on('connect', () => {
|
|
129
129
|
if (socket.destroyed)
|
|
130
130
|
return;
|
|
131
|
-
config.
|
|
132
|
-
type: 'single-stream', handshake: 'multistream-select-noise-yamux',
|
|
133
|
-
initialWritableBytes: socket.writableHighWaterMark
|
|
134
|
-
});
|
|
131
|
+
config.onWritableBytes(socket.writableHighWaterMark);
|
|
135
132
|
});
|
|
136
133
|
socket.on('close', (hasError) => {
|
|
137
134
|
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
|
*/
|