a big bundle of conversions and other changes.
This commit is contained in:
@@ -1 +0,0 @@
|
||||
decode-binary
|
||||
@@ -1,39 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"fiatjaf.com/nostr/eventstore/internal/binary"
|
||||
"fiatjaf.com/nostr"
|
||||
)
|
||||
|
||||
func main() {
|
||||
b, err := io.ReadAll(os.Stdin)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "failed to read from stdin: %s\n", err)
|
||||
os.Exit(1)
|
||||
return
|
||||
}
|
||||
b = bytes.TrimSpace(b)
|
||||
|
||||
if bytes.HasPrefix(b, []byte("0x")) {
|
||||
fromHex := make([]byte, (len(b)-2)/2)
|
||||
_, err := hex.Decode(fromHex, b[2:])
|
||||
if err == nil {
|
||||
b = fromHex
|
||||
}
|
||||
}
|
||||
|
||||
var evt nostr.Event
|
||||
err = binary.Unmarshal(b, &evt)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "failed to decode: %s\n", err)
|
||||
os.Exit(1)
|
||||
return
|
||||
}
|
||||
fmt.Println(evt.String())
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
package binary
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
|
||||
"fiatjaf.com/nostr"
|
||||
)
|
||||
|
||||
// Deprecated -- the encoding used here is not very elegant, we'll have a better binary format later.
|
||||
func Unmarshal(data []byte, evt *nostr.Event) (err error) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
err = fmt.Errorf("failed to decode binary for event %s from %s at %d: %v", evt.ID, evt.PubKey, evt.CreatedAt, r)
|
||||
}
|
||||
}()
|
||||
|
||||
evt.ID = hex.EncodeToString(data[0:32])
|
||||
evt.PubKey = hex.EncodeToString(data[32:64])
|
||||
evt.Sig = hex.EncodeToString(data[64:128])
|
||||
evt.CreatedAt = nostr.Timestamp(binary.BigEndian.Uint32(data[128:132]))
|
||||
evt.Kind = int(binary.BigEndian.Uint16(data[132:134]))
|
||||
contentLength := int(binary.BigEndian.Uint16(data[134:136]))
|
||||
evt.Content = string(data[136 : 136+contentLength])
|
||||
|
||||
curr := 136 + contentLength
|
||||
|
||||
nTags := binary.BigEndian.Uint16(data[curr : curr+2])
|
||||
curr++
|
||||
evt.Tags = make(nostr.Tags, nTags)
|
||||
|
||||
for t := range evt.Tags {
|
||||
curr++
|
||||
nItems := int(data[curr])
|
||||
tag := make(nostr.Tag, nItems)
|
||||
for i := range tag {
|
||||
curr = curr + 1
|
||||
itemSize := int(binary.BigEndian.Uint16(data[curr : curr+2]))
|
||||
itemStart := curr + 2
|
||||
item := string(data[itemStart : itemStart+itemSize])
|
||||
tag[i] = item
|
||||
curr = itemStart + itemSize
|
||||
}
|
||||
evt.Tags[t] = tag
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// Deprecated -- the encoding used here is not very elegant, we'll have a better binary format later.
|
||||
func Marshal(evt *nostr.Event) ([]byte, error) {
|
||||
content := []byte(evt.Content)
|
||||
buf := make([]byte, 32+32+64+4+2+2+len(content)+65536+len(evt.Tags)*40 /* blergh */)
|
||||
|
||||
hex.Decode(buf[0:32], []byte(evt.ID))
|
||||
hex.Decode(buf[32:64], []byte(evt.PubKey))
|
||||
hex.Decode(buf[64:128], []byte(evt.Sig))
|
||||
|
||||
if evt.CreatedAt > MaxCreatedAt {
|
||||
return nil, fmt.Errorf("created_at is too big: %d", evt.CreatedAt)
|
||||
}
|
||||
binary.BigEndian.PutUint32(buf[128:132], uint32(evt.CreatedAt))
|
||||
|
||||
if evt.Kind > MaxKind {
|
||||
return nil, fmt.Errorf("kind is too big: %d, max is %d", evt.Kind, MaxKind)
|
||||
}
|
||||
binary.BigEndian.PutUint16(buf[132:134], uint16(evt.Kind))
|
||||
|
||||
if contentLength := len(content); contentLength > MaxContentSize {
|
||||
return nil, fmt.Errorf("content is too large: %d, max is %d", contentLength, MaxContentSize)
|
||||
} else {
|
||||
binary.BigEndian.PutUint16(buf[134:136], uint16(contentLength))
|
||||
}
|
||||
copy(buf[136:], content)
|
||||
|
||||
if tagCount := len(evt.Tags); tagCount > MaxTagCount {
|
||||
return nil, fmt.Errorf("can't encode too many tags: %d, max is %d", tagCount, MaxTagCount)
|
||||
} else {
|
||||
binary.BigEndian.PutUint16(buf[136+len(content):136+len(content)+2], uint16(tagCount))
|
||||
}
|
||||
|
||||
buf = buf[0 : 136+len(content)+2]
|
||||
|
||||
for _, tag := range evt.Tags {
|
||||
if itemCount := len(tag); itemCount > MaxTagItemCount {
|
||||
return nil, fmt.Errorf("can't encode a tag with so many items: %d, max is %d", itemCount, MaxTagItemCount)
|
||||
} else {
|
||||
buf = append(buf, uint8(itemCount))
|
||||
}
|
||||
for _, item := range tag {
|
||||
itemb := []byte(item)
|
||||
itemSize := len(itemb)
|
||||
if itemSize > MaxTagItemSize {
|
||||
return nil, fmt.Errorf("tag item is too large: %d, max is %d", itemSize, MaxTagItemSize)
|
||||
}
|
||||
buf = binary.BigEndian.AppendUint16(buf, uint16(itemSize))
|
||||
buf = append(buf, itemb...)
|
||||
buf = append(buf, 0)
|
||||
}
|
||||
}
|
||||
return buf, nil
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package binary
|
||||
|
||||
import (
|
||||
"math"
|
||||
|
||||
"fiatjaf.com/nostr"
|
||||
)
|
||||
|
||||
const (
|
||||
MaxKind = math.MaxUint16
|
||||
MaxCreatedAt = math.MaxUint32
|
||||
MaxContentSize = math.MaxUint16
|
||||
MaxTagCount = math.MaxUint16
|
||||
MaxTagItemCount = math.MaxUint8
|
||||
MaxTagItemSize = math.MaxUint16
|
||||
)
|
||||
|
||||
func EventEligibleForBinaryEncoding(event *nostr.Event) bool {
|
||||
if len(event.Content) > MaxContentSize || event.Kind > MaxKind || event.CreatedAt > MaxCreatedAt || len(event.Tags) > MaxTagCount {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, tag := range event.Tags {
|
||||
if len(tag) > MaxTagItemCount {
|
||||
return false
|
||||
}
|
||||
for _, item := range tag {
|
||||
if len(item) > MaxTagItemSize {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
@@ -4,12 +4,7 @@ import (
|
||||
"fiatjaf.com/nostr/eventstore"
|
||||
"fiatjaf.com/nostr/eventstore/badger"
|
||||
"fiatjaf.com/nostr/eventstore/bluge"
|
||||
"fiatjaf.com/nostr/eventstore/edgedb"
|
||||
"fiatjaf.com/nostr/eventstore/lmdb"
|
||||
"fiatjaf.com/nostr/eventstore/mongo"
|
||||
"fiatjaf.com/nostr/eventstore/mysql"
|
||||
"fiatjaf.com/nostr/eventstore/postgresql"
|
||||
"fiatjaf.com/nostr/eventstore/sqlite3"
|
||||
"fiatjaf.com/nostr/eventstore/strfry"
|
||||
)
|
||||
|
||||
@@ -17,11 +12,6 @@ import (
|
||||
var (
|
||||
_ eventstore.Store = (*badger.BadgerBackend)(nil)
|
||||
_ eventstore.Store = (*lmdb.LMDBBackend)(nil)
|
||||
_ eventstore.Store = (*edgedb.EdgeDBBackend)(nil)
|
||||
_ eventstore.Store = (*postgresql.PostgresBackend)(nil)
|
||||
_ eventstore.Store = (*mongo.MongoDBBackend)(nil)
|
||||
_ eventstore.Store = (*sqlite3.SQLite3Backend)(nil)
|
||||
_ eventstore.Store = (*strfry.StrfryBackend)(nil)
|
||||
_ eventstore.Store = (*bluge.BlugeBackend)(nil)
|
||||
_ eventstore.Store = (*mysql.MySQLBackend)(nil)
|
||||
)
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"cmp"
|
||||
"math"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
mergesortedslices "fiatjaf.com/lib/merge-sorted-slices"
|
||||
"fiatjaf.com/nostr"
|
||||
)
|
||||
|
||||
func IsOlder(previous, next *nostr.Event) bool {
|
||||
func IsOlder(previous, next nostr.Event) bool {
|
||||
return previous.CreatedAt < next.CreatedAt ||
|
||||
(previous.CreatedAt == next.CreatedAt && previous.ID > next.ID)
|
||||
(previous.CreatedAt == next.CreatedAt && bytes.Compare(previous.ID[:], next.ID[:]) == 1)
|
||||
}
|
||||
|
||||
func ChooseNarrowestTag(filter nostr.Filter) (key string, values []string, goodness int) {
|
||||
@@ -80,7 +80,7 @@ func CopyMapWithoutKey[K comparable, V any](originalMap map[K]V, key K) map[K]V
|
||||
}
|
||||
|
||||
type IterEvent struct {
|
||||
*nostr.Event
|
||||
nostr.Event
|
||||
Q int
|
||||
}
|
||||
|
||||
@@ -166,18 +166,18 @@ func SwapDelete[A any](arr []A, i int) []A {
|
||||
}
|
||||
|
||||
func compareIterEvent(a, b IterEvent) int {
|
||||
if a.Event == nil {
|
||||
if b.Event == nil {
|
||||
if a.Event.ID == nostr.ZeroID {
|
||||
if b.Event.ID == nostr.ZeroID {
|
||||
return 0
|
||||
} else {
|
||||
return -1
|
||||
}
|
||||
} else if b.Event == nil {
|
||||
} else if b.Event.ID == nostr.ZeroID {
|
||||
return 1
|
||||
}
|
||||
|
||||
if a.CreatedAt == b.CreatedAt {
|
||||
return strings.Compare(a.ID, b.ID)
|
||||
return slices.Compare(a.ID[:], b.ID[:])
|
||||
}
|
||||
return cmp.Compare(a.CreatedAt, b.CreatedAt)
|
||||
}
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
go test fuzz v1
|
||||
uint(256)
|
||||
uint(31)
|
||||
uint(260)
|
||||
uint(2)
|
||||
uint(69)
|
||||
uint(385)
|
||||
uint(1)
|
||||
@@ -1,8 +0,0 @@
|
||||
go test fuzz v1
|
||||
uint(267)
|
||||
uint(50)
|
||||
uint(355)
|
||||
uint(2)
|
||||
uint(69)
|
||||
uint(213)
|
||||
uint(1)
|
||||
@@ -1,8 +0,0 @@
|
||||
go test fuzz v1
|
||||
uint(280)
|
||||
uint(0)
|
||||
uint(13)
|
||||
uint(2)
|
||||
uint(2)
|
||||
uint(0)
|
||||
uint(0)
|
||||
@@ -1,8 +0,0 @@
|
||||
go test fuzz v1
|
||||
uint(259)
|
||||
uint(126)
|
||||
uint(5)
|
||||
uint(23)
|
||||
uint(0)
|
||||
uint(0)
|
||||
uint(92)
|
||||
@@ -1,8 +0,0 @@
|
||||
go test fuzz v1
|
||||
uint(201)
|
||||
uint(50)
|
||||
uint(13)
|
||||
uint(97)
|
||||
uint(0)
|
||||
uint(0)
|
||||
uint(77)
|
||||
@@ -1,8 +0,0 @@
|
||||
go test fuzz v1
|
||||
uint(164)
|
||||
uint(50)
|
||||
uint(13)
|
||||
uint(1)
|
||||
uint(2)
|
||||
uint(13)
|
||||
uint(0)
|
||||
@@ -1,8 +0,0 @@
|
||||
go test fuzz v1
|
||||
uint(200)
|
||||
uint(50)
|
||||
uint(13)
|
||||
uint(8)
|
||||
uint(2)
|
||||
uint(0)
|
||||
uint(1)
|
||||
@@ -1,8 +0,0 @@
|
||||
go test fuzz v1
|
||||
uint(200)
|
||||
uint(117)
|
||||
uint(13)
|
||||
uint(2)
|
||||
uint(2)
|
||||
uint(0)
|
||||
uint(1)
|
||||
@@ -1,8 +0,0 @@
|
||||
go test fuzz v1
|
||||
uint(200)
|
||||
uint(50)
|
||||
uint(13)
|
||||
uint(2)
|
||||
uint(2)
|
||||
uint(0)
|
||||
uint(0)
|
||||
Reference in New Issue
Block a user