The chapter elaborates on all the important components in the previous diagram and as well as features we have implemented so far:
To communicate with the side chain, the parachain must include this pallet. Teerex has two important interfaces.
- 1.verify Intel's SGX node and accept the registration if verification is done.
- 2.get the request to call some extrinsic in SGX runtime in SGX. call sgx-runtime extrinsic includes a parameter, the type is Call that could be any byte code encoded with pallet id, extrinsic index, and parameters from SGX runtime.
Note: In the development environment, we can skip the verification via a compilation feature:
cargo build --features skip-ias-check
Litentry provides the service to compute customer's credit score based on the linked accounts and data related to these accounts. All accounts are stored in the SGX, the data fetch and score computing happened in SGX to avoid information leakage. This pallet is responsible to get the score from SGX side chain, the result may be encrypted by customer's public key, or used by Dapp based on Litentry SDK.
We define the runtime executed in the SGX in this repo. SGX runtime is similar to Substrate runtime, composed of pallets. The runtime can be compiled to a WASM blob or binary. The difference is SGX runtime depends on tee-sgx-sdk as mentioned before.
For Substrate runtime execution, we need two packages. First one is sp-externalities which provide the execution environment. Another one is sp-io for runtime to access the db, file systems, blockchain state and so on. Because SGX runtime is executed in the SGX, so both packages from Substrate not applicable in the SGX.
There are two packages from SGX runtime repo, are sgx-runtime/sp-io and sgx-runtime/sp-externalities, with the same name sp-io and sp-externalities. They make it possible for runtime executed in the SGX.
If the pallet includes some privacy data that need to be stored in the SGX node, we should put it in the SGX runtime. For example, Litentry first pallet account linker, the users links their Ethereum or Bitcoin addresses via link-eth and link-btc extrinsic. It may expose all these privacy data if we put the account linker in parachain.
So we put the account linker pallet into SGX runtime now, the code is not changed. Then all extrinsic parameters and linked addresses will be encrypted in the parachain, only SGX nodes know the private key, decrypts the data in the SGX, and dispatch the call to SGX runtime.
In the future, we will migrate more pallets from parachain to side chain.
The client interacts with both parachain and side chain via RPC / WSS connections. According to destination, we have different call types.
- 1.Untrusted call: client interacts with parachain node, it is similar to js client. Client includes some default pallets like teerex, we can use untrusted call to send transactions or some queries. For example, a user can call balance transfer via the client, it is an untrusted call.
- 2.Trust call: client interacts with worker server, which is counterpart to parachain node. The server also provides the RPC service. For example, a user can call link_eth, which is a extrinsic from sgx account linker pallet that is part of SGX runtime. Or query the encrypted data in SGX.
- 3.Direct call: client can call the extrinsic defined in the SGX runtime. the same use cases as trust call.
- 4.Indirect call: client wrappers the SGX runtime call, then send it to teerex pallet in parachain. worker node sync up the blocks from parachain, then identify the specific call_work extrinsic, parse the call from parameter and dispatch it to SGX runtime. The details could be found in the diagram in Litentry solution section.
The server is the most complicated part of whole solution, the major features are as follows:
- 1.get the verification report from Intel verification service and register itself to parachain
- 2.provide the execution environment for SGX runtime in the trusted node
- 3.sync up the blocks from parachain, decrypt and parse the data from call_work
- 4.generate side chain's block, sync up and consensus between nodes
- 5.provide RPC and WSS service
- 6.send the response to parachain via extrinsic
From a software running point of view, the server has a boundary between trusted and untrusted parts. Trusted code is executed in the SGX. Untrusted code includes start-up the process, RPC server, initializing the enclave, and so on.
The sharding is supported from the beginning of side chain design. The server node joins one shard, each call both direct and indirect has a default parameter shard identity. The server node just execute the call with the same shard that it joined. the benefit of shard is as follows
- the state for the different shard is isolated, the different shard nodes can't see each other private data
- shard nodes can skip the call from another shard, it saves the resource, makes it faster to execute less extrinsic in the block
- sharding make it possible to use our solution at a large scale, at the same time protecting the data