Skip to content

Latest commit

 

History

History
73 lines (44 loc) · 5.31 KB

4.4.2-trusted-off-chain-worker.md

File metadata and controls

73 lines (44 loc) · 5.31 KB

4.4.2 Trusted Off-chain Worker

What is an off-chain worker?

A TEE off-chain worker (TOCW) is used to execute arbitrary computing in a trusted manner. A client submits these operations to a substrate 'parentchain', which can be either a parachain or a solochain. Usually, this will be the Integritee Parachain. The operations are opaque to the parent chain because they are encrypted. Only the client and the TOCW TEE can see the operation's content.

Sending an encrypted operation to the parent chain, which is then picked up and executed by a TEE off-chain worker, is called indirect invocation. An off-chain-worker only supports indirect invocation and 'getters'. In order to encrypt the operation, a client can query the off-chain worker directly (with a 'getter') for the 'shielding key', which is an RSA 3072 public key.

Multiple off-chain workers running in parallel share only the shielding key, but nothing else. They arrive at the same state independently by executing all the operations found on the parent chain, which guarantees ordering of operations.

What is the difference between an off-chain worker and a sidechain validateer?

An off-chain worker supports only 'indirect invocation', which means it executes only operations that are submitted to the parent chain (encrypted, in an extrinsic). As a result, the operation throughput is limited by the block production cycle on a parent chain. 'Direct invocation', available in a sidechain validateer, allows a client to send operations directly to a worker, allowing for much higher operation throughput. This is possible because the sidechain allows sharing and synchronizing states between workers, without having to rely on the parent chain.

How to use the SDK

  1. Experiment with the template, running the offchain-worker demo
  2. Fork the worker repository https://github.com/integritee-network/worker.git from the SDK release branch (sdk-v0.13.0-polkadot-v0.9.42)
  3. Build the worker in offchain-worker mode
  4. Write and integrate your own business logic, e.g. in a substrate pallet
  5. Deploy on the Integritee parachain or your own testnet

Building the worker in off-chain worker mode

In order to build the worker in off-chain worker mode, the corresponding cargo feature offchain-worker needs to be set. In the Makefiles, the environment variable WORKER_MODE is used to set the cargo features for the worker mode.

In case you build with make directly, do so with:

WORKER_MODE=offchain-worker make

In case you use docker with our build.Dockerfile, use --build-arg WORKER_MODE_ARG=offchain-worker to set the corresponding docker ARG.

An example of a docker build command (as currently used for GitHub CI):

{% code lineNumbers="true" %}

docker build -t integritee-worker --target deployed-worker --build-arg WORKER_MODE_ARG=offchain-worker -f build.Dockerfile .

{% endcode %}

Customizing an off-chain worker

In case there are multiple off-chain workers, any of them will work, since they all share the same shielding key

  • Business logic / STF
    ****This is the core part of the code changes necessary to turn the generic worker into your specific use-case. Read more in this dedicated section.
  • RPC Interface
    ****In case you want to extend the existing RPC interface, this section tells you how.
  • CLI Client
    ****A simple CLI client implementation is available in the worker repository, to show case communication with the worker, either by 'direct invocation' or 'indirect invocation'. For a sidechain validateer, 'direct invocation' will likely be the predominant way of communicating with a worker.
    The CLI client uses JSON RPC 2.0 over web-socket to communicate with a worker (direct invocation and trusted getters), as can be seen here for example. The web-socket connection is secured by TLS with an enclave self-signed certificate.

Default client workflow for indirect invocation

Default workflow for executing operations on an off-chain worker from a client's perspective:

  1. Compose your trusted call, e.g. TrustedCall::balance_transfer
  2. Get the shielding key from an off-chain worker
    • In case there are multiple off-chain workers, any of them will work, since they all share the same shielding key
  3. Encode and encrypt the operation using the shielding key
  4. Wrap the encrypted operation into a parentchain extrinsic
  5. Send the extrinsic to the parent chain
  6. Wait for the ProcessedParentchainBlock event, with the hash of the parent chain block including your extrinsic.

Examples of this workflow can be found in our CLI client implementation, here and here.