@dignetwork/dig-sdk 0.0.1-alpha.47 → 0.0.1-alpha.49

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.
@@ -154,7 +154,7 @@ declare class DataIntegrityTree {
154
154
  * @param expectedRootHash - The expected root hash of the Merkle tree.
155
155
  * @returns A boolean indicating if the SHA-256 is present in the foreign tree and the root hash matches.
156
156
  */
157
- static validateKeyIntegrityWithForeignTree(key: string, sha256: string, serializedTree: object, expectedRootHash: string): boolean;
157
+ static validateKeyIntegrityWithForeignTree(hexkey: string, sha256: string, serializedTree: object, expectedRootHash: string, dataDir: string): Promise<boolean>;
158
158
  }
159
159
  export { DataIntegrityTree };
160
160
  //# sourceMappingURL=DataIntegrityTree.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"DataIntegrityTree.d.ts","sourceRoot":"","sources":["../../src/DataIntegrityTree/DataIntegrityTree.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DataIntegrityTree.d.ts","sourceRoot":"","sources":["../../src/DataIntegrityTree/DataIntegrityTree.ts"],"names":[],"mappings":"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"}
@@ -634,8 +634,8 @@ class DataIntegrityTree {
634
634
  * @param expectedRootHash - The expected root hash of the Merkle tree.
635
635
  * @returns A boolean indicating if the SHA-256 is present in the foreign tree and the root hash matches.
636
636
  */
637
- static validateKeyIntegrityWithForeignTree(key, sha256, serializedTree, expectedRootHash) {
638
- if (!isHexString(key)) {
637
+ static async validateKeyIntegrityWithForeignTree(hexkey, sha256, serializedTree, expectedRootHash, dataDir) {
638
+ if (!isHexString(hexkey)) {
639
639
  throw new Error("key must be a valid hex string");
640
640
  }
641
641
  if (!isHexString(sha256)) {
@@ -644,29 +644,59 @@ class DataIntegrityTree {
644
644
  if (!isHexString(expectedRootHash)) {
645
645
  throw new Error("expectedRootHash must be a valid hex string");
646
646
  }
647
- // Deserialize the foreign tree
648
- const leaves = serializedTree.leaves.map((leaf) => Buffer.from(leaf, "hex"));
649
- const tree = new merkletreejs_1.MerkleTree(leaves, crypto_js_1.SHA256, { sortPairs: true });
650
- // Verify that the deserialized tree's root matches the expected root hash
651
- const treeRootHash = tree.getRoot().toString("hex");
652
- if (treeRootHash !== expectedRootHash) {
653
- console.warn(`Expected root hash ${expectedRootHash}, but got ${treeRootHash}`);
654
- return false;
647
+ // File path based on sha256
648
+ const filePath = path.join(dataDir, sha256.match(/.{1,2}/g).join("/"));
649
+ // Check if the file exists
650
+ if (!fs.existsSync(filePath)) {
651
+ throw new Error(`File at path ${filePath} does not exist`);
655
652
  }
656
- // Rebuild the files map from the serialized tree
657
- // @ts-ignore
658
- tree.files = new Map(Object.entries(serializedTree.files).map(([key, value]) => [
659
- key,
660
- { hash: value.hash, sha256: value.sha256 },
661
- ]));
662
- // Check if the SHA-256 exists in the foreign tree's files
663
- const combinedHash = crypto
664
- .createHash("sha256")
665
- .update(`${toHex(key)}/${sha256}`)
666
- .digest("hex");
667
- const leaf = Buffer.from(combinedHash, "hex");
668
- const isInTree = tree.getLeafIndex(leaf) !== -1;
669
- return isInTree;
653
+ const compressedReadStream = fs.createReadStream(filePath);
654
+ const decompressStream = zlib.createGunzip();
655
+ const hash = crypto.createHash("sha256");
656
+ // Process file decompression and hash comparison
657
+ return new Promise((resolve, reject) => {
658
+ compressedReadStream.pipe(decompressStream);
659
+ decompressStream.on("data", (chunk) => {
660
+ hash.update(chunk);
661
+ });
662
+ decompressStream.on("end", () => {
663
+ const uncompressedSha256 = hash.digest("hex");
664
+ console.log(`SHA-256 of uncompressed file: ${uncompressedSha256}`);
665
+ if (uncompressedSha256 !== sha256) {
666
+ console.warn(`File hash mismatch. Expected: ${sha256}, got: ${uncompressedSha256}`);
667
+ return resolve(false);
668
+ }
669
+ // Deserialize the foreign tree
670
+ const leaves = serializedTree.leaves.map((leaf) => Buffer.from(leaf, "hex"));
671
+ const tree = new merkletreejs_1.MerkleTree(leaves, crypto_js_1.SHA256, { sortPairs: true });
672
+ // Verify that the deserialized tree's root matches the expected root hash
673
+ const treeRootHash = tree.getRoot().toString("hex");
674
+ if (treeRootHash !== expectedRootHash) {
675
+ console.warn(`Expected root hash ${expectedRootHash}, but got ${treeRootHash}`);
676
+ return resolve(false);
677
+ }
678
+ // Rebuild the files map from the serialized tree
679
+ // @ts-ignore
680
+ tree.files = new Map(Object.entries(serializedTree.files).map(([key, value]) => [
681
+ key,
682
+ { hash: value.hash, sha256: value.sha256 },
683
+ ]));
684
+ // Check if the SHA-256 exists in the foreign tree's files
685
+ const combinedHash = crypto
686
+ .createHash("sha256")
687
+ .update(`${hexkey}/${sha256}`)
688
+ .digest("hex");
689
+ const leaf = Buffer.from(combinedHash, "hex");
690
+ const isInTree = tree.getLeafIndex(leaf) !== -1;
691
+ resolve(isInTree);
692
+ });
693
+ decompressStream.on("error", (err) => {
694
+ reject(err);
695
+ });
696
+ compressedReadStream.on("error", (err) => {
697
+ reject(err);
698
+ });
699
+ });
670
700
  }
671
701
  }
672
702
  exports.DataIntegrityTree = DataIntegrityTree;
@@ -1 +1 @@
1
- {"version":3,"file":"DigNetwork.d.ts","sourceRoot":"","sources":["../../src/DigNetwork/DigNetwork.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWpC,qBAAa,UAAU;IACrB,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,aAAa,CAA2B;gBAEpC,OAAO,EAAE,MAAM;YAOb,eAAe;IA8ChB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAsDhD,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;WA6BrC,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;WAQhD,oBAAoB,CACtC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,GAAG,CAAC,EAAE,MAAM,EACZ,eAAe,GAAE,MAAM,EAAO,GAC7B,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;WAyDZ,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAQ5C,aAAa,CACxB,aAAa,GAAE,OAAe,EAC9B,iBAAiB,GAAE,OAAc,EACjC,QAAQ,GAAE,OAAe,GACxB,OAAO,CAAC,IAAI,CAAC;YAqHF,mBAAmB;YAWnB,kBAAkB;YASlB,oBAAoB;YASpB,qBAAqB;YAsFrB,cAAc;CAoB7B"}
1
+ {"version":3,"file":"DigNetwork.d.ts","sourceRoot":"","sources":["../../src/DigNetwork/DigNetwork.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAYpC,qBAAa,UAAU;IACrB,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,aAAa,CAA2B;gBAEpC,OAAO,EAAE,MAAM;YAOb,eAAe;IA8ChB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAsDhD,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;WA6BrC,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;WAQhD,oBAAoB,CACtC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,GAAG,CAAC,EAAE,MAAM,EACZ,eAAe,GAAE,MAAM,EAAO,GAC7B,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;WAyDZ,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAQ5C,aAAa,CACxB,aAAa,GAAE,OAAe,EAC9B,iBAAiB,GAAE,OAAc,EACjC,QAAQ,GAAE,OAAe,GACxB,OAAO,CAAC,IAAI,CAAC;YAkJF,mBAAmB;YAWnB,kBAAkB;YASlB,oBAAoB;YASpB,qBAAqB;YAsFrB,cAAc;CAoB7B"}
@@ -33,6 +33,7 @@ const hashUtils_1 = require("../utils/hashUtils");
33
33
  const blockchain_1 = require("../blockchain");
34
34
  const config_1 = require("../utils/config");
35
35
  const util_1 = require("util");
36
+ const DataIntegrityTree_1 = require("../DataIntegrityTree");
36
37
  const rename = (0, util_1.promisify)(fs.rename);
37
38
  const unlink = (0, util_1.promisify)(fs.unlink);
38
39
  class DigNetwork {
@@ -162,7 +163,7 @@ class DigNetwork {
162
163
  peerBlackList.push(peerIp);
163
164
  }
164
165
  catch (error) {
165
- console.error(`Error connecting to peer ${peerIp}. Resampling...`);
166
+ console.error(`Error connecting to DIG Peer ${peerIp}. Resampling...`);
166
167
  if (peerIp) {
167
168
  peerBlackList.push(peerIp); // Add to blacklist if error occurs
168
169
  }
@@ -192,6 +193,7 @@ class DigNetwork {
192
193
  const rootHistoryFiltered = rootHistory
193
194
  .filter((item) => item.timestamp !== undefined)
194
195
  .filter((item) => !fs.existsSync(`${this.storeDir}/${item.root_hash}.dat`))
196
+ // Reverse to download the latest first
195
197
  .reverse();
196
198
  if (!rootHistoryFiltered.length) {
197
199
  console.log("All root hashes already exist locally. No need for download.");
@@ -212,10 +214,16 @@ class DigNetwork {
212
214
  // Sequential file download
213
215
  for (const [storeKey, file] of Object.entries(root.files)) {
214
216
  const filePath = (0, hashUtils_1.getFilePathFromSha256)(file.sha256, `${this.storeDir}/data`);
215
- if (!fs.existsSync(filePath) || forceDownload) {
216
- console.log(`Downloading file with sha256: ${file.sha256}...`);
217
- await selectedPeer.downloadData(this.dataStore.StoreId, `data/${file.sha256.match(/.{1,2}/g).join("/")}`);
217
+ console.log(`Downloading file with sha256: ${file.sha256}...`);
218
+ await selectedPeer.downloadData(this.dataStore.StoreId, `data/${file.sha256.match(/.{1,2}/g).join("/")}`);
219
+ const integrityCheck = await DataIntegrityTree_1.DataIntegrityTree.validateKeyIntegrityWithForeignTree(storeKey, file.sha256, root, rootInfo.root_hash, `${this.storeDir}/data`);
220
+ if (integrityCheck) {
221
+ console.log(`\x1b[32mIntegrity check passed for file with sha256: ${file.sha256}.\x1b[0m`);
222
+ continue;
218
223
  }
224
+ console.error(`\x1b[31mIntegrity check failed for file with sha256: ${file.sha256}.\x1b[0m`);
225
+ await unlink(filePath);
226
+ throw new Error(`Store Integrity check failed. Syncing file from another peer.`);
219
227
  }
220
228
  }
221
229
  fs.writeFileSync(`${this.storeDir}/${rootInfo.root_hash}.dat`, rootResponse);
@@ -230,6 +238,10 @@ class DigNetwork {
230
238
  }
231
239
  }
232
240
  }
241
+ // Only process the first root hash so other stores can sync the latest.
242
+ // This has an effect where the latest roothash will always be synced first, even if new ones come in.
243
+ // Then it will backfill historical roothashes
244
+ break;
233
245
  }
234
246
  await this.downloadManifestFile(true);
235
247
  console.log("Syncing store complete.");
@@ -238,6 +250,7 @@ class DigNetwork {
238
250
  if (selectedPeer) {
239
251
  peerBlackList.push(selectedPeer.IpAddress);
240
252
  }
253
+ console.trace(error);
241
254
  throw error;
242
255
  }
243
256
  }
@@ -264,13 +277,13 @@ class DigNetwork {
264
277
  return;
265
278
  const blacklist = this.peerBlacklist.get(dataPath) || new Set();
266
279
  for (const digPeer of digPeers) {
267
- if (blacklist.has(digPeer.IpAddress))
268
- continue;
269
- const response = await digPeer.propagationServer.headStore();
270
- if (!response.success) {
271
- continue;
272
- }
273
280
  try {
281
+ if (blacklist.has(digPeer.IpAddress))
282
+ continue;
283
+ const response = await digPeer.propagationServer.headStore();
284
+ if (!response.success) {
285
+ continue;
286
+ }
274
287
  // Create directory if it doesn't exist
275
288
  const directory = path.dirname(tempFilePath);
276
289
  if (!fs.existsSync(directory)) {
@@ -1 +1 @@
1
- {"version":3,"file":"DigPeer.d.ts","sourceRoot":"","sources":["../../src/DigNetwork/DigPeer.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAIpD,OAAO,EAKL,MAAM,EACP,MAAM,8BAA8B,CAAC;AAUtC,qBAAa,OAAO;IAClB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,cAAc,CAAgB;IACtC,OAAO,CAAC,kBAAkB,CAAoB;IAC9C,OAAO,CAAC,gBAAgB,CAAkB;gBAE9B,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;IAS9C,IAAW,aAAa,IAAI,aAAa,CAExC;IAGD,IAAW,iBAAiB,IAAI,iBAAiB,CAEhD;IAGD,IAAW,eAAe,IAAI,eAAe,CAE5C;IAED,IAAW,SAAS,IAAI,MAAM,CAE7B;IAEY,aAAa,CACxB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EAAE,GACb,OAAO,CAAC,OAAO,CAAC;IAgHN,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC;WA2B3B,qBAAqB,CACjC,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EAAE,EACnB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EAAE,GACd,OAAO,CAAC,IAAI,CAAC;WAuBI,gBAAgB,CAClC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EAAE,GAChB,OAAO,CAAC,IAAI,CAAC;IAwCH,WAAW,CACtB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,KAAK,GAAE,MAAM,EAAO,GACnB,OAAO,CAAC,IAAI,CAAC;WAYF,iBAAiB,CAAC,OAAO,EAAE,MAAM;IAqBlC,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CA4C5E"}
1
+ {"version":3,"file":"DigPeer.d.ts","sourceRoot":"","sources":["../../src/DigNetwork/DigPeer.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAKpD,OAAO,EAKL,MAAM,EACP,MAAM,8BAA8B,CAAC;AAUtC,qBAAa,OAAO;IAClB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,cAAc,CAAgB;IACtC,OAAO,CAAC,kBAAkB,CAAoB;IAC9C,OAAO,CAAC,gBAAgB,CAAkB;gBAE9B,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;IAS9C,IAAW,aAAa,IAAI,aAAa,CAExC;IAGD,IAAW,iBAAiB,IAAI,iBAAiB,CAEhD;IAGD,IAAW,eAAe,IAAI,eAAe,CAE5C;IAED,IAAW,SAAS,IAAI,MAAM,CAE7B;IAEY,aAAa,CACxB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EAAE,GACb,OAAO,CAAC,OAAO,CAAC;IAiHN,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC;WA2B3B,qBAAqB,CACjC,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EAAE,EACnB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EAAE,GACd,OAAO,CAAC,IAAI,CAAC;WAuBI,gBAAgB,CAClC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EAAE,GAChB,OAAO,CAAC,IAAI,CAAC;IAwCH,WAAW,CACtB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,KAAK,GAAE,MAAM,EAAO,GACnB,OAAO,CAAC,IAAI,CAAC;WAYF,iBAAiB,CAAC,OAAO,EAAE,MAAM;IAqBlC,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CA4C5E"}
@@ -11,12 +11,13 @@ const PropagationServer_1 = require("./PropagationServer");
11
11
  const IncentiveServer_1 = require("./IncentiveServer");
12
12
  const blockchain_1 = require("../blockchain");
13
13
  const DataIntegrityTree_1 = require("../DataIntegrityTree");
14
+ const config_1 = require("../utils/config");
14
15
  const fs_1 = __importDefault(require("fs"));
15
16
  const datalayer_driver_1 = require("@dignetwork/datalayer-driver");
16
17
  const blockchain_2 = require("../blockchain");
17
18
  const blockchain_3 = require("../blockchain");
18
19
  const coins_1 = require("../blockchain/coins");
19
- const config_1 = require("../utils/config");
20
+ const config_2 = require("../utils/config");
20
21
  const util_1 = require("util");
21
22
  const rename = (0, util_1.promisify)(fs_1.default.rename);
22
23
  const unlink = (0, util_1.promisify)(fs_1.default.unlink);
@@ -103,7 +104,7 @@ class DigPeer {
103
104
  });
104
105
  });
105
106
  // Perform tree integrity validation using the datFileContent and the root hash
106
- const treeCheck = DataIntegrityTree_1.DataIntegrityTree.validateKeyIntegrityWithForeignTree(key, fileData.sha256, datFileContent, rootHash);
107
+ const treeCheck = DataIntegrityTree_1.DataIntegrityTree.validateKeyIntegrityWithForeignTree(key, fileData.sha256, datFileContent, rootHash, path_1.default.resolve(config_1.DIG_FOLDER_PATH, "stores", this.storeId, 'data'));
107
108
  if (!treeCheck) {
108
109
  console.error(`Tree validation failed for file ${key}.`);
109
110
  filesIntegrityIntact = false;
@@ -202,7 +203,7 @@ class DigPeer {
202
203
  return transformedBuffer;
203
204
  }
204
205
  async downloadData(storeId, dataPath) {
205
- const filePath = path_1.default.join(config_1.STORE_PATH, storeId, dataPath);
206
+ const filePath = path_1.default.join(config_2.STORE_PATH, storeId, dataPath);
206
207
  const tempFilePath = `${filePath}.tmp`;
207
208
  try {
208
209
  const headStoreResponse = await this.propagationServer.headStore();
@@ -3,6 +3,7 @@ export declare class FullNodePeer {
3
3
  private static cachedPeer;
4
4
  private static memoizedFetchNewPeerIPs;
5
5
  private peer;
6
+ private static deprioritizedIps;
6
7
  private constructor();
7
8
  static connect(): Promise<Peer>;
8
9
  private static isPortReachable;
@@ -1 +1 @@
1
- {"version":3,"file":"FullNodePeer.d.ts","sourceRoot":"","sources":["../../src/blockchain/FullNodePeer.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAC;AAmBpD,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAC,UAAU,CAAkD;IAC3E,OAAO,CAAC,MAAM,CAAC,uBAAuB,CAA0B;IAChE,OAAO,CAAC,IAAI,CAAO;IAQnB,OAAO;WAIa,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAK5C,OAAO,CAAC,MAAM,CAAC,eAAe;IAiB9B,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAM/B;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,kBAAkB;mBASZ,eAAe;mBAiDf,UAAU;IAyB/B,OAAO,CAAC,MAAM,CAAC,eAAe;mBAgDT,WAAW;IAgGzB,OAAO,IAAI,IAAI;WAIF,mBAAmB,CACrC,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,OAAO,CAAC;CAwBpB"}
1
+ {"version":3,"file":"FullNodePeer.d.ts","sourceRoot":"","sources":["../../src/blockchain/FullNodePeer.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAC;AAoBpD,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAC,UAAU,CAAkD;IAC3E,OAAO,CAAC,MAAM,CAAC,uBAAuB,CAA0B;IAChE,OAAO,CAAC,IAAI,CAAO;IACnB,OAAO,CAAC,MAAM,CAAC,gBAAgB,CAA0B;IAMzD,OAAO;WAIa,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAK5C,OAAO,CAAC,MAAM,CAAC,eAAe;IAiB9B,OAAO,CAAC,MAAM,CAAC,gBAAgB;IAM/B;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,kBAAkB;mBASZ,eAAe;mBA2Df,UAAU;IA2B/B,OAAO,CAAC,MAAM,CAAC,eAAe;mBAkDT,WAAW;IA+FzB,OAAO,IAAI,IAAI;WAIF,mBAAmB,CACrC,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,OAAO,CAAC;CAwBpB"}
@@ -16,6 +16,7 @@ const nanospinner_1 = require("nanospinner");
16
16
  const config_1 = require("../utils/config");
17
17
  const FULLNODE_PORT = 8444;
18
18
  const LOCALHOST = "127.0.0.1";
19
+ const CHIA_NODES_HOST = "chia-nodes";
19
20
  const DNS_HOSTS = [
20
21
  "dns-introducer.chia.net",
21
22
  "chia.ctrlaltdel.ch",
@@ -64,15 +65,22 @@ class FullNodePeer {
64
65
  static async fetchNewPeerIPs() {
65
66
  const trustedNodeIp = FullNodePeer.getTrustedFullNode();
66
67
  const priorityIps = [];
67
- // Prioritize trustedNodeIp
68
+ // Prioritize trustedNodeIp unless it's deprioritized
68
69
  if (trustedNodeIp &&
70
+ !FullNodePeer.deprioritizedIps.has(trustedNodeIp) &&
69
71
  (await FullNodePeer.isPortReachable(trustedNodeIp, FULLNODE_PORT))) {
70
72
  priorityIps.push(trustedNodeIp);
71
73
  }
72
- // Prioritize LOCALHOST
73
- if (await FullNodePeer.isPortReachable(LOCALHOST, FULLNODE_PORT)) {
74
+ // Prioritize LOCALHOST unless it's deprioritized
75
+ if (!FullNodePeer.deprioritizedIps.has(LOCALHOST) &&
76
+ (await FullNodePeer.isPortReachable(LOCALHOST, FULLNODE_PORT))) {
74
77
  priorityIps.push(LOCALHOST);
75
78
  }
79
+ // Prioritize CHIA_NODES_HOST unless it's deprioritized
80
+ if (!FullNodePeer.deprioritizedIps.has(CHIA_NODES_HOST) &&
81
+ (await FullNodePeer.isPortReachable(CHIA_NODES_HOST, FULLNODE_PORT))) {
82
+ priorityIps.push(CHIA_NODES_HOST);
83
+ }
76
84
  if (priorityIps.length > 0) {
77
85
  return priorityIps;
78
86
  }
@@ -114,6 +122,8 @@ class FullNodePeer {
114
122
  }
115
123
  // @ts-ignore
116
124
  if (FullNodePeer.memoizedFetchNewPeerIPs?.cache?.clear) {
125
+ // Clear cache and reset deprioritized IPs when cache is cleared
126
+ FullNodePeer.deprioritizedIps.clear();
117
127
  // @ts-ignore
118
128
  FullNodePeer.memoizedFetchNewPeerIPs.cache.clear();
119
129
  }
@@ -151,6 +161,8 @@ class FullNodePeer {
151
161
  FullNodePeer.cachedPeer = null;
152
162
  // @ts-ignore
153
163
  FullNodePeer.memoizedFetchNewPeerIPs.cache.clear();
164
+ FullNodePeer.deprioritizedIps.clear();
165
+ console.info(`Fullnode Peer error, reconnecting to a new peer...`);
154
166
  const newPeer = await FullNodePeer.getBestPeer();
155
167
  return newPeer[prop](...args);
156
168
  }
@@ -206,10 +218,11 @@ class FullNodePeer {
206
218
  throw new Error("No valid peak heights obtained from any peer.");
207
219
  }
208
220
  const highestPeak = Math.max(...validHeights);
209
- // Prioritize LOCALHOST and TRUSTED_NODE_IP if they have the highest peak height
221
+ // Prioritize LOCALHOST, TRUSTED_NODE_IP, and CHIA_NODES_HOST if they have the highest peak height
210
222
  let bestPeerIndex = validHeights.findIndex((height, index) => height === highestPeak &&
211
- (peerIPs[index] === LOCALHOST || peerIPs[index] === trustedNodeIp));
212
- // If LOCALHOST or TRUSTED_NODE_IP don't have the highest peak, select any peer with the highest peak
223
+ !FullNodePeer.deprioritizedIps.has(peerIPs[index]) && // Exclude deprioritized IPs
224
+ (peerIPs[index] === LOCALHOST || peerIPs[index] === trustedNodeIp || peerIPs[index] === CHIA_NODES_HOST));
225
+ // If LOCALHOST, TRUSTED_NODE_IP, or CHIA_NODES_HOST don't have the highest peak, select any peer with the highest peak
213
226
  if (bestPeerIndex === -1) {
214
227
  bestPeerIndex = validHeights.findIndex((height) => height === highestPeak);
215
228
  }
@@ -242,6 +255,7 @@ class FullNodePeer {
242
255
  }
243
256
  exports.FullNodePeer = FullNodePeer;
244
257
  FullNodePeer.cachedPeer = null;
258
+ FullNodePeer.deprioritizedIps = new Set(); // New set for deprioritized IPs
245
259
  (() => {
246
260
  FullNodePeer.memoizedFetchNewPeerIPs = (0, lodash_1.memoize)(FullNodePeer.fetchNewPeerIPs);
247
261
  })();
@@ -1 +1 @@
1
- {"version":3,"file":"ServerCoin.d.ts","sourceRoot":"","sources":["../../src/blockchain/ServerCoin.ts"],"names":[],"mappings":"AACA,OAAO,EAML,UAAU,IAAI,gBAAgB,EAE/B,MAAM,8BAA8B,CAAC;AAItC,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAMrD,qBAAa,UAAU;IACrB,OAAO,CAAC,OAAO,CAAS;IACxB,gBAAuB,iBAAiB,eAEtC;gBAEU,OAAO,EAAE,MAAM;IAKd,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA2DzD,kBAAkB,CAC7B,UAAU,EAAE,gBAAgB,EAC5B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC;IAqBH,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAoDjD,oBAAoB;IAerB,gBAAgB,CAC3B,KAAK,EAAE,MAAM,EACb,SAAS,GAAE,MAAM,EAAO,GACvB,OAAO,CAAC,MAAM,EAAE,CAAC;IAoCP,mBAAmB,CAC9B,SAAS,GAAE,MAAM,EAAO,GACvB,OAAO,CAAC,MAAM,EAAE,CAAC;IAMP,kBAAkB,CAC7B,UAAU,GAAE,MAAU,EACtB,SAAS,GAAE,MAAM,EAAO,GACvB,OAAO,CAAC,MAAM,EAAE,CAAC;IAMP,wBAAwB,CACnC,KAAK,EAAE,MAAM,EACb,UAAU,GAAE,MAAU,EACtB,SAAS,GAAE,MAAM,EAAO,GACvB,OAAO,CAAC,MAAM,EAAE,CAAC;WAON,eAAe,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE;IAKpD,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiDrD,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;WA+B1C,uBAAuB;YAkE7B,sBAAsB;IAWvB,uBAAuB,CAClC,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,OAAO,CAAC;WAuBL,sBAAsB,CAAC,mBAAmB,EAAE,IAAI,GAAG;QAC/D,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;KACf;CA2BF"}
1
+ {"version":3,"file":"ServerCoin.d.ts","sourceRoot":"","sources":["../../src/blockchain/ServerCoin.ts"],"names":[],"mappings":"AACA,OAAO,EAML,UAAU,IAAI,gBAAgB,EAE/B,MAAM,8BAA8B,CAAC;AAItC,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAUrD,qBAAa,UAAU;IACrB,OAAO,CAAC,OAAO,CAAS;IACxB,gBAAuB,iBAAiB,eAEtC;gBAEU,OAAO,EAAE,MAAM;IAKd,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA2DzD,kBAAkB,CAC7B,UAAU,EAAE,gBAAgB,EAC5B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC;IAqBH,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAoDjD,oBAAoB;IAerB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,GAAE,MAAM,EAAO,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IA2C5E,mBAAmB,CAC9B,SAAS,GAAE,MAAM,EAAO,GACvB,OAAO,CAAC,MAAM,EAAE,CAAC;IAMP,kBAAkB,CAC7B,UAAU,GAAE,MAAU,EACtB,SAAS,GAAE,MAAM,EAAO,GACvB,OAAO,CAAC,MAAM,EAAE,CAAC;IAMP,wBAAwB,CACnC,KAAK,EAAE,MAAM,EACb,UAAU,GAAE,MAAU,EACtB,SAAS,GAAE,MAAM,EAAO,GACvB,OAAO,CAAC,MAAM,EAAE,CAAC;WASN,eAAe,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE;IAKpD,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiDrD,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;WA+B1C,uBAAuB;YAkE7B,sBAAsB;IAWvB,uBAAuB,CAClC,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,OAAO,CAAC;WAuBL,sBAAsB,CAAC,mBAAmB,EAAE,IAAI,GAAG;QAC/D,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;KACf;CA2BF"}
@@ -11,7 +11,10 @@ const coins_1 = require("./coins");
11
11
  const Wallet_1 = require("./Wallet");
12
12
  const NconfManager_1 = require("../utils/NconfManager");
13
13
  const DataStore_1 = require("./DataStore");
14
+ const node_cache_1 = __importDefault(require("node-cache"));
14
15
  const serverCoinCollateral = 300000000;
16
+ // Initialize the cache with a TTL of 300 seconds (5 minutes)
17
+ const serverCoinPeersCache = new node_cache_1.default({ stdTTL: 300 });
15
18
  class ServerCoin {
16
19
  constructor(storeId) {
17
20
  this.storeId = storeId;
@@ -95,6 +98,12 @@ class ServerCoin {
95
98
  await ServerCoin.serverCoinManager.setConfigValue(`${this.storeId}:${peerIp}`, serverCoins);
96
99
  }
97
100
  async getAllEpochPeers(epoch, blacklist = []) {
101
+ const cacheKey = `serverCoinPeers-${this.storeId}-${epoch}`;
102
+ // Check if the result is already cached
103
+ const cachedPeers = serverCoinPeersCache.get(cacheKey);
104
+ if (cachedPeers) {
105
+ return cachedPeers;
106
+ }
98
107
  const epochBasedHint = (0, datalayer_driver_1.morphLauncherId)(Buffer.from(this.storeId, "hex"), BigInt(epoch));
99
108
  const peer = await FullNodePeer_1.FullNodePeer.connect();
100
109
  const maxClvmCost = BigInt(11000000000);
@@ -112,7 +121,10 @@ class ServerCoin {
112
121
  if (process.env.DIG_DEBUG === "1") {
113
122
  console.log("Server Coin Peers: ", serverCoinPeers);
114
123
  }
115
- return Array.from(serverCoinPeers);
124
+ const peerList = Array.from(serverCoinPeers);
125
+ // Cache the result
126
+ serverCoinPeersCache.set(cacheKey, peerList);
127
+ return peerList;
116
128
  }
117
129
  async getActiveEpochPeers(blacklist = []) {
118
130
  const { epoch } = ServerCoin.getCurrentEpoch();
@@ -126,7 +138,9 @@ class ServerCoin {
126
138
  // Sample server coins by epoch
127
139
  async sampleServerCoinsByEpoch(epoch, sampleSize = 5, blacklist = []) {
128
140
  const serverCoinPeers = await this.getAllEpochPeers(epoch, blacklist);
129
- console.log("Server Coin Peers: ", serverCoinPeers);
141
+ if (process.env.DIG_DEBUG === "1") {
142
+ console.log("Server Coin Peers: ", serverCoinPeers);
143
+ }
130
144
  return lodash_1.default.sampleSize(serverCoinPeers, sampleSize);
131
145
  }
132
146
  // Get the current epoch based on the current timestamp
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dignetwork/dig-sdk",
3
- "version": "0.0.1-alpha.47",
3
+ "version": "0.0.1-alpha.49",
4
4
  "description": "",
5
5
  "type": "commonjs",
6
6
  "main": "./dist/index.js",
@@ -41,6 +41,7 @@
41
41
  "merkletreejs": "^0.4.0",
42
42
  "nanospinner": "^1.1.0",
43
43
  "nconf": "^0.12.1",
44
+ "node-cache": "^5.1.2",
44
45
  "p-limit": "^6.1.0",
45
46
  "superagent": "^10.0.0"
46
47
  },