@leofcoin/chain 1.6.1 → 1.6.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.
@@ -1,5 +1,4 @@
1
- import { E as EasyWorker, B as BigNumber, C as ContractMessage, T as TransactionMessage } from './worker-CbAak_hM.js';
2
- import { randomUUID } from 'crypto';
1
+ import { E as EasyWorker, B as BigNumber, C as ContractMessage, T as TransactionMessage } from './worker-CFrwP8cD.js';
3
2
 
4
3
  const byteFormats = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
5
4
  const formatBytes = (bytes, decimals = 2) => {
@@ -103,351 +102,351 @@ class LittlePubSub {
103
102
  }
104
103
  }
105
104
 
106
- const pubsub = new LittlePubSub();
107
- const worker = new EasyWorker();
108
-
109
- const contractFactoryMessage = bytecodes.contractFactory;
110
- const nativeTokenMessage = bytecodes.nativeToken;
111
- const nameServiceMessage = bytecodes.nameService;
112
- const validatorsMessage = bytecodes.validators;
113
-
114
- const latestTransactions = [];
115
- let nativeCalls = 0;
116
- let nativeBurns = 0;
117
- let nativeMints = 0;
118
- let nativeTransfers = 0;
119
- let totalTransactions = 0;
120
-
121
- let blocks = [];
122
- let contracts = {};
123
- const _ = {};
124
-
125
- globalThis.BigNumber = BigNumber;
126
-
127
- let lastBlock = { index: -1, hash: '0x0', previousHash: '0x0' };
128
-
129
- const debug = (message) => {
130
- worker.postMessage({
131
- type: 'debug',
132
- message
133
- });
134
- };
135
-
136
- const has = (address) => {
137
- return contracts[address] ? true : false
138
- };
139
-
140
- const get = ({ contract, method, params }) => {
141
- let result;
142
- if (params?.length > 0) {
143
- result = contracts[contract][method](...params);
144
- } else {
145
- result = contracts[contract][method];
146
- }
147
- return result
148
- };
149
-
150
- const resolveContract = (address) => askFor('contract', address);
151
-
152
- const respond = (id, value) => {
153
- worker.postMessage({
154
- type: 'response',
155
- value,
156
- id
157
- });
158
- };
159
-
160
- _.runContract = async ({ decoded, hash, encoded }, state) => {
161
- const params = decoded.constructorParameters;
162
- try {
163
- const func = new Function(new TextDecoder().decode(decoded.contract));
164
- const Contract = func();
165
-
166
- if (state) params.push(state);
167
-
168
- globalThis.msg = createMessage(decoded.creator, hash);
169
- contracts[hash] = await new Contract(...params);
170
-
171
- debug(`loaded contract: ${hash} size: ${formatBytes(encoded.length)}`);
172
- } catch (e) {
173
- console.log(e);
174
- worker.postMessage({
175
- type: 'contractError',
176
- message: e.message,
177
- hash
178
- });
179
- }
180
- };
181
-
182
- _.execute = async ({ contract, method, params }) => {
183
- try {
184
- let result;
185
-
186
- // don't execute the method on a proxy
187
- if (contracts[contract].fallback) {
188
- result = await contracts[contract].fallback(method, params);
189
- } else {
190
- result = await contracts[contract][method](...params);
191
- }
192
- // state.put(result)
193
- return result
194
- } catch (e) {
195
- console.log({ e });
196
- throw new Error(
197
- `error: ${e.message}
198
- contract: ${contract}
199
- method: ${method}
200
- params: ${JSON.stringify(params, null, '\t')}
201
- `
202
- )
203
- }
204
- };
205
-
206
- const createMessage = (sender = globalThis.peerid, contract) => {
207
- return {
208
- contract,
209
- sender,
210
- call: _.execute,
211
- staticCall: get
212
- }
213
- };
214
-
215
- const _executeTransaction = async (transaction) => {
216
- const hash = await new TransactionMessage(transaction).hash();
217
- if (latestTransactions.includes(hash)) {
218
- throw new Error(`double transaction found: ${hash} in block ${block.index}`)
219
- } else {
220
- latestTransactions.push(hash);
221
- const { from, to, method, params, nonce } = transaction;
222
- globalThis.msg = createMessage(from);
223
-
224
- await _.execute({ contract: to, method, params });
225
- if (to === nativeToken$2) {
226
- nativeCalls += 1;
227
- if (method === 'burn') nativeBurns += 1;
228
- if (method === 'mint') nativeMints += 1;
229
- if (method === 'transfer') nativeTransfers += 1;
230
- }
231
- totalTransactions += 1;
232
-
233
- worker.postMessage({
234
- type: 'transactionLoaded',
235
- result: {
236
- hash,
237
- from,
238
- nonce: String(nonce)
239
- }
240
- });
241
- }
242
- };
243
-
244
- _.init = async (message) => {
245
- let { peerid, fromState, state } = message;
246
- globalThis.peerid = peerid;
247
- console.log({ fromState });
248
- if (fromState) {
249
- lastBlock = message.lastBlock;
250
- const setState = async (address, state) => {
251
- const contractBytes = await resolveContract(address);
252
- const contract = await new ContractMessage(contractBytes);
253
-
254
- await _.runContract({ hash: address, decoded: contract.decoded, encoded: contract.encoded }, state);
255
- };
256
-
257
- const entries = Object.entries(state);
258
- if (entries.length > 0) {
259
- const promises = [];
260
- for (const [address, value] of entries) {
261
- promises.push(setState(address, value));
262
- }
263
- await Promise.all(promises);
264
- }
265
-
266
- const promises = [];
267
- if (!contracts[addresses.contractFactory]) promises.push(setState(addresses.contractFactory));
268
- if (!contracts[addresses.nameService]) promises.push(setState(addresses.nameService));
269
- if (!contracts[addresses.validators]) promises.push(setState(addresses.validators));
270
- if (!contracts[addresses.nativeToken]) promises.push(setState(addresses.nativeToken));
271
- // contracts = await Promise.all(
272
- // contracts.map(async (contract) => {
273
- // contract = await new ContractMessage(new Uint8Array(contract.split(',')))
274
- // await _.runContract({ decoded: contract.decoded, encoded: contract.encoded, hash: await contract.hash() })
275
- // return contract
276
- // })
277
- // )
278
- await Promise.all(promises);
279
- } else {
280
- await Promise.all(
281
- [contractFactoryMessage, nativeTokenMessage, nameServiceMessage, validatorsMessage].map(async (contract) => {
282
- contract = await new ContractMessage(new Uint8Array(contract.split(',')));
283
- return _.runContract({ decoded: contract.decoded, encoded: contract.encoded, hash: await contract.hash() })
284
- })
285
- );
286
- console.log({ blocks: message.blocks });
287
- if (message.blocks?.length > 0) {
288
- let pre;
289
-
290
- try {
291
- const importee = await import('url');
292
- const url = importee.default;
293
- if (url) pre = url.fileURLToPath(new URL('.', import.meta.url));
294
- } catch {
295
- // browser env
296
- pre = './';
297
- }
298
-
299
- let _worker = await new EasyWorker(pre + './block-worker.js', {
300
- serialization: 'advanced',
301
- type: 'module'
302
- });
303
- blocks = await _worker.once(message.blocks);
304
- _worker = null;
305
- // blocks = unique(globalThis.blocks ? globalThis : [], blocks)
306
- // for (let i = 0; i < blocks.length; i++) {
307
-
308
- // }
309
- for (const block of blocks) {
310
- // we only revalidate the latest 24 blocks
311
- // every 24 blocks a snapshot is taken and stored in state
312
- // this means contracts will be restored from this state
313
- // this also means devs NEED to make sure the state can be restored
314
- // on contract deploy an error will be thrown if state wasn't recoverable
315
- if (block.index > 24) {
316
- const transactionCount = blocks[block.index - 1].transactions.length;
317
- latestTransactions.splice(-(transactionCount - 1), latestTransactions.length);
318
- }
319
-
320
- if (!block.loaded && !fromState) {
321
- const priority = block.transactions.filter((transaction) => transaction.priority);
322
- if (priority.length > 0)
323
- await Promise.all(
324
- priority.sort((a, b) => a.nonce - b.nonce).map((transaction) => _executeTransaction(transaction))
325
- );
326
-
327
- await Promise.all(
328
- block.transactions
329
- .filter((transaction) => !transaction.priority)
330
- .map(async (transaction) => _executeTransaction(transaction))
331
- );
332
- }
333
- block.loaded = true;
334
- worker.postMessage({
335
- type: 'debug',
336
- message: `loaded transactions for block: ${block.blockInfo.hash} @${block.blockInfo.index} ${formatBytes(
337
- block.blockInfo.size
338
- )}`
339
- });
340
- }
341
-
342
- if (blocks.length > 0) {
343
- lastBlock = blocks[blocks.length - 1];
344
- }
345
- globalThis.blocks = blocks;
346
- }
347
- }
348
-
349
- worker.postMessage({ type: 'machine-ready', lastBlock });
350
-
351
- // worker.postMessage({blocks});
352
- };
353
-
354
- _.addLoadedBlock = (block) => {
355
- blocks[block.index - 1] = block;
356
- lastBlock = blocks[blocks.length - 1];
357
- return true
358
- };
359
-
360
- _.loadBlock = (block) => {
361
- // todo validate here and deprecate addLoadedBlock
362
- };
363
-
364
- const askFor = (question, input) =>
365
- new Promise((resolve) => {
366
- const id = randomUUID();
367
- pubsub.subscribe(id, resolve);
368
- worker.postMessage({
369
- type: 'ask',
370
- question,
371
- input,
372
- id
373
- });
374
- });
375
-
376
- const runTask = async (id, taskName, input) => {
377
- try {
378
- const result = await _[taskName](input);
379
- respond(id, result);
380
- } catch (e) {
381
- worker.postMessage({
382
- type: `${taskName}Error`,
383
- message: e.message,
384
- id
385
- });
386
- }
387
- };
388
-
389
- worker.onmessage(({ id, type, input }) => {
390
- if (pubsub.hasSubscribers(id)) {
391
- pubsub.publish(id, input);
392
- return
393
- }
394
- switch (type) {
395
- case 'init':
396
- runTask(id, 'init', input);
397
- break
398
- case 'run':
399
- runTask(id, 'runContract', input);
400
- break
401
- case 'execute':
402
- runTask(id, 'execute', input);
403
- break
404
- case 'addLoadedBlock':
405
- runTask(id, 'addLoadedBlock', input);
406
- break
407
- case 'nativeCalls':
408
- respond(id, nativeCalls);
409
- break
410
- case 'contracts':
411
- respond(id, contracts);
412
- break
413
- case 'nativeMints':
414
- respond(id, nativeMints);
415
- break
416
- case 'nativeBurns':
417
- respond(id, nativeBurns);
418
- break
419
- case 'nativeTransfers':
420
- respond(id, nativeTransfers);
421
- break
422
- case 'totalTransfers':
423
- respond(id, totalTransfers);
424
- break
425
- case 'totalBlocks':
426
- respond(id, blocks.length);
427
- break
428
- case 'blocks':
429
- respond(id, input ? blocks.slice(input.from, input.to) : blocks);
430
- break
431
- case 'block':
432
- respond(id, blocks[input - 1]);
433
- break
434
- case 'lastBlock':
435
- respond(id, lastBlock);
436
- break
437
- case 'latestTransactions':
438
- respond(id, latestTransactions);
439
- break
440
- case 'totalTransactions':
441
- respond(id, totalTransactions);
442
- break
443
- case 'has':
444
- respond(id, has(input.address));
445
- break
446
- case 'get':
447
- respond(id, get(input));
448
- break
449
- default:
450
- console.log(`machine-worker: unsupported taskType: ${type}`);
451
- break
452
- }
105
+ const pubsub = new LittlePubSub();
106
+ const worker = new EasyWorker();
107
+
108
+ const contractFactoryMessage = bytecodes.contractFactory;
109
+ const nativeTokenMessage = bytecodes.nativeToken;
110
+ const nameServiceMessage = bytecodes.nameService;
111
+ const validatorsMessage = bytecodes.validators;
112
+
113
+ const latestTransactions = [];
114
+ let nativeCalls = 0;
115
+ let nativeBurns = 0;
116
+ let nativeMints = 0;
117
+ let nativeTransfers = 0;
118
+ let totalTransactions = 0;
119
+
120
+ let blocks = [];
121
+ let contracts = {};
122
+ const _ = {};
123
+
124
+ globalThis.BigNumber = BigNumber;
125
+
126
+ let lastBlock = { index: -1, hash: '0x0', previousHash: '0x0' };
127
+
128
+ const debug = (message) => {
129
+ worker.postMessage({
130
+ type: 'debug',
131
+ message
132
+ });
133
+ };
134
+
135
+ const has = (address) => {
136
+ return contracts[address] ? true : false
137
+ };
138
+
139
+ const get = ({ contract, method, params }) => {
140
+ let result;
141
+ if (params?.length > 0) {
142
+ result = contracts[contract][method](...params);
143
+ } else {
144
+ result = contracts[contract][method];
145
+ }
146
+ return result
147
+ };
148
+
149
+ const resolveContract = (address) => askFor('contract', address);
150
+
151
+ const respond = (id, value) => {
152
+ worker.postMessage({
153
+ type: 'response',
154
+ value,
155
+ id
156
+ });
157
+ };
158
+
159
+ _.runContract = async ({ decoded, hash, encoded }, state) => {
160
+ const params = decoded.constructorParameters;
161
+ try {
162
+ const func = new Function(new TextDecoder().decode(decoded.contract));
163
+ const Contract = func();
164
+
165
+ if (state) params.push(state);
166
+
167
+ globalThis.msg = createMessage(decoded.creator, hash);
168
+ contracts[hash] = await new Contract(...params);
169
+
170
+ debug(`loaded contract: ${hash} size: ${formatBytes(encoded.length)}`);
171
+ } catch (e) {
172
+ console.log(e);
173
+ worker.postMessage({
174
+ type: 'contractError',
175
+ message: e.message,
176
+ hash
177
+ });
178
+ }
179
+ };
180
+
181
+ _.execute = async ({ contract, method, params }) => {
182
+ try {
183
+ let result;
184
+
185
+ // don't execute the method on a proxy
186
+ if (contracts[contract].fallback) {
187
+ result = await contracts[contract].fallback(method, params);
188
+ } else {
189
+ result = await contracts[contract][method](...params);
190
+ }
191
+ // state.put(result)
192
+ return result
193
+ } catch (e) {
194
+ console.log({ e });
195
+ throw new Error(
196
+ `error: ${e.message}
197
+ contract: ${contract}
198
+ method: ${method}
199
+ params: ${JSON.stringify(params, null, '\t')}
200
+ `
201
+ )
202
+ }
203
+ };
204
+
205
+ const createMessage = (sender = globalThis.peerid, contract) => {
206
+ return {
207
+ contract,
208
+ sender,
209
+ call: _.execute,
210
+ staticCall: get
211
+ }
212
+ };
213
+
214
+ const _executeTransaction = async (transaction) => {
215
+ const hash = await new TransactionMessage(transaction).hash();
216
+ if (latestTransactions.includes(hash)) {
217
+ throw new Error(`double transaction found: ${hash} in block ${block.index}`)
218
+ } else {
219
+ latestTransactions.push(hash);
220
+ const { from, to, method, params, nonce } = transaction;
221
+ globalThis.msg = createMessage(from);
222
+
223
+ await _.execute({ contract: to, method, params });
224
+ if (to === nativeToken$2) {
225
+ nativeCalls += 1;
226
+ if (method === 'burn') nativeBurns += 1;
227
+ if (method === 'mint') nativeMints += 1;
228
+ if (method === 'transfer') nativeTransfers += 1;
229
+ }
230
+ totalTransactions += 1;
231
+
232
+ worker.postMessage({
233
+ type: 'transactionLoaded',
234
+ result: {
235
+ hash,
236
+ from,
237
+ nonce: String(nonce)
238
+ }
239
+ });
240
+ }
241
+ };
242
+
243
+ _.init = async (message) => {
244
+ let { peerid, fromState, state } = message;
245
+ globalThis.peerid = peerid;
246
+ console.log({ fromState });
247
+ if (fromState) {
248
+ lastBlock = message.lastBlock;
249
+ const setState = async (address, state) => {
250
+ const contractBytes = await resolveContract(address);
251
+ const contract = await new ContractMessage(contractBytes);
252
+
253
+ await _.runContract({ hash: address, decoded: contract.decoded, encoded: contract.encoded }, state);
254
+ };
255
+
256
+ const entries = Object.entries(state);
257
+ if (entries.length > 0) {
258
+ const promises = [];
259
+ for (const [address, value] of entries) {
260
+ promises.push(setState(address, value));
261
+ }
262
+ await Promise.all(promises);
263
+ }
264
+
265
+ const promises = [];
266
+ if (!contracts[addresses.contractFactory]) promises.push(setState(addresses.contractFactory));
267
+ if (!contracts[addresses.nameService]) promises.push(setState(addresses.nameService));
268
+ if (!contracts[addresses.validators]) promises.push(setState(addresses.validators));
269
+ if (!contracts[addresses.nativeToken]) promises.push(setState(addresses.nativeToken));
270
+ // contracts = await Promise.all(
271
+ // contracts.map(async (contract) => {
272
+ // contract = await new ContractMessage(new Uint8Array(contract.split(',')))
273
+ // await _.runContract({ decoded: contract.decoded, encoded: contract.encoded, hash: await contract.hash() })
274
+ // return contract
275
+ // })
276
+ // )
277
+ await Promise.all(promises);
278
+ } else {
279
+ await Promise.all(
280
+ [contractFactoryMessage, nativeTokenMessage, nameServiceMessage, validatorsMessage].map(async (contract) => {
281
+ contract = await new ContractMessage(new Uint8Array(contract.split(',')));
282
+ return _.runContract({ decoded: contract.decoded, encoded: contract.encoded, hash: await contract.hash() })
283
+ })
284
+ );
285
+ console.log({ blocks: message.blocks });
286
+ if (message.blocks?.length > 0) {
287
+ let pre;
288
+
289
+ try {
290
+ const importee = await import('url');
291
+ const url = importee.default;
292
+ if (url) pre = url.fileURLToPath(new URL('.', import.meta.url));
293
+ } catch {
294
+ // browser env
295
+ pre = './';
296
+ }
297
+
298
+ let _worker = await new EasyWorker(pre + './block-worker.js', {
299
+ serialization: 'advanced',
300
+ type: 'module'
301
+ });
302
+ blocks = await _worker.once(message.blocks);
303
+ _worker = null;
304
+ // blocks = unique(globalThis.blocks ? globalThis : [], blocks)
305
+ // for (let i = 0; i < blocks.length; i++) {
306
+
307
+ // }
308
+ for (const block of blocks) {
309
+ // we only revalidate the latest 24 blocks
310
+ // every 24 blocks a snapshot is taken and stored in state
311
+ // this means contracts will be restored from this state
312
+ // this also means devs NEED to make sure the state can be restored
313
+ // on contract deploy an error will be thrown if state wasn't recoverable
314
+ if (block.index > 24) {
315
+ const transactionCount = blocks[block.index - 1].transactions.length;
316
+ latestTransactions.splice(-(transactionCount - 1), latestTransactions.length);
317
+ }
318
+
319
+ if (!block.loaded && !fromState) {
320
+ const priority = block.transactions.filter((transaction) => transaction.priority);
321
+ if (priority.length > 0)
322
+ await Promise.all(
323
+ priority.sort((a, b) => a.nonce - b.nonce).map((transaction) => _executeTransaction(transaction))
324
+ );
325
+
326
+ await Promise.all(
327
+ block.transactions
328
+ .filter((transaction) => !transaction.priority)
329
+ .map(async (transaction) => _executeTransaction(transaction))
330
+ );
331
+ }
332
+ block.loaded = true;
333
+ worker.postMessage({
334
+ type: 'debug',
335
+ message: `loaded transactions for block: ${block.blockInfo.hash} @${block.blockInfo.index} ${formatBytes(
336
+ block.blockInfo.size
337
+ )}`
338
+ });
339
+ }
340
+
341
+ if (blocks.length > 0) {
342
+ lastBlock = blocks[blocks.length - 1];
343
+ }
344
+ globalThis.blocks = blocks;
345
+ }
346
+ }
347
+
348
+ worker.postMessage({ type: 'machine-ready', lastBlock });
349
+
350
+ // worker.postMessage({blocks});
351
+ };
352
+
353
+ _.addLoadedBlock = (block) => {
354
+ blocks[block.index - 1] = block;
355
+ lastBlock = blocks[blocks.length - 1];
356
+ return true
357
+ };
358
+
359
+ _.loadBlock = (block) => {
360
+ // todo validate here and deprecate addLoadedBlock
361
+ };
362
+
363
+ const askFor = (question, input) =>
364
+ new Promise((resolve) => {
365
+ const id = globalThis.crypto.randomUUID();
366
+ pubsub.subscribe(id, resolve);
367
+ worker.postMessage({
368
+ type: 'ask',
369
+ question,
370
+ input,
371
+ id
372
+ });
373
+ });
374
+
375
+ const runTask = async (id, taskName, input) => {
376
+ try {
377
+ const result = await _[taskName](input);
378
+ respond(id, result);
379
+ } catch (e) {
380
+ worker.postMessage({
381
+ type: `${taskName}Error`,
382
+ message: e.message,
383
+ id
384
+ });
385
+ }
386
+ };
387
+
388
+ worker.onmessage(({ id, type, input }) => {
389
+ if (pubsub.hasSubscribers(id)) {
390
+ pubsub.publish(id, input);
391
+ return
392
+ }
393
+ switch (type) {
394
+ case 'init':
395
+ runTask(id, 'init', input);
396
+ break
397
+ case 'run':
398
+ runTask(id, 'runContract', input);
399
+ break
400
+ case 'execute':
401
+ runTask(id, 'execute', input);
402
+ break
403
+ case 'addLoadedBlock':
404
+ runTask(id, 'addLoadedBlock', input);
405
+ break
406
+ case 'nativeCalls':
407
+ respond(id, nativeCalls);
408
+ break
409
+ case 'contracts':
410
+ respond(id, contracts);
411
+ break
412
+ case 'nativeMints':
413
+ respond(id, nativeMints);
414
+ break
415
+ case 'nativeBurns':
416
+ respond(id, nativeBurns);
417
+ break
418
+ case 'nativeTransfers':
419
+ respond(id, nativeTransfers);
420
+ break
421
+ case 'totalTransfers':
422
+ respond(id, totalTransfers);
423
+ break
424
+ case 'totalBlocks':
425
+ respond(id, blocks.length);
426
+ break
427
+ case 'blocks':
428
+ respond(id, input ? blocks.slice(input.from, input.to) : blocks);
429
+ break
430
+ case 'block':
431
+ respond(id, blocks[input - 1]);
432
+ break
433
+ case 'lastBlock':
434
+ respond(id, lastBlock);
435
+ break
436
+ case 'latestTransactions':
437
+ respond(id, latestTransactions);
438
+ break
439
+ case 'totalTransactions':
440
+ respond(id, totalTransactions);
441
+ break
442
+ case 'has':
443
+ respond(id, has(input.address));
444
+ break
445
+ case 'get':
446
+ respond(id, get(input));
447
+ break
448
+ default:
449
+ console.log(`machine-worker: unsupported taskType: ${type}`);
450
+ break
451
+ }
453
452
  });