Skip to content

Commit

Permalink
Updating sphinx docs (#759)
Browse files Browse the repository at this point in the history
  • Loading branch information
eddyashton authored Jan 30, 2020
1 parent 5603c60 commit 26a60ad
Show file tree
Hide file tree
Showing 13 changed files with 209 additions and 121 deletions.
2 changes: 1 addition & 1 deletion sphinx/source/concepts.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Nodes are run and maintained by :term:`operators`. However, nodes must be truste
Application
-----------

Each node runs the same application (a.k.a. transaction engine). An application is a collection of endpoints that can be triggered by trusted :term:`users`' :term:`JSON-RPC` requests over :term:`TLS`.
Each node runs the same application (a.k.a. transaction engine). An application is a collection of endpoints that can be triggered by trusted :term:`users`' commands over :term:`TLS`.

Each endpoint mutates an in-enclave-memory Key-Value Store that is replicated across all nodes in the network. Changes to the Key-Value Store must be agreed by a variable number of nodes, depending on the consensus algorithm selected (either Raft or PBFT), before being applied.

Expand Down
10 changes: 8 additions & 2 deletions sphinx/source/developers/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ Application Entry Point
Application Handler
-------------------

.. doxygenclass:: ccf::RpcFrontend
.. doxygenclass:: ccf::UserRpcFrontend
:project: CCF
:members:
:members:
:undoc-members:

.. doxygenclass:: ccf::HandlerRegistry
:project: CCF
:members:
:undoc-members:
2 changes: 1 addition & 1 deletion sphinx/source/developers/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Writing CCF Applications

This section describes how CCF applications can be developed and deployed to a CCF network.

Applications can be written in C++ or Lua (see :ref:`developers/example:Example Application`). An application consists of a collection of endpoints that can be triggered by :term:`users` using JSON-RPC. Each endpoint can define an :ref:`developers/logging_cpp:API Schema` to validate user requests.
Applications can be written in C++ or Lua (see :ref:`developers/example:Example Application`). An application consists of a collection of endpoints that can be triggered by :term:`users`. Each endpoint can define an :ref:`developers/logging_cpp:API Schema` to validate user requests.

These endpoints mutate the state of a unique :ref:`developers/kv/index:Key-Value Store` that represents the internal state of the application. Applications define a set of ``Maps`` (see :ref:`developers/kv/kv_how_to:Creating a Map`), mapping from a key to a value. When an application endpoint is triggered, the effects on the Store are committed atomically.

Expand Down
15 changes: 3 additions & 12 deletions sphinx/source/developers/logging_cpp.rst
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,15 @@ The Logging application simply has:
RPC Handler
-----------

The handler returned by :cpp:func:`ccfapp::getRpcHandler()` needs to subclass :cpp:class:`ccf::UserRpcFrontend`:
The handler returned by :cpp:func:`ccfapp::get_rpc_handler()` should subclass :cpp:class:`ccf::UserRpcFrontend`, providing an implementation of :cpp:class:`ccf::HandlerRegistry`:

.. literalinclude:: ../../../src/apps/logging/logging.cpp
:language: cpp
:start-after: SNIPPET: inherit_frontend
:lines: 1
:dedent: 2

The constructor then needs to create a handler function or lambda for each transaction type. This takes a transaction object and the request's ``params``, interacts with the KV tables, and returns a result:
The logging app defines :cpp:class:`ccfapp::LoggerHandlers`, which creates and installs handler functions or lambdas for each transaction type. These take a transaction object and the request's ``params``, interact with the KV tables, and return a result:

.. literalinclude:: ../../../src/apps/logging/logging.cpp
:language: cpp
Expand All @@ -71,16 +71,7 @@ A handler can either be installed as:
- ``Read``: this handler can be executed on any node of the network.
- ``MayWrite``: the execution of this handler on a specific node depends on the value of the ``"readonly"`` parameter in the JSON-RPC command.

App-defined errors
~~~~~~~~~~~~~~~~~~

Applications can define their own error codes. These should be between ``-32050`` and ``-32099`` to avoid conflicting with CCF's error codes. The Logging application returns errors if the user tries to get an id which has not been logged, or tries to log an empty message. These error codes should be given their own ``enum class``, and a ``get_error_prefix`` function should be defined in the same namespace to help users distinguish error messages:

.. literalinclude:: ../../../src/apps/logging/logging.cpp
:language: cpp
:start-after: SNIPPET_START: errors
:end-before: SNIPPET_END: errors
:dedent: 2
.. warning:: These handlers currently return JSON-RPC error codes, and all responses are returned in the body of a ``200 OK`` HTTP response. In future these handlers will be able to directly set the HTTP return code and payload.

API Schema
~~~~~~~~~~
Expand Down
2 changes: 1 addition & 1 deletion sphinx/source/glossary.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Glossary
`Flexible Launch Control <https://github.com/intel/linux-sgx/blob/master/psw/ae/ref_le/ref_le.md#flexible-launch-control>`_ is a feature of the Intel :term:`SGX` architecture.

JSON-RPC
`JSON-RPC <https://en.wikipedia.org/wiki/JSON-RPC>`_ is a remote procedure call protocol encoded in JSON. It is the format used by clients (i.e. members, users and operators) to interact with CCF.
`JSON-RPC <https://en.wikipedia.org/wiki/JSON-RPC>`_ is a remote procedure call protocol encoded in JSON.

Members
Constitute the consortium governing a CCF network. Their public identity should be registered in CCF.
Expand Down
2 changes: 1 addition & 1 deletion sphinx/source/introduction.rst
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,4 @@ in one or many cloud-hosted data centers, including :term:`Microsoft Azure`, or

Ledger providers can use CCF to enable higher throughput and higher confidentiality guarantees for distributed ledger applications.
CCF developers can write application logic (also known as smart contracts) and enforce application-level access control in several languages by configuring CCF
to embed one of several language runtimes on top of its key-value store. Clients then communicate with a running CCF service using :term:`JSON-RPC` interfaces over :term:`TLS`.
to embed one of several language runtimes on top of its key-value store. Clients then communicate with a running CCF service over :term:`TLS`.
65 changes: 38 additions & 27 deletions sphinx/source/members/common_member_operations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,7 @@ Trusting a New Node

As opposed to an opening network in which nodes are trusted automatically, new nodes added to an open network must be trusted by a quorum of members before becoming part of the network.

When an operator starts a new node with the ``join`` option (see :ref:`operators/start_network:Adding a New Node to the Network`), the joining node is assigned a unique node id and is recorded in state `PENDING`. Then, members can vote to accept the new node, using the unique assigned node id:

.. code-block:: bash
$ memberclient --cert member1_cert --privk member1_privk --rpc-address rpc_ip:rpc_port --ca network_cert trust_node --node-id new_node_id
{"commit":13,"global_commit":12,"id":0,"jsonrpc":"2.0","result":{"completed":false,"id":2},"term":2}
$ memberclient --cert member2_cert --privk member2_privk --rpc-address rpc_ip:rpc_port --ca network_cert vote --proposal-id 2 --accept
{"commit":15,"global_commit":14,"id":0,"jsonrpc":"2.0","result":false,"term":2}
$ memberclient --cert member3_cert --privk member3_privk --rpc-address rpc_ip:rpc_port --ca network_cert vote --proposal-id 2 --accept
{"commit":17,"global_commit":16,"id":0,"jsonrpc":"2.0","result":true,"term":2}
When an operator starts a new node with the ``join`` option (see :ref:`operators/start_network:Adding a New Node to the Network`), the joining node is assigned a unique node id and is recorded in state `PENDING`. Then, members can vote to accept the new node, using the unique assigned node id (see :ref:`members/proposals:Proposing and Voting for a Proposal` for more detail).

Once the proposal successfully completes, the new node automatically becomes part of the network.

Expand All @@ -28,11 +17,7 @@ Updating Code Version

For new nodes to be able to join the network, the version of the code they run (as specified by the ``--enclave-file``) should be first trusted by the consortium of members.

If the version of the code being executed needs to be updated (for example, to support additional endpoints), members can create a ``new_code`` proposal, specifying the new code version (e.g. ``3175971c02d00c1a8f9dd23ca89e64955c5caa94e24f4a3a0579dcfb2e6aebf9``):

.. code-block:: bash
$ memberclient --cert member_cert --privk member_privk --rpc-address node_ip:node_port --ca network_cert add_code --new-code-id code_version
If the version of the code being executed needs to be updated (for example, to support additional endpoints), members can create a ``new_code`` proposal, specifying the new code version.

.. note:: For a given :term:`Open Enclave` enclave library, the version of the code (``mrenclave``) can be found by running the ``oesign`` utility:

Expand Down Expand Up @@ -68,13 +53,26 @@ The first member proposes to recover the network, passing the sealed network sec

.. code-block:: bash
$ memberclient --rpc-address node2_rpc_ip:node2_rpc_port --cert member1_cert.pem --privk member1_privk.pem --ca /path/to/new/network/certificate accept_recovery --sealed-secrets /path/to/sealed/secrets/file
$ cat accept_recovery.json
{
"jsonrpc": "2.0",
"id": 0,
"method": "members/propose",
"params": {
"parameter": [<sealed secrets>],
"script": {
"text": "tables, sealed_secrets = ...; return Calls:call(\"accept_recovery\", sealed_secrets)"
}
}
}
$ curl https://<ccf-node-address>/members/propose --cacert network_cert --key member1_privk --cert member1_cert --data-binary @accept_recovery.json
{"commit":100,"global_commit":99,"id":0,"jsonrpc":"2.0","result":{"completed":false,"id":1},"term":2}
$ memberclient --rpc-address node2_rpc_ip:node2_rpc_port --cert member2_cert.pem --privk member2_privk.pem --ca /path/to/new/network/certificate vote --accept --proposal-id 1
$ ./scurl.sh https://<ccf-node-address>/members/vote --cacert network_cert --key member2_privk --cert member2_cert --data-binary @vote_accept_1.json
{"commit":102,"global_commit":101,"id":0,"jsonrpc":"2.0","result":false,"term":2}
$ memberclient --rpc-address node2_rpc_ip:node2_rpc_port --cert member3_cert.pem --privk member3_privk.pem --ca /path/to/new/network/certificate vote --accept --proposal-id 1
$ ./scurl.sh https://<ccf-node-address>/members/vote --cacert network_cert --key member3_privk --cert member3_cert --data-binary @vote_accept_1.json
{"commit":104,"global_commit":103,"id":0,"jsonrpc":"2.0","result":true,"term":2}
Once a :term:`quorum` of members have agreed to recover the network, the network secrets are unsealed and each node begins recovery of the private ledger entries.
Expand Down Expand Up @@ -103,10 +101,10 @@ Once a :term:`quorum` of members have agreed to recover the network, the network
Note over Node 3: Part of Network

loop Business transactions
Users->>+Node 2: JSON-RPC Request
Node 2-->>Users: JSON-RPC Response
Users->>+Node 3: JSON-RPC Request
Node 3-->>Users: JSON-RPC Response
Users->>+Node 2: Request
Node 2-->>Users: Response
Users->>+Node 3: Request
Node 3-->>Users: Response
end

Once the recovery of the private ledger on all the nodes that have joined the new network is complete, the ledger is fully recovered and users are able to continue issuing business transactions.
Expand All @@ -118,13 +116,26 @@ To limit the scope of key compromise, members of the consortium can refresh the

.. code-block:: bash
$ memberclient --rpc-address node2_rpc_ip:node2_rpc_port --cert member1_cert.pem --privk member1_privk.pem --ca /path/to/new/network/certificate rekey_ledger
$ cat rekey_ledger.json
{
"jsonrpc": "2.0",
"id": 0,
"method": "members/propose",
"params": {
"parameter": [<sealed secrets>],
"script": {
"text": "return Calls:call(\"rekey_ledger\")"
}
}
}
$ curl https://<ccf-node-address>/members/propose --cacert network_cert --key member1_privk --cert member1_cert --data-binary @rekey_ledger.json
{"commit":100,"global_commit":99,"id":0,"jsonrpc":"2.0","result":{"completed":false,"id":1},"term":2}
$ memberclient --rpc-address node2_rpc_ip:node2_rpc_port --cert member2_cert.pem --privk member2_privk.pem --ca /path/to/new/network/certificate vote --accept --proposal-id 1
$ ./scurl.sh https://<ccf-node-address>/members/vote --cacert network_cert --key member2_privk --cert member2_cert --data-binary @vote_accept_1.json
{"commit":102,"global_commit":101,"id":0,"jsonrpc":"2.0","result":false,"term":2}
$ memberclient --rpc-address node2_rpc_ip:node2_rpc_port --cert member3_cert.pem --privk member3_privk.pem --ca /path/to/new/network/certificate vote --accept --proposal-id 1
$ ./scurl.sh https://<ccf-node-address>/members/vote --cacert network_cert --key member3_privk --cert member3_cert --data-binary @vote_accept_1.json
{"commit":104,"global_commit":103,"id":0,"jsonrpc":"2.0","result":true,"term":2}
Once the proposal is accepted (``"result":true``), all subsequent transactions (in this case, with a ``commit`` index greater than ``104``) will be encrypted with a fresh new ledger encryption key. This key is sealed to disk once the rekey transaction is globally committed.
Loading

0 comments on commit 26a60ad

Please sign in to comment.