Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions changelog/syjn99_fix-unmarshal-response-web3signer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
### Fixed

- Return the decode error from the remote web3signer client's response unmarshalling. A shadowed variable made it return `nil` on malformed responses, so `GetPublicKeys` reported zero public keys and no error.
6 changes: 3 additions & 3 deletions validator/keymanager/remote-web3signer/internal/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,12 +191,12 @@ func (client *ApiClient) doRequest(ctx context.Context, httpMethod, fullPath str
// unmarshalResponse is a utility method for unmarshalling responses.
func unmarshalResponse(responseBody io.ReadCloser, unmarshalledResponseObject any) error {
defer closeBody(responseBody)
if err := json.NewDecoder(responseBody).Decode(&unmarshalledResponseObject); err != nil {
if decodeErr := json.NewDecoder(responseBody).Decode(&unmarshalledResponseObject); decodeErr != nil {
body, err := io.ReadAll(responseBody)
if err != nil {
return errors.Wrap(err, "failed to read response body")
return errors.Wrapf(decodeErr, "invalid format, unable to read response body: %v", err)
}
return errors.Wrap(err, fmt.Sprintf("invalid format, unable to read response body: %v", string(body)))
return errors.Wrapf(decodeErr, "invalid format, unable to read response body: %v", string(body))
}
return nil
}
Expand Down
16 changes: 16 additions & 0 deletions validator/keymanager/remote-web3signer/internal/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"fmt"
"io"
"net/http"
"net/http/httptest"
"net/url"
"testing"

Expand Down Expand Up @@ -183,3 +184,18 @@ func TestClient_GetServerStatus_HappyPath(t *testing.T) {
assert.NotNil(t, resp)
assert.Nil(t, err)
}

func TestClient_GetPublicKeys_MalformedJsonReturnsError(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
w.Header().Set("Content-Type", "application/json")
_, err := w.Write([]byte(`{not json`))
require.NoError(t, err)
}))
defer srv.Close()
u, err := url.Parse(srv.URL)
require.NoError(t, err)
cl := internal.ApiClient{BaseURL: u, RestClient: srv.Client()}
keys, err := cl.GetPublicKeys(t.Context(), srv.URL+"/api/v1/eth2/publicKeys")
assert.NotNil(t, err)
assert.Equal(t, 0, len(keys))
}
1 change: 0 additions & 1 deletion validator/keymanager/remote-web3signer/keymanager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,6 @@ func TestKeymanager_Sign(t *testing.T) {
config := &SetupConfig{
BaseEndpoint: "http://example.com",
GenesisValidatorsRoot: root,
PublicKeysURL: "http://example2.com/api/v1/eth2/publicKeys",

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No PublicKeysURL: Sign only needs the mocked client, and a real URL would hit the network.

}
km, err := NewKeymanager(ctx, config)
require.NoError(t, err)
Expand Down
Loading