smoldot 1.0.8 → 1.0.9

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.
@@ -272,8 +272,26 @@ export function start(options, wasmModule, platformBindings) {
272
272
  potentialRelayChainsIds.push(id);
273
273
  }
274
274
  }
275
+ // Sanitize `jsonRpcMaxPendingRequests`.
276
+ let jsonRpcMaxPendingRequests = options.jsonRpcMaxPendingRequests === undefined ? Infinity : options.jsonRpcMaxPendingRequests;
277
+ jsonRpcMaxPendingRequests = Math.floor(jsonRpcMaxPendingRequests);
278
+ if (jsonRpcMaxPendingRequests <= 0 || isNaN(jsonRpcMaxPendingRequests)) {
279
+ throw new AddChainError("Invalid value for `jsonRpcMaxPendingRequests`");
280
+ }
281
+ if (jsonRpcMaxPendingRequests > 0xffffffff) {
282
+ jsonRpcMaxPendingRequests = 0xffffffff;
283
+ }
284
+ // Sanitize `jsonRpcMaxSubscriptions`.
285
+ let jsonRpcMaxSubscriptions = options.jsonRpcMaxSubscriptions === undefined ? Infinity : options.jsonRpcMaxSubscriptions;
286
+ jsonRpcMaxSubscriptions = Math.floor(jsonRpcMaxSubscriptions);
287
+ if (jsonRpcMaxSubscriptions < 0 || isNaN(jsonRpcMaxSubscriptions)) {
288
+ throw new AddChainError("Invalid value for `jsonRpcMaxSubscriptions`");
289
+ }
290
+ if (jsonRpcMaxSubscriptions > 0xffffffff) {
291
+ jsonRpcMaxSubscriptions = 0xffffffff;
292
+ }
275
293
  const promise = new Promise((resolve) => state.addChainResults.push(resolve));
276
- state.instance.instance.addChain(options.chainSpec, typeof options.databaseContent === 'string' ? options.databaseContent : "", potentialRelayChainsIds, !!options.disableJsonRpc);
294
+ state.instance.instance.addChain(options.chainSpec, typeof options.databaseContent === 'string' ? options.databaseContent : "", potentialRelayChainsIds, !!options.disableJsonRpc, jsonRpcMaxPendingRequests, jsonRpcMaxSubscriptions);
277
295
  const outcome = yield promise;
278
296
  if (!outcome.success)
279
297
  throw new AddChainError(outcome.error);
@@ -94,7 +94,7 @@ export type ParsedMultiaddr = {
94
94
  export interface Instance {
95
95
  request: (request: string, chainId: number) => number;
96
96
  peekJsonRpcResponse: (chainId: number) => string | null;
97
- addChain: (chainSpec: string, databaseContent: string, potentialRelayChains: number[], disableJsonRpc: boolean) => void;
97
+ addChain: (chainSpec: string, databaseContent: string, potentialRelayChains: number[], disableJsonRpc: boolean, jsonRpcMaxPendingRequests: number, jsonRpcMaxSubscriptions: number) => void;
98
98
  removeChain: (chainId: number) => void;
99
99
  /**
100
100
  * Notifies the background executor that it should stop. Once it has effectively stopped,
@@ -420,11 +420,13 @@ export function startLocalInstance(config, wasmModule, eventCallback) {
420
420
  return null;
421
421
  }
422
422
  },
423
- addChain: (chainSpec, databaseContent, potentialRelayChains, disableJsonRpc) => {
423
+ addChain: (chainSpec, databaseContent, potentialRelayChains, disableJsonRpc, jsonRpcMaxPendingRequests, jsonRpcMaxSubscriptions) => {
424
424
  if (!state.instance) {
425
425
  eventCallback({ ty: "add-chain-result", success: false, error: "Smoldot has crashed" });
426
426
  return;
427
427
  }
428
+ // The caller is supposed to avoid this situation.
429
+ console.assert(disableJsonRpc || jsonRpcMaxPendingRequests != 0, "invalid jsonRpcMaxPendingRequests value passed to local-instance::addChain");
428
430
  // `add_chain` unconditionally allocates a chain id. If an error occurs, however, this chain
429
431
  // id will refer to an *erroneous* chain. `chain_is_ok` is used below to determine whether it
430
432
  // has succeeeded or not.
@@ -435,7 +437,7 @@ export function startLocalInstance(config, wasmModule, eventCallback) {
435
437
  buffer.writeUInt32LE(potentialRelayChainsEncoded, idx * 4, potentialRelayChains[idx]);
436
438
  }
437
439
  state.bufferIndices[2] = potentialRelayChainsEncoded;
438
- const chainId = state.instance.exports.add_chain(0, 1, disableJsonRpc ? 0 : 1, 2);
440
+ const chainId = state.instance.exports.add_chain(0, 1, disableJsonRpc ? 0 : jsonRpcMaxPendingRequests, jsonRpcMaxSubscriptions, 2);
439
441
  delete state.bufferIndices[0];
440
442
  delete state.bufferIndices[1];
441
443
  delete state.bufferIndices[2];
@@ -143,9 +143,9 @@ export function connectToInstanceServer(config) {
143
143
  config.eventCallback(message);
144
144
  };
145
145
  return {
146
- addChain(chainSpec, databaseContent, potentialRelayChains, disableJsonRpc) {
146
+ addChain(chainSpec, databaseContent, potentialRelayChains, disableJsonRpc, jsonRpcMaxPendingRequests, jsonRpcMaxSubscriptions) {
147
147
  return __awaiter(this, void 0, void 0, function* () {
148
- const msg = { ty: "add-chain", chainSpec, databaseContent, potentialRelayChains, disableJsonRpc };
148
+ const msg = { ty: "add-chain", chainSpec, databaseContent, potentialRelayChains, disableJsonRpc, jsonRpcMaxPendingRequests, jsonRpcMaxSubscriptions };
149
149
  portToServer.postMessage(msg);
150
150
  });
151
151
  },
@@ -282,7 +282,7 @@ export function startInstanceServer(config, initPortToClient) {
282
282
  const message = messageEvent.data;
283
283
  switch (message.ty) {
284
284
  case "add-chain": {
285
- state.instance.addChain(message.chainSpec, message.databaseContent, message.potentialRelayChains, message.disableJsonRpc);
285
+ state.instance.addChain(message.chainSpec, message.databaseContent, message.potentialRelayChains, message.disableJsonRpc, message.jsonRpcMaxPendingRequests, message.jsonRpcMaxSubscriptions);
286
286
  break;
287
287
  }
288
288
  case "remove-chain": {
@@ -122,10 +122,9 @@ function connect(config) {
122
122
  })
123
123
  };
124
124
  socket.inner = socket.inner.then((established) => {
125
- // TODO: at the time of writing of this comment, `setNoDelay` is still unstable
126
- //established.setNoDelay();
127
125
  if (socket.destroyed)
128
126
  return established;
127
+ established === null || established === void 0 ? void 0 : established.setNoDelay();
129
128
  config.onOpen({ type: 'single-stream', handshake: 'multistream-select-noise-yamux', initialWritableBytes: 1024 * 1024, writeClosable: true });
130
129
  // Spawns an asynchronous task that continuously reads from the socket.
131
130
  // Every time data is read, the task re-executes itself in order to continue reading.
@@ -365,4 +365,25 @@ export interface AddChainOptions {
365
365
  * this chain.
366
366
  */
367
367
  disableJsonRpc?: boolean;
368
+ /**
369
+ * Maximum number of JSON-RPC requests that haven't been answered yet. Any further request will
370
+ * be rejected.
371
+ *
372
+ * This field is ignored if {@link AddChainOptions.disableJsonRpc} is `true`.
373
+ *
374
+ * A zero, negative or NaN value is invalid.
375
+ *
376
+ * If this value is not set, it means that there is no maximum.
377
+ */
378
+ jsonRpcMaxPendingRequests?: number;
379
+ /**
380
+ * Maximum number of active JSON-RPC subscriptions. Any further subscription will be rejected.
381
+ *
382
+ * This field is ignored if {@link AddChainOptions.disableJsonRpc} is `true`.
383
+ *
384
+ * A negative or NaN value is invalid.
385
+ *
386
+ * If this value is not set, it means that there is no maximum.
387
+ */
388
+ jsonRpcMaxSubscriptions?: number;
368
389
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "smoldot",
3
- "version": "1.0.8",
3
+ "version": "1.0.9",
4
4
  "description": "Light client that connects to Polkadot and Substrate-based blockchains",
5
5
  "author": "Parity Technologies <admin@parity.io>",
6
6
  "license": "GPL-3.0-or-later WITH Classpath-exception-2.0",