@leofcoin/chain 1.5.24 → 1.5.26
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 +148 -97
- package/exports/browser/{index-de7cd283.js → index-055d5584.js} +16 -2
- package/exports/browser/{index-329e0324-a0469bb9.js → index-329e0324-f8858eb6.js} +2 -2
- package/exports/browser/{messages-000b7f84-8465e629.js → messages-000b7f84-2f945543.js} +2 -2
- package/exports/browser/{node-browser-c27ce598.js → node-browser-ccafb3fc.js} +6 -4
- package/exports/browser/node-browser.js +2 -2
- package/exports/browser/workers/block-worker.js +32 -28
- package/exports/browser/workers/machine-worker.js +222 -233
- package/exports/browser/workers/{worker-156dda16.js → worker-5b02efbe.js} +10 -2
- package/exports/chain.d.ts +1 -0
- package/exports/chain.js +137 -86
- package/exports/contract.d.ts +1 -1
- package/exports/jobs/jobber.d.ts +1 -1
- package/exports/node.js +3 -1
- package/exports/state.d.ts +8 -2
- package/exports/transaction.d.ts +2 -2
- package/exports/version-control.d.ts +1 -1
- package/exports/workers/block-worker.js +32 -28
- package/exports/workers/machine-worker.js +222 -233
- package/exports/workers/{worker-156dda16.js → worker-5b02efbe.js} +10 -2
- package/package.json +2 -1
- package/exports/browser/index-329e0324-dcac6dff.js +0 -37
- package/exports/browser/index-b3d08518.js +0 -5703
- package/exports/browser/messages-000b7f84-8b18c4c6.js +0 -225
- package/exports/browser/node-browser-f8484520.js +0 -20987
package/exports/browser/chain.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { B as BigNumber, L as Logger, v as version$1, h as hexZeroPad, i as isBigNumberish, a as arrayify, b as isBytes, T as TransactionMessage, t as toBase58, C as ContractMessage, R as RawTransactionMessage, c as BlockMessage, d as BWMessage, e as BWRequestMessage } from './index-
|
|
1
|
+
import { B as BigNumber, L as Logger, v as version$1, h as hexZeroPad, i as isBigNumberish, a as arrayify, b as isBytes, T as TransactionMessage, t as toBase58, C as ContractMessage, R as RawTransactionMessage, c as BlockMessage, d as BWMessage, e as BWRequestMessage } from './index-055d5584.js';
|
|
2
2
|
|
|
3
3
|
const logger$1 = new Logger(version$1);
|
|
4
4
|
const _constructorGuard = {};
|
|
@@ -410,15 +410,15 @@ var addresses$1 = {
|
|
|
410
410
|
validators: validators$1
|
|
411
411
|
};
|
|
412
412
|
|
|
413
|
-
const contractFactory$2 = addresses$1.contractFactory;
|
|
414
|
-
const nameService$2 = addresses$1.nameService;
|
|
415
|
-
const nativeToken$2 = addresses$1.nativeToken;
|
|
416
|
-
const validators$2 = addresses$1.validators;
|
|
417
|
-
var addresses = {
|
|
418
|
-
contractFactory: contractFactory$2,
|
|
419
|
-
nameService: nameService$2,
|
|
420
|
-
nativeToken: nativeToken$2,
|
|
421
|
-
validators: validators$2
|
|
413
|
+
const contractFactory$2 = addresses$1.contractFactory;
|
|
414
|
+
const nameService$2 = addresses$1.nameService;
|
|
415
|
+
const nativeToken$2 = addresses$1.nativeToken;
|
|
416
|
+
const validators$2 = addresses$1.validators;
|
|
417
|
+
var addresses = {
|
|
418
|
+
contractFactory: contractFactory$2,
|
|
419
|
+
nameService: nameService$2,
|
|
420
|
+
nativeToken: nativeToken$2,
|
|
421
|
+
validators: validators$2
|
|
422
422
|
};
|
|
423
423
|
|
|
424
424
|
var contractFactory = "237,198,141,3,53,89,84,113,119,88,110,55,76,101,103,89,119,65,109,100,117,75,88,119,116,83,52,118,52,100,97,114,113,66,84,81,82,76,90,106,50,57,117,106,112,114,98,104,52,119,121,76,106,112,56,50,87,106,173,5,99,108,97,115,115,32,70,97,99,116,111,114,121,123,35,110,97,109,101,61,34,65,114,116,79,110,108,105,110,101,67,111,110,116,114,97,99,116,70,97,99,116,111,114,121,34,59,35,116,111,116,97,108,67,111,110,116,114,97,99,116,115,61,48,59,35,99,111,110,116,114,97,99,116,115,61,91,93,59,99,111,110,115,116,114,117,99,116,111,114,40,115,116,97,116,101,41,123,115,116,97,116,101,38,38,40,116,104,105,115,46,35,99,111,110,116,114,97,99,116,115,61,115,116,97,116,101,46,99,111,110,116,114,97,99,116,115,44,116,104,105,115,46,35,116,111,116,97,108,67,111,110,116,114,97,99,116,115,61,115,116,97,116,101,46,116,111,116,97,108,67,111,110,116,114,97,99,116,115,41,125,103,101,116,32,115,116,97,116,101,40,41,123,114,101,116,117,114,110,123,116,111,116,97,108,67,111,110,116,114,97,99,116,115,58,116,104,105,115,46,35,116,111,116,97,108,67,111,110,116,114,97,99,116,115,44,99,111,110,116,114,97,99,116,115,58,116,104,105,115,46,35,99,111,110,116,114,97,99,116,115,125,125,103,101,116,32,110,97,109,101,40,41,123,114,101,116,117,114,110,32,116,104,105,115,46,35,110,97,109,101,125,103,101,116,32,99,111,110,116,114,97,99,116,115,40,41,123,114,101,116,117,114,110,91,46,46,46,116,104,105,115,46,35,99,111,110,116,114,97,99,116,115,93,125,103,101,116,32,116,111,116,97,108,67,111,110,116,114,97,99,116,115,40,41,123,114,101,116,117,114,110,32,116,104,105,115,46,35,116,111,116,97,108,67,111,110,116,114,97,99,116,115,125,105,115,82,101,103,105,115,116,101,114,101,100,40,97,100,100,114,101,115,115,41,123,114,101,116,117,114,110,32,116,104,105,115,46,35,99,111,110,116,114,97,99,116,115,46,105,110,99,108,117,100,101,115,40,97,100,100,114,101,115,115,41,125,97,115,121,110,99,32,114,101,103,105,115,116,101,114,67,111,110,116,114,97,99,116,40,97,100,100,114,101,115,115,41,123,105,102,40,97,119,97,105,116,32,109,115,103,46,115,116,97,116,105,99,67,97,108,108,40,97,100,100,114,101,115,115,44,34,104,97,115,82,111,108,101,34,44,91,109,115,103,46,115,101,110,100,101,114,44,34,79,87,78,69,82,34,93,41,44,116,104,105,115,46,35,99,111,110,116,114,97,99,116,115,46,105,110,99,108,117,100,101,115,40,97,100,100,114,101,115,115,41,41,116,104,114,111,119,32,110,101,119,32,69,114,114,111,114,40,34,97,108,114,101,97,100,121,32,114,101,103,105,115,116,101,114,101,100,34,41,59,116,104,105,115,46,35,116,111,116,97,108,67,111,110,116,114,97,99,116,115,43,61,49,44,116,104,105,115,46,35,99,111,110,116,114,97,99,116,115,46,112,117,115,104,40,97,100,100,114,101,115,115,41,125,125,114,101,116,117,114,110,32,70,97,99,116,111,114,121,59,2,91,93";
|
|
@@ -474,7 +474,7 @@ const requestTimeout = 30000;
|
|
|
474
474
|
const syncTimeout = 30000;
|
|
475
475
|
class Protocol {
|
|
476
476
|
constructor() {
|
|
477
|
-
this.resolveTimeout =
|
|
477
|
+
this.resolveTimeout = 10000;
|
|
478
478
|
}
|
|
479
479
|
get limit() {
|
|
480
480
|
return limit;
|
|
@@ -503,11 +503,11 @@ class Transaction extends Protocol {
|
|
|
503
503
|
return new Promise(async (resolve, reject) => {
|
|
504
504
|
let size = 0;
|
|
505
505
|
const _transactions = [];
|
|
506
|
-
await Promise.all(transactions
|
|
507
|
-
.map(async (tx) => {
|
|
506
|
+
await Promise.all(transactions.map(async (tx) => {
|
|
508
507
|
tx = await new TransactionMessage(tx);
|
|
509
508
|
size += tx.encoded.length;
|
|
510
|
-
if (!formatBytes(size).includes('MB') ||
|
|
509
|
+
if (!formatBytes(size).includes('MB') ||
|
|
510
|
+
(formatBytes(size).includes('MB') && Number(formatBytes(size).split(' MB')[0]) <= 0.75))
|
|
511
511
|
_transactions.push({ ...tx.decoded, hash: await tx.hash() });
|
|
512
512
|
else
|
|
513
513
|
resolve(_transactions);
|
|
@@ -521,7 +521,7 @@ class Transaction extends Protocol {
|
|
|
521
521
|
* @returns {TransactionMessage}
|
|
522
522
|
*/
|
|
523
523
|
async promiseTransactions(transactions) {
|
|
524
|
-
transactions = await Promise.all(transactions.map(tx => new TransactionMessage(tx.encoded || tx)));
|
|
524
|
+
transactions = await Promise.all(transactions.map((tx) => new TransactionMessage(tx.encoded || tx)));
|
|
525
525
|
return transactions;
|
|
526
526
|
}
|
|
527
527
|
/**
|
|
@@ -530,7 +530,7 @@ class Transaction extends Protocol {
|
|
|
530
530
|
* @returns {Object} {transaction.decoded, transaction.hash}
|
|
531
531
|
*/
|
|
532
532
|
async promiseTransactionsContent(transactions) {
|
|
533
|
-
transactions = await Promise.all(transactions.map(tx => new Promise(async (resolve, reject) => {
|
|
533
|
+
transactions = await Promise.all(transactions.map((tx) => new Promise(async (resolve, reject) => {
|
|
534
534
|
resolve({ ...tx.decoded, hash: await tx.hash() });
|
|
535
535
|
})));
|
|
536
536
|
return transactions;
|
|
@@ -543,7 +543,7 @@ class Transaction extends Protocol {
|
|
|
543
543
|
async #getNonceFallback(address) {
|
|
544
544
|
let transactions = await globalThis.transactionPoolStore.values();
|
|
545
545
|
transactions = await this.promiseTransactions(transactions);
|
|
546
|
-
transactions = transactions.filter(tx => tx.decoded.from === address);
|
|
546
|
+
transactions = transactions.filter((tx) => tx.decoded.from === address);
|
|
547
547
|
transactions = await this.promiseTransactionsContent(transactions);
|
|
548
548
|
// @ts-ignore
|
|
549
549
|
if (this.lastBlock?.hash && transactions.length === 0 && this.lastBlock.hash !== '0x0') {
|
|
@@ -554,11 +554,11 @@ class Transaction extends Protocol {
|
|
|
554
554
|
// tx = await peernet.get(tx, 'transaction')
|
|
555
555
|
// transactions.push(new TransactionMessage(tx))
|
|
556
556
|
// }
|
|
557
|
-
transactions = transactions.filter(tx => tx.from === address);
|
|
557
|
+
transactions = transactions.filter((tx) => tx.from === address);
|
|
558
558
|
while (transactions.length === 0 && block.decoded.index !== 0 && block.decoded.previousHash !== '0x0') {
|
|
559
559
|
block = await globalThis.blockStore.get(block.decoded.previousHash);
|
|
560
560
|
block = await new BlockMessage(block);
|
|
561
|
-
transactions = block.decoded.transactions.filter(tx => tx.from === address);
|
|
561
|
+
transactions = block.decoded.transactions.filter((tx) => tx.from === address);
|
|
562
562
|
}
|
|
563
563
|
}
|
|
564
564
|
if (transactions.length === 0)
|
|
@@ -572,7 +572,7 @@ class Transaction extends Protocol {
|
|
|
572
572
|
* @returns {Number} nonce
|
|
573
573
|
*/
|
|
574
574
|
async getNonce(address) {
|
|
575
|
-
if (!await globalThis.accountsStore.has(address)) {
|
|
575
|
+
if (!(await globalThis.accountsStore.has(address))) {
|
|
576
576
|
const nonce = await this.#getNonceFallback(address);
|
|
577
577
|
await globalThis.accountsStore.put(address, new TextEncoder().encode(String(nonce)));
|
|
578
578
|
}
|
|
@@ -581,7 +581,7 @@ class Transaction extends Protocol {
|
|
|
581
581
|
nonce = new TextDecoder().decode(nonce);
|
|
582
582
|
let transactions = await globalThis.transactionPoolStore.values();
|
|
583
583
|
transactions = await this.promiseTransactions(transactions);
|
|
584
|
-
transactions = transactions.filter(tx => tx.decoded.from === address);
|
|
584
|
+
transactions = transactions.filter((tx) => tx.decoded.from === address);
|
|
585
585
|
transactions = await this.promiseTransactionsContent(transactions);
|
|
586
586
|
for (const transaction of transactions) {
|
|
587
587
|
if (transaction.nonce > nonce)
|
|
@@ -598,7 +598,7 @@ class Transaction extends Protocol {
|
|
|
598
598
|
throw new Error(`a transaction with the same nonce already exists`);
|
|
599
599
|
let transactions = await globalThis.transactionPoolStore.values();
|
|
600
600
|
transactions = await this.promiseTransactions(transactions);
|
|
601
|
-
transactions = transactions.filter(tx => tx.decoded.from === address);
|
|
601
|
+
transactions = transactions.filter((tx) => tx.decoded.from === address);
|
|
602
602
|
for (const transaction of transactions) {
|
|
603
603
|
if (transaction.decoded.nonce > nonce)
|
|
604
604
|
throw new Error(`a transaction with a higher nonce already exists`);
|
|
@@ -677,8 +677,7 @@ class Contract extends Transaction {
|
|
|
677
677
|
constructor() {
|
|
678
678
|
super();
|
|
679
679
|
}
|
|
680
|
-
async init() {
|
|
681
|
-
}
|
|
680
|
+
async init() { }
|
|
682
681
|
/**
|
|
683
682
|
*
|
|
684
683
|
* @param {Address} creator
|
|
@@ -728,7 +727,7 @@ class Contract extends Transaction {
|
|
|
728
727
|
}
|
|
729
728
|
}
|
|
730
729
|
|
|
731
|
-
const randombytes = strength => crypto.getRandomValues(new Uint8Array(strength));
|
|
730
|
+
const randombytes = (strength) => crypto.getRandomValues(new Uint8Array(strength));
|
|
732
731
|
|
|
733
732
|
class EasyWorker {
|
|
734
733
|
#messageEvent = 'message'
|
|
@@ -899,7 +898,10 @@ class Machine {
|
|
|
899
898
|
// browser env
|
|
900
899
|
pre = './';
|
|
901
900
|
}
|
|
902
|
-
this.worker = await new EasyWorker(pre + 'workers/machine-worker.js', {
|
|
901
|
+
this.worker = await new EasyWorker(pre + 'workers/machine-worker.js', {
|
|
902
|
+
serialization: 'advanced',
|
|
903
|
+
type: 'module'
|
|
904
|
+
});
|
|
903
905
|
this.worker.onmessage(this.#onmessage.bind(this));
|
|
904
906
|
// const blocks = await blockStore.values()
|
|
905
907
|
const contracts = await Promise.all([
|
|
@@ -925,7 +927,7 @@ class Machine {
|
|
|
925
927
|
return new Promise((resolve, reject) => {
|
|
926
928
|
// @ts-ignore
|
|
927
929
|
const id = randombytes(20).toString('hex');
|
|
928
|
-
const onmessage = message => {
|
|
930
|
+
const onmessage = (message) => {
|
|
929
931
|
pubsub.unsubscribe(id, onmessage);
|
|
930
932
|
if (message?.error)
|
|
931
933
|
reject(message.error);
|
|
@@ -957,7 +959,7 @@ class Machine {
|
|
|
957
959
|
if (await this.has(parameters[0]))
|
|
958
960
|
throw new Error(`duplicate contract @${parameters[0]}`);
|
|
959
961
|
let message;
|
|
960
|
-
if (!await globalThis.contractStore.has(parameters[0])) {
|
|
962
|
+
if (!(await globalThis.contractStore.has(parameters[0]))) {
|
|
961
963
|
message = await peernet.get(parameters[0], 'contract');
|
|
962
964
|
message = await new ContractMessage(message);
|
|
963
965
|
await globalThis.contractStore.put(await message.hash(), message.encoded);
|
|
@@ -966,7 +968,7 @@ class Machine {
|
|
|
966
968
|
message = await globalThis.contractStore.get(parameters[0]);
|
|
967
969
|
message = await new ContractMessage(message);
|
|
968
970
|
}
|
|
969
|
-
if (!await this.has(await message.hash()))
|
|
971
|
+
if (!(await this.has(await message.hash())))
|
|
970
972
|
await this.#runContract(message);
|
|
971
973
|
}
|
|
972
974
|
}
|
|
@@ -976,7 +978,7 @@ class Machine {
|
|
|
976
978
|
return new Promise((resolve, reject) => {
|
|
977
979
|
// @ts-ignore
|
|
978
980
|
const id = randombytes(20).toString('hex');
|
|
979
|
-
const onmessage = message => {
|
|
981
|
+
const onmessage = (message) => {
|
|
980
982
|
pubsub.unsubscribe(id, onmessage);
|
|
981
983
|
if (message?.error)
|
|
982
984
|
reject(new ExecutionError(message.error));
|
|
@@ -998,7 +1000,7 @@ class Machine {
|
|
|
998
1000
|
get(contract, method, parameters) {
|
|
999
1001
|
return new Promise((resolve, reject) => {
|
|
1000
1002
|
const id = randombytes(20).toString();
|
|
1001
|
-
const onmessage = message => {
|
|
1003
|
+
const onmessage = (message) => {
|
|
1002
1004
|
pubsub.unsubscribe(id, onmessage);
|
|
1003
1005
|
resolve(message);
|
|
1004
1006
|
};
|
|
@@ -1018,7 +1020,7 @@ class Machine {
|
|
|
1018
1020
|
return new Promise((resolve, reject) => {
|
|
1019
1021
|
// @ts-ignore
|
|
1020
1022
|
const id = randombytes(20).toString('hex');
|
|
1021
|
-
const onmessage = message => {
|
|
1023
|
+
const onmessage = (message) => {
|
|
1022
1024
|
pubsub.unsubscribe(id, onmessage);
|
|
1023
1025
|
if (message?.error)
|
|
1024
1026
|
reject(message.error);
|
|
@@ -1044,7 +1046,7 @@ class Machine {
|
|
|
1044
1046
|
*/
|
|
1045
1047
|
async deleteAll() {
|
|
1046
1048
|
let hashes = await globalThis.contractStore.keys();
|
|
1047
|
-
hashes = Object.keys(hashes).map(hash => this.delete(hash));
|
|
1049
|
+
hashes = Object.keys(hashes).map((hash) => this.delete(hash));
|
|
1048
1050
|
return Promise.all(hashes);
|
|
1049
1051
|
}
|
|
1050
1052
|
}
|
|
@@ -1060,7 +1062,7 @@ class Jobber {
|
|
|
1060
1062
|
const timeout = setTimeout(() => {
|
|
1061
1063
|
reject('timeout');
|
|
1062
1064
|
}, this.timeout);
|
|
1063
|
-
this.
|
|
1065
|
+
this.destroy = () => {
|
|
1064
1066
|
clearTimeout(timeout);
|
|
1065
1067
|
this.busy = false;
|
|
1066
1068
|
resolve('stopped');
|
|
@@ -1072,6 +1074,7 @@ class Jobber {
|
|
|
1072
1074
|
resolve(result);
|
|
1073
1075
|
}
|
|
1074
1076
|
catch (error) {
|
|
1077
|
+
clearTimeout(timeout);
|
|
1075
1078
|
reject(error);
|
|
1076
1079
|
}
|
|
1077
1080
|
});
|
|
@@ -1085,6 +1088,7 @@ class State extends Contract {
|
|
|
1085
1088
|
#resolving;
|
|
1086
1089
|
#resolveErrorCount;
|
|
1087
1090
|
#syncState;
|
|
1091
|
+
#chainState;
|
|
1088
1092
|
#lastBlockInQue;
|
|
1089
1093
|
#syncErrorCount;
|
|
1090
1094
|
#blockHashMap;
|
|
@@ -1094,6 +1098,12 @@ class State extends Contract {
|
|
|
1094
1098
|
#totalSize;
|
|
1095
1099
|
#machine;
|
|
1096
1100
|
#loaded;
|
|
1101
|
+
get state() {
|
|
1102
|
+
return {
|
|
1103
|
+
sync: this.#syncState,
|
|
1104
|
+
chain: this.#chainState
|
|
1105
|
+
};
|
|
1106
|
+
}
|
|
1097
1107
|
get blockHashMap() {
|
|
1098
1108
|
return this.#blockHashMap.entries();
|
|
1099
1109
|
}
|
|
@@ -1155,8 +1165,10 @@ class State extends Contract {
|
|
|
1155
1165
|
}
|
|
1156
1166
|
constructor() {
|
|
1157
1167
|
super();
|
|
1168
|
+
this.#lastResolvedTime = 0;
|
|
1158
1169
|
this.#resolving = false;
|
|
1159
1170
|
this.#resolveErrorCount = 0;
|
|
1171
|
+
this.#chainState = 'loading';
|
|
1160
1172
|
this.#syncErrorCount = 0;
|
|
1161
1173
|
this.#blockHashMap = new Map();
|
|
1162
1174
|
this.#chainSyncing = false;
|
|
@@ -1188,12 +1200,28 @@ class State extends Contract {
|
|
|
1188
1200
|
* {Number}
|
|
1189
1201
|
*/
|
|
1190
1202
|
this.#totalTransactions = 0;
|
|
1203
|
+
this.#chainStateHandler = () => {
|
|
1204
|
+
return new globalThis.peernet.protos['peernet-response']({
|
|
1205
|
+
response: this.#chainState
|
|
1206
|
+
});
|
|
1207
|
+
};
|
|
1208
|
+
this.#lastBlockHandler = async () => {
|
|
1209
|
+
return new globalThis.peernet.protos['peernet-response']({
|
|
1210
|
+
response: { hash: this.#lastBlock?.hash, index: this.#lastBlock?.index }
|
|
1211
|
+
});
|
|
1212
|
+
};
|
|
1213
|
+
this.#knownBlocksHandler = async () => {
|
|
1214
|
+
return new globalThis.peernet.protos['peernet-response']({
|
|
1215
|
+
response: { blocks: this.#blocks.map((block) => block.hash) }
|
|
1216
|
+
});
|
|
1217
|
+
};
|
|
1191
1218
|
this.#loadBlockTransactions = (transactions) => Promise.all(transactions.map((transaction) => new TransactionMessage(transaction)));
|
|
1192
1219
|
this.#getLastTransactions = async () => {
|
|
1193
|
-
let lastTransactions = (await Promise.all(this.#blocks
|
|
1194
|
-
.
|
|
1195
|
-
.
|
|
1196
|
-
|
|
1220
|
+
let lastTransactions = (await Promise.all(this.#blocks
|
|
1221
|
+
.filter((block) => block.loaded)
|
|
1222
|
+
.slice(-128)
|
|
1223
|
+
.map((block) => this.#loadBlockTransactions(block.transactions)))).reduce((all, transactions) => [...all, ...transactions], []);
|
|
1224
|
+
return Promise.all(lastTransactions.map((transaction) => transaction.hash()));
|
|
1197
1225
|
};
|
|
1198
1226
|
}
|
|
1199
1227
|
async clearPool() {
|
|
@@ -1208,12 +1236,16 @@ class State extends Contract {
|
|
|
1208
1236
|
await globalThis.blockStore.clear();
|
|
1209
1237
|
await globalThis.transactionPoolStore.clear();
|
|
1210
1238
|
}
|
|
1239
|
+
#chainStateHandler;
|
|
1240
|
+
#lastBlockHandler;
|
|
1241
|
+
#knownBlocksHandler;
|
|
1211
1242
|
async init() {
|
|
1212
|
-
this.jobber = new Jobber(
|
|
1243
|
+
this.jobber = new Jobber(this.resolveTimeout);
|
|
1213
1244
|
if (super.init)
|
|
1214
1245
|
await super.init();
|
|
1215
|
-
await globalThis.peernet.addRequestHandler('lastBlock', this.#lastBlockHandler
|
|
1216
|
-
await globalThis.peernet.addRequestHandler('knownBlocks', this.#knownBlocksHandler
|
|
1246
|
+
await globalThis.peernet.addRequestHandler('lastBlock', this.#lastBlockHandler);
|
|
1247
|
+
await globalThis.peernet.addRequestHandler('knownBlocks', this.#knownBlocksHandler);
|
|
1248
|
+
await globalThis.peernet.addRequestHandler('chainState', this.#chainStateHandler);
|
|
1217
1249
|
try {
|
|
1218
1250
|
let localBlock;
|
|
1219
1251
|
try {
|
|
@@ -1227,7 +1259,10 @@ class State extends Contract {
|
|
|
1227
1259
|
if (localBlock && localBlock !== '0x0') {
|
|
1228
1260
|
localBlock = await globalThis.peernet.get(localBlock, 'block');
|
|
1229
1261
|
localBlock = await new BlockMessage(localBlock);
|
|
1230
|
-
this.#lastBlock = {
|
|
1262
|
+
this.#lastBlock = {
|
|
1263
|
+
...localBlock.decoded,
|
|
1264
|
+
hash: await localBlock.hash()
|
|
1265
|
+
};
|
|
1231
1266
|
}
|
|
1232
1267
|
else {
|
|
1233
1268
|
if (globalThis.peernet?.connections.length > 0) {
|
|
@@ -1268,12 +1303,6 @@ class State extends Contract {
|
|
|
1268
1303
|
await globalThis.chainStore.put('lastBlock', hash);
|
|
1269
1304
|
globalThis.pubsub.publish('lastBlock', this.#lastBlock);
|
|
1270
1305
|
}
|
|
1271
|
-
async #lastBlockHandler() {
|
|
1272
|
-
return new globalThis.peernet.protos['peernet-response']({ response: { hash: this.#lastBlock?.hash, index: this.#lastBlock?.index } });
|
|
1273
|
-
}
|
|
1274
|
-
async #knownBlocksHandler() {
|
|
1275
|
-
return new globalThis.peernet.protos['peernet-response']({ response: { blocks: this.#blocks.map((block) => block.hash) } });
|
|
1276
|
-
}
|
|
1277
1306
|
getLatestBlock() {
|
|
1278
1307
|
// @ts-ignore
|
|
1279
1308
|
return this.#getLatestBlock();
|
|
@@ -1286,7 +1315,7 @@ class State extends Contract {
|
|
|
1286
1315
|
const { index } = block.decoded;
|
|
1287
1316
|
if (this.#blocks[index - 1] && this.#blocks[index - 1].hash !== block.hash)
|
|
1288
1317
|
throw `invalid block ${hash} @${index}`;
|
|
1289
|
-
if (!await globalThis.peernet.has(hash))
|
|
1318
|
+
if (!(await globalThis.peernet.has(hash)))
|
|
1290
1319
|
await globalThis.peernet.put(hash, block.encoded, 'block');
|
|
1291
1320
|
}
|
|
1292
1321
|
return block;
|
|
@@ -1314,8 +1343,6 @@ class State extends Contract {
|
|
|
1314
1343
|
this.#lastResolvedTime = Date.now();
|
|
1315
1344
|
}
|
|
1316
1345
|
catch (error) {
|
|
1317
|
-
this.#resolving = false;
|
|
1318
|
-
this.#chainSyncing = false;
|
|
1319
1346
|
throw new ResolveError(`block: ${hash}@${index}`);
|
|
1320
1347
|
}
|
|
1321
1348
|
return;
|
|
@@ -1328,6 +1355,8 @@ class State extends Contract {
|
|
|
1328
1355
|
if (this.#resolving)
|
|
1329
1356
|
return 'already resolving';
|
|
1330
1357
|
this.#resolving = true;
|
|
1358
|
+
if (this.jobber.busy && this.jobber.destroy)
|
|
1359
|
+
await this.jobber.destroy();
|
|
1331
1360
|
try {
|
|
1332
1361
|
await this.jobber.add(() => this.#resolveBlock(hash));
|
|
1333
1362
|
this.#resolving = false;
|
|
@@ -1337,6 +1366,7 @@ class State extends Contract {
|
|
|
1337
1366
|
catch (error) {
|
|
1338
1367
|
console.log({ error });
|
|
1339
1368
|
this.#resolveErrorCount += 1;
|
|
1369
|
+
this.#resolving = false;
|
|
1340
1370
|
if (this.#resolveErrorCount < 3)
|
|
1341
1371
|
return this.resolveBlock(hash);
|
|
1342
1372
|
this.#resolveErrorCount = 0;
|
|
@@ -1345,8 +1375,8 @@ class State extends Contract {
|
|
|
1345
1375
|
}
|
|
1346
1376
|
async resolveBlocks() {
|
|
1347
1377
|
try {
|
|
1348
|
-
if (this.jobber.busy && this.jobber.
|
|
1349
|
-
await this.jobber.
|
|
1378
|
+
if (this.jobber.busy && this.jobber.destroy) {
|
|
1379
|
+
await this.jobber.destroy();
|
|
1350
1380
|
}
|
|
1351
1381
|
}
|
|
1352
1382
|
catch (error) {
|
|
@@ -1362,10 +1392,10 @@ class State extends Contract {
|
|
|
1362
1392
|
}
|
|
1363
1393
|
catch (error) {
|
|
1364
1394
|
console.log(error);
|
|
1395
|
+
this.#chainSyncing = false;
|
|
1396
|
+
this.#syncState = 'errored';
|
|
1365
1397
|
this.#resolveErrored = true;
|
|
1366
|
-
this
|
|
1367
|
-
this.#resolving = false;
|
|
1368
|
-
this.restoreChain();
|
|
1398
|
+
return this.restoreChain();
|
|
1369
1399
|
// console.log(e);
|
|
1370
1400
|
}
|
|
1371
1401
|
}
|
|
@@ -1383,23 +1413,24 @@ class State extends Contract {
|
|
|
1383
1413
|
this.#resolveErrored = true;
|
|
1384
1414
|
this.#resolveErrorCount += 1;
|
|
1385
1415
|
this.#resolving = false;
|
|
1386
|
-
this.restoreChain();
|
|
1416
|
+
return this.restoreChain();
|
|
1387
1417
|
// console.log(e);
|
|
1388
1418
|
}
|
|
1389
1419
|
}
|
|
1420
|
+
destroyResolveJob() { }
|
|
1390
1421
|
async syncChain(lastBlock) {
|
|
1391
|
-
if (!this.shouldSync)
|
|
1422
|
+
if (!this.shouldSync)
|
|
1392
1423
|
return;
|
|
1393
|
-
|
|
1424
|
+
this.#syncState;
|
|
1425
|
+
this.#chainSyncing = true;
|
|
1394
1426
|
try {
|
|
1395
|
-
if (this.jobber.busy && this.jobber.
|
|
1396
|
-
await this.jobber.
|
|
1427
|
+
if (this.jobber.busy && this.jobber.destroy) {
|
|
1428
|
+
await this.jobber.destroy();
|
|
1397
1429
|
}
|
|
1398
1430
|
}
|
|
1399
1431
|
catch (error) {
|
|
1400
1432
|
console.error(error);
|
|
1401
1433
|
}
|
|
1402
|
-
this.#chainSyncing = true;
|
|
1403
1434
|
if (!lastBlock)
|
|
1404
1435
|
lastBlock = await this.#getLatestBlock();
|
|
1405
1436
|
console.log('starting sync');
|
|
@@ -1414,7 +1445,8 @@ class State extends Contract {
|
|
|
1414
1445
|
return this.syncChain(lastBlock);
|
|
1415
1446
|
this.#syncErrorCount = 0;
|
|
1416
1447
|
this.#chainSyncing = false;
|
|
1417
|
-
|
|
1448
|
+
this.#syncState = 'errored';
|
|
1449
|
+
return this.#syncState;
|
|
1418
1450
|
}
|
|
1419
1451
|
if (lastBlock.index === this.#lastBlockInQue?.index)
|
|
1420
1452
|
this.#lastBlockInQue = undefined;
|
|
@@ -1422,7 +1454,8 @@ class State extends Contract {
|
|
|
1422
1454
|
this.#chainSyncing = false;
|
|
1423
1455
|
if (this.#lastBlockInQue)
|
|
1424
1456
|
return this.syncChain(this.#lastBlockInQue);
|
|
1425
|
-
|
|
1457
|
+
this.#syncState = 'synced';
|
|
1458
|
+
return this.#syncState;
|
|
1426
1459
|
}
|
|
1427
1460
|
async #syncChain(lastBlock) {
|
|
1428
1461
|
try {
|
|
@@ -1443,7 +1476,7 @@ class State extends Contract {
|
|
|
1443
1476
|
console.log('ok');
|
|
1444
1477
|
let blocksSynced = localIndex > 0 ? (localIndex > index ? localIndex - index : index + -localIndex) : index;
|
|
1445
1478
|
globalThis.debug(`synced ${blocksSynced} ${blocksSynced > 1 ? 'blocks' : 'block'}`);
|
|
1446
|
-
const start =
|
|
1479
|
+
const start = this.#blocks.length - blocksSynced;
|
|
1447
1480
|
if (this.#machine)
|
|
1448
1481
|
await this.#loadBlocks(this.blocks.slice(start));
|
|
1449
1482
|
await this.updateState(new BlockMessage(this.#blocks[this.#blocks.length - 1]));
|
|
@@ -1456,7 +1489,9 @@ class State extends Contract {
|
|
|
1456
1489
|
}
|
|
1457
1490
|
async #getLatestBlock() {
|
|
1458
1491
|
let promises = [];
|
|
1459
|
-
let data = await new globalThis.peernet.protos['peernet-request']({
|
|
1492
|
+
let data = await new globalThis.peernet.protos['peernet-request']({
|
|
1493
|
+
request: 'lastBlock'
|
|
1494
|
+
});
|
|
1460
1495
|
let node = await globalThis.peernet.prepareMessage(data);
|
|
1461
1496
|
for (const peer of globalThis.peernet?.connections) {
|
|
1462
1497
|
// @ts-ignore
|
|
@@ -1488,7 +1523,9 @@ class State extends Contract {
|
|
|
1488
1523
|
latest = { ...message.decoded, hash };
|
|
1489
1524
|
const peer = promises[0].peer;
|
|
1490
1525
|
if (peer.connected && peer.version === this.version) {
|
|
1491
|
-
let data = await new globalThis.peernet.protos['peernet-request']({
|
|
1526
|
+
let data = await new globalThis.peernet.protos['peernet-request']({
|
|
1527
|
+
request: 'knownBlocks'
|
|
1528
|
+
});
|
|
1492
1529
|
let node = await globalThis.peernet.prepareMessage(data);
|
|
1493
1530
|
let message = await peer.request(node);
|
|
1494
1531
|
message = await new globalThis.peernet.protos['peernet-response'](message);
|
|
@@ -1504,6 +1541,7 @@ class State extends Contract {
|
|
|
1504
1541
|
* @param {Block[]} blocks
|
|
1505
1542
|
*/
|
|
1506
1543
|
async #loadBlocks(blocks) {
|
|
1544
|
+
this.#chainState = 'loading';
|
|
1507
1545
|
let poolTransactionKeys = await globalThis.transactionPoolStore.keys();
|
|
1508
1546
|
for (const block of blocks) {
|
|
1509
1547
|
if (block && !block.loaded) {
|
|
@@ -1556,6 +1594,7 @@ class State extends Contract {
|
|
|
1556
1594
|
globalThis.pubsub.publish('block-loaded', { ...block });
|
|
1557
1595
|
}
|
|
1558
1596
|
}
|
|
1597
|
+
this.#chainState = 'loaded';
|
|
1559
1598
|
return true;
|
|
1560
1599
|
}
|
|
1561
1600
|
promiseRequests(promises) {
|
|
@@ -1586,9 +1625,12 @@ class State extends Contract {
|
|
|
1586
1625
|
return true;
|
|
1587
1626
|
}
|
|
1588
1627
|
get shouldSync() {
|
|
1589
|
-
if (this
|
|
1590
|
-
|
|
1591
|
-
|
|
1628
|
+
if (this.#chainSyncing)
|
|
1629
|
+
return false;
|
|
1630
|
+
if (this.#resolveErrored ||
|
|
1631
|
+
this.#syncState === 'errored' ||
|
|
1632
|
+
this.#syncState === 'connectionless' ||
|
|
1633
|
+
(!this.canSync && this.#lastResolvedTime + this.resolveTimeout > Date.now()))
|
|
1592
1634
|
return true;
|
|
1593
1635
|
return false;
|
|
1594
1636
|
}
|
|
@@ -1608,7 +1650,7 @@ class VersionControl extends State {
|
|
|
1608
1650
|
super();
|
|
1609
1651
|
}
|
|
1610
1652
|
async init() {
|
|
1611
|
-
super.init && await super.init();
|
|
1653
|
+
super.init && (await super.init());
|
|
1612
1654
|
console.log('init');
|
|
1613
1655
|
try {
|
|
1614
1656
|
const version = await globalThis.chainStore.get('version');
|
|
@@ -1690,29 +1732,34 @@ class Chain extends VersionControl {
|
|
|
1690
1732
|
console.error(error);
|
|
1691
1733
|
}
|
|
1692
1734
|
const end = Date.now();
|
|
1693
|
-
console.log((
|
|
1735
|
+
console.log((end - start) / 1000 + ' s');
|
|
1694
1736
|
if (await this.hasTransactionToHandle())
|
|
1695
1737
|
return this.#runEpoch();
|
|
1696
1738
|
this.#runningEpoch = false;
|
|
1697
1739
|
// if (await this.hasTransactionToHandle() && !this.#runningEpoch) return this.#runEpoch()
|
|
1698
1740
|
}
|
|
1699
1741
|
async #setup() {
|
|
1700
|
-
const contracts = [
|
|
1742
|
+
const contracts = [
|
|
1743
|
+
{
|
|
1701
1744
|
address: addresses.contractFactory,
|
|
1702
1745
|
message: contractFactoryMessage
|
|
1703
|
-
},
|
|
1746
|
+
},
|
|
1747
|
+
{
|
|
1704
1748
|
address: addresses.nativeToken,
|
|
1705
1749
|
message: nativeTokenMessage
|
|
1706
|
-
},
|
|
1750
|
+
},
|
|
1751
|
+
{
|
|
1707
1752
|
address: addresses.validators,
|
|
1708
1753
|
message: validatorsMessage
|
|
1709
|
-
},
|
|
1754
|
+
},
|
|
1755
|
+
{
|
|
1710
1756
|
address: addresses.nameService,
|
|
1711
1757
|
message: nameServiceMessage
|
|
1712
|
-
}
|
|
1758
|
+
}
|
|
1759
|
+
];
|
|
1713
1760
|
await Promise.all(contracts.map(async ({ address, message }) => {
|
|
1714
1761
|
// @ts-ignore
|
|
1715
|
-
message = await new ContractMessage(Uint8Array.from(message.split(',').map(string => Number(string))));
|
|
1762
|
+
message = await new ContractMessage(Uint8Array.from(message.split(',').map((string) => Number(string))));
|
|
1716
1763
|
// @ts-ignore
|
|
1717
1764
|
await globalThis.contractStore.put(address, message.encoded);
|
|
1718
1765
|
}));
|
|
@@ -1734,7 +1781,7 @@ class Chain extends VersionControl {
|
|
|
1734
1781
|
return new BWMessage(globalThis.peernet.client.bw) || { up: 0, down: 0 };
|
|
1735
1782
|
});
|
|
1736
1783
|
// await globalThis.peernet.addRequestHandler('peerId', () => {
|
|
1737
|
-
// let node =
|
|
1784
|
+
// let node =
|
|
1738
1785
|
// globalThis.peernet.protos['peernet-response']({response: node.encoded})
|
|
1739
1786
|
// })
|
|
1740
1787
|
await globalThis.peernet.addRequestHandler('transactionPool', this.#transactionPoolHandler.bind(this));
|
|
@@ -1771,31 +1818,36 @@ class Chain extends VersionControl {
|
|
|
1771
1818
|
response = await new globalThis.peernet.protos['peernet-response'](new Uint8Array(Object.values(response)));
|
|
1772
1819
|
return response.decoded.response;
|
|
1773
1820
|
}
|
|
1821
|
+
async getPeerTransactionPool(peer) {
|
|
1822
|
+
const transactionsInPool = await this.#makeRequest(peer, 'transactionPool');
|
|
1823
|
+
// todo iterate vs getting all keys?
|
|
1824
|
+
const transactions = await globalThis.transactionPoolStore.keys();
|
|
1825
|
+
const transactionsToGet = [];
|
|
1826
|
+
for (const key of transactionsInPool) {
|
|
1827
|
+
!transactions.includes(key) &&
|
|
1828
|
+
!ignorelist.includes(key) &&
|
|
1829
|
+
transactionsToGet.push(transactionPoolStore.put(key, await peernet.get(key, 'transaction')));
|
|
1830
|
+
}
|
|
1831
|
+
return Promise.all(transactionsToGet);
|
|
1832
|
+
}
|
|
1774
1833
|
async #peerConnected(peer) {
|
|
1775
1834
|
// todo handle version changes
|
|
1776
1835
|
// for now just do nothing if version doesn't match
|
|
1777
1836
|
if (!peer.version || peer.version !== this.version)
|
|
1778
1837
|
return;
|
|
1779
1838
|
const lastBlock = await this.#makeRequest(peer, 'lastBlock');
|
|
1780
|
-
|
|
1781
|
-
const
|
|
1782
|
-
const transactionsToGet = [];
|
|
1783
|
-
for (const key of transactionsInPool) {
|
|
1784
|
-
if (!transactions.includes(key) && !ignorelist.includes(key))
|
|
1785
|
-
transactionsToGet.push(transactionPoolStore.put(key, (await peernet.get(key, 'transaction'))));
|
|
1786
|
-
}
|
|
1787
|
-
await Promise.all(transactionsToGet);
|
|
1839
|
+
const higherThenCurrentLocal = lastBlock.index > this.lastBlock?.index;
|
|
1840
|
+
const peerTransactionPool = (higherThenCurrentLocal && (await this.getPeerTransactionPool(peer))) || [];
|
|
1788
1841
|
if (Object.keys(lastBlock).length > 0) {
|
|
1789
|
-
if (!this.lastBlock ||
|
|
1842
|
+
if (!this.lastBlock || higherThenCurrentLocal) {
|
|
1790
1843
|
this.knownBlocks = await this.#makeRequest(peer, 'knownBlocks');
|
|
1791
1844
|
await this.syncChain(lastBlock);
|
|
1792
|
-
// if (await this.hasTransactionToHandle() && this.#participating) this.#runEpoch()
|
|
1793
1845
|
}
|
|
1794
1846
|
else if (!this.knownBlocks)
|
|
1795
1847
|
this.knownBlocks = await this.#makeRequest(peer, 'knownBlocks');
|
|
1796
1848
|
}
|
|
1797
|
-
if (this.#participating)
|
|
1798
|
-
this.#runEpoch();
|
|
1849
|
+
if (this.#participating && peerTransactionPool.length > 0)
|
|
1850
|
+
return this.#runEpoch();
|
|
1799
1851
|
}
|
|
1800
1852
|
#epochTimeout;
|
|
1801
1853
|
async #transactionPoolHandler() {
|
|
@@ -1874,7 +1926,7 @@ class Chain extends VersionControl {
|
|
|
1874
1926
|
// peerReputation(peerId)
|
|
1875
1927
|
// {bandwith: {up, down}, uptime}
|
|
1876
1928
|
this.#participating = true;
|
|
1877
|
-
if (!await this.staticCall(addresses.validators, 'has', [address])) {
|
|
1929
|
+
if (!(await this.staticCall(addresses.validators, 'has', [address]))) {
|
|
1878
1930
|
const rawTransaction = {
|
|
1879
1931
|
from: address,
|
|
1880
1932
|
to: addresses.validators,
|
|
@@ -1886,13 +1938,13 @@ class Chain extends VersionControl {
|
|
|
1886
1938
|
const transaction = await signTransaction(rawTransaction, globalThis.peernet.identity);
|
|
1887
1939
|
await this.sendTransaction(transaction);
|
|
1888
1940
|
}
|
|
1889
|
-
if (await this.hasTransactionToHandle() && !this.#runningEpoch && this.#participating)
|
|
1941
|
+
if ((await this.hasTransactionToHandle()) && !this.#runningEpoch && this.#participating)
|
|
1890
1942
|
await this.#runEpoch();
|
|
1891
1943
|
}
|
|
1892
1944
|
// todo filter tx that need to wait on prev nonce
|
|
1893
1945
|
async #createBlock(limit = this.transactionLimit) {
|
|
1894
1946
|
// vote for transactions
|
|
1895
|
-
if (await globalThis.transactionPoolStore.size() === 0)
|
|
1947
|
+
if ((await globalThis.transactionPoolStore.size()) === 0)
|
|
1896
1948
|
return;
|
|
1897
1949
|
let transactions = await globalThis.transactionPoolStore.values(this.transactionLimit);
|
|
1898
1950
|
for (const hash of await globalThis.transactionPoolStore.keys()) {
|
|
@@ -1985,7 +2037,7 @@ class Chain extends VersionControl {
|
|
|
1985
2037
|
}
|
|
1986
2038
|
}
|
|
1987
2039
|
}
|
|
1988
|
-
block.validators = block.validators.map(validator => {
|
|
2040
|
+
block.validators = block.validators.map((validator) => {
|
|
1989
2041
|
validator.reward = block.fees;
|
|
1990
2042
|
validator.reward = validator.reward.add(block.reward);
|
|
1991
2043
|
validator.reward = validator.reward.div(block.validators.length);
|
|
@@ -2003,8 +2055,7 @@ class Chain extends VersionControl {
|
|
|
2003
2055
|
// block.reward = block.reward.toString()
|
|
2004
2056
|
// block.fees = block.fees.toString()
|
|
2005
2057
|
try {
|
|
2006
|
-
block.transactions = await Promise.all(block.transactions
|
|
2007
|
-
.map(async (transaction) => {
|
|
2058
|
+
block.transactions = await Promise.all(block.transactions.map(async (transaction) => {
|
|
2008
2059
|
await globalThis.transactionPoolStore.delete(await transaction.hash());
|
|
2009
2060
|
return transaction.decoded;
|
|
2010
2061
|
}));
|