eventstore: more consistent ErrDupEvent firing.
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
"fiatjaf.com/nostr"
|
||||
"fiatjaf.com/nostr/eventstore"
|
||||
"fiatjaf.com/nostr/eventstore/codec/betterbinary"
|
||||
"github.com/PowerDNS/lmdb-go/lmdb"
|
||||
)
|
||||
@@ -32,6 +33,10 @@ func (b *LMDBBackend) SaveEvent(evt nostr.Event) error {
|
||||
return b.save(txn, evt)
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
return eventstore.ErrDupEvent
|
||||
}
|
||||
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"unsafe"
|
||||
|
||||
"fiatjaf.com/nostr"
|
||||
"fiatjaf.com/nostr/eventstore"
|
||||
"fiatjaf.com/nostr/eventstore/codec/betterbinary"
|
||||
"github.com/PowerDNS/lmdb-go/lmdb"
|
||||
)
|
||||
@@ -80,7 +81,7 @@ func (b *MultiMmapManager) storeOn(
|
||||
ilid := binary.BigEndian.Uint16(val[s : s+2])
|
||||
if il.id == ilid {
|
||||
// already on the specified layer, we can end here
|
||||
return false, nil
|
||||
return false, eventstore.ErrDupEvent
|
||||
}
|
||||
}
|
||||
} else if !lmdb.IsNotFound(err) {
|
||||
|
||||
@@ -33,12 +33,11 @@ func (w StorePublisher) Publish(ctx context.Context, evt nostr.Event) error {
|
||||
// regular events are just saved directly
|
||||
if err := w.SaveEvent(evt); err != nil && err != eventstore.ErrDupEvent {
|
||||
return fmt.Errorf("failed to save: %w", err)
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// others are replaced
|
||||
w.Store.ReplaceEvent(evt)
|
||||
|
||||
return nil
|
||||
return w.Store.ReplaceEvent(evt)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
package wrappers
|
||||
|
||||
import (
|
||||
"fiatjaf.com/nostr"
|
||||
"fiatjaf.com/nostr/eventstore"
|
||||
)
|
||||
|
||||
// UniqueReactionsWrapper ensures that only the latest reaction or poll response from an author to an event is kept.
|
||||
// When a new reaction (kind 7) or poll response (kind 1018) is received, it deletes any previous ones from the same author to the same event.
|
||||
type UniqueReactionsWrapper struct {
|
||||
eventstore.Store
|
||||
}
|
||||
|
||||
func (w *UniqueReactionsWrapper) SaveEvent(event nostr.Event) error {
|
||||
// check if it's a reaction or poll response
|
||||
if event.Kind == 7 || event.Kind == 1018 {
|
||||
// find the referenced event ID
|
||||
ref := event.Tags.Find("e")
|
||||
if ref != nil {
|
||||
// query for existing events of same kind from same author referencing the same event and delete them
|
||||
for old := range w.Store.QueryEvents(nostr.Filter{
|
||||
Authors: []nostr.PubKey{event.PubKey},
|
||||
Kinds: []nostr.Kind{event.Kind},
|
||||
Tags: nostr.TagMap{"e": []string{ref[1]}},
|
||||
}, 1_000) {
|
||||
w.Store.DeleteEvent(old.ID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Save the new event
|
||||
return w.Store.SaveEvent(event)
|
||||
}
|
||||
Reference in New Issue
Block a user