From 437cdecfb1e5a1576e8681266e2f8019a7a17ea0 Mon Sep 17 00:00:00 2001 From: fiatjaf Date: Tue, 20 Aug 2024 13:19:21 -0300 Subject: [PATCH] nip13: CommittedDifficulty() --- nip13/nip13.go | 20 ++++++++++++++++++-- nip13/nip13_test.go | 21 +++++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/nip13/nip13.go b/nip13/nip13.go index 53538e4..ee01d4c 100644 --- a/nip13/nip13.go +++ b/nip13/nip13.go @@ -1,5 +1,3 @@ -// Package nip13 implements NIP-13 -// See https://github.com/nostr-protocol/nips/blob/master/13.md for details. package nip13 import ( @@ -18,6 +16,24 @@ var ( ErrMissingPubKey = errors.New("nip13: attempting to work on an event without a pubkey, which makes no sense") ) +// CommittedDifficulty returns the Difficulty but checks the "nonce" tag for a target. +// +// if the target is smaller than the actual difficulty then the value of the target is used. +// if the target is bigger than the actual difficulty then it returns 0. +func CommittedDifficulty(event *nostr.Event) int { + work := 0 + if nonceTag := event.Tags.GetFirst([]string{"nonce", ""}); nonceTag != nil && len(*nonceTag) >= 3 { + work = Difficulty(event.ID) + target, _ := strconv.Atoi((*nonceTag)[2]) + if target <= work { + work = target + } else { + work = 0 + } + } + return work +} + // Difficulty counts the number of leading zero bits in an event ID. func Difficulty(id string) int { var zeros int diff --git a/nip13/nip13_test.go b/nip13/nip13_test.go index 93d6d94..3d1821d 100644 --- a/nip13/nip13_test.go +++ b/nip13/nip13_test.go @@ -8,6 +8,7 @@ import ( "time" nostr "github.com/nbd-wtf/go-nostr" + "github.com/stretchr/testify/require" ) func TestCheck(t *testing.T) { @@ -31,6 +32,26 @@ func TestCheck(t *testing.T) { } } +func TestCommittedDifficulty(t *testing.T) { + tests := []struct { + result int + id string + tags nostr.Tags + }{ + {18, "000000000e9d97a1ab09fc381030b346cdd7a142ad57e6df0b46dc9bef6c7e2d", nostr.Tags{{"-"}, {"nonce", "654", "18"}}}, + {36, "000000000e9d97a1ab09fc381030b346cdd7a142ad57e6df0b46dc9bef6c7e2d", nostr.Tags{{"nonce", "12315", "36"}}}, + {0, "000000000e9d97a1ab09fc381030b346cdd7a142ad57e6df0b46dc9bef6c7e2d", nostr.Tags{{"nonce", "12315", "37"}}}, + {0, "000000000e9d97a1ab09fc381030b346cdd7a142ad57e6df0b46dc9bef6c7e2d", nostr.Tags{{"nonce", "654", "64"}, {"t", "spam"}}}, + {0, "000000000e9d97a1ab09fc381030b346cdd7a142ad57e6df0b46dc9bef6c7e2d", nostr.Tags{}}, + } + for i, tc := range tests { + t.Run(strconv.Itoa(i), func(t *testing.T) { + work := CommittedDifficulty(&nostr.Event{ID: tc.id, Tags: tc.tags}) + require.Equal(t, tc.result, work) + }) + } +} + func TestGenerateShort(t *testing.T) { event := &nostr.Event{ Kind: nostr.KindTextNote,