mirror of
https://github.com/corda/corda.git
synced 2024-12-18 20:47:57 +00:00
Updated network docs (#4154)
* Renaming and reordering to help users navigate the Networks section. * Split of pages between bootstrapped, existing and dynamic compatibility zones. Reintegrates Mike H content about creating a dynamic zone. * Address review feedback except BNO point. * Documents BNO app. * Better docs of networkServices config option. Better comments of NetworkParameters fields. * Documents additional network map protocol endpoint. * Address review feedback. * Addresses Kostas review feedback. * Update protocol due to bug. * Addresses Kostas's review feedback. * Addresses Kostas's review feedback.
This commit is contained in:
parent
9fcf15e825
commit
8b2ab41057
@ -1,5 +1,5 @@
|
||||
Supported cipher suites
|
||||
=======================
|
||||
Cipher suites supported by Corda
|
||||
================================
|
||||
|
||||
.. contents::
|
||||
|
||||
|
@ -4,54 +4,29 @@
|
||||
<script type="text/javascript" src="_static/jquery.js"></script>
|
||||
<script type="text/javascript" src="_static/codesets.js"></script>
|
||||
|
||||
Compatibility zones
|
||||
===================
|
||||
What is a compatibility zone?
|
||||
=============================
|
||||
|
||||
Every Corda node is part of a "zone" (also sometimes called a Corda network) that is *permissioned*. Production
|
||||
deployments require a secure certificate authority. Most users will join an existing network such as Corda
|
||||
Network (the main network) or the Corda Testnet. We use the term "zone" to refer to a set of technically compatible nodes reachable
|
||||
over a TCP/IP network like the internet. The word "network" is used in Corda but can be ambiguous with the concept
|
||||
of a "business network", which is usually more like a membership list or subset of nodes in a zone that have agreed
|
||||
to trade with each other.
|
||||
deployments require a secure certificate authority. We use the term "zone" to refer to a set of technically compatible
|
||||
nodes reachable over a TCP/IP network like the internet. The word "network" is used in Corda but can be ambiguous with
|
||||
the concept of a "business network", which is usually more like a membership list or subset of nodes in a zone that
|
||||
have agreed to trade with each other.
|
||||
|
||||
To connect to a compatibility zone you need to register with its certificate signing authority (doorman) by submitting
|
||||
a certificate signing request (CSR) to obtain a valid identity for the zone. You could do this out of band, for instance
|
||||
via email or a web form, but there's also a simple request/response protocol built into Corda.
|
||||
How do I become part of a compatibility zone?
|
||||
---------------------------------------------
|
||||
|
||||
Before you can register, you must first have received the trust store file containing the root certificate from the zone
|
||||
operator. For high security zones this might be delivered physically. Then run the following command:
|
||||
Bootstrapping a compatibility zone
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
You can easily bootstrap a compatibility zone for testing or pre-production use with either the
|
||||
:doc:`network-bootstrapper` or the :doc:`network-builder` tools.
|
||||
|
||||
``java -jar corda.jar --initial-registration --network-root-truststore-password <trust store password>``
|
||||
Joining an existing compatibility zone
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
After the testing and pre-production phases, users are encouraged to join an existing compatibility zone such as Corda
|
||||
Network (the main compatibility zone) or the Corda Testnet. See :doc:`joining-a-compatibility-zone`.
|
||||
|
||||
By default it will expect the trust store file to be in the location ``certificates/network-root-truststore.jks``.
|
||||
This can be overridden with the additional ``--network-root-truststore`` flag.
|
||||
|
||||
The certificate signing request will be created based on node information obtained from the node configuration.
|
||||
The following information from the node configuration file is needed to generate the request.
|
||||
|
||||
* **myLegalName** Your company's legal name as an X.500 string. X.500 allows differentiation between entities with the same
|
||||
name, as the legal name needs to be unique on the network. If another node has already been permissioned with this
|
||||
name then the permissioning server will automatically reject the request. The request will also be rejected if it
|
||||
violates legal name rules, see :ref:`node_naming` for more information. You can use the X.500 schema to disambiguate
|
||||
entities that have the same or similar brand names.
|
||||
|
||||
* **emailAddress** e.g. "admin@company.com"
|
||||
|
||||
* **devMode** must be set to false
|
||||
|
||||
* **networkServices** or **compatibilityZoneURL** The Corda compatibility zone services must be configured. This must be either:
|
||||
|
||||
* **compatibilityZoneURL** The Corda compatibility zone network management service root URL.
|
||||
* **networkServices** Replaces the ``compatibilityZoneURL`` when the doorman and network map services
|
||||
are configured to operate on different URL endpoints. The ``doorman`` entry is used for registration.
|
||||
|
||||
A new pair of private and public keys generated by the Corda node will be used to create the request.
|
||||
|
||||
The utility will submit the request to the doorman server and poll for a result periodically to retrieve the
|
||||
certificates. Once the request has been approved and the certificates downloaded from the server, the node will create
|
||||
the keystore and trust store using the certificates and the generated private key.
|
||||
|
||||
.. note:: You can exit the utility at any time if the approval process is taking longer than expected. The request
|
||||
process will resume on restart as long as the ``--initial-registration`` flag is specified.
|
||||
|
||||
This process only is needed when the node connects to the network for the first time, or when the certificate expires.
|
||||
Setting up a dynamic compatibility zone
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Some users may also be interested in setting up their own dynamic compatibility zone. For instructions and a discussion
|
||||
of whether this approach is suitable for you, see :doc:`setting-up-a-dynamic-compatibility-zone`.
|
||||
|
@ -5,14 +5,13 @@ Networks
|
||||
:maxdepth: 1
|
||||
|
||||
compatibility-zones
|
||||
corda-testnet-intro
|
||||
running-a-notary
|
||||
permissioning
|
||||
network-map
|
||||
versioning
|
||||
azure-vm-explore
|
||||
aws-vm-explore
|
||||
gcp-vm
|
||||
deploy-locally
|
||||
testnet-explorer-corda
|
||||
cipher-suites
|
||||
joining-a-compatibility-zone
|
||||
corda-testnet-intro
|
||||
deploy-to-testnet-index
|
||||
testnet-explorer-corda
|
||||
setting-up-a-dynamic-compatibility-zone
|
||||
running-a-notary
|
||||
|
@ -1,5 +1,5 @@
|
||||
The Corda Testnet
|
||||
=================
|
||||
Joining Corda Testnet
|
||||
=====================
|
||||
|
||||
.. contents::
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
Setting up your local environment to allow the deployment of a Corda node
|
||||
=========================================================================
|
||||
Deploying Corda to Corda Testnet from your local environment
|
||||
============================================================
|
||||
|
||||
.. contents::
|
||||
|
||||
|
10
docs/source/deploy-to-testnet-index.rst
Normal file
10
docs/source/deploy-to-testnet-index.rst
Normal file
@ -0,0 +1,10 @@
|
||||
Deploying Corda to Testnet
|
||||
==========================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
azure-vm-explore
|
||||
aws-vm-explore
|
||||
gcp-vm
|
||||
deploy-locally
|
58
docs/source/joining-a-compatibility-zone.rst
Normal file
58
docs/source/joining-a-compatibility-zone.rst
Normal file
@ -0,0 +1,58 @@
|
||||
.. highlight:: kotlin
|
||||
.. raw:: html
|
||||
|
||||
<script type="text/javascript" src="_static/jquery.js"></script>
|
||||
<script type="text/javascript" src="_static/codesets.js"></script>
|
||||
|
||||
Joining an existing compatibility zone
|
||||
======================================
|
||||
|
||||
To connect to a compatibility zone you need to register with its certificate signing authority (or *doorman*) by
|
||||
submitting a certificate signing request (CSR) to obtain a valid identity for the zone. This process is only necessary
|
||||
when the node connects to the network for the first time, or when the certificate expires. You could do this out of
|
||||
band, for instance via email or a web form, but there's also a simple request/response utility built into the node.
|
||||
|
||||
Before using this utility, you must first have received the trust store file containing the root certificate from the
|
||||
zone operator. For high security zones, this might be delivered physically. Then run the following command:
|
||||
|
||||
``java -jar corda.jar --initial-registration --network-root-truststore-password <trust store password>``
|
||||
|
||||
By default, the utility expects the trust store file to be in the location ``certificates/network-root-truststore.jks``.
|
||||
This can be overridden using the additional ``--network-root-truststore`` flag.
|
||||
|
||||
The utility performs the following steps:
|
||||
|
||||
1. It creates a certificate signing request based on the following information from the node's configuration file (see
|
||||
:doc:`corda-configuration-file`):
|
||||
|
||||
* **myLegalName** Your company's legal name as an X.500 string. X.500 allows differentiation between entities with the same
|
||||
name, as the legal name needs to be unique on the network. If another node has already been permissioned with this
|
||||
name then the permissioning server will automatically reject the request. The request will also be rejected if it
|
||||
violates legal name rules, see :ref:`node_naming` for more information. You can use the X.500 schema to disambiguate
|
||||
entities that have the same or similar brand names
|
||||
|
||||
* **emailAddress** e.g. "admin@company.com"
|
||||
|
||||
* **devMode** must be set to false
|
||||
|
||||
* **compatibilityZoneURL** or **networkServices** The address(es) used to register with the compatibility zone and
|
||||
retrieve the network map. These should be provided to you by the operator of the zone. This must be either:
|
||||
|
||||
* **compatibilityZoneURL** The root address of the network management service. Use this if both the doorman and the
|
||||
network map service are operating on the same URL endpoint
|
||||
* **networkServices** The root addresses of the doorman and the network map service. Use this if the doorman and the
|
||||
network map service are operating on the same URL endpoint, where:
|
||||
|
||||
* **doormanURL** is the root address of the doorman. This is the address used for initial registration
|
||||
* **networkMapURL** is the root address of the network map service
|
||||
|
||||
2. It generates a new private/public keypair to sign the certificate signing request
|
||||
|
||||
3. It submits the request to the doorman server and polls periodically to retrieve the corresponding certificates
|
||||
|
||||
4. It creates the node's keystore and trust store using the received certificates
|
||||
|
||||
5. It creates and stores the node's TLS keys and legal identity key along with their corresponding certificate-chains
|
||||
|
||||
.. note:: You can exit the utility at any time if the approval process is taking longer than expected. The request
|
||||
process will resume on restart as long as the ``--initial-registration`` flag is specified.
|
@ -1,5 +1,5 @@
|
||||
Network map
|
||||
===========
|
||||
The network map
|
||||
===============
|
||||
|
||||
.. contents::
|
||||
|
||||
@ -45,6 +45,8 @@ The set of REST end-points for the network map service are as follows.
|
||||
+----------------+-----------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| GET | /network-map/network-parameters/{hash} | Retrieve the signed network parameters (see below). The entire object is signed with the network map certificate which is also attached. |
|
||||
+----------------+-----------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
| GET | /network-map/my-hostname | Retrieve the IP address of the caller (and **not** of the network map). |
|
||||
+----------------+-----------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------+
|
||||
|
||||
HTTP is used for the network map service instead of Corda's own AMQP based peer to peer messaging protocol to
|
||||
enable the server to be placed behind caching content delivery networks like Cloudflare, Akamai, Amazon Cloudfront and so on.
|
||||
|
@ -4,8 +4,8 @@
|
||||
<script type="text/javascript" src="_static/jquery.js"></script>
|
||||
<script type="text/javascript" src="_static/codesets.js"></script>
|
||||
|
||||
Network permissioning
|
||||
=====================
|
||||
Network certificates
|
||||
====================
|
||||
|
||||
.. contents::
|
||||
|
||||
|
191
docs/source/setting-up-a-dynamic-compatibility-zone.rst
Normal file
191
docs/source/setting-up-a-dynamic-compatibility-zone.rst
Normal file
@ -0,0 +1,191 @@
|
||||
.. highlight:: kotlin
|
||||
.. raw:: html
|
||||
|
||||
<script type="text/javascript" src="_static/jquery.js"></script>
|
||||
<script type="text/javascript" src="_static/codesets.js"></script>
|
||||
|
||||
Setting up a dynamic compatibility zone
|
||||
=======================================
|
||||
|
||||
.. contents::
|
||||
|
||||
Do you need to create your own dynamic compatibility zone?
|
||||
----------------------------------------------------------
|
||||
|
||||
By *dynamic compatibility zone*, we mean a compatibility zone that relies on a network map server to allow nodes to
|
||||
join dynamically, instead of requiring each node to be bootstrapped and have the node-infos distributed manually. While
|
||||
this may sound appealing, think twice before going down this route:
|
||||
|
||||
1. If you need to test a CorDapp, it is easier to create a test network using the network bootstrapper tool (see below)
|
||||
2. If you need to control who uses your CorDapp, it is easier to apply permissioning by creating a business network
|
||||
(see below)
|
||||
|
||||
**Testing.** Creating a production-ready zone isn't necessary for testing as you can use the *network bootstrapper*
|
||||
tool to create all the certificates, keys, and distribute the needed map files to run many nodes. The bootstrapper can
|
||||
create a network locally on your desktop/laptop but it also knows how to automate cloud providers via their APIs and
|
||||
using Docker. In this way you can bring up a simulation of a real Corda network with different nodes on different
|
||||
machines in the cloud for your own testing. Testing this way has several advantages, most obviously that you avoid
|
||||
race conditions in your tests caused by nodes/tests starting before all map data has propagated to all nodes.
|
||||
You can read more about the reasons for the creation of the bootstrapper tool
|
||||
`in a blog post on the design thinking behind Corda's network map infrastructure <https://medium.com/corda/cordas-new-network-map-infrastructure-8c4c248fd7f3>`__.
|
||||
|
||||
**Permissioning.** And creating a zone is also unnecessary for imposing permissioning requirements beyond that of the
|
||||
base Corda network. You can control who can use your app by creating a *business network*. A business network is what we
|
||||
call a coalition of nodes that have chosen to run a particular app within a given commercial context. Business networks
|
||||
aren't represented in the Corda API at this time, partly because the technical side is so simple. You can create one
|
||||
via a simple three step process:
|
||||
|
||||
1. Distribute a list of X.500 names that are members of your business network. You can use the
|
||||
`reference Business Network Membership Service implementation <https://github.com/corda/corda-solutions/tree/master/bn-apps/memberships-management>`_.
|
||||
Alternatively, you could do this is by hosting a text file with one name per line on your website at a fixed HTTPS
|
||||
URL. You could also write a simple request/response flow that serves the list over the Corda protocol itself,
|
||||
although this requires the business network to have its own node.
|
||||
2. Write a bit of code that downloads and caches the contents of this file on disk, and which loads it into memory in
|
||||
the node. A good place to do this is in a class annotated with ``@CordaService``, because this class can expose
|
||||
a ``Set<Party>`` field representing the membership of your service.
|
||||
3. In your flows use ``serviceHub.findService`` to get a reference to your ``@CordaService`` class, read the list of
|
||||
members and at the start of each flow, throw a FlowException if the counterparty isn't in the membership list.
|
||||
|
||||
In this way you can impose a centrally controlled ACL that all members will collectively enforce.
|
||||
|
||||
.. note:: A production-ready Corda network and a new iteration of the testnet will be available soon.
|
||||
|
||||
Why create your own zone?
|
||||
-------------------------
|
||||
|
||||
The primary reason to create a zone and provide the associated infrastructure is control over *network parameters*. These
|
||||
are settings that control Corda's operation, and on which all users in a network must agree. Failure to agree would create
|
||||
the Corda equivalent of a blockchain "hard fork". Parameters control things like the root of identity,
|
||||
how quickly users should upgrade, how long nodes can be offline before they are evicted from the system and so on.
|
||||
|
||||
Creating a zone involves the following steps:
|
||||
|
||||
1. Create the zone private keys and certificates. This procedure is conventional and no special knowledge is required:
|
||||
any self-signed set of certificates can be used. A professional quality zone will probably keep the keys inside a
|
||||
hardware security module (as the main Corda network and test networks do).
|
||||
2. Write a network map server.
|
||||
3. Optionally, create a doorman server.
|
||||
4. Finally, you would select and generate your network parameter file.
|
||||
|
||||
How to create your own compatibility zone
|
||||
-----------------------------------------
|
||||
|
||||
Using an existing network map implementation
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
You can use an existing network map implementation such as the
|
||||
`Cordite Network Map Service <https://gitlab.com/cordite/network-map-service>`_ to create a dynamic compatibility zone.
|
||||
|
||||
Creating your own network map implementation
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Writing a network map server
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This server implements a simple HTTP based protocol described in the ":doc:`network-map`" page.
|
||||
The map server is responsible for gathering NodeInfo files from nodes, storing them, and distributing them back to the
|
||||
nodes in the zone. By doing this it is also responsible for choosing who is in and who is out: having a signed
|
||||
identity certificate is not enough to be a part of a Corda zone, you also need to be listed in the network map.
|
||||
It can be thought of as a DNS equivalent. If you want to de-list a user, you would do it here.
|
||||
|
||||
It is very likely that your map server won't be entirely standalone, but rather, integrated with whatever your master
|
||||
user database is.
|
||||
|
||||
The network map server also distributes signed network parameter files and controls the rollout schedule for when they
|
||||
become available for download and opt-in, and when they become enforced. This is again a policy decision you will
|
||||
probably choose to place some simple UI or workflow tooling around, in particular to enforce restrictions on who can
|
||||
edit the map or the parameters.
|
||||
|
||||
Writing a doorman server
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This step is optional because your users can obtain a signed certificate in many different ways. The doorman protocol
|
||||
is again a very simple HTTP based approach in which a node creates keys and requests a certificate, polling until it
|
||||
gets back what it expects. However, you could also integrate this process with the rest of your signup process. For example,
|
||||
by building a tool that's integrated with your payment flow (if payment is required to take part in your zone at all).
|
||||
Alternatively you may wish to distribute USB smartcard tokens that generate the private key on first use, as is typically
|
||||
seen in national PKIs. There are many options.
|
||||
|
||||
If you do choose to make a doorman server, the bulk of the code you write will be workflow related. For instance,
|
||||
related to keeping track of an applicant as they proceed through approval. You should also impose any naming policies
|
||||
you have in the doorman process. If names are meant to match identities registered in government databases then that
|
||||
should be enforced here, alternatively, if names can be self-selected or anonymous, you would only bother with a
|
||||
deduplication check. Again it will likely be integrated with a master user database.
|
||||
|
||||
Corda does not currently provide a doorman or network map service out of the box, partly because when stripped of the
|
||||
zone specific policy there isn't much to them: just a basic HTTP server that most programmers will have favourite
|
||||
frameworks for anyway.
|
||||
|
||||
The protocol is:
|
||||
|
||||
* If $URL = ``https://some.server.com/some/path``
|
||||
* Node submits a PKCS#10 certificate signing request using HTTP POST to ``$URL/certificate``. It will have a MIME
|
||||
type of ``application/octet-stream``. The ``Client-Version`` header is set to be "1.0".
|
||||
* The server returns an opaque string that references this request (let's call it ``$requestid``, or an HTTP error if something went wrong.
|
||||
* The returned request ID should be persisted to disk, to handle zones where approval may take a long time due to manual
|
||||
intervention being required.
|
||||
* The node starts polling ``$URL/$requestid`` using HTTP GET. The poll interval can be controlled by the server returning
|
||||
a response with a ``Cache-Control`` header.
|
||||
* If the request is answered with a ``200 OK`` response, the body is expected to be a zip file. Each file is expected to
|
||||
be a binary X.509 certificate, and the certs are expected to be in order.
|
||||
* If the request is answered with a ``204 No Content`` response, the node will try again later.
|
||||
* If the request is answered with a ``403 Not Authorized`` response, the node will treat that as request rejection and give up.
|
||||
* Other response codes will cause the node to abort with an exception.
|
||||
|
||||
Setting zone parameters
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Zone parameters are stored in a file containing a Corda AMQP serialised ``SignedDataWithCert<NetworkParameters>``
|
||||
object. It is easy to create such a file with a small Java or Kotlin program. The ``NetworkParameters`` object is a
|
||||
simple data holder that could be read from e.g. a config file, or settings from a database. Signing and saving the
|
||||
resulting file is just a few lines of code. A full example can be found in ``NetworkParametersCopier.kt`` in the source
|
||||
tree, but a flavour of it looks like this:
|
||||
|
||||
.. container:: codeset
|
||||
|
||||
.. sourcecode:: java
|
||||
|
||||
NetworkParameters networkParameters = new NetworkParameters(
|
||||
4, // minPlatformVersion
|
||||
Collections.emptyList(), // the `NotaryInfo`s of all the network's notaries
|
||||
1024 * 1024 * 20, // maxMessageSize
|
||||
1024 * 1024 * 15, // maxTransactionSize
|
||||
Instant.now(), // modifiedTime
|
||||
2, // epoch
|
||||
Collections.emptyMap() // whitelisted contract code JARs
|
||||
);
|
||||
CertificateAndKeyPair signingCertAndKeyPair = loadNetworkMapCA();
|
||||
SerializedBytes<SignedDataWithCert<NetworkParameters>> bytes = SerializedBytes.from(netMapCA.sign(networkParameters));
|
||||
Files.copy(bytes.open(), Paths.get("params-file"));
|
||||
|
||||
.. sourcecode:: kotlin
|
||||
|
||||
val networkParameters = NetworkParameters(
|
||||
minimumPlatformVersion = 4,
|
||||
notaries = listOf(...),
|
||||
maxMessageSize = 1024 * 1024 * 20 // 20mb, for example.
|
||||
maxTransactionSize = 1024 * 1024 * 15,
|
||||
modifiedTime = Instant.now(),
|
||||
epoch = 2,
|
||||
... etc ...
|
||||
)
|
||||
val signingCertAndKeyPair: CertificateAndKeyPair = loadNetworkMapCA()
|
||||
val signedParams: SerializedBytes<SignedNetworkParameters> = signingCertAndKeyPair.sign(networkParameters).serialize()
|
||||
signedParams.open().copyTo(Paths.get("/some/path"))
|
||||
|
||||
Each individual parameter is documented in `the JavaDocs/KDocs for the NetworkParameters class
|
||||
<https://docs.corda.net/api/kotlin/corda/net.corda.core.node/-network-parameters/index.html>`__. The network map
|
||||
certificate is usually chained off the root certificate, and can be created according to the instructions above. Each
|
||||
time the zone parameters are changed, the epoch should be incremented. Epochs are essentially version numbers for the
|
||||
parameters, and they therefore cannot go backwards. Once saved, the new parameters can be served by the network map server.
|
||||
|
||||
Selecting parameter values
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
How to choose the parameters? This is the most complex question facing you as a new zone operator. Some settings may seem
|
||||
straightforward and others may involve cost/benefit tradeoffs specific to your business. For example, you could choose
|
||||
to run a validating notary yourself, in which case you would (in the absence of SGX) see all the users' data. Or you could
|
||||
run a non-validating notary, with BFT fault tolerance, which implies recruiting others to take part in the cluster.
|
||||
|
||||
New network parameters will be added over time as Corda evolves. You will need to ensure that when your users upgrade,
|
||||
all the new network parameters are being served. You can ask for advice on the `corda-dev mailing list <https://groups.io/g/corda-dev>`__.
|
Loading…
Reference in New Issue
Block a user