Browse Source

fix pow

imwald
Silberengel 3 weeks ago
parent
commit
ef96586d53
  1. 19
      src/lib/event-pow.test.ts
  2. 51
      src/lib/event.ts

19
src/lib/event-pow.test.ts

@ -0,0 +1,19 @@
import { describe, expect, it } from 'vitest'
import { getPow } from 'nostr-tools/nip13'
import { minePow } from '@/lib/event'
describe('minePow', () => {
it('uses NIP-13 nonce tag and meets requested difficulty', async () => {
const unsigned = {
kind: 1,
content: 'pow test',
tags: [] as string[][],
created_at: 1_700_000_000,
pubkey: 'a'.repeat(64)
}
const mined = await minePow(unsigned, 1)
expect(unsigned.tags).toEqual([])
expect(mined.tags.some((t) => t[0] === 'nonce' && t[2] === '1')).toBe(true)
expect(getPow(mined.id)).toBeGreaterThanOrEqual(1)
})
})

51
src/lib/event.ts

@ -7,7 +7,7 @@ import client from '@/services/client.service'
import { TImetaInfo } from '@/types' import { TImetaInfo } from '@/types'
import { LRUCache } from 'lru-cache' import { LRUCache } from 'lru-cache'
import { Event, getEventHash, kinds, nip19, UnsignedEvent } from 'nostr-tools' import { Event, getEventHash, kinds, nip19, UnsignedEvent } from 'nostr-tools'
import { getPow } from 'nostr-tools/nip13' import { minePow as nip13MinePow } from 'nostr-tools/nip13'
import { hexPubkeysEqual, normalizeHexPubkey } from './pubkey' import { hexPubkeysEqual, normalizeHexPubkey } from './pubkey'
import { import {
generateBech32IdFromATag, generateBech32IdFromATag,
@ -727,44 +727,27 @@ export function createFakeEvent(event: Partial<Event>): Event {
} }
} }
function cloneUnsignedEvent(unsigned: UnsignedEvent): UnsignedEvent {
return {
kind: unsigned.kind,
content: unsigned.content,
tags: unsigned.tags.map((tag) => [...tag]),
created_at: unsigned.created_at,
pubkey: unsigned.pubkey
}
}
/** NIP-13 PoW via {@link nip13MinePow}; clones input so draft tags are not mutated. */
export async function minePow( export async function minePow(
unsigned: UnsignedEvent, unsigned: UnsignedEvent,
difficulty: number difficulty: number
): Promise<Omit<Event, 'sig'>> { ): Promise<Omit<Event, 'sig'>> {
let count = 0 const draft = cloneUnsignedEvent(unsigned)
const event = unsigned as Omit<Event, 'sig'>
const tag = ['nonce', count.toString(), difficulty.toString()]
event.tags.push(tag)
return new Promise((resolve) => { return new Promise((resolve) => {
const mine = () => { // Yield once so posting UI can paint before the synchronous mine loop runs.
let iterations = 0 setTimeout(() => {
resolve(nip13MinePow(draft, difficulty))
while (iterations < 1000) { }, 0)
const now = Math.floor(new Date().getTime() / 1000)
if (now !== event.created_at) {
count = 0
event.created_at = now
}
tag[1] = (++count).toString()
event.id = getEventHash(event)
if (getPow(event.id) >= difficulty) {
resolve(event)
return
}
iterations++
}
setTimeout(mine, 0)
}
mine()
}) })
} }

Loading…
Cancel
Save