smoldot 1.0.1 → 1.0.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/client.js +13 -13
- package/dist/cjs/instance/autogen/wasm0.js +1 -1
- package/dist/cjs/instance/autogen/wasm1.js +1 -1
- package/dist/cjs/instance/autogen/wasm2.js +1 -1
- package/dist/cjs/instance/bindings-smoldot-light.d.ts +10 -4
- package/dist/cjs/instance/bindings-smoldot-light.js +28 -26
- package/dist/cjs/instance/bindings-wasi.d.ts +4 -0
- package/dist/cjs/instance/bindings-wasi.js +30 -0
- package/dist/cjs/instance/bindings.d.ts +5 -6
- package/dist/cjs/instance/buffer.d.ts +1 -0
- package/dist/cjs/instance/buffer.js +13 -1
- package/dist/cjs/instance/instance.js +19 -25
- package/dist/cjs/instance/raw-instance.d.ts +1 -1
- package/dist/cjs/instance/raw-instance.js +4 -2
- package/dist/mjs/client.js +13 -13
- package/dist/mjs/instance/autogen/wasm0.js +1 -1
- package/dist/mjs/instance/autogen/wasm1.js +1 -1
- package/dist/mjs/instance/autogen/wasm2.js +1 -1
- package/dist/mjs/instance/bindings-smoldot-light.d.ts +10 -4
- package/dist/mjs/instance/bindings-smoldot-light.js +28 -26
- package/dist/mjs/instance/bindings-wasi.d.ts +4 -0
- package/dist/mjs/instance/bindings-wasi.js +30 -0
- package/dist/mjs/instance/bindings.d.ts +5 -6
- package/dist/mjs/instance/buffer.d.ts +1 -0
- package/dist/mjs/instance/buffer.js +11 -0
- package/dist/mjs/instance/instance.js +19 -25
- package/dist/mjs/instance/raw-instance.d.ts +1 -1
- package/dist/mjs/instance/raw-instance.js +4 -2
- package/package.json +3 -3
|
@@ -2,9 +2,11 @@ import type { SmoldotWasmInstance } from './bindings.js';
|
|
|
2
2
|
export interface Config {
|
|
3
3
|
instance?: SmoldotWasmInstance;
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
5
|
+
* Array used to store the buffers provided to the Rust code.
|
|
6
|
+
*
|
|
7
|
+
* When `buffer_size` or `buffer_index` are called, the buffer is found here.
|
|
6
8
|
*/
|
|
7
|
-
|
|
9
|
+
bufferIndices: Array<Uint8Array>;
|
|
8
10
|
/**
|
|
9
11
|
* Tries to open a new connection using the given configuration.
|
|
10
12
|
*
|
|
@@ -65,7 +67,7 @@ export interface Connection {
|
|
|
65
67
|
*
|
|
66
68
|
* The connection and stream must currently be in the `Open` state.
|
|
67
69
|
*
|
|
68
|
-
* The number of bytes
|
|
70
|
+
* The number of bytes must never exceed the number of "writable bytes" of the stream.
|
|
69
71
|
* `onWritableBytes` can be used in order to notify that more writable bytes are available.
|
|
70
72
|
*
|
|
71
73
|
* The `streamId` must be provided if and only if the connection is of type "multi-stream".
|
|
@@ -154,7 +156,8 @@ export interface ConnectionConfig {
|
|
|
154
156
|
*/
|
|
155
157
|
onStreamReset: (streamId: number) => void;
|
|
156
158
|
/**
|
|
157
|
-
* Callback called when
|
|
159
|
+
* Callback called when some data sent using {@link Connection.send} has effectively been
|
|
160
|
+
* written on the stream, meaning that some buffer space is now free.
|
|
158
161
|
*
|
|
159
162
|
* Can only happen while the connection is in the `Open` state.
|
|
160
163
|
*
|
|
@@ -162,6 +165,9 @@ export interface ConnectionConfig {
|
|
|
162
165
|
*
|
|
163
166
|
* The `streamId` parameter must be provided if and only if the connection is of type
|
|
164
167
|
* "multi-stream".
|
|
168
|
+
*
|
|
169
|
+
* Only a number of bytes equal to the size of the data provided to {@link Connection.send}
|
|
170
|
+
* must be reported. In other words, the `initialWritableBytes` must never be exceeded.
|
|
165
171
|
*/
|
|
166
172
|
onWritableBytes: (numExtra: number, streamId?: number) => void;
|
|
167
173
|
/**
|
|
@@ -55,6 +55,16 @@ function default_1(config) {
|
|
|
55
55
|
const message = buffer.utf8BytesToString(new Uint8Array(instance.exports.memory.buffer), ptr, len);
|
|
56
56
|
config.onPanic(message);
|
|
57
57
|
},
|
|
58
|
+
buffer_size: (bufferIndex) => {
|
|
59
|
+
const buf = config.bufferIndices[bufferIndex];
|
|
60
|
+
return buf.byteLength;
|
|
61
|
+
},
|
|
62
|
+
buffer_copy: (bufferIndex, targetPtr) => {
|
|
63
|
+
const instance = config.instance;
|
|
64
|
+
targetPtr = targetPtr >>> 0;
|
|
65
|
+
const buf = config.bufferIndices[bufferIndex];
|
|
66
|
+
new Uint8Array(instance.exports.memory.buffer).set(buf, targetPtr);
|
|
67
|
+
},
|
|
58
68
|
// Used by the Rust side to notify that a JSON-RPC response or subscription notification
|
|
59
69
|
// is available in the queue of JSON-RPC responses.
|
|
60
70
|
json_rpc_responses_non_empty: (chainId) => {
|
|
@@ -79,10 +89,6 @@ function default_1(config) {
|
|
|
79
89
|
config.logCallback(level, target, message);
|
|
80
90
|
}
|
|
81
91
|
},
|
|
82
|
-
// Must return the UNIX time in milliseconds.
|
|
83
|
-
unix_time_ms: () => Date.now(),
|
|
84
|
-
// Must return the value of a monotonic clock in milliseconds.
|
|
85
|
-
monotonic_clock_ms: () => config.performanceNow(),
|
|
86
92
|
// Must call `timer_finished` after the given number of milliseconds has elapsed.
|
|
87
93
|
start_timer: (id, ms) => {
|
|
88
94
|
if (killedTracked.killed)
|
|
@@ -120,11 +126,11 @@ function default_1(config) {
|
|
|
120
126
|
},
|
|
121
127
|
// Must create a new connection object. This implementation stores the created object in
|
|
122
128
|
// `connections`.
|
|
123
|
-
connection_new: (connectionId, addrPtr, addrLen,
|
|
129
|
+
connection_new: (connectionId, addrPtr, addrLen, errorBufferIndexPtr) => {
|
|
124
130
|
const instance = config.instance;
|
|
125
131
|
addrPtr >>>= 0;
|
|
126
132
|
addrLen >>>= 0;
|
|
127
|
-
|
|
133
|
+
errorBufferIndexPtr >>>= 0;
|
|
128
134
|
if (!!connections[connectionId]) {
|
|
129
135
|
throw new Error("internal error: connection already allocated");
|
|
130
136
|
}
|
|
@@ -144,13 +150,13 @@ function default_1(config) {
|
|
|
144
150
|
break;
|
|
145
151
|
}
|
|
146
152
|
case 'multi-stream': {
|
|
147
|
-
const
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
153
|
+
const handshakeTy = new Uint8Array(1 + info.localTlsCertificateMultihash.length + info.remoteTlsCertificateMultihash.length);
|
|
154
|
+
buffer.writeUInt8(handshakeTy, 0, 0);
|
|
155
|
+
handshakeTy.set(info.localTlsCertificateMultihash, 1);
|
|
156
|
+
handshakeTy.set(info.remoteTlsCertificateMultihash, 1 + info.localTlsCertificateMultihash.length);
|
|
157
|
+
config.bufferIndices[0] = handshakeTy;
|
|
158
|
+
instance.exports.connection_open_multi_stream(connectionId, 0);
|
|
159
|
+
delete config.bufferIndices[0];
|
|
154
160
|
break;
|
|
155
161
|
}
|
|
156
162
|
}
|
|
@@ -161,10 +167,9 @@ function default_1(config) {
|
|
|
161
167
|
if (killedTracked.killed)
|
|
162
168
|
return;
|
|
163
169
|
try {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
instance.exports.connection_reset(connectionId, ptr, encoded.length);
|
|
170
|
+
config.bufferIndices[0] = new TextEncoder().encode(message);
|
|
171
|
+
instance.exports.connection_reset(connectionId, 0);
|
|
172
|
+
delete config.bufferIndices[0];
|
|
168
173
|
}
|
|
169
174
|
catch (_error) { }
|
|
170
175
|
},
|
|
@@ -180,9 +185,9 @@ function default_1(config) {
|
|
|
180
185
|
if (killedTracked.killed)
|
|
181
186
|
return;
|
|
182
187
|
try {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
188
|
+
config.bufferIndices[0] = message;
|
|
189
|
+
instance.exports.stream_message(connectionId, streamId || 0, 0);
|
|
190
|
+
delete config.bufferIndices[0];
|
|
186
191
|
}
|
|
187
192
|
catch (_error) { }
|
|
188
193
|
},
|
|
@@ -213,12 +218,9 @@ function default_1(config) {
|
|
|
213
218
|
errorStr = error.toString();
|
|
214
219
|
}
|
|
215
220
|
const mem = new Uint8Array(instance.exports.memory.buffer);
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
buffer.writeUInt32LE(mem, errorPtrPtr, ptr);
|
|
220
|
-
buffer.writeUInt32LE(mem, errorPtrPtr + 4, encoded.length);
|
|
221
|
-
buffer.writeUInt8(mem, errorPtrPtr + 8, isBadAddress ? 1 : 0);
|
|
221
|
+
config.bufferIndices[0] = new TextEncoder().encode(errorStr);
|
|
222
|
+
buffer.writeUInt32LE(mem, errorBufferIndexPtr, 0);
|
|
223
|
+
buffer.writeUInt8(mem, errorBufferIndexPtr + 4, isBadAddress ? 1 : 0);
|
|
222
224
|
return 1;
|
|
223
225
|
}
|
|
224
226
|
},
|
|
@@ -5,6 +5,10 @@ export interface Config {
|
|
|
5
5
|
* Fills the given buffer with randomly-generated bytes.
|
|
6
6
|
*/
|
|
7
7
|
getRandomValues: (buffer: Uint8Array) => void;
|
|
8
|
+
/**
|
|
9
|
+
* Returns the number of milliseconds since an arbitrary epoch.
|
|
10
|
+
*/
|
|
11
|
+
performanceNow: () => number;
|
|
8
12
|
/**
|
|
9
13
|
* List of environment variables to feed to the Rust program. An array of strings.
|
|
10
14
|
* Example: `["RUST_BACKTRACE=1", "RUST_LOG=foo"];`
|
|
@@ -41,6 +41,36 @@ exports.default = (config) => {
|
|
|
41
41
|
}
|
|
42
42
|
return 0;
|
|
43
43
|
},
|
|
44
|
+
clock_time_get: (clockId, _precision, outPtr) => {
|
|
45
|
+
// See <https://github.com/rust-lang/rust/blob/master/library/std/src/sys/wasi/time.rs>
|
|
46
|
+
// and <docs.rs/wasi/> for help.
|
|
47
|
+
const instance = config.instance;
|
|
48
|
+
const mem = new Uint8Array(instance.exports.memory.buffer);
|
|
49
|
+
outPtr >>>= 0;
|
|
50
|
+
// We ignore the precision, as it can't be implemented anyway.
|
|
51
|
+
switch (clockId) {
|
|
52
|
+
case 0: {
|
|
53
|
+
// Realtime clock.
|
|
54
|
+
const now = BigInt(Math.floor(Date.now())) * BigInt(1000000);
|
|
55
|
+
buffer.writeUInt64LE(mem, outPtr, now);
|
|
56
|
+
// Success.
|
|
57
|
+
return 0;
|
|
58
|
+
}
|
|
59
|
+
case 1: {
|
|
60
|
+
// Monotonic clock.
|
|
61
|
+
const nowMs = config.performanceNow();
|
|
62
|
+
const nowMsInt = Math.floor(nowMs);
|
|
63
|
+
const now = BigInt(nowMsInt) * BigInt(1000000) +
|
|
64
|
+
BigInt(Math.floor(((nowMs - nowMsInt) * 1000000)));
|
|
65
|
+
buffer.writeUInt64LE(mem, outPtr, now);
|
|
66
|
+
// Success.
|
|
67
|
+
return 0;
|
|
68
|
+
}
|
|
69
|
+
default:
|
|
70
|
+
// Return an `EINVAL` error.
|
|
71
|
+
return 28;
|
|
72
|
+
}
|
|
73
|
+
},
|
|
44
74
|
// Writing to a file descriptor is used in order to write to stdout/stderr.
|
|
45
75
|
fd_write: (fd, addr, num, outPtr) => {
|
|
46
76
|
const instance = config.instance;
|
|
@@ -9,22 +9,21 @@ export interface SmoldotWasmExports extends WebAssembly.Exports {
|
|
|
9
9
|
init: (maxLogLevel: number, enableCurrentTask: number, cpuRateLimit: number, periodicallyYield: number) => void;
|
|
10
10
|
set_periodically_yield: (periodicallyYield: number) => void;
|
|
11
11
|
start_shutdown: () => void;
|
|
12
|
-
|
|
13
|
-
add_chain: (chainSpecPointer: number, chainSpecLen: number, databaseContentPointer: number, databaseContentLen: number, jsonRpcRunning: number, potentialRelayChainsPtr: number, potentialRelayChainsLen: number) => number;
|
|
12
|
+
add_chain: (chainSpecBufferIndex: number, databaseContentBufferIndex: number, jsonRpcRunning: number, potentialRelayChainsBufferIndex: number) => number;
|
|
14
13
|
remove_chain: (chainId: number) => void;
|
|
15
14
|
chain_is_ok: (chainId: number) => number;
|
|
16
15
|
chain_error_len: (chainId: number) => number;
|
|
17
16
|
chain_error_ptr: (chainId: number) => number;
|
|
18
|
-
json_rpc_send: (
|
|
17
|
+
json_rpc_send: (textBufferIndex: number, chainId: number) => number;
|
|
19
18
|
json_rpc_responses_peek: (chainId: number) => number;
|
|
20
19
|
json_rpc_responses_pop: (chainId: number) => void;
|
|
21
20
|
timer_finished: (timerId: number) => void;
|
|
22
21
|
connection_open_single_stream: (connectionId: number, handshakeTy: number, initialWritableBytes: number, writeClosable: number) => void;
|
|
23
|
-
connection_open_multi_stream: (connectionId: number,
|
|
22
|
+
connection_open_multi_stream: (connectionId: number, handshakeTyBufferIndex: number) => void;
|
|
24
23
|
stream_writable_bytes: (connectionId: number, streamId: number, numBytes: number) => void;
|
|
25
|
-
stream_message: (connectionId: number, streamId: number,
|
|
24
|
+
stream_message: (connectionId: number, streamId: number, bufferIndex: number) => void;
|
|
26
25
|
connection_stream_opened: (connectionId: number, streamId: number, outbound: number, initialWritableBytes: number) => void;
|
|
27
|
-
connection_reset: (connectionId: number,
|
|
26
|
+
connection_reset: (connectionId: number, bufferIndex: number) => void;
|
|
28
27
|
stream_reset: (connectionId: number, streamId: number) => void;
|
|
29
28
|
}
|
|
30
29
|
export interface SmoldotWasmInstance extends WebAssembly.Instance {
|
|
@@ -8,3 +8,4 @@ export declare function readUInt32LE(buffer: Uint8Array, offset: number): number
|
|
|
8
8
|
*/
|
|
9
9
|
export declare function writeUInt8(buffer: Uint8Array, offset: number, value: number): void;
|
|
10
10
|
export declare function writeUInt32LE(buffer: Uint8Array, offset: number, value: number): void;
|
|
11
|
+
export declare function writeUInt64LE(buffer: Uint8Array, offset: number, value: bigint): void;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// Copyright (C) 2019-2022 Parity Technologies (UK) Ltd.
|
|
4
4
|
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.writeUInt32LE = exports.writeUInt8 = exports.readUInt32LE = exports.utf8BytesToString = void 0;
|
|
6
|
+
exports.writeUInt64LE = exports.writeUInt32LE = exports.writeUInt8 = exports.readUInt32LE = exports.utf8BytesToString = void 0;
|
|
7
7
|
// This program is free software: you can redistribute it and/or modify
|
|
8
8
|
// it under the terms of the GNU General Public License as published by
|
|
9
9
|
// the Free Software Foundation, either version 3 of the License, or
|
|
@@ -45,6 +45,18 @@ function writeUInt32LE(buffer, offset, value) {
|
|
|
45
45
|
buffer[offset] = value & 0xff;
|
|
46
46
|
}
|
|
47
47
|
exports.writeUInt32LE = writeUInt32LE;
|
|
48
|
+
function writeUInt64LE(buffer, offset, value) {
|
|
49
|
+
checkRange(buffer, offset, 8);
|
|
50
|
+
buffer[offset + 7] = Number((value >> BigInt(56)) & BigInt(0xff));
|
|
51
|
+
buffer[offset + 6] = Number((value >> BigInt(48)) & BigInt(0xff));
|
|
52
|
+
buffer[offset + 5] = Number((value >> BigInt(40)) & BigInt(0xff));
|
|
53
|
+
buffer[offset + 4] = Number((value >> BigInt(32)) & BigInt(0xff));
|
|
54
|
+
buffer[offset + 3] = Number((value >> BigInt(24)) & BigInt(0xff));
|
|
55
|
+
buffer[offset + 2] = Number((value >> BigInt(16)) & BigInt(0xff));
|
|
56
|
+
buffer[offset + 1] = Number((value >> BigInt(8)) & BigInt(0xff));
|
|
57
|
+
buffer[offset] = Number(value & BigInt(0xff));
|
|
58
|
+
}
|
|
59
|
+
exports.writeUInt64LE = writeUInt64LE;
|
|
48
60
|
function checkRange(buffer, offset, length) {
|
|
49
61
|
if (!Number.isInteger(offset) || offset < 0)
|
|
50
62
|
throw new RangeError();
|
|
@@ -104,7 +104,7 @@ function start(configMessage, platformBindings) {
|
|
|
104
104
|
cpuRateLimit: configMessage.cpuRateLimit,
|
|
105
105
|
};
|
|
106
106
|
state = {
|
|
107
|
-
initialized: false, promise: instance.startInstance(config, platformBindings).then((instance) => {
|
|
107
|
+
initialized: false, promise: instance.startInstance(config, platformBindings).then(([instance, bufferIndices]) => {
|
|
108
108
|
// `config.cpuRateLimit` is a floating point that should be between 0 and 1, while the value
|
|
109
109
|
// to pass as parameter must be between `0` and `2^32-1`.
|
|
110
110
|
// The few lines of code below should handle all possible values of `number`, including
|
|
@@ -127,8 +127,8 @@ function start(configMessage, platformBindings) {
|
|
|
127
127
|
}
|
|
128
128
|
});
|
|
129
129
|
instance.exports.init(configMessage.maxLogLevel, configMessage.enableCurrentTask ? 1 : 0, cpuRateLimit, periodicallyYield ? 1 : 0);
|
|
130
|
-
state = { initialized: true, instance, unregisterCallback };
|
|
131
|
-
return instance;
|
|
130
|
+
state = { initialized: true, instance, bufferIndices, unregisterCallback };
|
|
131
|
+
return [instance, bufferIndices];
|
|
132
132
|
})
|
|
133
133
|
};
|
|
134
134
|
function queueOperation(operation) {
|
|
@@ -138,11 +138,11 @@ function start(configMessage, platformBindings) {
|
|
|
138
138
|
if (!state.initialized) {
|
|
139
139
|
// A message has been received while the Wasm VM is still initializing. Queue it for when
|
|
140
140
|
// initialization is over.
|
|
141
|
-
return state.promise.then((instance) => operation(instance));
|
|
141
|
+
return state.promise.then(([instance, bufferIndices]) => operation(instance, bufferIndices));
|
|
142
142
|
}
|
|
143
143
|
else {
|
|
144
144
|
// Everything is already initialized. Process the message synchronously.
|
|
145
|
-
return operation(state.instance);
|
|
145
|
+
return operation(state.instance, state.bufferIndices);
|
|
146
146
|
}
|
|
147
147
|
});
|
|
148
148
|
}
|
|
@@ -157,10 +157,8 @@ function start(configMessage, platformBindings) {
|
|
|
157
157
|
throw crashError.error;
|
|
158
158
|
let retVal;
|
|
159
159
|
try {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
new Uint8Array(state.instance.exports.memory.buffer).set(encoded, ptr);
|
|
163
|
-
retVal = state.instance.exports.json_rpc_send(ptr, encoded.length, chainId) >>> 0;
|
|
160
|
+
state.bufferIndices[0] = new TextEncoder().encode(request);
|
|
161
|
+
retVal = state.instance.exports.json_rpc_send(0, chainId) >>> 0;
|
|
164
162
|
}
|
|
165
163
|
catch (_error) {
|
|
166
164
|
console.assert(crashError.error);
|
|
@@ -207,29 +205,25 @@ function start(configMessage, platformBindings) {
|
|
|
207
205
|
}
|
|
208
206
|
}),
|
|
209
207
|
addChain: (chainSpec, databaseContent, potentialRelayChains, disableJsonRpc) => {
|
|
210
|
-
return queueOperation((instance) => {
|
|
208
|
+
return queueOperation((instance, bufferIndices) => {
|
|
211
209
|
if (crashError.error)
|
|
212
210
|
throw crashError.error;
|
|
213
211
|
try {
|
|
214
|
-
// Write the chain specification into memory.
|
|
215
|
-
const chainSpecEncoded = new TextEncoder().encode(chainSpec);
|
|
216
|
-
const chainSpecPtr = instance.exports.alloc(chainSpecEncoded.length) >>> 0;
|
|
217
|
-
new Uint8Array(instance.exports.memory.buffer).set(chainSpecEncoded, chainSpecPtr);
|
|
218
|
-
// Write the database content into memory.
|
|
219
|
-
const databaseContentEncoded = new TextEncoder().encode(databaseContent);
|
|
220
|
-
const databaseContentPtr = instance.exports.alloc(databaseContentEncoded.length) >>> 0;
|
|
221
|
-
new Uint8Array(instance.exports.memory.buffer).set(databaseContentEncoded, databaseContentPtr);
|
|
222
|
-
// Write the potential relay chains into memory.
|
|
223
|
-
const potentialRelayChainsLen = potentialRelayChains.length;
|
|
224
|
-
const potentialRelayChainsPtr = instance.exports.alloc(potentialRelayChainsLen * 4) >>> 0;
|
|
225
|
-
for (let idx = 0; idx < potentialRelayChains.length; ++idx) {
|
|
226
|
-
buffer.writeUInt32LE(new Uint8Array(instance.exports.memory.buffer), potentialRelayChainsPtr + idx * 4, potentialRelayChains[idx]);
|
|
227
|
-
}
|
|
228
212
|
// `add_chain` unconditionally allocates a chain id. If an error occurs, however, this chain
|
|
229
213
|
// id will refer to an *erroneous* chain. `chain_is_ok` is used below to determine whether it
|
|
230
214
|
// has succeeeded or not.
|
|
231
215
|
// Note that `add_chain` properly de-allocates buffers even if it failed.
|
|
232
|
-
|
|
216
|
+
bufferIndices[0] = new TextEncoder().encode(chainSpec);
|
|
217
|
+
bufferIndices[1] = new TextEncoder().encode(databaseContent);
|
|
218
|
+
const potentialRelayChainsEncoded = new Uint8Array(potentialRelayChains.length * 4);
|
|
219
|
+
for (let idx = 0; idx < potentialRelayChains.length; ++idx) {
|
|
220
|
+
buffer.writeUInt32LE(potentialRelayChainsEncoded, idx * 4, potentialRelayChains[idx]);
|
|
221
|
+
}
|
|
222
|
+
bufferIndices[2] = potentialRelayChainsEncoded;
|
|
223
|
+
const chainId = instance.exports.add_chain(0, 1, disableJsonRpc ? 0 : 1, 2);
|
|
224
|
+
delete bufferIndices[0];
|
|
225
|
+
delete bufferIndices[1];
|
|
226
|
+
delete bufferIndices[2];
|
|
233
227
|
if (instance.exports.chain_is_ok(chainId) != 0) {
|
|
234
228
|
console.assert(!chains.has(chainId));
|
|
235
229
|
chains.set(chainId, {
|
|
@@ -62,4 +62,4 @@ export interface PlatformBindings {
|
|
|
62
62
|
*/
|
|
63
63
|
connect(config: ConnectionConfig): Connection;
|
|
64
64
|
}
|
|
65
|
-
export declare function startInstance(config: Config, platformBindings: PlatformBindings): Promise<SmoldotWasmInstance>;
|
|
65
|
+
export declare function startInstance(config: Config, platformBindings: PlatformBindings): Promise<[SmoldotWasmInstance, Array<Uint8Array>]>;
|
|
@@ -36,8 +36,9 @@ function startInstance(config, platformBindings) {
|
|
|
36
36
|
// cross-platform cross-bundler approach.
|
|
37
37
|
const wasmBytecode = yield platformBindings.trustedBase64DecodeAndZlibInflate(wasm_js_1.default);
|
|
38
38
|
let killAll;
|
|
39
|
+
const bufferIndices = new Array;
|
|
39
40
|
// Used to bind with the smoldot-light bindings. See the `bindings-smoldot-light.js` file.
|
|
40
|
-
const smoldotJsConfig = Object.assign({
|
|
41
|
+
const smoldotJsConfig = Object.assign({ bufferIndices, connect: platformBindings.connect, onPanic: (message) => {
|
|
41
42
|
killAll();
|
|
42
43
|
config.onWasmPanic(message);
|
|
43
44
|
throw new Error();
|
|
@@ -46,6 +47,7 @@ function startInstance(config, platformBindings) {
|
|
|
46
47
|
const wasiConfig = {
|
|
47
48
|
envVars: [],
|
|
48
49
|
getRandomValues: platformBindings.getRandomValues,
|
|
50
|
+
performanceNow: platformBindings.performanceNow,
|
|
49
51
|
onProcExit: (retCode) => {
|
|
50
52
|
killAll();
|
|
51
53
|
config.onWasmPanic(`proc_exit called: ${retCode}`);
|
|
@@ -66,7 +68,7 @@ function startInstance(config, platformBindings) {
|
|
|
66
68
|
const instance = result.instance;
|
|
67
69
|
smoldotJsConfig.instance = instance;
|
|
68
70
|
wasiConfig.instance = instance;
|
|
69
|
-
return instance;
|
|
71
|
+
return [instance, bufferIndices];
|
|
70
72
|
});
|
|
71
73
|
}
|
|
72
74
|
exports.startInstance = startInstance;
|
package/dist/mjs/client.js
CHANGED
|
@@ -77,10 +77,10 @@ export function start(options, platformBindings) {
|
|
|
77
77
|
// For each chain object returned by `addChain`, the associated internal chain id.
|
|
78
78
|
//
|
|
79
79
|
// Immediately cleared when `remove()` is called on a chain.
|
|
80
|
-
|
|
80
|
+
const chainIds = new WeakMap();
|
|
81
81
|
// If `Client.terminate()̀ is called, this error is set to a value.
|
|
82
82
|
// All the functions of the public API check if this contains a value.
|
|
83
|
-
|
|
83
|
+
const alreadyDestroyedError = { value: null };
|
|
84
84
|
const instance = startInstance({
|
|
85
85
|
// Maximum level of log entries sent by the client.
|
|
86
86
|
// 0 = Logging disabled, 1 = Error, 2 = Warn, 3 = Info, 4 = Debug, 5 = Trace
|
|
@@ -94,8 +94,8 @@ export function start(options, platformBindings) {
|
|
|
94
94
|
}, platformBindings);
|
|
95
95
|
return {
|
|
96
96
|
addChain: (options) => __awaiter(this, void 0, void 0, function* () {
|
|
97
|
-
if (alreadyDestroyedError)
|
|
98
|
-
throw alreadyDestroyedError;
|
|
97
|
+
if (alreadyDestroyedError.value)
|
|
98
|
+
throw alreadyDestroyedError.value;
|
|
99
99
|
// Passing a JSON object for the chain spec is an easy mistake, so we provide a more
|
|
100
100
|
// readable error.
|
|
101
101
|
if (!(typeof options.chainSpec === 'string'))
|
|
@@ -120,8 +120,8 @@ export function start(options, platformBindings) {
|
|
|
120
120
|
// Resolve the promise that `addChain` returned to the user.
|
|
121
121
|
const newChain = {
|
|
122
122
|
sendJsonRpc: (request) => {
|
|
123
|
-
if (alreadyDestroyedError)
|
|
124
|
-
throw alreadyDestroyedError;
|
|
123
|
+
if (alreadyDestroyedError.value)
|
|
124
|
+
throw alreadyDestroyedError.value;
|
|
125
125
|
if (wasDestroyed.destroyed)
|
|
126
126
|
throw new AlreadyDestroyedError();
|
|
127
127
|
if (options.disableJsonRpc)
|
|
@@ -133,8 +133,8 @@ export function start(options, platformBindings) {
|
|
|
133
133
|
instance.request(request, chainId);
|
|
134
134
|
},
|
|
135
135
|
nextJsonRpcResponse: () => {
|
|
136
|
-
if (alreadyDestroyedError)
|
|
137
|
-
return Promise.reject(alreadyDestroyedError);
|
|
136
|
+
if (alreadyDestroyedError.value)
|
|
137
|
+
return Promise.reject(alreadyDestroyedError.value);
|
|
138
138
|
if (wasDestroyed.destroyed)
|
|
139
139
|
return Promise.reject(new AlreadyDestroyedError());
|
|
140
140
|
if (options.disableJsonRpc)
|
|
@@ -142,8 +142,8 @@ export function start(options, platformBindings) {
|
|
|
142
142
|
return instance.nextJsonRpcResponse(chainId);
|
|
143
143
|
},
|
|
144
144
|
remove: () => {
|
|
145
|
-
if (alreadyDestroyedError)
|
|
146
|
-
throw alreadyDestroyedError;
|
|
145
|
+
if (alreadyDestroyedError.value)
|
|
146
|
+
throw alreadyDestroyedError.value;
|
|
147
147
|
if (wasDestroyed.destroyed)
|
|
148
148
|
throw new AlreadyDestroyedError();
|
|
149
149
|
wasDestroyed.destroyed = true;
|
|
@@ -156,9 +156,9 @@ export function start(options, platformBindings) {
|
|
|
156
156
|
return newChain;
|
|
157
157
|
}),
|
|
158
158
|
terminate: () => __awaiter(this, void 0, void 0, function* () {
|
|
159
|
-
if (alreadyDestroyedError)
|
|
160
|
-
throw alreadyDestroyedError;
|
|
161
|
-
alreadyDestroyedError = new AlreadyDestroyedError();
|
|
159
|
+
if (alreadyDestroyedError.value)
|
|
160
|
+
throw alreadyDestroyedError.value;
|
|
161
|
+
alreadyDestroyedError.value = new AlreadyDestroyedError();
|
|
162
162
|
instance.startShutdown();
|
|
163
163
|
})
|
|
164
164
|
};
|