Our initial attempt at running Corda with the DJVM enabled highlighted the amount of time spent deserialising PublicKey objects. The current SandboxPublicKeySerializer does the following:
While this works, it also pulls the entire Crypto object into the sandbox, along with its dependencies. More disturbingly, the complex cryptographic code now inside the sandbox has no opportunity to be compiled into optimized native code before its classloader is discarded.
This serializer must use the cryptography functions from Corda's existing Crypto object, which has already been compiled. We must assume that the decodePublicKey() method is already pure.
Unfortunately, this issue runs deeper than just the SandboxPublicKeySerializer because any use of Crypto inside the sandbox will have the exact same problem. Not only that, but CorDapps are expected to use the Crypto API for cryptography inside Corda. The only solution is therefore to make Crypto “safe” somehow.
Initial performance testing suggests that the DJVM spends a lot of time initialising the EdDSANamedCurveTable class:
This class is referenced by several public static SignatureScheme fields on the Crypto object, all of which must be created inside Crypto.<clinit>. By default, the DJVM has mapped the EdDSANamedCurveTable class into the sandbox where it works but performs “sub-optimally”.
I am going to provide the node with a “hand-written” Crypto object for use inside the sandbox. This object will delegate all cryptographic operations to Corda’s own Crypto object and will omit the problematic AlgorithmParameterSpec elements from the sandboxed versions of theSignatureScheme fields. This new version of the Crypto class should therefore be considerably cheaper to initialise. For good measure, I will also prevent Corda’s ProviderMap class from being mapped into the sandbox by substituting a “hand-written” empty version.