publish: correctly report failed command statuses from nip-20 relays

the client never reported a failed status, for example when a relay
responds with a:

    ["OK", event-id, false, "blocked"]

this was due to Relay.statusChans map missing a channel for an event
when a nip-20 status command is reported by a relay. the reason this
happened is due to the method's receiver, which was copied instead of
referenced by a pointer:

    func (r Relay) Publish(event Event) chan Status {
      // uses a **copy** of statusChans here:
      r.statusChans.Store(event.ID, statusChan)
      ...
    }

the bugfix is a one character change:

    func (r *Relay) Publish(event Event) chan Status

but while there, spotted another bug where an ok variable was shadowed
and the status chan would've reported incorrect value:

    // ok, which is a command status from earlier, is shadowed here:
    if statusChan, ok := r.statusChans.Load(eventId); ok {
      statusChan <- ...
    }

as a side effect, Relay.Publish now reports PublishStatusSucceeded
twice for relays which implement nip-20: once from an OK command status
and the other one from its adhoc subscription to observe whether the
event has been seen. added a todo to address it in the future.
This commit is contained in:
alex
2022-12-26 17:20:56 +01:00
committed by fiatjaf
parent 5bfb398f4d
commit 435579dc75
2 changed files with 139 additions and 2 deletions

View File

@@ -176,7 +176,7 @@ func (r *Relay) ConnectContext(ctx context.Context) error {
json.Unmarshal(jsonMessage[1], &eventId)
json.Unmarshal(jsonMessage[2], &ok)
if statusChan, ok := r.statusChans.Load(eventId); ok {
if statusChan, exist := r.statusChans.Load(eventId); exist {
if ok {
statusChan <- PublishStatusSucceeded
} else {
@@ -190,7 +190,7 @@ func (r *Relay) ConnectContext(ctx context.Context) error {
return nil
}
func (r Relay) Publish(event Event) chan Status {
func (r *Relay) Publish(event Event) chan Status {
statusChan := make(chan Status, 4)
go func() {
@@ -206,6 +206,9 @@ func (r Relay) Publish(event Event) chan Status {
}
statusChan <- PublishStatusSent
// TODO: there's no reason to sub if the relay supports nip-20 (command results).
// in fact, subscribing here with nip20-enabled relays makes it send PublishStatusSucceded
// twice: once here, and the other on "OK" command result.
sub := r.Subscribe(Filters{Filter{IDs: []string{event.ID}}})
for {
select {