Adjust ACL behavior for "none" mode and make query cache optional
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:
2025-12-05 11:25:34 +00:00
parent 6b72f1f2b7
commit c1bd05fb04
19 changed files with 201 additions and 285 deletions

View File

@@ -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),
}

View File

@@ -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)

View File

@@ -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
}
}
}

View File

@@ -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) {