Skip to content

Commit bf5c007

Browse files
Merge pull request #110 from DIG-Network/release/v0.0.1-alpha.121
Release/v0.0.1 alpha.121
2 parents 0997049 + 4599cb4 commit bf5c007

File tree

4 files changed

+141
-3
lines changed

4 files changed

+141
-3
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22

33
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
44

5+
### [0.0.1-alpha.121](https://github.com/DIG-Network/dig-chia-sdk/compare/v0.0.1-alpha.120...v0.0.1-alpha.121) (2024-10-03)
6+
7+
8+
### Features
9+
10+
* add store monitor ([8a0997d](https://github.com/DIG-Network/dig-chia-sdk/commit/8a0997d0079c62db4bdd8f6c04eb94b749b66572))
11+
512
### [0.0.1-alpha.120](https://github.com/DIG-Network/dig-chia-sdk/compare/v0.0.1-alpha.119...v0.0.1-alpha.120) (2024-10-03)
613

714
### [0.0.1-alpha.119](https://github.com/DIG-Network/dig-chia-sdk/compare/v0.0.1-alpha.118...v0.0.1-alpha.119) (2024-10-03)

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@dignetwork/dig-sdk",
3-
"version": "0.0.1-alpha.120",
3+
"version": "0.0.1-alpha.121",
44
"description": "",
55
"type": "commonjs",
66
"main": "./dist/index.js",

src/blockchain/DataStore.ts

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import NodeCache from "node-cache";
4040
import { MAIN_NET_GENISES_CHALLENGE } from "../utils/config";
4141
import { StoreInfoCacheUpdater } from "./StoreInfoCacheUpdater";
4242
import { Environment } from "../utils";
43+
import { get } from "lodash";
4344

4445
// Initialize the cache with a TTL of 180 seconds (3 minutes)
4546
const rootHistoryCache = new NodeCache({ stdTTL: 180 });
@@ -50,6 +51,7 @@ const readdir = promisify(fs.readdir);
5051
export class DataStore {
5152
private storeId: string;
5253
private tree: DataIntegrityTree;
54+
private static activeMonitors: Map<string, boolean> = new Map();
5355

5456
constructor(storeId: string, options?: DataIntegrityTreeOptions) {
5557
this.storeId = storeId;
@@ -66,6 +68,10 @@ export class DataStore {
6668
}
6769

6870
this.tree = new DataIntegrityTree(storeId, _options);
71+
72+
if (!Environment.CLI_MODE) {
73+
DataStore.monitorStoreIndefinitely(this.storeId);
74+
}
6975
}
7076

7177
public get StoreId(): string {
@@ -308,6 +314,131 @@ export class DataStore {
308314
return storIds.map((storeId) => DataStore.from(storeId));
309315
}
310316

317+
/**
318+
* Monitors the store indefinitely by syncing it with a peer.
319+
* Logs store retrieval and caching operations. If an error occurs, logs the error and restarts the process after a short delay.
320+
* Only one monitor can be active per storeId.
321+
* @param {string} storeId - The store identifier to monitor.
322+
* @returns {Promise<void>} Never resolves; runs indefinitely.
323+
*/
324+
public static async monitorStoreIndefinitely(storeId: string): Promise<void> {
325+
// Check if a monitor is already running for this storeId
326+
if (this.activeMonitors.get(storeId)) {
327+
console.log(`Monitor already running for storeId: ${storeId}`);
328+
return;
329+
}
330+
331+
// Set the monitor as active
332+
this.activeMonitors.set(storeId, true);
333+
334+
const storeCoinCache = new FileCache<{
335+
latestStore: ReturnType<DataStoreSerializer["serialize"]>;
336+
latestHeight: number;
337+
latestHash: string;
338+
}>(`stores`);
339+
340+
// Clear the cache at the start
341+
console.log(`Clearing cache for storeId: ${storeId}`);
342+
storeCoinCache.delete(storeId);
343+
344+
while (true) {
345+
try {
346+
console.log(`Connecting to peer for storeId: ${storeId}`);
347+
const peer = await FullNodePeer.connect();
348+
const cachedInfo = storeCoinCache.get(storeId);
349+
350+
if (cachedInfo) {
351+
// Log cached store info retrieval
352+
console.log(
353+
`Cached store info found for storeId: ${storeId}, syncing...`
354+
);
355+
356+
// Deserialize cached info and wait for the coin to be spent
357+
const previousStore = DataStoreSerializer.deserialize({
358+
latestStore: cachedInfo.latestStore,
359+
latestHeight: cachedInfo.latestHeight.toString(),
360+
latestHash: cachedInfo.latestHash,
361+
});
362+
363+
console.log(
364+
`Waiting for coin to be spent for storeId: ${storeId}...`
365+
);
366+
await peer.waitForCoinToBeSpent(
367+
getCoinId(previousStore.latestStore.coin),
368+
previousStore.latestHeight,
369+
previousStore.latestHash
370+
);
371+
372+
// Sync store and get updated details
373+
console.log(`Syncing store for storeId: ${storeId}`);
374+
const { latestStore, latestHeight } = await peer.syncStore(
375+
previousStore.latestStore,
376+
previousStore.latestHeight,
377+
previousStore.latestHash,
378+
false
379+
);
380+
const latestHash = await peer.getHeaderHash(latestHeight);
381+
382+
// Serialize and cache the updated store info
383+
const serializedLatestStore = new DataStoreSerializer(
384+
latestStore,
385+
latestHeight,
386+
latestHash
387+
).serialize();
388+
389+
console.log(`Caching updated store info for storeId: ${storeId}`);
390+
storeCoinCache.set(storeId, {
391+
latestStore: serializedLatestStore,
392+
latestHeight,
393+
latestHash: latestHash.toString("hex"),
394+
});
395+
396+
continue; // Continue monitoring
397+
}
398+
399+
// If no cached info exists, log and sync from the creation height
400+
console.log(
401+
`No cached info found for storeId: ${storeId}. Retrieving creation height.`
402+
);
403+
404+
const dataStore = DataStore.from(storeId);
405+
const { createdAtHeight, createdAtHash } = await dataStore.getCreationHeight();
406+
407+
// Sync store from the peer using launcher ID
408+
console.log(`Syncing store from launcher ID for storeId: ${storeId}`);
409+
const { latestStore, latestHeight } = await peer.syncStoreFromLauncherId(
410+
Buffer.from(storeId, "hex"),
411+
createdAtHeight,
412+
createdAtHash,
413+
false
414+
);
415+
416+
const latestHash = await peer.getHeaderHash(latestHeight);
417+
418+
// Serialize and cache the new store info
419+
const serializedLatestStore = new DataStoreSerializer(
420+
latestStore,
421+
latestHeight,
422+
latestHash
423+
).serialize();
424+
425+
console.log(`Caching new store info for storeId: ${storeId}`);
426+
storeCoinCache.set(storeId, {
427+
latestStore: serializedLatestStore,
428+
latestHeight,
429+
latestHash: latestHash.toString("hex"),
430+
});
431+
} catch (error: any) {
432+
console.error(
433+
`Error in monitorStoreIndefinitely for storeId: ${storeId} - ${error.message}`
434+
);
435+
436+
// Delay before restarting to avoid rapid retries
437+
await new Promise((resolve) => setTimeout(resolve, 5000));
438+
}
439+
}
440+
}
441+
311442
public async fetchCoinInfo(): Promise<{
312443
latestStore: DataStoreDriver;
313444
latestHeight: number;

0 commit comments

Comments
 (0)