From 1d12099f1c4dd7a65ff2c27a74de8016cfa2d463 Mon Sep 17 00:00:00 2001 From: mleku Date: Wed, 5 Nov 2025 06:19:28 +0000 Subject: [PATCH] Enhance WebSocket connection management and signer implementation - Added a pong handler to extend the read deadline upon receiving PONG messages in WebSocket connections, improving connection stability. - Updated the signer implementation to serialize the x-only public key to 32 bytes, ensuring compatibility with the internal format. - Refactored tests to utilize MustNew() for signer initialization, enhancing error handling during key generation. - Bumped version to v0.25.1 to reflect these updates. --- app/handle-websocket.go | 10 ++++++++++ pkg/interfaces/signer/p8k/p8k.go | 18 ++++++++++++------ pkg/policy/policy_integration_test.go | 11 +++++------ pkg/policy/policy_test.go | 4 ++-- pkg/version/version | 2 +- 5 files changed, 30 insertions(+), 15 deletions(-) diff --git a/app/handle-websocket.go b/app/handle-websocket.go index fae2a59..67804f4 100644 --- a/app/handle-websocket.go +++ b/app/handle-websocket.go @@ -76,6 +76,12 @@ whitelist: // Set initial read deadline - pong handler will extend it when pongs are received conn.SetReadDeadline(time.Now().Add(DefaultPongWait)) + // Add pong handler to extend read deadline when client responds to pings + conn.SetPongHandler(func(string) error { + log.T.F("received PONG from %s, extending read deadline", remote) + return conn.SetReadDeadline(time.Now().Add(DefaultPongWait)) + }) + defer conn.Close() listener := &Listener{ ctx: ctx, @@ -231,6 +237,10 @@ func (s *Server) Pinger( defer func() { log.D.F("pinger shutting down") ticker.Stop() + // Recover from panic if channel is closed + if r := recover(); r != nil { + log.D.F("pinger recovered from panic (channel likely closed): %v", r) + } }() pingCount := 0 for { diff --git a/pkg/interfaces/signer/p8k/p8k.go b/pkg/interfaces/signer/p8k/p8k.go index 8db7e30..ed9a815 100644 --- a/pkg/interfaces/signer/p8k/p8k.go +++ b/pkg/interfaces/signer/p8k/p8k.go @@ -52,15 +52,18 @@ func (s *Signer) Generate() (err error) { return } - // Extract x-only public key + // Extract x-only public key (internal 64-byte format) var xonly secp.XOnlyPublicKey var parity int32 if xonly, parity, err = s.ctx.KeypairXOnlyPub(s.keypair); err != nil { return } _ = parity - // XOnlyPublicKey is [64]byte, but we only need the first 32 bytes (the x coordinate) - s.pubKey = xonly[:32] + + // Serialize the x-only public key to 32 bytes + if s.pubKey, err = s.ctx.SerializeXOnlyPublicKey(xonly[:]); err != nil { + return + } return } @@ -79,15 +82,18 @@ func (s *Signer) InitSec(sec []byte) (err error) { return } - // Extract x-only public key + // Extract x-only public key (internal 64-byte format) var xonly secp.XOnlyPublicKey var parity int32 if xonly, parity, err = s.ctx.KeypairXOnlyPub(s.keypair); err != nil { return } _ = parity - // XOnlyPublicKey is [64]byte, but we only need the first 32 bytes (the x coordinate) - s.pubKey = xonly[:32] + + // Serialize the x-only public key to 32 bytes + if s.pubKey, err = s.ctx.SerializeXOnlyPublicKey(xonly[:]); err != nil { + return + } return } diff --git a/pkg/policy/policy_integration_test.go b/pkg/policy/policy_integration_test.go index 3bca06f..bc460ee 100644 --- a/pkg/policy/policy_integration_test.go +++ b/pkg/policy/policy_integration_test.go @@ -9,11 +9,11 @@ import ( "time" "lol.mleku.dev/chk" - "next.orly.dev/pkg/interfaces/signer/p8k" "next.orly.dev/pkg/encoders/event" "next.orly.dev/pkg/encoders/hex" "next.orly.dev/pkg/encoders/kind" "next.orly.dev/pkg/encoders/tag" + "next.orly.dev/pkg/interfaces/signer/p8k" ) // TestPolicyIntegration runs the relay with policy enabled and tests event filtering @@ -23,13 +23,13 @@ func TestPolicyIntegration(t *testing.T) { } // Generate test keys - allowedSigner := p8k.New() + allowedSigner := p8k.MustNew() if err := allowedSigner.Generate(); chk.E(err) { t.Fatalf("Failed to generate allowed signer: %v", err) } allowedPubkeyHex := hex.Enc(allowedSigner.Pub()) - unauthorizedSigner := p8k.New() + unauthorizedSigner := p8k.MustNew() if err := unauthorizedSigner.Generate(); chk.E(err) { t.Fatalf("Failed to generate unauthorized signer: %v", err) } @@ -367,13 +367,13 @@ func TestPolicyWithRelay(t *testing.T) { } // Generate keys - allowedSigner := p8k.New() + allowedSigner := p8k.MustNew() if err := allowedSigner.Generate(); chk.E(err) { t.Fatalf("Failed to generate allowed signer: %v", err) } allowedPubkeyHex := hex.Enc(allowedSigner.Pub()) - unauthorizedSigner := p8k.New() + unauthorizedSigner := p8k.MustNew() if err := unauthorizedSigner.Generate(); chk.E(err) { t.Fatalf("Failed to generate unauthorized signer: %v", err) } @@ -513,4 +513,3 @@ func TestPolicyWithRelay(t *testing.T) { }) } } - diff --git a/pkg/policy/policy_test.go b/pkg/policy/policy_test.go index 7f00687..2f11809 100644 --- a/pkg/policy/policy_test.go +++ b/pkg/policy/policy_test.go @@ -23,7 +23,7 @@ func int64Ptr(i int64) *int64 { // Helper function to generate a keypair for testing func generateTestKeypair(t *testing.T) (signer *p8k.Signer, pubkey []byte) { - signer = p8k.New() + signer = p8k.MustNew() if err := signer.Generate(); chk.E(err) { t.Fatalf("Failed to generate test keypair: %v", err) } @@ -33,7 +33,7 @@ func generateTestKeypair(t *testing.T) (signer *p8k.Signer, pubkey []byte) { // Helper function to generate a keypair for benchmarks func generateTestKeypairB(b *testing.B) (signer *p8k.Signer, pubkey []byte) { - signer = p8k.New() + signer = p8k.MustNew() if err := signer.Generate(); chk.E(err) { b.Fatalf("Failed to generate test keypair: %v", err) } diff --git a/pkg/version/version b/pkg/version/version index 540758e..a53af1e 100644 --- a/pkg/version/version +++ b/pkg/version/version @@ -1 +1 @@ -v0.25.0 \ No newline at end of file +v0.25.1 \ No newline at end of file