0
votes

Recently, when I wanted to sign something with a certificate outside node, I got the below exceptions:

Caused by: java.lang.IllegalStateException: Expected exactly 1 of {nodeSerializationEnv, globalSerializationEnv, contextSerializationEnv, inheritableContextSerializationEnv} but got: {} https://github.com/corda/corda/blob/671a9d232cf1f29dbce4432bc91096ffd098a91c/core/src/main/kotlin/net/corda/core/serialization/internal/SerializationEnvironment.kt#L91

On debugging, I found it's first serialised and then signed. So, I had to set up the serialisation context to get it serialised and signed.

I have a limited understanding of why is it required. I understand that different contexts are required for P2P and RPC calls, but I'm not entirely sure can someone please fill me in with some background.

1

1 Answers

1
votes

The internal library you are using to sign the certificate requires the certificate to be serialised first. In turn, this requires you to specify a serialisation context. A serialisation contexts defines how serialisation is performed in various situations, such as P2P, client-side RPC, server-side RPC, storage and checkpointing.

Note that these serialisation contexts are set for you automatically when running a node or a suite of node tests. You are only encountering this issue because you are using an internal library outside the context where it is expected to be used.

In your case, you should probably use globalSerializationEnv, which is the serialisation environment used for mock nodes and nodes created using the node driver. nodeSerializationEnv is used by the node itself, and contextSerializationEnv and inheritableContextSerializationEnv are used for various platform tests.

For educational purposes, it can be helpful to look at how the node sets up its serialisation framwork when it starts up (see https://github.com/corda/corda/blob/release-V3/node/src/main/kotlin/net/corda/node/internal/Node.kt):

nodeSerializationEnv = SerializationEnvironmentImpl(
    SerializationFactoryImpl().apply {
        registerScheme(KryoServerSerializationScheme())
        registerScheme(AMQPServerSerializationScheme(cordappLoader.cordapps))
    },
    p2pContext = AMQP_P2P_CONTEXT.withClassLoader(classloader),
    rpcServerContext = KRYO_RPC_SERVER_CONTEXT.withClassLoader(classloader),
    storageContext = AMQP_STORAGE_CONTEXT.withClassLoader(classloader),
    checkpointContext = KRYO_CHECKPOINT_CONTEXT.withClassLoader(classloader))