Skip to content

Commit bb888fe

Browse files
authored
Use canonical json for JSON RPC request and response marshaling (#1610)
* Use cannonical json for jsonrpc2 request&response marshalling * Update tests
1 parent a7f07f3 commit bb888fe

4 files changed

Lines changed: 14 additions & 7 deletions

File tree

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ require (
1212
github.com/dominikbraun/graph v0.23.0
1313
github.com/fxamacker/cbor/v2 v2.7.0
1414
github.com/gagliardetto/utilz v0.1.3
15+
github.com/gibson042/canonicaljson-go v1.0.3
1516
github.com/go-json-experiment/json v0.0.0-20250223041408-d3c622f1b874
1617
github.com/go-playground/validator/v10 v10.26.0
1718
github.com/go-viper/mapstructure/v2 v2.4.0

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrP
6868
github.com/gagliardetto/hashsearch v0.0.0-20191005111333-09dd671e19f9/go.mod h1:513DXpQPzeRo7d4dsCP3xO3XI8hgvruMl9njxyQeraQ=
6969
github.com/gagliardetto/utilz v0.1.3 h1:A+asc+6/3a9qNBrgticApj3yW5F7y4TaJd8Ijg+o0zM=
7070
github.com/gagliardetto/utilz v0.1.3/go.mod h1:b+rGFkRHz3HWJD0RYMzat47JyvbTtpE0iEcYTRJTLLA=
71+
github.com/gibson042/canonicaljson-go v1.0.3 h1:EAyF8L74AWabkyUmrvEFHEt/AGFQeD6RfwbAuf0j1bI=
72+
github.com/gibson042/canonicaljson-go v1.0.3/go.mod h1:DsLpJTThXyGNO+KZlI85C1/KDcImpP67k/RKVjcaEqo=
7173
github.com/go-json-experiment/json v0.0.0-20250223041408-d3c622f1b874 h1:F8d1AJ6M9UQCavhwmO6ZsrYLfG8zVFWfEfMS2MXPkSY=
7274
github.com/go-json-experiment/json v0.0.0-20250223041408-d3c622f1b874/go.mod h1:TiCD2a1pcmjd7YnhGH0f/zKNcCD06B029pHhzV23c2M=
7375
github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=

pkg/jsonrpc2/types.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import (
66
"encoding/json"
77
"fmt"
88
"strings"
9+
10+
canonicaljson "github.com/gibson042/canonicaljson-go"
911
)
1012

1113
const (
@@ -59,9 +61,9 @@ func (r *Request[Params]) ServiceName() string {
5961
}
6062

6163
// Digest returns a digest of the request. This is used for signature verification.
62-
// The digest is a SHA256 hash of the JSON string of the request.
64+
// The digest is a SHA256 hash of the canonical JSON string of the request excluding the auth field.
6365
func (r *Request[Params]) Digest() (string, error) {
64-
canonicalJSONBytes, err := json.Marshal(Request[Params]{
66+
canonicalJSONBytes, err := canonicaljson.Marshal(Request[Params]{
6567
Version: r.Version,
6668
ID: r.ID,
6769
Method: r.Method,
@@ -87,8 +89,10 @@ type Response[Result any] struct {
8789
Error *WireError `json:"error,omitempty"`
8890
}
8991

92+
// Digest returns a digest of the response. This is used for signature verification.
93+
// The digest is a SHA256 hash of the canonical JSON string of the response.
9094
func (r *Response[Result]) Digest() (string, error) {
91-
canonicalJSONBytes, err := json.Marshal(r)
95+
canonicalJSONBytes, err := canonicaljson.Marshal(r)
9296
if err != nil {
9397
return "", fmt.Errorf("error marshaling JSON: %w", err)
9498
}

pkg/jsonrpc2/types_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ func TestTypes(t *testing.T) {
2626
}
2727
digest, err := req.Digest()
2828
require.NoError(t, err)
29-
require.Equal(t, "01025753dbedc82b0771489d77f87b4fe8bbe7255be218caafce6704cc4b45a6", digest)
29+
require.Equal(t, "0d390d82191fcc4fe7b321124f55e3880bf3f754c725d10bcc0668cebf6a6ded", digest)
3030
})
3131

3232
t.Run("Request.Digest - JSON marshal error", func(t *testing.T) {
@@ -47,7 +47,7 @@ func TestTypes(t *testing.T) {
4747

4848
digest, err := req.Digest()
4949
require.Error(t, err)
50-
require.Equal(t, "error marshaling JSON: json: unsupported type: chan string", err.Error())
50+
require.Equal(t, "error marshaling JSON: canonicaljson: unsupported type: chan string", err.Error())
5151
require.Empty(t, digest)
5252
})
5353

@@ -79,7 +79,7 @@ func TestResponseDigest(t *testing.T) {
7979
digest, err := resp.Digest()
8080
require.NoError(t, err)
8181
require.NotEmpty(t, digest)
82-
require.Equal(t, "4d255b455d6394594ea08abb31f02cbc09d6a33b84cb9617edb34d5b489e46a9", digest)
82+
require.Equal(t, "b2915f4ca34315c3cade73ce8e1d69225d3512550a12819374e287ed8327ba25", digest)
8383
})
8484

8585
t.Run("Response.Digest - with error", func(t *testing.T) {
@@ -95,7 +95,7 @@ func TestResponseDigest(t *testing.T) {
9595
digest, err := resp.Digest()
9696
require.NoError(t, err)
9797
require.NotEmpty(t, digest)
98-
require.Equal(t, "71f971121945d17b6f32a486ebfc2576c1eaf6d26e46987af46c898fc7fa9166", digest)
98+
require.Equal(t, "a8e6e0e131f05fc98fedc4826550a13bbdeb93b01bd9b97aa462a2411860e7d9", digest)
9999
})
100100

101101
t.Run("Response.Digest - JSON marshal error", func(t *testing.T) {

0 commit comments

Comments
 (0)