@leofcoin/chain 1.7.148 → 1.7.150
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 +112 -50
- package/exports/chain.js +112 -50
- package/exports/state.d.ts +1 -1
- package/package.json +1 -1
package/exports/browser/chain.js
CHANGED
|
@@ -4646,6 +4646,9 @@ class State extends Contract {
|
|
|
4646
4646
|
#totalSize;
|
|
4647
4647
|
#machine;
|
|
4648
4648
|
#loaded;
|
|
4649
|
+
#resolvingBlocks;
|
|
4650
|
+
#maxConcurrentResolves;
|
|
4651
|
+
#blockResolveQueue;
|
|
4649
4652
|
/**
|
|
4650
4653
|
* contains transactions we need before we can successfully load
|
|
4651
4654
|
*/
|
|
@@ -4735,6 +4738,9 @@ class State extends Contract {
|
|
|
4735
4738
|
this.#totalSize = 0;
|
|
4736
4739
|
this.#loaded = false;
|
|
4737
4740
|
this._wantList = [];
|
|
4741
|
+
this.#resolvingBlocks = new Set();
|
|
4742
|
+
this.#maxConcurrentResolves = 10;
|
|
4743
|
+
this.#blockResolveQueue = [];
|
|
4738
4744
|
this.#chainStateHandler = () => {
|
|
4739
4745
|
return new globalThis.peernet.protos['peernet-response']({
|
|
4740
4746
|
response: this.#chainState
|
|
@@ -4873,45 +4879,40 @@ class State extends Contract {
|
|
|
4873
4879
|
return block;
|
|
4874
4880
|
}
|
|
4875
4881
|
async #resolveBlock(hash) {
|
|
4876
|
-
|
|
4877
|
-
|
|
4878
|
-
try {
|
|
4879
|
-
if (await globalThis.stateStore.has('lastBlock'))
|
|
4880
|
-
localHash = await globalThis.stateStore.get('lastBlock');
|
|
4882
|
+
if (this.#resolvingBlocks.has(hash)) {
|
|
4883
|
+
return; // Already resolving this block
|
|
4881
4884
|
}
|
|
4882
|
-
|
|
4883
|
-
|
|
4884
|
-
|
|
4885
|
-
|
|
4886
|
-
|
|
4887
|
-
|
|
4888
|
-
if (this.#blocks[index]) {
|
|
4889
|
-
// Block already exists, check if we need to resolve previous blocks
|
|
4890
|
-
const previousHash = this.#blocks[index].previousHash;
|
|
4891
|
-
if (previousHash === localHash)
|
|
4892
|
-
return;
|
|
4893
|
-
if (previousHash !== '0x0') {
|
|
4894
|
-
// Previous block not in memory, recursively resolve it
|
|
4895
|
-
return this.resolveBlock(previousHash);
|
|
4896
|
-
}
|
|
4897
|
-
else {
|
|
4898
|
-
// Previous block already exists or is genesis, stop resolving
|
|
4885
|
+
this.#resolvingBlocks.add(hash);
|
|
4886
|
+
try {
|
|
4887
|
+
let index = this.#blockHashMap.get(hash);
|
|
4888
|
+
debug$1(`resolving block: ${hash} @${index !== undefined ? index : 'unknown'}`);
|
|
4889
|
+
if (this.#blocks[index]) {
|
|
4890
|
+
// Block already exists
|
|
4899
4891
|
return;
|
|
4900
4892
|
}
|
|
4901
|
-
}
|
|
4902
|
-
try {
|
|
4903
4893
|
const block = await this.getAndPutBlock(hash);
|
|
4904
|
-
await Promise.all(block.decoded.transactions.map(async (hash) => {
|
|
4905
|
-
// should be in a transaction store already
|
|
4906
|
-
if (!(await transactionStore.has(hash))) {
|
|
4907
|
-
const data = await peernet.get(hash, 'transaction');
|
|
4908
|
-
await transactionStore.put(hash, data);
|
|
4909
|
-
}
|
|
4910
|
-
;
|
|
4911
|
-
(await transactionPoolStore.has(hash)) && (await transactionPoolStore.delete(hash));
|
|
4912
|
-
}));
|
|
4913
4894
|
index = block.decoded.index;
|
|
4914
4895
|
const size = block.encoded.length > 0 ? block.encoded.length : block.encoded.byteLength;
|
|
4896
|
+
// Batch transaction operations
|
|
4897
|
+
const transactionsToFetch = [];
|
|
4898
|
+
const transactionHashes = block.decoded.transactions || [];
|
|
4899
|
+
for (const txHash of transactionHashes) {
|
|
4900
|
+
if (!(await globalThis.transactionStore.has(txHash))) {
|
|
4901
|
+
transactionsToFetch.push(txHash);
|
|
4902
|
+
}
|
|
4903
|
+
}
|
|
4904
|
+
// Fetch all missing transactions in parallel
|
|
4905
|
+
if (transactionsToFetch.length > 0) {
|
|
4906
|
+
const fetchedTransactions = await Promise.all(transactionsToFetch.map((txHash) => globalThis.peernet.get(txHash, 'transaction')));
|
|
4907
|
+
// Batch store all transactions
|
|
4908
|
+
await Promise.all(transactionsToFetch.map((txHash, i) => globalThis.transactionStore.put(txHash, fetchedTransactions[i])));
|
|
4909
|
+
}
|
|
4910
|
+
// Remove from pool
|
|
4911
|
+
await Promise.all(transactionHashes.map(async (txHash) => {
|
|
4912
|
+
if (await globalThis.transactionPoolStore.has(txHash)) {
|
|
4913
|
+
await globalThis.transactionPoolStore.delete(txHash);
|
|
4914
|
+
}
|
|
4915
|
+
}));
|
|
4915
4916
|
this.#totalSize += size;
|
|
4916
4917
|
this.#blocks[index] = { hash, ...block.decoded };
|
|
4917
4918
|
this.#blockHashMap.set(hash, index);
|
|
@@ -4921,42 +4922,103 @@ class State extends Contract {
|
|
|
4921
4922
|
this.#lastResolvedTime = Date.now();
|
|
4922
4923
|
}
|
|
4923
4924
|
catch (error) {
|
|
4924
|
-
throw new ResolveError(`block: ${hash}
|
|
4925
|
+
throw new ResolveError(`block: ${hash}`);
|
|
4925
4926
|
}
|
|
4926
|
-
|
|
4927
|
+
finally {
|
|
4928
|
+
this.#resolvingBlocks.delete(hash);
|
|
4929
|
+
}
|
|
4930
|
+
}
|
|
4931
|
+
async #buildBlockChain(latestHash, maxBlocks = 1000) {
|
|
4932
|
+
const chain = [];
|
|
4933
|
+
let currentHash = latestHash;
|
|
4934
|
+
let attempts = 0;
|
|
4935
|
+
while (currentHash !== '0x0' && chain.length < maxBlocks && attempts < maxBlocks + 5) {
|
|
4936
|
+
attempts++;
|
|
4937
|
+
// Check if we already have this block
|
|
4938
|
+
if (this.#blockHashMap.has(currentHash)) {
|
|
4939
|
+
const block = this.#blocks[this.#blockHashMap.get(currentHash)];
|
|
4940
|
+
if (block) {
|
|
4941
|
+
chain.push(currentHash);
|
|
4942
|
+
currentHash = block.previousHash;
|
|
4943
|
+
continue;
|
|
4944
|
+
}
|
|
4945
|
+
}
|
|
4946
|
+
chain.push(currentHash);
|
|
4947
|
+
// Try to get the block to find previous hash
|
|
4948
|
+
try {
|
|
4949
|
+
const block = await this.getAndPutBlock(currentHash);
|
|
4950
|
+
currentHash = block.decoded.previousHash;
|
|
4951
|
+
}
|
|
4952
|
+
catch (error) {
|
|
4953
|
+
debug$1(`Could not fetch block ${currentHash} to determine chain: ${error}`);
|
|
4954
|
+
break;
|
|
4955
|
+
}
|
|
4956
|
+
}
|
|
4957
|
+
return chain;
|
|
4958
|
+
}
|
|
4959
|
+
async #resolveBlocksInParallel(hashes) {
|
|
4960
|
+
// Resolve blocks in parallel with concurrency limit
|
|
4961
|
+
const resolving = [];
|
|
4962
|
+
let index = 0;
|
|
4963
|
+
const resolveNext = async () => {
|
|
4964
|
+
while (index < hashes.length) {
|
|
4965
|
+
const hash = hashes[index++];
|
|
4966
|
+
try {
|
|
4967
|
+
await this.#resolveBlock(hash);
|
|
4968
|
+
}
|
|
4969
|
+
catch (error) {
|
|
4970
|
+
debug$1(`Failed to resolve block ${hash}: ${error}`);
|
|
4971
|
+
this.#blockResolveQueue.push({ hash, retries: 0 });
|
|
4972
|
+
}
|
|
4973
|
+
}
|
|
4974
|
+
};
|
|
4975
|
+
// Start concurrent resolution tasks
|
|
4976
|
+
for (let i = 0; i < Math.min(this.#maxConcurrentResolves, hashes.length); i++) {
|
|
4977
|
+
resolving.push(resolveNext());
|
|
4978
|
+
}
|
|
4979
|
+
await Promise.all(resolving);
|
|
4927
4980
|
}
|
|
4928
4981
|
async resolveBlock(hash) {
|
|
4929
4982
|
if (!hash)
|
|
4930
4983
|
throw new Error(`expected hash, got: ${hash}`);
|
|
4931
4984
|
if (hash === '0x0')
|
|
4932
4985
|
return;
|
|
4933
|
-
if (this.#resolving)
|
|
4934
|
-
|
|
4986
|
+
if (this.#resolving) {
|
|
4987
|
+
debug$1('Already resolving, queueing block');
|
|
4988
|
+
return;
|
|
4989
|
+
}
|
|
4935
4990
|
this.#resolving = true;
|
|
4936
|
-
if (this.jobber.busy && this.jobber.destroy)
|
|
4937
|
-
await this.jobber.destroy();
|
|
4938
4991
|
try {
|
|
4939
|
-
|
|
4992
|
+
// Build the entire block chain from latest to genesis
|
|
4993
|
+
debug$1(`Building block chain from ${hash}`);
|
|
4994
|
+
const blockChain = await this.#buildBlockChain(hash);
|
|
4995
|
+
debug$1(`Built chain of ${blockChain.length} blocks`);
|
|
4996
|
+
// Resolve all blocks in parallel
|
|
4997
|
+
if (blockChain.length > 0) {
|
|
4998
|
+
await this.#resolveBlocksInParallel(blockChain);
|
|
4999
|
+
}
|
|
4940
5000
|
this.#resolving = false;
|
|
5001
|
+
this.#resolveErrorCount = 0;
|
|
5002
|
+
this.#resolveErrored = false;
|
|
4941
5003
|
try {
|
|
4942
5004
|
const lastBlockHash = await globalThis.stateStore.get('lastBlock');
|
|
4943
5005
|
if (lastBlockHash === hash) {
|
|
4944
|
-
|
|
5006
|
+
debug$1('Resolved to latest block state');
|
|
4945
5007
|
return;
|
|
4946
5008
|
}
|
|
4947
5009
|
}
|
|
4948
5010
|
catch (error) {
|
|
4949
5011
|
debug$1('no local state found');
|
|
4950
5012
|
}
|
|
4951
|
-
if (!this.#blockHashMap.has(this.#lastResolved.previousHash) && this.#lastResolved.previousHash !== '0x0')
|
|
4952
|
-
return this.resolveBlock(this.#lastResolved.previousHash);
|
|
4953
5013
|
}
|
|
4954
5014
|
catch (error) {
|
|
4955
5015
|
console.log({ error });
|
|
4956
5016
|
this.#resolveErrorCount += 1;
|
|
4957
5017
|
this.#resolving = false;
|
|
4958
|
-
if (this.#resolveErrorCount < 3)
|
|
5018
|
+
if (this.#resolveErrorCount < 3) {
|
|
5019
|
+
debug$1(`Retry ${this.#resolveErrorCount}/3 for block ${hash}`);
|
|
4959
5020
|
return this.resolveBlock(hash);
|
|
5021
|
+
}
|
|
4960
5022
|
this.#resolveErrorCount = 0;
|
|
4961
5023
|
this.wantList.push(hash);
|
|
4962
5024
|
throw new ResolveError(`block: ${hash}`, { cause: error });
|
|
@@ -5157,7 +5219,7 @@ class State extends Contract {
|
|
|
5157
5219
|
let node = await globalThis.peernet.prepareMessage(data);
|
|
5158
5220
|
let message = await peer.request(node.encode());
|
|
5159
5221
|
message = await new globalThis.peernet.protos['peernet-response'](message);
|
|
5160
|
-
this.
|
|
5222
|
+
this.wantList.push(...message.decoded.response);
|
|
5161
5223
|
}
|
|
5162
5224
|
}
|
|
5163
5225
|
return latest;
|
|
@@ -5906,11 +5968,11 @@ class Chain extends VersionControl {
|
|
|
5906
5968
|
const higherThenCurrentLocal = !localBlock?.index ? true : lastBlock.index > localBlock.index;
|
|
5907
5969
|
if (lastBlock) {
|
|
5908
5970
|
if (!this.lastBlock || higherThenCurrentLocal) {
|
|
5909
|
-
|
|
5910
|
-
|
|
5911
|
-
|
|
5912
|
-
|
|
5913
|
-
|
|
5971
|
+
const knownBlocksResponse = await this.#makeRequest(peer, 'knownBlocks');
|
|
5972
|
+
if (knownBlocksResponse.blocks)
|
|
5973
|
+
for (const hash of knownBlocksResponse.blocks) {
|
|
5974
|
+
this.wantList.push(hash);
|
|
5975
|
+
}
|
|
5914
5976
|
}
|
|
5915
5977
|
}
|
|
5916
5978
|
if (this.wantList.length > 0) {
|
package/exports/chain.js
CHANGED
|
@@ -786,6 +786,9 @@ class State extends Contract {
|
|
|
786
786
|
#totalSize;
|
|
787
787
|
#machine;
|
|
788
788
|
#loaded;
|
|
789
|
+
#resolvingBlocks;
|
|
790
|
+
#maxConcurrentResolves;
|
|
791
|
+
#blockResolveQueue;
|
|
789
792
|
/**
|
|
790
793
|
* contains transactions we need before we can successfully load
|
|
791
794
|
*/
|
|
@@ -875,6 +878,9 @@ class State extends Contract {
|
|
|
875
878
|
this.#totalSize = 0;
|
|
876
879
|
this.#loaded = false;
|
|
877
880
|
this._wantList = [];
|
|
881
|
+
this.#resolvingBlocks = new Set();
|
|
882
|
+
this.#maxConcurrentResolves = 10;
|
|
883
|
+
this.#blockResolveQueue = [];
|
|
878
884
|
this.#chainStateHandler = () => {
|
|
879
885
|
return new globalThis.peernet.protos['peernet-response']({
|
|
880
886
|
response: this.#chainState
|
|
@@ -1013,45 +1019,40 @@ class State extends Contract {
|
|
|
1013
1019
|
return block;
|
|
1014
1020
|
}
|
|
1015
1021
|
async #resolveBlock(hash) {
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
try {
|
|
1019
|
-
if (await globalThis.stateStore.has('lastBlock'))
|
|
1020
|
-
localHash = await globalThis.stateStore.get('lastBlock');
|
|
1022
|
+
if (this.#resolvingBlocks.has(hash)) {
|
|
1023
|
+
return; // Already resolving this block
|
|
1021
1024
|
}
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
if (this.#blocks[index]) {
|
|
1029
|
-
// Block already exists, check if we need to resolve previous blocks
|
|
1030
|
-
const previousHash = this.#blocks[index].previousHash;
|
|
1031
|
-
if (previousHash === localHash)
|
|
1032
|
-
return;
|
|
1033
|
-
if (previousHash !== '0x0') {
|
|
1034
|
-
// Previous block not in memory, recursively resolve it
|
|
1035
|
-
return this.resolveBlock(previousHash);
|
|
1036
|
-
}
|
|
1037
|
-
else {
|
|
1038
|
-
// Previous block already exists or is genesis, stop resolving
|
|
1025
|
+
this.#resolvingBlocks.add(hash);
|
|
1026
|
+
try {
|
|
1027
|
+
let index = this.#blockHashMap.get(hash);
|
|
1028
|
+
debug$1(`resolving block: ${hash} @${index !== undefined ? index : 'unknown'}`);
|
|
1029
|
+
if (this.#blocks[index]) {
|
|
1030
|
+
// Block already exists
|
|
1039
1031
|
return;
|
|
1040
1032
|
}
|
|
1041
|
-
}
|
|
1042
|
-
try {
|
|
1043
1033
|
const block = await this.getAndPutBlock(hash);
|
|
1044
|
-
await Promise.all(block.decoded.transactions.map(async (hash) => {
|
|
1045
|
-
// should be in a transaction store already
|
|
1046
|
-
if (!(await transactionStore.has(hash))) {
|
|
1047
|
-
const data = await peernet.get(hash, 'transaction');
|
|
1048
|
-
await transactionStore.put(hash, data);
|
|
1049
|
-
}
|
|
1050
|
-
;
|
|
1051
|
-
(await transactionPoolStore.has(hash)) && (await transactionPoolStore.delete(hash));
|
|
1052
|
-
}));
|
|
1053
1034
|
index = block.decoded.index;
|
|
1054
1035
|
const size = block.encoded.length > 0 ? block.encoded.length : block.encoded.byteLength;
|
|
1036
|
+
// Batch transaction operations
|
|
1037
|
+
const transactionsToFetch = [];
|
|
1038
|
+
const transactionHashes = block.decoded.transactions || [];
|
|
1039
|
+
for (const txHash of transactionHashes) {
|
|
1040
|
+
if (!(await globalThis.transactionStore.has(txHash))) {
|
|
1041
|
+
transactionsToFetch.push(txHash);
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
// Fetch all missing transactions in parallel
|
|
1045
|
+
if (transactionsToFetch.length > 0) {
|
|
1046
|
+
const fetchedTransactions = await Promise.all(transactionsToFetch.map((txHash) => globalThis.peernet.get(txHash, 'transaction')));
|
|
1047
|
+
// Batch store all transactions
|
|
1048
|
+
await Promise.all(transactionsToFetch.map((txHash, i) => globalThis.transactionStore.put(txHash, fetchedTransactions[i])));
|
|
1049
|
+
}
|
|
1050
|
+
// Remove from pool
|
|
1051
|
+
await Promise.all(transactionHashes.map(async (txHash) => {
|
|
1052
|
+
if (await globalThis.transactionPoolStore.has(txHash)) {
|
|
1053
|
+
await globalThis.transactionPoolStore.delete(txHash);
|
|
1054
|
+
}
|
|
1055
|
+
}));
|
|
1055
1056
|
this.#totalSize += size;
|
|
1056
1057
|
this.#blocks[index] = { hash, ...block.decoded };
|
|
1057
1058
|
this.#blockHashMap.set(hash, index);
|
|
@@ -1061,42 +1062,103 @@ class State extends Contract {
|
|
|
1061
1062
|
this.#lastResolvedTime = Date.now();
|
|
1062
1063
|
}
|
|
1063
1064
|
catch (error) {
|
|
1064
|
-
throw new ResolveError(`block: ${hash}
|
|
1065
|
+
throw new ResolveError(`block: ${hash}`);
|
|
1066
|
+
}
|
|
1067
|
+
finally {
|
|
1068
|
+
this.#resolvingBlocks.delete(hash);
|
|
1069
|
+
}
|
|
1070
|
+
}
|
|
1071
|
+
async #buildBlockChain(latestHash, maxBlocks = 1000) {
|
|
1072
|
+
const chain = [];
|
|
1073
|
+
let currentHash = latestHash;
|
|
1074
|
+
let attempts = 0;
|
|
1075
|
+
while (currentHash !== '0x0' && chain.length < maxBlocks && attempts < maxBlocks + 5) {
|
|
1076
|
+
attempts++;
|
|
1077
|
+
// Check if we already have this block
|
|
1078
|
+
if (this.#blockHashMap.has(currentHash)) {
|
|
1079
|
+
const block = this.#blocks[this.#blockHashMap.get(currentHash)];
|
|
1080
|
+
if (block) {
|
|
1081
|
+
chain.push(currentHash);
|
|
1082
|
+
currentHash = block.previousHash;
|
|
1083
|
+
continue;
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
chain.push(currentHash);
|
|
1087
|
+
// Try to get the block to find previous hash
|
|
1088
|
+
try {
|
|
1089
|
+
const block = await this.getAndPutBlock(currentHash);
|
|
1090
|
+
currentHash = block.decoded.previousHash;
|
|
1091
|
+
}
|
|
1092
|
+
catch (error) {
|
|
1093
|
+
debug$1(`Could not fetch block ${currentHash} to determine chain: ${error}`);
|
|
1094
|
+
break;
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
return chain;
|
|
1098
|
+
}
|
|
1099
|
+
async #resolveBlocksInParallel(hashes) {
|
|
1100
|
+
// Resolve blocks in parallel with concurrency limit
|
|
1101
|
+
const resolving = [];
|
|
1102
|
+
let index = 0;
|
|
1103
|
+
const resolveNext = async () => {
|
|
1104
|
+
while (index < hashes.length) {
|
|
1105
|
+
const hash = hashes[index++];
|
|
1106
|
+
try {
|
|
1107
|
+
await this.#resolveBlock(hash);
|
|
1108
|
+
}
|
|
1109
|
+
catch (error) {
|
|
1110
|
+
debug$1(`Failed to resolve block ${hash}: ${error}`);
|
|
1111
|
+
this.#blockResolveQueue.push({ hash, retries: 0 });
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
};
|
|
1115
|
+
// Start concurrent resolution tasks
|
|
1116
|
+
for (let i = 0; i < Math.min(this.#maxConcurrentResolves, hashes.length); i++) {
|
|
1117
|
+
resolving.push(resolveNext());
|
|
1065
1118
|
}
|
|
1066
|
-
|
|
1119
|
+
await Promise.all(resolving);
|
|
1067
1120
|
}
|
|
1068
1121
|
async resolveBlock(hash) {
|
|
1069
1122
|
if (!hash)
|
|
1070
1123
|
throw new Error(`expected hash, got: ${hash}`);
|
|
1071
1124
|
if (hash === '0x0')
|
|
1072
1125
|
return;
|
|
1073
|
-
if (this.#resolving)
|
|
1074
|
-
|
|
1126
|
+
if (this.#resolving) {
|
|
1127
|
+
debug$1('Already resolving, queueing block');
|
|
1128
|
+
return;
|
|
1129
|
+
}
|
|
1075
1130
|
this.#resolving = true;
|
|
1076
|
-
if (this.jobber.busy && this.jobber.destroy)
|
|
1077
|
-
await this.jobber.destroy();
|
|
1078
1131
|
try {
|
|
1079
|
-
|
|
1132
|
+
// Build the entire block chain from latest to genesis
|
|
1133
|
+
debug$1(`Building block chain from ${hash}`);
|
|
1134
|
+
const blockChain = await this.#buildBlockChain(hash);
|
|
1135
|
+
debug$1(`Built chain of ${blockChain.length} blocks`);
|
|
1136
|
+
// Resolve all blocks in parallel
|
|
1137
|
+
if (blockChain.length > 0) {
|
|
1138
|
+
await this.#resolveBlocksInParallel(blockChain);
|
|
1139
|
+
}
|
|
1080
1140
|
this.#resolving = false;
|
|
1141
|
+
this.#resolveErrorCount = 0;
|
|
1142
|
+
this.#resolveErrored = false;
|
|
1081
1143
|
try {
|
|
1082
1144
|
const lastBlockHash = await globalThis.stateStore.get('lastBlock');
|
|
1083
1145
|
if (lastBlockHash === hash) {
|
|
1084
|
-
|
|
1146
|
+
debug$1('Resolved to latest block state');
|
|
1085
1147
|
return;
|
|
1086
1148
|
}
|
|
1087
1149
|
}
|
|
1088
1150
|
catch (error) {
|
|
1089
1151
|
debug$1('no local state found');
|
|
1090
1152
|
}
|
|
1091
|
-
if (!this.#blockHashMap.has(this.#lastResolved.previousHash) && this.#lastResolved.previousHash !== '0x0')
|
|
1092
|
-
return this.resolveBlock(this.#lastResolved.previousHash);
|
|
1093
1153
|
}
|
|
1094
1154
|
catch (error) {
|
|
1095
1155
|
console.log({ error });
|
|
1096
1156
|
this.#resolveErrorCount += 1;
|
|
1097
1157
|
this.#resolving = false;
|
|
1098
|
-
if (this.#resolveErrorCount < 3)
|
|
1158
|
+
if (this.#resolveErrorCount < 3) {
|
|
1159
|
+
debug$1(`Retry ${this.#resolveErrorCount}/3 for block ${hash}`);
|
|
1099
1160
|
return this.resolveBlock(hash);
|
|
1161
|
+
}
|
|
1100
1162
|
this.#resolveErrorCount = 0;
|
|
1101
1163
|
this.wantList.push(hash);
|
|
1102
1164
|
throw new ResolveError(`block: ${hash}`, { cause: error });
|
|
@@ -1297,7 +1359,7 @@ class State extends Contract {
|
|
|
1297
1359
|
let node = await globalThis.peernet.prepareMessage(data);
|
|
1298
1360
|
let message = await peer.request(node.encode());
|
|
1299
1361
|
message = await new globalThis.peernet.protos['peernet-response'](message);
|
|
1300
|
-
this.
|
|
1362
|
+
this.wantList.push(...message.decoded.response);
|
|
1301
1363
|
}
|
|
1302
1364
|
}
|
|
1303
1365
|
return latest;
|
|
@@ -2046,11 +2108,11 @@ class Chain extends VersionControl {
|
|
|
2046
2108
|
const higherThenCurrentLocal = !localBlock?.index ? true : lastBlock.index > localBlock.index;
|
|
2047
2109
|
if (lastBlock) {
|
|
2048
2110
|
if (!this.lastBlock || higherThenCurrentLocal) {
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2111
|
+
const knownBlocksResponse = await this.#makeRequest(peer, 'knownBlocks');
|
|
2112
|
+
if (knownBlocksResponse.blocks)
|
|
2113
|
+
for (const hash of knownBlocksResponse.blocks) {
|
|
2114
|
+
this.wantList.push(hash);
|
|
2115
|
+
}
|
|
2054
2116
|
}
|
|
2055
2117
|
}
|
|
2056
2118
|
if (this.wantList.length > 0) {
|
package/exports/state.d.ts
CHANGED
|
@@ -53,7 +53,7 @@ export default class State extends Contract {
|
|
|
53
53
|
updateState(message: BlockMessage): Promise<void>;
|
|
54
54
|
getLatestBlock(): Promise<BlockMessage['decoded']>;
|
|
55
55
|
getAndPutBlock(hash: string): Promise<BlockMessage>;
|
|
56
|
-
resolveBlock(hash:
|
|
56
|
+
resolveBlock(hash: string): Promise<void>;
|
|
57
57
|
resolveBlocks(): Promise<any>;
|
|
58
58
|
restoreChain(): any;
|
|
59
59
|
syncChain(lastBlock?: any): Promise<SyncState>;
|