@leofcoin/chain 1.8.12 → 1.8.14
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/exports/browser/chain.js +107 -27
- package/exports/browser/workers/block-worker.js +1 -1
- package/exports/browser/workers/machine-worker.js +67 -43
- package/exports/browser/workers/{worker-CPvGlmOu-CPvGlmOu.js → worker-iOnLaHA--iOnLaHA-.js} +734 -80
- package/exports/chain.js +2818 -2831
- package/exports/workers/block-worker.js +1 -1
- package/exports/workers/machine-worker.js +67 -43
- package/exports/workers/{worker-CPvGlmOu-CPvGlmOu.js → worker-iOnLaHA--iOnLaHA-.js} +734 -80
- package/package.json +2 -2
package/exports/browser/chain.js
CHANGED
|
@@ -3977,7 +3977,12 @@ class Transaction extends Protocol {
|
|
|
3977
3977
|
});
|
|
3978
3978
|
await globalThis.transactionPoolStore.put(hash, message.encoded);
|
|
3979
3979
|
// debug(`Added ${hash} to the transaction pool`)
|
|
3980
|
-
|
|
3980
|
+
try {
|
|
3981
|
+
peernet.publish('add-transaction', message.encoded);
|
|
3982
|
+
}
|
|
3983
|
+
catch (publishError) {
|
|
3984
|
+
console.warn('peernet publish failed: add-transaction', publishError?.message ?? publishError);
|
|
3985
|
+
}
|
|
3981
3986
|
const fee = await calculateFee(message.decoded);
|
|
3982
3987
|
return { hash, data, fee, wait, message };
|
|
3983
3988
|
}
|
|
@@ -4919,10 +4924,16 @@ class Machine {
|
|
|
4919
4924
|
return this.getBlocks();
|
|
4920
4925
|
}
|
|
4921
4926
|
get lastBlock() {
|
|
4922
|
-
return this.#askWorker('lastBlock')
|
|
4927
|
+
return this.#askWorker('lastBlock').catch((error) => {
|
|
4928
|
+
debug$2('lastBlock fallback after worker timeout:', error?.message ?? error);
|
|
4929
|
+
return this.states.lastBlock;
|
|
4930
|
+
});
|
|
4923
4931
|
}
|
|
4924
4932
|
get lastBlockHeight() {
|
|
4925
|
-
return this.#askWorker('lastBlockHeight')
|
|
4933
|
+
return this.#askWorker('lastBlockHeight').catch((error) => {
|
|
4934
|
+
debug$2('lastBlockHeight fallback after worker timeout:', error?.message ?? error);
|
|
4935
|
+
return Number(this.states.lastBlock?.index ?? 0);
|
|
4936
|
+
});
|
|
4926
4937
|
}
|
|
4927
4938
|
getBlocks(from, to) {
|
|
4928
4939
|
return this.#askWorker('blocks', { from, to });
|
|
@@ -5496,6 +5507,8 @@ class State extends Contract {
|
|
|
5496
5507
|
return { result: Uint8Array.from(Object.values(result)), peer };
|
|
5497
5508
|
}
|
|
5498
5509
|
catch (error) {
|
|
5510
|
+
const peerId = peer?.peerId || peer?.id || peer?.address || 'unknown';
|
|
5511
|
+
debug$1(`lastBlock request failed: ${peerId}:`, error?.message ?? error);
|
|
5499
5512
|
throw error;
|
|
5500
5513
|
}
|
|
5501
5514
|
};
|
|
@@ -5523,9 +5536,16 @@ class State extends Contract {
|
|
|
5523
5536
|
request: 'knownBlocks'
|
|
5524
5537
|
});
|
|
5525
5538
|
let node = await globalThis.peernet.prepareMessage(data);
|
|
5526
|
-
|
|
5527
|
-
|
|
5528
|
-
|
|
5539
|
+
try {
|
|
5540
|
+
let message = await peer.request(node.encode());
|
|
5541
|
+
message = await new globalThis.peernet.protos['peernet-response'](message);
|
|
5542
|
+
this.wantList.push(...message.decoded.response.blocks.filter((block) => !this.knownBlocks.includes(block)));
|
|
5543
|
+
}
|
|
5544
|
+
catch (error) {
|
|
5545
|
+
const peerId = peer?.peerId || peer?.id || peer?.address || 'unknown';
|
|
5546
|
+
debug$1(`knownBlocks request failed: ${peerId}:`, error?.message ?? error);
|
|
5547
|
+
throw error;
|
|
5548
|
+
}
|
|
5529
5549
|
}
|
|
5530
5550
|
}
|
|
5531
5551
|
return latest;
|
|
@@ -6274,9 +6294,16 @@ class Chain extends VersionControl {
|
|
|
6274
6294
|
}
|
|
6275
6295
|
async #makeRequest(peer, request) {
|
|
6276
6296
|
const node = await this.#prepareRequest(request);
|
|
6277
|
-
|
|
6278
|
-
|
|
6279
|
-
|
|
6297
|
+
try {
|
|
6298
|
+
let response = await peer.request(node.encoded);
|
|
6299
|
+
response = await new globalThis.peernet.protos['peernet-response'](new Uint8Array(Object.values(response)));
|
|
6300
|
+
return response.decoded.response;
|
|
6301
|
+
}
|
|
6302
|
+
catch (error) {
|
|
6303
|
+
const peerId = peer?.peerId || peer?.id || peer?.address || 'unknown';
|
|
6304
|
+
debug(`peernet request failed: ${request} -> ${peerId}:`, error?.message ?? error);
|
|
6305
|
+
throw error;
|
|
6306
|
+
}
|
|
6280
6307
|
}
|
|
6281
6308
|
async getPeerTransactionPool(peer) {
|
|
6282
6309
|
const transactionsInPool = await this.#makeRequest(peer, 'transactionPool');
|
|
@@ -6315,18 +6342,35 @@ class Chain extends VersionControl {
|
|
|
6315
6342
|
debug(`versions don't match`);
|
|
6316
6343
|
return;
|
|
6317
6344
|
}
|
|
6318
|
-
|
|
6345
|
+
let lastBlock;
|
|
6346
|
+
try {
|
|
6347
|
+
lastBlock = await this.#makeRequest(peer, 'lastBlock');
|
|
6348
|
+
}
|
|
6349
|
+
catch (error) {
|
|
6350
|
+
const peerName = peer?.peerId || peer?.id || peer?.address || peerId || 'unknown';
|
|
6351
|
+
debug(`lastBlock request failed: ${peerName}:`, error?.message ?? error);
|
|
6352
|
+
return;
|
|
6353
|
+
}
|
|
6319
6354
|
const localBlock = await this.lastBlock;
|
|
6320
|
-
if (lastBlock.hash === '0x0')
|
|
6355
|
+
if (!lastBlock || !lastBlock.hash || lastBlock.hash === '0x0') {
|
|
6356
|
+
debug(`peer has no lastBlock: ${peerId}`);
|
|
6321
6357
|
return;
|
|
6358
|
+
}
|
|
6322
6359
|
const higherThenCurrentLocal = !localBlock?.index ? true : lastBlock.index > localBlock.index;
|
|
6323
6360
|
if (lastBlock) {
|
|
6324
6361
|
if (!this.lastBlock || higherThenCurrentLocal) {
|
|
6325
|
-
|
|
6326
|
-
|
|
6327
|
-
|
|
6328
|
-
|
|
6329
|
-
|
|
6362
|
+
try {
|
|
6363
|
+
const knownBlocksResponse = await this.#makeRequest(peer, 'knownBlocks');
|
|
6364
|
+
if (knownBlocksResponse.blocks)
|
|
6365
|
+
for (const hash of knownBlocksResponse.blocks) {
|
|
6366
|
+
this.wantList.push(hash);
|
|
6367
|
+
}
|
|
6368
|
+
}
|
|
6369
|
+
catch (error) {
|
|
6370
|
+
const peerName = peer?.peerId || peer?.id || peer?.address || peerId || 'unknown';
|
|
6371
|
+
debug(`knownBlocks request failed: ${peerName}:`, error?.message ?? error);
|
|
6372
|
+
return;
|
|
6373
|
+
}
|
|
6330
6374
|
}
|
|
6331
6375
|
}
|
|
6332
6376
|
if (this.wantList.length > 0) {
|
|
@@ -6341,13 +6385,26 @@ class Chain extends VersionControl {
|
|
|
6341
6385
|
await this.triggerSync();
|
|
6342
6386
|
}
|
|
6343
6387
|
setTimeout(async () => {
|
|
6344
|
-
|
|
6345
|
-
|
|
6346
|
-
|
|
6388
|
+
try {
|
|
6389
|
+
const peerTransactionPool = (higherThenCurrentLocal && (await this.getPeerTransactionPool(peer))) || [];
|
|
6390
|
+
if (this.#participating && peerTransactionPool.length > 0)
|
|
6391
|
+
return this.#runEpoch();
|
|
6392
|
+
}
|
|
6393
|
+
catch (error) {
|
|
6394
|
+
const peerName = peer?.peerId || peer?.id || peer?.address || peerId || 'unknown';
|
|
6395
|
+
debug(`transactionPool request failed: ${peerName}:`, error?.message ?? error);
|
|
6396
|
+
}
|
|
6347
6397
|
}, 3000);
|
|
6348
|
-
|
|
6349
|
-
|
|
6350
|
-
|
|
6398
|
+
try {
|
|
6399
|
+
const stateInfo = await this.#makeRequest(peer, 'stateInfo');
|
|
6400
|
+
await this.syncChain(lastBlock);
|
|
6401
|
+
this.machine.states.info = stateInfo;
|
|
6402
|
+
}
|
|
6403
|
+
catch (error) {
|
|
6404
|
+
const peerName = peer?.peerId || peer?.id || peer?.address || peerId || 'unknown';
|
|
6405
|
+
debug(`stateInfo/syncChain failed: ${peerName}:`, error?.message ?? error);
|
|
6406
|
+
return;
|
|
6407
|
+
}
|
|
6351
6408
|
}
|
|
6352
6409
|
#epochTimeout;
|
|
6353
6410
|
async #transactionPoolHandler() {
|
|
@@ -6367,7 +6424,12 @@ class Chain extends VersionControl {
|
|
|
6367
6424
|
}
|
|
6368
6425
|
catch (error) {
|
|
6369
6426
|
await transactionPoolStore.delete(hash);
|
|
6370
|
-
|
|
6427
|
+
try {
|
|
6428
|
+
globalThis.peernet.publish('invalid-transaction', hash);
|
|
6429
|
+
}
|
|
6430
|
+
catch (publishError) {
|
|
6431
|
+
debug('peernet publish failed: invalid-transaction', publishError?.message ?? publishError);
|
|
6432
|
+
}
|
|
6371
6433
|
globalThis.pubsub.publish(`transaction.completed.${hash}`, { status: 'fail', hash, error: error });
|
|
6372
6434
|
throw { error, hash, from, to, params, nonce };
|
|
6373
6435
|
}
|
|
@@ -6582,7 +6644,10 @@ class Chain extends VersionControl {
|
|
|
6582
6644
|
bw: bw.up + bw.down
|
|
6583
6645
|
});
|
|
6584
6646
|
}
|
|
6585
|
-
catch {
|
|
6647
|
+
catch (error) {
|
|
6648
|
+
const peerId = peer?.peerId || peer?.id || peer?.address || 'unknown';
|
|
6649
|
+
debug(`bw request failed: ${peerId}:`, error?.message ?? error);
|
|
6650
|
+
}
|
|
6586
6651
|
}
|
|
6587
6652
|
else if (globalThis.peernet.selectedAccount === validator) {
|
|
6588
6653
|
block.validators.push({
|
|
@@ -6622,7 +6687,12 @@ class Chain extends VersionControl {
|
|
|
6622
6687
|
debug(`created block: ${hash} @${block.index}`);
|
|
6623
6688
|
// Publish canonical encoded form via codec interface
|
|
6624
6689
|
console.log(`[chain] 📤 Publishing block #${block.index} | hash: ${hash} | encoded bytes: ${blockMessage.encoded.length}`);
|
|
6625
|
-
|
|
6690
|
+
try {
|
|
6691
|
+
globalThis.peernet.publish('add-block', blockMessage.encoded);
|
|
6692
|
+
}
|
|
6693
|
+
catch (publishError) {
|
|
6694
|
+
debug('peernet publish failed: add-block', publishError?.message ?? publishError);
|
|
6695
|
+
}
|
|
6626
6696
|
globalThis.pubsub.publish('add-block', blockMessage.encoded);
|
|
6627
6697
|
}
|
|
6628
6698
|
catch (error) {
|
|
@@ -6644,7 +6714,12 @@ class Chain extends VersionControl {
|
|
|
6644
6714
|
this.#runEpoch();
|
|
6645
6715
|
}
|
|
6646
6716
|
catch (e) {
|
|
6647
|
-
|
|
6717
|
+
try {
|
|
6718
|
+
globalThis.peernet.publish('invalid-transaction', hash);
|
|
6719
|
+
}
|
|
6720
|
+
catch (publishError) {
|
|
6721
|
+
debug('peernet publish failed: invalid-transaction', publishError?.message ?? publishError);
|
|
6722
|
+
}
|
|
6648
6723
|
throw new Error('invalid transaction');
|
|
6649
6724
|
}
|
|
6650
6725
|
}
|
|
@@ -6657,7 +6732,12 @@ class Chain extends VersionControl {
|
|
|
6657
6732
|
const transactionMessage = await new TransactionMessage({ ...transaction });
|
|
6658
6733
|
const event = await super.sendTransaction(transactionMessage);
|
|
6659
6734
|
this.#sendTransaction(transactionMessage.encoded);
|
|
6660
|
-
|
|
6735
|
+
try {
|
|
6736
|
+
globalThis.peernet.publish('send-transaction', transactionMessage.encoded);
|
|
6737
|
+
}
|
|
6738
|
+
catch (publishError) {
|
|
6739
|
+
debug('peernet publish failed: send-transaction', publishError?.message ?? publishError);
|
|
6740
|
+
}
|
|
6661
6741
|
return event;
|
|
6662
6742
|
}
|
|
6663
6743
|
async addContract(transaction, contractMessage) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { E as EasyWorker, C as ContractMessage, T as TransactionMessage } from './worker-
|
|
1
|
+
import { E as EasyWorker, C as ContractMessage, T as TransactionMessage } from './worker-iOnLaHA--iOnLaHA-.js';
|
|
2
2
|
|
|
3
3
|
/* Do NOT modify this file; see /src.ts/_admin/update-version.ts */
|
|
4
4
|
/**
|
|
@@ -104,58 +104,73 @@ var bytecodes = {
|
|
|
104
104
|
};
|
|
105
105
|
|
|
106
106
|
class LittlePubSub {
|
|
107
|
-
subscribers =
|
|
107
|
+
subscribers = new Map();
|
|
108
108
|
verbose;
|
|
109
109
|
constructor(verbose) {
|
|
110
|
-
this.verbose = verbose;
|
|
111
|
-
}
|
|
112
|
-
_handleContext(handler, context) {
|
|
113
|
-
if (typeof context === 'undefined') {
|
|
114
|
-
context = handler;
|
|
115
|
-
}
|
|
116
|
-
return context;
|
|
110
|
+
this.verbose = verbose ?? false;
|
|
117
111
|
}
|
|
118
112
|
hasSubscribers(event) {
|
|
119
|
-
return this.subscribers
|
|
113
|
+
return this.subscribers.has(event);
|
|
114
|
+
}
|
|
115
|
+
subscriberCount(event) {
|
|
116
|
+
return this.subscribers.get(event)?.handlers.length ?? 0;
|
|
117
|
+
}
|
|
118
|
+
clear() {
|
|
119
|
+
this.subscribers.clear();
|
|
120
120
|
}
|
|
121
121
|
getValue(event) {
|
|
122
|
-
|
|
123
|
-
return this.subscribers[event].value;
|
|
124
|
-
return undefined;
|
|
122
|
+
return this.subscribers.get(event)?.value;
|
|
125
123
|
}
|
|
126
124
|
subscribe(event, handler, options) {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
if
|
|
133
|
-
|
|
125
|
+
let subscriber = this.subscribers.get(event);
|
|
126
|
+
if (subscriber === undefined) {
|
|
127
|
+
subscriber = { handlers: [], value: undefined };
|
|
128
|
+
this.subscribers.set(event, subscriber);
|
|
129
|
+
}
|
|
130
|
+
// Only bind if context is provided
|
|
131
|
+
const context = options?.context;
|
|
132
|
+
const boundHandler = context
|
|
133
|
+
? handler.bind(context)
|
|
134
|
+
: handler;
|
|
135
|
+
subscriber.handlers.push({ original: handler, bound: boundHandler });
|
|
136
|
+
// Call handler immediately if value already exists
|
|
137
|
+
if (subscriber.value !== undefined) {
|
|
138
|
+
boundHandler(subscriber.value, undefined);
|
|
139
|
+
}
|
|
140
|
+
// Return unsubscribe function
|
|
141
|
+
return () => this.unsubscribe(event, handler, options);
|
|
134
142
|
}
|
|
135
143
|
unsubscribe(event, handler, options) {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
if (!this.hasSubscribers(event))
|
|
144
|
+
const subscriber = this.subscribers.get(event);
|
|
145
|
+
if (subscriber === undefined)
|
|
139
146
|
return;
|
|
140
|
-
const
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
+
const handlers = subscriber.handlers;
|
|
148
|
+
// Find and remove handler by original reference
|
|
149
|
+
for (let i = 0, len = handlers.length; i < len; i++) {
|
|
150
|
+
if (handlers[i].original === handler) {
|
|
151
|
+
handlers.splice(i, 1);
|
|
152
|
+
break;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
// Delete event if no handlers left (unless keepValue is true)
|
|
156
|
+
if (handlers.length === 0 && !options?.keepValue) {
|
|
157
|
+
this.subscribers.delete(event);
|
|
158
|
+
}
|
|
147
159
|
}
|
|
148
160
|
publish(event, value, verbose) {
|
|
149
|
-
|
|
150
|
-
if (
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
const oldValue =
|
|
161
|
+
let subscriber = this.subscribers.get(event);
|
|
162
|
+
if (subscriber === undefined) {
|
|
163
|
+
subscriber = { handlers: [], value: undefined };
|
|
164
|
+
this.subscribers.set(event, subscriber);
|
|
165
|
+
}
|
|
166
|
+
const oldValue = subscriber.value;
|
|
167
|
+
// Only trigger handlers if verbose or value changed
|
|
155
168
|
if (this.verbose || verbose || oldValue !== value) {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
169
|
+
subscriber.value = value;
|
|
170
|
+
const handlers = subscriber.handlers;
|
|
171
|
+
const len = handlers.length;
|
|
172
|
+
for (let i = 0; i < len; i++) {
|
|
173
|
+
handlers[i].bound(value, oldValue);
|
|
159
174
|
}
|
|
160
175
|
}
|
|
161
176
|
}
|
|
@@ -163,12 +178,21 @@ class LittlePubSub {
|
|
|
163
178
|
this.publish(event, value, true);
|
|
164
179
|
}
|
|
165
180
|
once(event, options) {
|
|
166
|
-
return new Promise((resolve) => {
|
|
167
|
-
|
|
181
|
+
return new Promise((resolve, reject) => {
|
|
182
|
+
let timeoutId;
|
|
183
|
+
const handler = (value) => {
|
|
184
|
+
if (timeoutId !== undefined)
|
|
185
|
+
clearTimeout(timeoutId);
|
|
168
186
|
resolve(value);
|
|
169
|
-
this.unsubscribe(event,
|
|
187
|
+
this.unsubscribe(event, handler, options);
|
|
170
188
|
};
|
|
171
|
-
this.subscribe(event,
|
|
189
|
+
this.subscribe(event, handler, options);
|
|
190
|
+
if (options?.timeout !== undefined) {
|
|
191
|
+
timeoutId = setTimeout(() => {
|
|
192
|
+
this.unsubscribe(event, handler, options);
|
|
193
|
+
reject(new Error(`Timeout waiting for event "${event}"`));
|
|
194
|
+
}, options.timeout);
|
|
195
|
+
}
|
|
172
196
|
});
|
|
173
197
|
}
|
|
174
198
|
}
|