-
Notifications
You must be signed in to change notification settings - Fork 122
Description
Summary
jwt_generator.build_jwt() calls serialization.load_pem_private_key() on every single REST request, re-deriving the private key object from the raw PEM bytes each time. Since the private key never changes for the lifetime of a RESTClient, this work is entirely redundant and adds unnecessary latency to every API call.
Details
The current flow for every authenticated REST request is:
RESTBase.set_headers()callsjwt_generator.build_rest_jwt(uri, self.api_key, self.api_secret)build_rest_jwt()callsbuild_jwt(key_var, secret_var, uri=uri)build_jwt()re-parses the PEM key on every invocation:
# jwt_generator.py, lines 15-18
private_key_bytes = secret_var.encode("utf-8")
private_key = serialization.load_pem_private_key(
private_key_bytes, password=None
)load_pem_private_key() performs ASN.1/DER parsing and key deserialization, which is non-trivial overhead — especially when combined with the subsequent ES256 (ECDSA) signing operation. In latency-sensitive use cases (e.g. trading), this adds up.
Suggested fix
Parse the private key once (e.g. in RESTBase.__init__() or lazily on first use) and pass the pre-parsed key object into build_jwt(). For example:
# In RESTBase.__init__():
if self.is_authenticated:
private_key_bytes = self.api_secret.encode("utf-8")
self._private_key = serialization.load_pem_private_key(
private_key_bytes, password=None
)Then update build_jwt() to accept an already-parsed key object instead of the raw secret string.
Environment
- SDK version: coinbase-advanced-py (latest)
- Python: 3.x
- Dependencies: cryptography >= 42.0.4, PyJWT >= 2.8.0