nip46: hopefully fix "send on closed channel" cases on client responses.

This commit is contained in:
fiatjaf
2025-07-21 17:21:30 -03:00
parent e164b49aad
commit ae076a7be2

View File

@@ -24,7 +24,6 @@ type BunkerClient struct {
relays []string relays []string
conversationKey [32]byte // nip44 conversationKey [32]byte // nip44
listeners *xsync.MapOf[string, chan Response] listeners *xsync.MapOf[string, chan Response]
expectingAuth *xsync.MapOf[string, struct{}]
idPrefix string idPrefix string
onAuth func(string) onAuth func(string)
@@ -126,9 +125,8 @@ func NewBunker(
relays: relays, relays: relays,
conversationKey: conversationKey, conversationKey: conversationKey,
listeners: xsync.NewMapOf[string, chan Response](), listeners: xsync.NewMapOf[string, chan Response](),
expectingAuth: xsync.NewMapOf[string, struct{}](),
onAuth: onAuth, onAuth: onAuth,
idPrefix: "gn-" + strconv.Itoa(rand.Intn(65536)), idPrefix: "nl-" + strconv.Itoa(rand.Intn(65536)),
} }
go func() { go func() {
@@ -159,13 +157,11 @@ func NewBunker(
if resp.Result == "auth_url" { if resp.Result == "auth_url" {
// special case // special case
authURL := resp.Error authURL := resp.Error
if _, ok := bunker.expectingAuth.Load(resp.ID); ok {
bunker.onAuth(authURL) bunker.onAuth(authURL)
}
continue continue
} }
if dispatcher, ok := bunker.listeners.Load(resp.ID); ok { if dispatcher, ok := bunker.listeners.LoadAndDelete(resp.ID); ok {
dispatcher <- resp dispatcher <- resp
continue continue
} }
@@ -282,12 +278,9 @@ func (bunker *BunkerClient) RPC(ctx context.Context, method string, params []str
return "", fmt.Errorf("failed to sign request event: %w", err) return "", fmt.Errorf("failed to sign request event: %w", err)
} }
respWaiter := make(chan Response) dispatcher := make(chan Response)
bunker.listeners.Store(id, respWaiter) bunker.listeners.Store(id, dispatcher)
defer func() { defer bunker.listeners.Delete(id)
bunker.listeners.Delete(id)
close(respWaiter)
}()
relayConnectionWorked := make(chan struct{}) relayConnectionWorked := make(chan struct{})
bunkerConnectionWorked := make(chan struct{}) bunkerConnectionWorked := make(chan struct{})
@@ -324,7 +317,7 @@ func (bunker *BunkerClient) RPC(ctx context.Context, method string, params []str
select { select {
case <-ctx.Done(): case <-ctx.Done():
return "", fmt.Errorf("context canceled") return "", fmt.Errorf("context canceled")
case resp := <-respWaiter: case resp := <-dispatcher:
if resp.Error != "" { if resp.Error != "" {
return "", fmt.Errorf("response error: %s", resp.Error) return "", fmt.Errorf("response error: %s", resp.Error)
} }