Adjust ACL behavior for "none" mode and make query cache optional
Some checks failed
Go / build-and-release (push) Has been cancelled
Some checks failed
Go / build-and-release (push) Has been cancelled
This commit allows skipping authentication, permission checks, and certain filters (e.g., deletions, expirations) when the ACL mode is set to "none" (open relay mode). It also introduces a configuration option to disable query caching to reduce memory usage. These changes improve operational flexibility for open relay setups and resource-constrained environments.
This commit is contained in:
@@ -106,6 +106,12 @@ func NewWithConfig(
|
||||
|
||||
queryCacheSize := int64(queryCacheSizeMB * 1024 * 1024)
|
||||
|
||||
// Create query cache only if not disabled
|
||||
var qc *querycache.EventCache
|
||||
if !cfg.QueryCacheDisabled {
|
||||
qc = querycache.NewEventCache(queryCacheSize, queryCacheMaxAge)
|
||||
}
|
||||
|
||||
d = &D{
|
||||
ctx: ctx,
|
||||
cancel: cancel,
|
||||
@@ -114,7 +120,7 @@ func NewWithConfig(
|
||||
DB: nil,
|
||||
seq: nil,
|
||||
ready: make(chan struct{}),
|
||||
queryCache: querycache.NewEventCache(queryCacheSize, queryCacheMaxAge),
|
||||
queryCache: qc,
|
||||
serialCache: NewSerialCache(serialCachePubkeys, serialCacheEventIds),
|
||||
}
|
||||
|
||||
|
||||
@@ -18,10 +18,11 @@ type DatabaseConfig struct {
|
||||
LogLevel string
|
||||
|
||||
// Badger-specific settings
|
||||
BlockCacheMB int // ORLY_DB_BLOCK_CACHE_MB
|
||||
IndexCacheMB int // ORLY_DB_INDEX_CACHE_MB
|
||||
QueryCacheSizeMB int // ORLY_QUERY_CACHE_SIZE_MB
|
||||
QueryCacheMaxAge time.Duration // ORLY_QUERY_CACHE_MAX_AGE
|
||||
BlockCacheMB int // ORLY_DB_BLOCK_CACHE_MB
|
||||
IndexCacheMB int // ORLY_DB_INDEX_CACHE_MB
|
||||
QueryCacheDisabled bool // ORLY_QUERY_CACHE_DISABLED - disable query cache to reduce memory usage
|
||||
QueryCacheSizeMB int // ORLY_QUERY_CACHE_SIZE_MB
|
||||
QueryCacheMaxAge time.Duration // ORLY_QUERY_CACHE_MAX_AGE
|
||||
|
||||
// Serial cache settings for compact event storage
|
||||
SerialCachePubkeys int // ORLY_SERIAL_CACHE_PUBKEYS - max pubkeys to cache (default: 100000)
|
||||
|
||||
@@ -13,6 +13,7 @@ import (
|
||||
"lol.mleku.dev/log"
|
||||
"github.com/minio/sha256-simd"
|
||||
"next.orly.dev/pkg/database/indexes/types"
|
||||
"next.orly.dev/pkg/mode"
|
||||
"git.mleku.dev/mleku/nostr/encoders/event"
|
||||
"git.mleku.dev/mleku/nostr/encoders/filter"
|
||||
"git.mleku.dev/mleku/nostr/encoders/hex"
|
||||
@@ -102,7 +103,8 @@ func (d *D) QueryEventsWithOptions(c context.Context, f *filter.F, includeDelete
|
||||
}
|
||||
|
||||
// check for an expiration tag and delete after returning the result
|
||||
if CheckExpiration(ev) {
|
||||
// Skip expiration check when ACL is "none" (open relay mode)
|
||||
if !mode.IsOpen() && CheckExpiration(ev) {
|
||||
log.T.F(
|
||||
"QueryEvents: id=%s filtered out due to expiration", idHex,
|
||||
)
|
||||
@@ -112,9 +114,12 @@ func (d *D) QueryEventsWithOptions(c context.Context, f *filter.F, includeDelete
|
||||
}
|
||||
|
||||
// skip events that have been deleted by a proper deletion event
|
||||
if derr := d.CheckForDeleted(ev, nil); derr != nil {
|
||||
log.T.F("QueryEvents: id=%s filtered out due to deletion: %v", idHex, derr)
|
||||
continue
|
||||
// Skip deletion check when ACL is "none" (open relay mode)
|
||||
if !mode.IsOpen() {
|
||||
if derr := d.CheckForDeleted(ev, nil); derr != nil {
|
||||
log.T.F("QueryEvents: id=%s filtered out due to deletion: %v", idHex, derr)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// Add the event to the results
|
||||
@@ -210,13 +215,15 @@ func (d *D) QueryEventsWithOptions(c context.Context, f *filter.F, includeDelete
|
||||
}
|
||||
|
||||
// check for an expiration tag and delete after returning the result
|
||||
if CheckExpiration(ev) {
|
||||
// Skip expiration check when ACL is "none" (open relay mode)
|
||||
if !mode.IsOpen() && CheckExpiration(ev) {
|
||||
expDeletes = append(expDeletes, ser)
|
||||
expEvs = append(expEvs, ev)
|
||||
continue
|
||||
}
|
||||
// Process deletion events to build our deletion maps
|
||||
if ev.Kind == kind.Deletion.K {
|
||||
// Skip deletion processing when ACL is "none" (open relay mode)
|
||||
if !mode.IsOpen() && ev.Kind == kind.Deletion.K {
|
||||
// Check for 'e' tags that directly reference event IDs
|
||||
eTags := ev.Tags.GetAll([]byte("e"))
|
||||
for _, eTag := range eTags {
|
||||
@@ -433,8 +440,10 @@ func (d *D) QueryEventsWithOptions(c context.Context, f *filter.F, includeDelete
|
||||
}
|
||||
}
|
||||
// Check if this specific event has been deleted
|
||||
// Skip deletion checks when ACL is "none" (open relay mode)
|
||||
aclActive := !mode.IsOpen()
|
||||
eventIdHex := hex.Enc(ev.ID)
|
||||
if deletedEventIds[eventIdHex] {
|
||||
if aclActive && deletedEventIds[eventIdHex] {
|
||||
// Skip this event if it has been specifically deleted
|
||||
continue
|
||||
}
|
||||
@@ -446,7 +455,7 @@ func (d *D) QueryEventsWithOptions(c context.Context, f *filter.F, includeDelete
|
||||
// deletion Only skip this event if it has been deleted by
|
||||
// kind/pubkey and is not in the filter AND there isn't a newer
|
||||
// event with the same kind/pubkey
|
||||
if deletionsByKindPubkey[key] && !isIdInFilter {
|
||||
if aclActive && deletionsByKindPubkey[key] && !isIdInFilter {
|
||||
// This replaceable event has been deleted, skip it
|
||||
continue
|
||||
} else if wantMultipleVersions {
|
||||
@@ -475,11 +484,14 @@ func (d *D) QueryEventsWithOptions(c context.Context, f *filter.F, includeDelete
|
||||
}
|
||||
|
||||
// Check if this event has been deleted via an a-tag
|
||||
if deletionMap, exists := deletionsByKindPubkeyDTag[key]; exists {
|
||||
// If there is a deletion timestamp and this event is older than the deletion,
|
||||
// and this event is not specifically requested by ID, skip it
|
||||
if delTs, ok := deletionMap[dValue]; ok && ev.CreatedAt < delTs && !isIdInFilter {
|
||||
continue
|
||||
// Skip deletion check when ACL is "none" (open relay mode)
|
||||
if aclActive {
|
||||
if deletionMap, exists := deletionsByKindPubkeyDTag[key]; exists {
|
||||
// If there is a deletion timestamp and this event is older than the deletion,
|
||||
// and this event is not specifically requested by ID, skip it
|
||||
if delTs, ok := deletionMap[dValue]; ok && ev.CreatedAt < delTs && !isIdInFilter {
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
"lol.mleku.dev/log"
|
||||
"next.orly.dev/pkg/database/indexes"
|
||||
"next.orly.dev/pkg/database/indexes/types"
|
||||
"next.orly.dev/pkg/mode"
|
||||
"git.mleku.dev/mleku/nostr/encoders/event"
|
||||
"git.mleku.dev/mleku/nostr/encoders/filter"
|
||||
"git.mleku.dev/mleku/nostr/encoders/hex"
|
||||
@@ -177,13 +178,16 @@ func (d *D) SaveEvent(c context.Context, ev *event.E) (
|
||||
}
|
||||
|
||||
// Check if the event has been deleted before allowing resubmission
|
||||
if err = d.CheckForDeleted(ev, nil); err != nil {
|
||||
// log.I.F(
|
||||
// "SaveEvent: rejecting resubmission of deleted event ID=%s: %v",
|
||||
// hex.Enc(ev.ID), err,
|
||||
// )
|
||||
err = fmt.Errorf("blocked: %s", err.Error())
|
||||
return
|
||||
// Skip deletion check when ACL is "none" (open relay mode)
|
||||
if !mode.IsOpen() {
|
||||
if err = d.CheckForDeleted(ev, nil); err != nil {
|
||||
// log.I.F(
|
||||
// "SaveEvent: rejecting resubmission of deleted event ID=%s: %v",
|
||||
// hex.Enc(ev.ID), err,
|
||||
// )
|
||||
err = fmt.Errorf("blocked: %s", err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
// check for replacement - only validate, don't delete old events
|
||||
if kind.IsReplaceable(ev.Kind) || kind.IsParameterizedReplaceable(ev.Kind) {
|
||||
|
||||
Reference in New Issue
Block a user