Skip to content

Commit

Permalink
make timestamps into a struct with embedded value like the rest of th…
Browse files Browse the repository at this point in the history
…e things
  • Loading branch information
mleku committed Dec 7, 2024
1 parent 5699562 commit 1075f7c
Show file tree
Hide file tree
Showing 11 changed files with 143 additions and 69 deletions.
109 changes: 109 additions & 0 deletions event/canonical.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package event

import (
"reflect"

"realy.lol/hex"
"realy.lol/json"
"realy.lol/kind"
"realy.lol/tags"
"realy.lol/text"
"realy.lol/timestamp"
)

// ToCanonical converts the event to the canonical encoding used to derive the
// event ID.
func (ev *T) ToCanonical(dst by) (b by) {
b = dst
b = append(b, "[0,\""...)
b = hex.EncAppend(b, ev.PubKey)
b = append(b, "\","...)
b = ev.CreatedAt.Marshal(b)
b = append(b, ',')
b = ev.Kind.Marshal(b)
b = append(b, ',')
b = ev.Tags.Marshal(b)
b = append(b, ',')
b = text.AppendQuote(b, ev.Content, text.NostrEscape)
b = append(b, ']')
return
}

// GetIDBytes returns the raw SHA256 hash of the canonical form of an T.
func (ev *T) GetIDBytes() by { return Hash(ev.ToCanonical(nil)) }

func NewCanonical() (a *json.Array) {
a = &json.Array{
V: []json.I{
&json.Unsigned{}, // 0
&json.Hex{}, // pubkey
&timestamp.T{}, // created_at
&kind.T{}, // kind
&tags.T{}, // tags
&json.String{}, // content
},
}
return
}

func FromCanonical(b by) (ev *T, rem by, err er) {
id := Hash(b)
c := NewCanonical()
if rem, err = c.Unmarshal(b); chk.E(err) {
return
}
if len(rem) > 0 {
log.I.F("rem %s", rem)
}
// unwrap the array
x := (*c).V
if v, ok := x[0].(*json.Unsigned); !ok {
err = errorf.E("did not encode expected type in first field of canonical event %v %v",
reflect.TypeOf(x[0]), x[0])
return
} else {
if v.V != 0 {
err = errorf.E("unexpected value %d in first field of canonical event, expect 0", v.V)
return
}
}
// create the event, use the ID hash to populate the ID
ev = &T{ID: id}
// unwrap the pubkey
if v, ok := x[1].(*json.Hex); !ok {
err = errorf.E("failed to decode pubkey from canonical form of event %s", b)
return
} else {
ev.PubKey = v.V
}
// populate the timestamp field
if v, ok := x[2].(*timestamp.T); !ok {
err = errorf.E("did not encode expected type in third (created_at) field of canonical event %v %v",
reflect.TypeOf(x[0]), x[0])
} else {
ev.CreatedAt = v
}
// populate the kind field
if v, ok := x[3].(*kind.T); !ok {
err = errorf.E("did not encode expected type in fourth (kind) field of canonical event %v %v",
reflect.TypeOf(x[0]), x[0])
} else {
ev.Kind = v
}
// populate the tags field
if v, ok := x[3].(*tags.T); !ok {
err = errorf.E("did not encode expected type in fourth (tags) field of canonical event %v %v",
reflect.TypeOf(x[0]), x[0])
} else {
ev.Tags = v
}
// populate the content field
if v, ok := x[3].(*json.String); !ok {
err = errorf.E("did not encode expected type in fourth (content) field of canonical event %v %v",
reflect.TypeOf(x[0]), x[0])
} else {
ev.Content = v.V
}

return
}
2 changes: 1 addition & 1 deletion event/codectester/divider/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ func main() {
if len(rem) > 0 {
log.I.F("remainder:\n%s", rem)
}
can := ev.ToCanonical()
can := ev.ToCanonical(nil)
eh := event.Hash(can)
eq := equals(ev.ID, eh)
if !eq {
Expand Down
20 changes: 1 addition & 19 deletions event/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ type T struct {
type Ts []*T

func (ev Ts) Len() no { return len(ev) }
func (ev Ts) Less(i, j no) bo { return *ev[i].CreatedAt > *ev[j].CreatedAt }
func (ev Ts) Less(i, j no) bo { return ev[i].CreatedAt.I64() > ev[j].CreatedAt.I64() }
func (ev Ts) Swap(i, j no) { ev[i], ev[j] = ev[j], ev[i] }

type C chan *T
Expand All @@ -49,21 +49,6 @@ func New() (ev *T) { return &T{} }

func (ev *T) Serialize() (b by) { return ev.Marshal(nil) }

func (ev *T) ToCanonical() (b by) {
b = append(b, "[0,\""...)
b = hex.EncAppend(b, ev.PubKey)
b = append(b, "\","...)
b = ev.CreatedAt.Marshal(b)
b = append(b, ',')
b = ev.Kind.Marshal(b)
b = append(b, ',')
b = ev.Tags.Marshal(b)
b = append(b, ',')
b = text.AppendQuote(b, ev.Content, text.NostrEscape)
b = append(b, ']')
return
}

// stringy functions for retarded other libraries

func (ev *T) IDString() (s st) { return hex.Enc(ev.ID) }
Expand All @@ -78,9 +63,6 @@ func Hash(in by) (out by) {
return h[:]
}

// GetIDBytes returns the raw SHA256 hash of the canonical form of an T.
func (ev *T) GetIDBytes() by { return Hash(ev.ToCanonical()) }

func GenerateRandomTextNoteEvent(sign signer.I, maxSize no) (ev *T,
err er) {

Expand Down
4 changes: 2 additions & 2 deletions event/sort.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ package event
type Ascending []*T

func (ev Ascending) Len() no { return len(ev) }
func (ev Ascending) Less(i, j no) bo { return *ev[i].CreatedAt < *ev[j].CreatedAt }
func (ev Ascending) Less(i, j no) bo { return ev[i].CreatedAt.I64() < ev[j].CreatedAt.I64() }
func (ev Ascending) Swap(i, j no) { ev[i], ev[j] = ev[j], ev[i] }

// Descending sorts a slice of events in reverse chronological order (newest
// first)
type Descending []*T

func (e Descending) Len() no { return len(e) }
func (e Descending) Less(i, j no) bo { return *e[i].CreatedAt > *e[j].CreatedAt }
func (e Descending) Less(i, j no) bo { return e[i].CreatedAt.I64() > e[j].CreatedAt.I64() }
func (e Descending) Swap(i, j no) { e[i], e[j] = e[j], e[i] }
3 changes: 1 addition & 2 deletions filter/filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -553,8 +553,7 @@ func GenFilter() (f *T, err er) {
}
}
tn := no(timestamp.Now().I64())
before := timestamp.T(tn - frand.Intn(10000))
f.Since = &before
f.Since = &timestamp.T{int64(tn - frand.Intn(10000))}
f.Until = timestamp.Now()
f.Search = by("token search text")
return
Expand Down
1 change: 1 addition & 0 deletions ints/ints.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ func New[V uint | no | uint64 | uint32 | uint16 | uint8 | int64 | int32 | int16
}

func (n *T) Uint64() uint64 { return n.N }
func (n *T) Int64() int64 { return int64(n.N) }
func (n *T) Uint16() uint16 { return uint16(n.N) }

var powers = []*T{
Expand Down
4 changes: 1 addition & 3 deletions ratel/keys/createdat/createdat.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ var _ keys.Element = &T{}

func New(c *timestamp.T) (p *T) { return &T{Val: c} }

func (c *T) Write(buf *bytes.Buffer) {
buf.Write(c.Val.Bytes())
}
func (c *T) Write(buf *bytes.Buffer) { buf.Write(c.Val.Bytes()) }

func (c *T) Read(buf *bytes.Buffer) (el keys.Element) {
b := make(by, Len)
Expand Down
8 changes: 4 additions & 4 deletions ratel/preparequeries.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,18 +158,18 @@ func PrepareQueries(f *filter.T) (
}
// log.T.S("other", qs)
}
var until uint64 = math.MaxUint64
var until int64 = math.MaxInt64
if f.Until != nil {
if fu := uint64(*f.Until); fu < until {
if fu := f.Until.I64(); fu < until {
until = fu - 1
}
}
for i, q := range qs {
qs[i].start = binary.BigEndian.AppendUint64(q.searchPrefix, until)
qs[i].start = binary.BigEndian.AppendUint64(q.searchPrefix, uint64(until))
}
// this is where we'll end the iteration
if f.Since != nil {
if fs := uint64(*f.Since); fs > since {
if fs := f.Since.U64(); fs > since {
since = fs
}
}
Expand Down
2 changes: 1 addition & 1 deletion realy/version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v1.2.40
v1.2.41
49 changes: 17 additions & 32 deletions timestamp/timestamp.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,13 @@ import (

// T is a convenience type for UNIX 64 bit timestamps of 1 second
// precision.
type T int64
type T struct{ V int64 }

func New() (t *T) {
tt := T(0)
return &tt
}
func New() (t *T) { return &T{} }

// Now returns the current UNIX timestamp of the current second.
func Now() *T {
tt := T(time.Now().Unix())
tt := T{time.Now().Unix()}
return &tt
}

Expand All @@ -28,67 +25,58 @@ func (t *T) U64() uint64 {
if t == nil {
return 0
}
return uint64(*t)
return uint64(t.V)
}

// I64 returns the current UNIX timestamp of the current second as int64.
func (t *T) I64() int64 {
if t == nil {
return 0
}
return int64(*t)
return t.V
}

// Time converts a timestamp.Time value into a canonical UNIX 64 bit 1 second
// precision timestamp.
func (t *T) Time() time.Time { return time.Unix(int64(*t), 0) }
func (t *T) Time() time.Time { return time.Unix(t.V, 0) }

// Int returns the timestamp as an int.
func (t *T) Int() no {
if t == nil {
return 0
}
return no(*t)
return no(t.V)
}

func (t *T) Bytes() (b by) {
b = make(by, 8)
binary.BigEndian.PutUint64(b, uint64(*t))
binary.BigEndian.PutUint64(b, uint64(t.V))
return
}

// FromTime returns a T from a time.Time
func FromTime(t time.Time) *T {
tt := T(t.Unix())
return &tt
}
func FromTime(t time.Time) *T { return &T{t.Unix()} }

// FromUnix converts from a standard int64 unix timestamp.
func FromUnix(t int64) *T {
tt := T(t)
return &tt
}
func (t *T) FromInt(i no) { *t = T(i) }
func FromUnix(t int64) *T { return &T{t} }

func (t *T) FromInt(i no) { *t = T{int64(i)} }

// FromBytes converts from a string of raw bytes.
func FromBytes(b by) *T {
tt := T(binary.BigEndian.Uint64(b))
return &tt
}
func FromBytes(b by) *T { return &T{int64(binary.BigEndian.Uint64(b))} }

func FromVarint(b by) (t *T, rem by, err er) {
n, read := binary.Varint(b)
if read < 1 {
err = errorf.E("failed to decode varint timestamp %v", b)
return
}
tt := T(n)
t = &tt
t = &T{n}
rem = b[:read]
return
}

func ToVarint(dst by, t *T) by { return binary.AppendVarint(dst, int64(*t)) }
func ToVarint(dst by, t *T) by { return binary.AppendVarint(dst, t.V) }

func (t *T) FromVarint(dst by) (b by) { return ToVarint(dst, t) }

Expand All @@ -99,14 +87,11 @@ func (t *T) String() (s st) {
return unsafe.String(&b[0], len(b))
}

func (t *T) Marshal(dst by) (b by) {
tt := ints.New(t.U64())
return tt.Marshal(dst)
}
func (t *T) Marshal(dst by) (b by) { return ints.New(t.U64()).Marshal(dst) }

func (t *T) Unmarshal(b by) (r by, err er) {
n := ints.New(0)
r, err = n.Unmarshal(b)
*t = T(n.Uint64())
*t = T{n.Int64()}
return
}
10 changes: 5 additions & 5 deletions ws/pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ func (pool *SimplePool) subMany(c cx, urls []st, ff *filters.T,
ctx, cancel := context.Cancel(c)
_ = cancel // do this so `go vet` will stop complaining
events := make(chan IncomingEvent)
seenAlready := xsync.NewMapOf[st, timestamp.T]()
seenAlready := xsync.NewMapOf[st, *timestamp.T]()
ticker := time.NewTicker(time.Duration(seenAlreadyDropTick) * time.Second)
eose := false
pending := xsync.NewCounter()
Expand Down Expand Up @@ -215,7 +215,7 @@ func (pool *SimplePool) subMany(c cx, urls []st, ff *filters.T,
}
if unique {
if _, seen := seenAlready.LoadOrStore(evt.EventID().String(),
*evt.CreatedAt); seen {
evt.CreatedAt); seen {
continue
}
}
Expand All @@ -225,9 +225,9 @@ func (pool *SimplePool) subMany(c cx, urls []st, ff *filters.T,
}
case <-ticker.C:
if eose {
old := timestamp.T(timestamp.Now().Int() - seenAlreadyDropTick)
seenAlready.Range(func(id st, value timestamp.T) bo {
if value < old {
old := &timestamp.T{int64(timestamp.Now().Int() - seenAlreadyDropTick)}
seenAlready.Range(func(id st, value *timestamp.T) bo {
if value.I64() < old.I64() {
seenAlready.Delete(id)
}
return true
Expand Down

0 comments on commit 1075f7c

Please sign in to comment.