tests run (but not pass) and fine-tuning (specially tag filters) on filter_easyjson.go

This commit is contained in:
fiatjaf 2023-04-16 16:12:42 -03:00
parent 0a3e898c2f
commit c42059f4b4
No known key found for this signature in database
GPG Key ID: BAD43C4BE5C1A3A1
12 changed files with 116 additions and 129 deletions

View File

@ -4,7 +4,6 @@ import (
"crypto/sha256"
"encoding/hex"
"fmt"
"time"
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/btcec/v2/schnorr"
@ -24,12 +23,6 @@ type Event struct {
extra map[string]any
}
type Timestamp int64
func (t Timestamp) Time() time.Time {
return time.Unix(int64(t), 0)
}
const (
KindSetMetadata int = 0
KindTextNote int = 1

View File

@ -27,6 +27,7 @@ func easyjsonF642ad3eDecodeGithubComNbdWtfGoNostr(in *jlexer.Lexer, out *Event)
in.Skip()
return
}
out.extra = make(map[string]any)
in.Delim('{')
for !in.IsDelim('}') {
key := in.UnsafeFieldName(true)

View File

@ -3,7 +3,6 @@ package nostr
import (
"encoding/json"
"testing"
"time"
)
func TestEventParsingAndVerifying(t *testing.T) {
@ -47,7 +46,7 @@ func TestEventSerialization(t *testing.T) {
ID: "92570b321da503eac8014b23447301eb3d0bbdfbace0d11a4e4072e72bb7205d",
PubKey: "e9142f724955c5854de36324dab0434f97b15ec6b33464d56ebe491e3f559d1b",
Kind: 4,
CreatedAt: time.Unix(1671028682, 0),
CreatedAt: Timestamp(1671028682),
Tags: Tags{Tag{"p", "f8340b2bde651576b75af61aa26c80e13c65029f00f7f64004eece679bf7059f"}},
Content: "you say yes, I say no",
Sig: "ed08d2dd5b0f7b6a3cdc74643d4adee3158ddede9cc848e8cd97630c097001acc2d052d2d3ec2b7ac4708b2314b797106d1b3c107322e61b5e5cc2116e099b79",
@ -68,7 +67,7 @@ func TestEventSerialization(t *testing.T) {
}
if evt.ID != re.ID || evt.PubKey != re.PubKey || evt.Content != re.Content ||
!evt.CreatedAt.Equal(re.CreatedAt) || evt.Sig != re.Sig ||
evt.CreatedAt != re.CreatedAt || evt.Sig != re.Sig ||
len(evt.Tags) != len(evt.Tags) {
t.Error("reparsed event differs from original")
}
@ -93,7 +92,7 @@ func TestEventSerializationWithExtraFields(t *testing.T) {
ID: "92570b321da503eac8014b23447301eb3d0bbdfbace0d11a4e4072e72bb7205d",
PubKey: "e9142f724955c5854de36324dab0434f97b15ec6b33464d56ebe491e3f559d1b",
Kind: 7,
CreatedAt: time.Unix(1671028682, 0),
CreatedAt: Timestamp(1671028682),
Content: "there is an extra field here",
Sig: "ed08d2dd5b0f7b6a3cdc74643d4adee3158ddede9cc848e8cd97630c097001acc2d052d2d3ec2b7ac4708b2314b797106d1b3c107322e61b5e5cc2116e099b79",
}
@ -115,7 +114,7 @@ func TestEventSerializationWithExtraFields(t *testing.T) {
}
if evt.ID != re.ID || evt.PubKey != re.PubKey || evt.Content != re.Content ||
!evt.CreatedAt.Equal(re.CreatedAt) || evt.Sig != re.Sig ||
evt.CreatedAt != re.CreatedAt || evt.Sig != re.Sig ||
len(evt.Tags) != len(evt.Tags) {
t.Error("reparsed event differs from original")
}

View File

@ -9,14 +9,14 @@ import (
type Filters []Filter
type Filter struct {
IDs []string
Kinds []int
Authors []string
Tags TagMap
Since Timestamp
Until Timestamp
Limit int
Search string
IDs []string `json:"ids"`
Kinds []int `json:"kinds"`
Authors []string `json:"authors"`
Tags TagMap `json:"-"`
Since *Timestamp `json:"since"`
Until *Timestamp `json:"until"`
Limit int `json:"limit"`
Search string `json:"search"`
}
type TagMap map[string][]string
@ -63,11 +63,11 @@ func (ef Filter) Matches(event *Event) bool {
}
}
if event.CreatedAt < ef.Since {
if ef.Since != nil && event.CreatedAt < *ef.Since {
return false
}
if ef.Until != 0 && event.CreatedAt > ef.Until {
if ef.Until != nil && event.CreatedAt > *ef.Until {
return false
}

View File

@ -4,6 +4,7 @@ package nostr
import (
json "encoding/json"
easyjson "github.com/mailru/easyjson"
jlexer "github.com/mailru/easyjson/jlexer"
jwriter "github.com/mailru/easyjson/jwriter"
@ -26,6 +27,7 @@ func easyjson4d398eaaDecodeGithubComNbdWtfGoNostr(in *jlexer.Lexer, out *Filter)
in.Skip()
return
}
out.Tags = make(TagMap)
in.Delim('{')
for !in.IsDelim('}') {
key := in.UnsafeFieldName(false)
@ -36,7 +38,7 @@ func easyjson4d398eaaDecodeGithubComNbdWtfGoNostr(in *jlexer.Lexer, out *Filter)
continue
}
switch key {
case "IDs":
case "ids":
if in.IsNull() {
in.Skip()
out.IDs = nil
@ -44,7 +46,7 @@ func easyjson4d398eaaDecodeGithubComNbdWtfGoNostr(in *jlexer.Lexer, out *Filter)
in.Delim('[')
if out.IDs == nil {
if !in.IsDelim(']') {
out.IDs = make([]string, 0, 4)
out.IDs = make([]string, 0, 20)
} else {
out.IDs = []string{}
}
@ -59,7 +61,7 @@ func easyjson4d398eaaDecodeGithubComNbdWtfGoNostr(in *jlexer.Lexer, out *Filter)
}
in.Delim(']')
}
case "Kinds":
case "kinds":
if in.IsNull() {
in.Skip()
out.Kinds = nil
@ -82,7 +84,7 @@ func easyjson4d398eaaDecodeGithubComNbdWtfGoNostr(in *jlexer.Lexer, out *Filter)
}
in.Delim(']')
}
case "Authors":
case "authors":
if in.IsNull() {
in.Skip()
out.Authors = nil
@ -90,7 +92,7 @@ func easyjson4d398eaaDecodeGithubComNbdWtfGoNostr(in *jlexer.Lexer, out *Filter)
in.Delim('[')
if out.Authors == nil {
if !in.IsDelim(']') {
out.Authors = make([]string, 0, 4)
out.Authors = make([]string, 0, 40)
} else {
out.Authors = []string{}
}
@ -105,53 +107,56 @@ func easyjson4d398eaaDecodeGithubComNbdWtfGoNostr(in *jlexer.Lexer, out *Filter)
}
in.Delim(']')
}
case "Tags":
case "since":
if in.IsNull() {
in.Skip()
out.Since = nil
} else {
in.Delim('{')
out.Tags = make(TagMap)
for !in.IsDelim('}') {
key := string(in.String())
in.WantColon()
var v4 []string
if in.IsNull() {
in.Skip()
v4 = nil
} else {
in.Delim('[')
if v4 == nil {
if !in.IsDelim(']') {
v4 = make([]string, 0, 4)
} else {
v4 = []string{}
}
} else {
v4 = (v4)[:0]
}
for !in.IsDelim(']') {
var v5 string
v5 = string(in.String())
v4 = append(v4, v5)
in.WantComma()
}
in.Delim(']')
}
(out.Tags)[key] = v4
in.WantComma()
if out.Since == nil {
out.Since = new(Timestamp)
}
in.Delim('}')
*out.Since = Timestamp(in.Int64())
}
case "Since":
out.Since = Timestamp(in.Int64())
case "Until":
out.Until = Timestamp(in.Int64())
case "Limit":
case "until":
if in.IsNull() {
in.Skip()
out.Until = nil
} else {
if out.Until == nil {
out.Until = new(Timestamp)
}
*out.Until = Timestamp(in.Int64())
}
case "limit":
out.Limit = int(in.Int())
case "Search":
case "search":
out.Search = string(in.String())
default:
in.SkipRecursive()
if len(key) > 1 && key[0] == '#' {
tagValues := make([]string, 0, 40)
if !in.IsNull() {
in.Delim('[')
if out.Authors == nil {
if !in.IsDelim(']') {
tagValues = make([]string, 0, 4)
} else {
tagValues = []string{}
}
} else {
tagValues = (tagValues)[:0]
}
for !in.IsDelim(']') {
var v3 string
v3 = string(in.String())
tagValues = append(tagValues, v3)
in.WantComma()
}
in.Delim(']')
}
out.Tags[key[1:]] = tagValues
} else {
in.SkipRecursive()
}
}
in.WantComma()
}
@ -160,107 +165,84 @@ func easyjson4d398eaaDecodeGithubComNbdWtfGoNostr(in *jlexer.Lexer, out *Filter)
in.Consumed()
}
}
func easyjson4d398eaaEncodeGithubComNbdWtfGoNostr(out *jwriter.Writer, in Filter) {
out.RawByte('{')
first := true
_ = first
{
const prefix string = ",\"IDs\":"
const prefix string = ",\"ids\":"
out.RawString(prefix[1:])
if in.IDs == nil && (out.Flags&jwriter.NilSliceAsEmpty) == 0 {
out.RawString("null")
} else {
out.RawByte('[')
for v6, v7 := range in.IDs {
if v6 > 0 {
for v4, v5 := range in.IDs {
if v4 > 0 {
out.RawByte(',')
}
out.String(string(v7))
out.String(string(v5))
}
out.RawByte(']')
}
}
{
const prefix string = ",\"Kinds\":"
const prefix string = ",\"kinds\":"
out.RawString(prefix)
if in.Kinds == nil && (out.Flags&jwriter.NilSliceAsEmpty) == 0 {
out.RawString("null")
} else {
out.RawByte('[')
for v8, v9 := range in.Kinds {
if v8 > 0 {
for v6, v7 := range in.Kinds {
if v6 > 0 {
out.RawByte(',')
}
out.Int(int(v9))
out.Int(int(v7))
}
out.RawByte(']')
}
}
{
const prefix string = ",\"Authors\":"
const prefix string = ",\"authors\":"
out.RawString(prefix)
if in.Authors == nil && (out.Flags&jwriter.NilSliceAsEmpty) == 0 {
out.RawString("null")
} else {
out.RawByte('[')
for v10, v11 := range in.Authors {
if v10 > 0 {
for v8, v9 := range in.Authors {
if v8 > 0 {
out.RawByte(',')
}
out.String(string(v11))
out.String(string(v9))
}
out.RawByte(']')
}
}
{
const prefix string = ",\"Tags\":"
const prefix string = ",\"since\":"
out.RawString(prefix)
if in.Tags == nil && (out.Flags&jwriter.NilMapAsEmpty) == 0 {
out.RawString(`null`)
if in.Since == nil {
out.RawString("null")
} else {
out.RawByte('{')
v12First := true
for v12Name, v12Value := range in.Tags {
if v12First {
v12First = false
} else {
out.RawByte(',')
}
out.String(string(v12Name))
out.RawByte(':')
if v12Value == nil && (out.Flags&jwriter.NilSliceAsEmpty) == 0 {
out.RawString("null")
} else {
out.RawByte('[')
for v13, v14 := range v12Value {
if v13 > 0 {
out.RawByte(',')
}
out.String(string(v14))
}
out.RawByte(']')
}
}
out.RawByte('}')
out.Int64(int64(*in.Since))
}
}
{
const prefix string = ",\"Since\":"
const prefix string = ",\"until\":"
out.RawString(prefix)
out.Int64(int64(in.Since))
if in.Until == nil {
out.RawString("null")
} else {
out.Int64(int64(*in.Until))
}
}
{
const prefix string = ",\"Until\":"
out.RawString(prefix)
out.Int64(int64(in.Until))
}
{
const prefix string = ",\"Limit\":"
const prefix string = ",\"limit\":"
out.RawString(prefix)
out.Int(int(in.Limit))
}
{
const prefix string = ",\"Search\":"
const prefix string = ",\"search\":"
out.RawString(prefix)
out.String(string(in.Search))
}

View File

@ -3,7 +3,6 @@ package nostr
import (
"encoding/json"
"testing"
"time"
"golang.org/x/exp/slices"
)
@ -16,7 +15,7 @@ func TestFilterUnmarshal(t *testing.T) {
t.Errorf("failed to parse filter json: %v", err)
}
if f.Since == nil || f.Since.UTC().Format("2006-01-02") != "2022-02-07" ||
if f.Since == nil || f.Since.Time().UTC().Format("2006-01-02") != "2022-02-07" ||
f.Until != nil ||
f.Tags == nil || len(f.Tags) != 2 || !slices.Contains(f.Tags["something"], "bab") ||
f.Search != "test" {
@ -25,12 +24,11 @@ func TestFilterUnmarshal(t *testing.T) {
}
func TestFilterMarshal(t *testing.T) {
tm := time.Unix(12345678, 0)
until := Timestamp(12345678)
filterj, err := json.Marshal(Filter{
Kinds: []int{1, 2, 4},
Tags: TagMap{"fruit": {"banana", "mango"}},
Until: &tm,
Until: &until,
})
if err != nil {
t.Errorf("failed to marshal filter json: %v", err)
@ -93,7 +91,7 @@ func TestFilterEquality(t *testing.T) {
t.Error("kind+tags filters should be equal")
}
tm := time.Now()
tm := Now()
if !FilterEqual(
Filter{
Kinds: []int{4, 5},

View File

@ -64,7 +64,7 @@ func Generate(event *nostr.Event, targetDifficulty int, timeout time.Duration) (
for {
nonce++
tag[1] = strconv.FormatUint(nonce, 10)
event.CreatedAt = time.Now()
event.CreatedAt = nostr.Now()
if Difficulty(event.GetID()) >= targetDifficulty {
return event, nil
}

View File

@ -135,10 +135,10 @@ jump1:
}
jump2:
if d.since != nil && ev.CreatedAt.Before(*d.since) {
if d.since != nil && ev.CreatedAt.Time().Before(*d.since) {
return false, fmt.Errorf("Event is created before delegation conditions allow.")
}
if d.until != nil && ev.CreatedAt.After(*d.until) {
if d.until != nil && ev.CreatedAt.Time().After(*d.until) {
return false, fmt.Errorf("Event is created after delegation conditions allow.")
}
@ -166,7 +166,7 @@ func DelegatedSign(ev *nostr.Event, d *DelegationToken, delegatee_sk string) err
return fmt.Errorf("event already has delegation token")
}
}
if d.since != nil && ev.CreatedAt.Before(*d.since) || d.until != nil && ev.CreatedAt.After(*d.until) {
if d.since != nil && ev.CreatedAt.Time().Before(*d.since) || d.until != nil && ev.CreatedAt.Time().After(*d.until) {
return fmt.Errorf("event created_at field is not compatible with delegation token time conditions.")
}
if len(d.kinds) > 0 {

View File

@ -1,9 +1,10 @@
package nip26
import (
"github.com/nbd-wtf/go-nostr"
"testing"
"time"
"github.com/nbd-wtf/go-nostr"
)
func TestDelegateSign(t *testing.T) {
@ -16,7 +17,7 @@ func TestDelegateSign(t *testing.T) {
t.Error(err)
}
ev := &nostr.Event{}
ev.CreatedAt = time.Unix(1600000050, 0)
ev.CreatedAt = nostr.Timestamp(1600000050)
ev.Content = "hello world"
ev.Kind = 1
if err != nil {

View File

@ -13,7 +13,7 @@ import (
func CreateUnsignedAuthEvent(challenge, pubkey, relayURL string) nostr.Event {
return nostr.Event{
PubKey: pubkey,
CreatedAt: time.Now(),
CreatedAt: nostr.Now(),
Kind: 22242,
Tags: nostr.Tags{
nostr.Tag{"relay", relayURL},
@ -60,7 +60,7 @@ func ValidateAuthEvent(event *nostr.Event, challenge string, relayURL string) (p
}
now := time.Now()
if event.CreatedAt.After(now.Add(10*time.Minute)) || event.CreatedAt.Before(now.Add(-10*time.Minute)) {
if event.CreatedAt.Time().After(now.Add(10*time.Minute)) || event.CreatedAt.Time().Before(now.Add(-10*time.Minute)) {
return "", false
}

View File

@ -21,7 +21,7 @@ func TestPublish(t *testing.T) {
textNote := Event{
Kind: 1,
Content: "hello",
CreatedAt: time.Unix(1672068534, 0), // random fixed timestamp
CreatedAt: Timestamp(1672068534), // random fixed timestamp
Tags: Tags{[]string{"foo", "bar"}},
PubKey: pub,
}

13
timestamp.go Normal file
View File

@ -0,0 +1,13 @@
package nostr
import "time"
type Timestamp int64
func Now() Timestamp {
return Timestamp(time.Now().Unix())
}
func (t Timestamp) Time() time.Time {
return time.Unix(int64(t), 0)
}