diff --git a/demo/scripts/setupTypeScript.js b/demo/scripts/setupTypeScript.js index 40c7a68..78bd6e7 100644 --- a/demo/scripts/setupTypeScript.js +++ b/demo/scripts/setupTypeScript.js @@ -127,8 +127,8 @@ fs.writeFileSync(path.join(projectRoot, ".vscode", "extensions.json"), `{ } `) -//console.log("Converted to TypeScript.") +////console.log("Converted to TypeScript.") if (fs.existsSync(path.join(projectRoot, "node_modules"))) { - //console.log("\nYou will need to re-run your dependency manager to get started.") + ////console.log("\nYou will need to re-run your dependency manager to get started.") } diff --git a/demo/src/App.svelte b/demo/src/App.svelte index cd25908..aceffd2 100644 --- a/demo/src/App.svelte +++ b/demo/src/App.svelte @@ -56,7 +56,7 @@ }); } - function startMining() { + async function startMining() { const currentUser = get(user); const currentContent = get(contentState); @@ -65,7 +65,8 @@ return; } - miningState.update(m => ({ ...m, mining: true, result: 'Mining started...' })); + resetMiningState(); + miningState.update(m => ({ ...m, mining: true })); notemine = new Notemine({ content: currentContent.content, @@ -108,12 +109,15 @@ successSub = notemine.success$.subscribe(async ({ result: minedResult }) => { // const currentActiveRelays = get(activeRelays); - console.log(`currentActiveRelays: ${$activeRelays}`); - await publishEvent(minedResult.event) + // //console.log(`currentActiveRelays: ${$activeRelays}`); miningState.update(m => ({ ...m, mining: false, result: minedResult ? JSON.stringify(minedResult, null, 2) : 'No result received.', + })); + await publishEvent(minedResult.event) + miningState.update(m => ({ + ...m, relayStatus: `Published to relays: ${$activeRelays.join(', ')}` })); }); @@ -127,7 +131,8 @@ })); }); - notemine.mine(); + await notemine.mine(); + console.log('All workers mining.') } const resetMiningState = () => { @@ -137,7 +142,8 @@ result: '', relayStatus: '', hashRate: 0, - overallBestPow: null + overallBestPow: null, + publishSuccessNum: 0 })); } diff --git a/demo/src/lib/nostr.js b/demo/src/lib/nostr.js index 1de8e0e..863976f 100644 --- a/demo/src/lib/nostr.js +++ b/demo/src/lib/nostr.js @@ -1,38 +1,58 @@ import { SimplePool } from "nostr-tools"; import { get } from 'svelte/store'; import { finalizeEvent, verifyEvent } from "nostr-tools"; -import { relaySettings, user, events, activeRelays, usub } from './stores/index'; +import { relaySettings, user, events, activeRelays, usub, miningState } from './stores/index'; import { verifyPow } from './utils.js'; let pubs; export const pool = new SimplePool(); +const timeout = (promise, ms) => new Promise((resolve, reject) => { + const timer = setTimeout(() => reject(new Error("Timeout")), ms); + promise + .then(value => { + clearTimeout(timer); + resolve(value); + }) + .catch(err => { + clearTimeout(timer); + reject(err); + }); +}); + export const publishEvent = async (ev) => { - console.log(ev) + //console.log(ev); const pow = verifyPow(ev); - console.log('Publishing event:', ev); + //console.log('Publishing event:', ev); try { - const {isAnon, secret} = get(user); - if(isAnon) { - ev = finalizeEvent(ev, secret); - } - else { - ev = await window.nostr.signEvent(ev) - } - let isGood = verifyEvent(ev); - if (!isGood) throw new Error('Event is not valid'); - const currentActiveRelays = get(activeRelays); - pubs = pool.publish(currentActiveRelays, ev); - await Promise.allSettled(pubs); - console.log('Event published successfully.'); + const { isAnon, secret } = get(user); + if (isAnon) { + ev = finalizeEvent(ev, secret); + } else { + ev = await window.nostr.signEvent(ev); + } + const isGood = verifyEvent(ev); + if (!isGood) throw new Error('Event is not valid'); + + const currentActiveRelays = get(activeRelays); + const pubs = pool.publish(currentActiveRelays, ev).map(p => timeout(p, 10000)); + + const results = await Promise.allSettled(pubs); + const successCount = results.filter(result => result.status === 'fulfilled').length; + + miningState.update( m => ({...m, publishSuccessNum: successCount}) ) + + //console.log(`Event published successfully to ${successCount} relays.`); } catch (error) { - console.error('Error publishing event:', error); + console.error('Error publishing event:', error); } }; + + function setMyRelays(relays) { - console.log(`Setting my relays: ${relays}`); + //console.log(`Setting my relays: ${relays}`); relaySettings.update(r => ({ ...r, myRelays: Array.from(new Set([...r.myRelays, ...relays])) @@ -52,7 +72,7 @@ export function onK0(event){ catch(e){ console.error('Error parsing K0 content:', e) } - console.log('K0 profile:', profile) + //console.log('K0 profile:', profile) events.update( e => ({...e, k0: event}) ) } @@ -66,14 +86,14 @@ export function onK3(event){ console.warn('K3 content:', event.content) } - console.log('K3 relays:', relays) + //console.log('K3 relays:', relays) setMyRelays(relays) events.update( e => ({...e, k3: event}) ) } export function onK10002(event){ const relays = event.tags.filter( t => t[0] === 'r' ).map( r => r[1] ) - console.log('K10002 relays:', relays) + //console.log('K10002 relays:', relays) setMyRelays(relays?.length? relays : []) events.update( e => ({...e, k10002: event}) ) } diff --git a/demo/src/lib/stores/mining-state.js b/demo/src/lib/stores/mining-state.js index 1f4aa69..3acdec6 100644 --- a/demo/src/lib/stores/mining-state.js +++ b/demo/src/lib/stores/mining-state.js @@ -6,5 +6,6 @@ export const miningState = writable({ relayStatus: '', hashRate: 0, overallBestPow: null, - workersBestPow: [] + workersBestPow: [], + publishSuccessNum: 0, }); \ No newline at end of file diff --git a/demo/src/lib/utils.js b/demo/src/lib/utils.js index eb8cf45..2314b7d 100644 --- a/demo/src/lib/utils.js +++ b/demo/src/lib/utils.js @@ -17,7 +17,7 @@ export const getPow = (hex) => { } export const verifyPow = (event) => { - console.log(event) + //console.log(event) const hash = getEventHash(event); const count = getPow(hash); const nonceTag = event.tags.find(tag => tag[0] === 'nonce'); diff --git a/src/index.ts b/src/index.ts index b21d7bf..a9be701 100644 --- a/src/index.ts +++ b/src/index.ts @@ -137,8 +137,8 @@ export class Notemine { return this._totalHashRate; } - mine(): void { - //console.log('mine()') + async mine(): Promise { + ////console.log('mine()') if (this.mining$.getValue()) return; if (!this.pubkey) { @@ -156,7 +156,7 @@ export class Notemine { this.workersPow$.next({}); this.highestPow$.next({}); - this.initializeWorkers(); + await this.initializeWorkers(); } stop(): void { @@ -173,12 +173,12 @@ export class Notemine { this.cancelledEventSubject.next({ reason: 'Mining cancelled by user.' }); } - private initializeWorkers(): void { + private async initializeWorkers(): Promise { try { - //console.log('Initializing workers...'); + ////console.log('Initializing workers...'); const workers: Worker[] = []; for (let i = 0; i < this.numberOfWorkers; i++) { - //console.log(`Creating worker ${i}`); + ////console.log(`Creating worker ${i}`); const worker = MineWorker(); worker.onmessage = this.handleWorkerMessage.bind(this); worker.onerror = this.handleWorkerError.bind(this); @@ -193,10 +193,11 @@ export class Notemine { }); workers.push(worker); + await new Promise(resolve => setTimeout(resolve, 100)); } this.workers$.next(workers); - //console.log(`Initialized ${workers.length} workers.`); + ////console.log(`Initialized ${workers.length} workers.`); } catch (error) { this.errorSubject.next({ error }); console.error('Error initializing workers:', error); @@ -207,10 +208,10 @@ export class Notemine { const data = e.data; const { type, workerId, hashRate } = data; - //console.log('Message from worker:', data); + ////console.log('Message from worker:', data); if (type === 'initialized') { - //console.log(`Worker ${workerId} initialized:`, data.message); + ////console.log(`Worker ${workerId} initialized:`, data.message); } else if (type === 'progress') { let bestPowData: BestPowData | undefined; @@ -221,11 +222,11 @@ export class Notemine { workersPow[workerId] = bestPowData; this.workersPow$.next(workersPow); - console.log(`Worker ${workerId} best PoW: ${bestPowData.bestPow}`); + //console.log(`Worker ${workerId} best PoW: ${bestPowData.bestPow}`); const highestPow = this.highestPow$.getValue() - console.log(`Highest PoW: ${highestPow?.bestPow}`); + //console.log(`Highest PoW: ${highestPow?.bestPow}`); if (!highestPow || (bestPowData && bestPowData.bestPow > (highestPow?.bestPow || 0))) { this.highestPow$.next({ @@ -239,7 +240,7 @@ export class Notemine { this.progressSubject.next({ workerId, hashRate, bestPowData }); } else if (type === 'result') { - //console.log('Mining result received:', data.data); + ////console.log('Mining result received:', data.data); this.result$.next(data.data); this.mining$.next(false); @@ -289,7 +290,7 @@ export class Notemine { } private async recordMaxRate(workerId: number, hashRate: number){ - console.log(`Worker ${workerId} hash rate: ${Math.round(hashRate/1000)}`); + //console.log(`Worker ${workerId} hash rate: ${Math.round(hashRate/1000)}`); const maxHashRate = this._workerMaxHashRates.get(workerId); if (maxHashRate === undefined || hashRate > maxHashRate) { this._workerMaxHashRates.set(workerId, Math.round(hashRate)); @@ -309,7 +310,7 @@ export class Notemine { return; } - console.log(`Refreshing hash rate... total: ${this.totalHashRate}`); + //console.log(`Refreshing hash rate... total: ${this.totalHashRate}`); let totalRate = 0; this._workerHashRates.forEach((hashRates) => { diff --git a/src/mine.worker.ts b/src/mine.worker.ts index cde3f01..83da696 100644 --- a/src/mine.worker.ts +++ b/src/mine.worker.ts @@ -11,7 +11,7 @@ let workerId: number; let miningCancelled = false; const destructureBestPowData = (data: BestPowDataMap | any): BestPowData => { - //console.log('Destructuring bestPowData:', data, typeof data, data.get ? 'has get' : 'no get'); + ////console.log('Destructuring bestPowData:', data, typeof data, data.get ? 'has get' : 'no get'); let bestPow: number; let nonce: string; @@ -45,13 +45,13 @@ self.postMessage({ type: 'initialized', message: 'Worker initialized successfull self.onmessage = async function (e: MessageEvent) { if (e?.data?.name) { - //console.log("Ignoring injected message:", e.data); + ////console.log("Ignoring injected message:", e.data); return; } - //console.log('Worker received message:', e.data); + ////console.log('Worker received message:', e.data); try { const { type, event, difficulty, id, totalWorkers } = e.data; - //console.log(e.data) + ////console.log(e.data) // return @@ -66,15 +66,15 @@ self.onmessage = async function (e: MessageEvent) { mining = true; try { - //console.log('Initializing WASM...'); + ////console.log('Initializing WASM...'); await initWasm(wasm); - //console.log('WASM Initialized successfully.'); + ////console.log('WASM Initialized successfully.'); const startNonce = BigInt(workerId); const nonceStep = BigInt(totalWorkers); const reportProgress = (hashRate: number, bestPowData: any) => { - //console.log('Progress:', hashRate, bestPowData); + ////console.log('Progress:', hashRate, bestPowData); const message: any = { type: 'progress', workerId, @@ -86,7 +86,7 @@ self.onmessage = async function (e: MessageEvent) { const shouldCancel = () => miningCancelled; - //console.log('Starting mining with event:', event, 'difficulty:', difficulty); + ////console.log('Starting mining with event:', event, 'difficulty:', difficulty); const minedResult = mine_event( event, difficulty, @@ -96,7 +96,7 @@ self.onmessage = async function (e: MessageEvent) { shouldCancel ); - //console.log('Mining completed successfully:', minedResult); + ////console.log('Mining completed successfully:', minedResult); self.postMessage({ type: 'result', data: minedResult, workerId }); } catch (error: unknown) { const errorMessage = error instanceof Error ? error.message : JSON.stringify(error); @@ -107,7 +107,7 @@ self.onmessage = async function (e: MessageEvent) { } } else if (type === 'cancel') { miningCancelled = true; - //console.log('Mining cancelled by user.'); + ////console.log('Mining cancelled by user.'); } } catch (err: any) { const errorMessage = err.message || 'Unknown error occurred in worker';