From 480b48a050ff1a7febb2c651e288bf86a430d23a Mon Sep 17 00:00:00 2001 From: Joel Dudley Date: Fri, 6 Apr 2018 14:42:04 +0100 Subject: [PATCH 1/3] Adds a table of contents. Readds Dockerform instructions. --- docs/source/generating-a-node.rst | 89 ++++++++++++++++++++++++++++--- 1 file changed, 82 insertions(+), 7 deletions(-) diff --git a/docs/source/generating-a-node.rst b/docs/source/generating-a-node.rst index 3625692701..9d36bb1e12 100644 --- a/docs/source/generating-a-node.rst +++ b/docs/source/generating-a-node.rst @@ -1,9 +1,11 @@ Creating nodes locally ====================== +.. contents:: + Node structure -------------- -Each Corda node has the following structure: +A Corda node has the following structure: .. sourcecode:: none @@ -101,7 +103,10 @@ in the `Kotlin CorDapp Template ``` +included in the samples directory of main Corda GitHub repository: + +.. sourcecode:: groovy + + def rpcUsersList = [ + ['username' : "user", + 'password' : "password", + 'permissions' : [ + "StartFlow.net.corda.irs.flows.AutoOfferFlow\$Requester", + "StartFlow.net.corda.irs.flows.UpdateBusinessDayFlow\$Broadcast", + "StartFlow.net.corda.irs.api.NodeInterestRates\$UploadFixesFlow", + "InvokeRpc.vaultQueryBy", + "InvokeRpc.networkMapSnapshot", + "InvokeRpc.currentNodeTime", + "InvokeRpc.wellKnownPartyFromX500Name" + ]] + ] + + // (...) + + task prepareDockerNodes(type: net.corda.plugins.Dockerform, dependsOn: ['jar']) { + + node { + name "O=Notary Service,L=Zurich,C=CH" + notary = [validating : true] + cordapps = ["${project(":finance").group}:finance:$corda_release_version"] + rpcUsers = rpcUsersList + useTestClock true + } + node { + name "O=Bank A,L=London,C=GB" + cordapps = ["${project(":finance").group}:finance:$corda_release_version"] + rpcUsers = rpcUsersList + useTestClock true + } + node { + name "O=Bank B,L=New York,C=US" + cordapps = ["${project(":finance").group}:finance:$corda_release_version"] + rpcUsers = rpcUsersList + useTestClock true + } + node { + name "O=Regulator,L=Moscow,C=RU" + cordapps = ["${project.group}:finance:$corda_release_version"] + rpcUsers = rpcUsersList + useTestClock true + } + } + +There is no need to specify the ports, as every node is a separated container, so no ports conflict will occur. +Running the task will create the same folders structure as described in :ref:`The Cordform task` with an additional +```Dockerfile`` in each node directory, and ```docker-compose.yml``` in ```build/nodes``` directory. Every node +by default exposes port 10003 which is the default one for RPC connections. + +.. warning:: Webserver is not supported by this task! + +.. warning:: Nodes are run without the local shell enabled! + +Running the Cordform/Dockerform tasks +------------------------------------- To create the nodes defined in our ``deployNodes`` task, run the following command in a terminal window from the root of the project where the ``deployNodes`` task is defined: From e48cd808b0a9317e274679ccdde8614554774d59 Mon Sep 17 00:00:00 2001 From: Viktor Kolomeyko Date: Fri, 6 Apr 2018 17:11:03 +0100 Subject: [PATCH 2/3] Try to improve stability of `NodeRegistrationTest` (#2942) Since we are running web-server and different handling methods will be called from different threads, it is more appropriate to use concurrent data structures for exchanging information between threads. Prior to this change I observed the following exception which is likely to be due `certPaths` not synchronized between threads: ``` Caused by: kotlin.KotlinNullPointerException at net.corda.node.utilities.registration.RegistrationHandler$reply$1.invoke(NodeRegistrationTest.kt:151) ~[integrationTest/:?] at net.corda.node.utilities.registration.RegistrationHandler$reply$1.invoke(NodeRegistrationTest.kt:122) ~[integrationTest/:?] at net.corda.core.internal.InternalUtils.logElapsedTime(InternalUtils.kt:221) ~[corda-core-corda-4.0-snapshot.jar:?] at net.corda.core.internal.InternalUtils.logElapsedTime(InternalUtils.kt:213) ~[corda-core-corda-4.0-snapshot.jar:?] at net.corda.node.utilities.registration.RegistrationHandler.reply(NodeRegistrationTest.kt:149) ~[integrationTest/:?] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_161] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_161] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_161] at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_161] ``` --- .../node/utilities/registration/NodeRegistrationTest.kt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/node/src/integration-test/kotlin/net/corda/node/utilities/registration/NodeRegistrationTest.kt b/node/src/integration-test/kotlin/net/corda/node/utilities/registration/NodeRegistrationTest.kt index eb691ea415..685b47c057 100644 --- a/node/src/integration-test/kotlin/net/corda/node/utilities/registration/NodeRegistrationTest.kt +++ b/node/src/integration-test/kotlin/net/corda/node/utilities/registration/NodeRegistrationTest.kt @@ -37,6 +37,8 @@ import java.security.KeyPair import java.security.cert.CertPath import java.security.cert.Certificate import java.security.cert.X509Certificate +import java.util.concurrent.ConcurrentHashMap +import java.util.concurrent.ConcurrentSkipListSet import java.util.zip.ZipEntry import java.util.zip.ZipOutputStream import javax.ws.rs.* @@ -119,8 +121,8 @@ class NodeRegistrationTest { @Path("certificate") class RegistrationHandler(private val rootCertAndKeyPair: CertificateAndKeyPair) { - private val certPaths = HashMap() - val idsPolled = HashSet() + private val certPaths = ConcurrentHashMap() + val idsPolled = ConcurrentSkipListSet() companion object { val log = loggerFor() From 2792716157d79e1162ed20438d5d0db33e7b3a8a Mon Sep 17 00:00:00 2001 From: Katarzyna Streich Date: Sat, 7 Apr 2018 15:18:05 +0100 Subject: [PATCH 3/3] CORDA-1181: Add back information on initial registration (#2943) --- .../resources/example-network-map-node.conf | 4 -- .../src/main/resources/example-node.conf | 1 - .../net/corda/docs/ExampleConfigTest.kt | 3 +- docs/source/generating-a-node.rst | 2 + docs/source/permissioning.rst | 38 +++++++++++++++++++ 5 files changed, 41 insertions(+), 7 deletions(-) delete mode 100644 docs/source/example-code/src/main/resources/example-network-map-node.conf diff --git a/docs/source/example-code/src/main/resources/example-network-map-node.conf b/docs/source/example-code/src/main/resources/example-network-map-node.conf deleted file mode 100644 index d36b5b222c..0000000000 --- a/docs/source/example-code/src/main/resources/example-network-map-node.conf +++ /dev/null @@ -1,4 +0,0 @@ -myLegalName : "O=Notary Service,OU=corda,L=London,C=GB" -keyStorePassword : "cordacadevpass" -trustStorePassword : "trustpass" -p2pAddress : "my-network-map:10000" \ No newline at end of file diff --git a/docs/source/example-code/src/main/resources/example-node.conf b/docs/source/example-code/src/main/resources/example-node.conf index 48595226ab..1d3075391b 100644 --- a/docs/source/example-code/src/main/resources/example-node.conf +++ b/docs/source/example-code/src/main/resources/example-node.conf @@ -18,4 +18,3 @@ rpcUsers : [ { username=user1, password=letmein, permissions=[ StartFlow.net.corda.protocols.CashProtocol ] } ] devMode : true -// certificateSigningService : "https://testnet.certificate.corda.net" diff --git a/docs/source/example-code/src/test/kotlin/net/corda/docs/ExampleConfigTest.kt b/docs/source/example-code/src/test/kotlin/net/corda/docs/ExampleConfigTest.kt index 014c93c312..2cd762ec4e 100644 --- a/docs/source/example-code/src/test/kotlin/net/corda/docs/ExampleConfigTest.kt +++ b/docs/source/example-code/src/test/kotlin/net/corda/docs/ExampleConfigTest.kt @@ -29,8 +29,7 @@ class ExampleConfigTest { fun `example node_confs parses fine`() { readAndCheckConfigurations( "example-node.conf", - "example-out-of-process-verifier-node.conf", - "example-network-map-node.conf" + "example-out-of-process-verifier-node.conf" ) { val baseDirectory = Paths.get("some-example-base-dir") ConfigHelper.loadConfig( diff --git a/docs/source/generating-a-node.rst b/docs/source/generating-a-node.rst index 9d36bb1e12..f2bcfd6d6d 100644 --- a/docs/source/generating-a-node.rst +++ b/docs/source/generating-a-node.rst @@ -25,6 +25,8 @@ In development mode (i.e. when ``devMode = true``, see :doc:`corda-configuration directory is filled with pre-configured keystores if the required keystores do not exist. This ensures that developers can get the nodes working as quickly as possible. However, these pre-configured keystores are not secure, to learn more see :doc:`permissioning`. +.. _node_naming: + Node naming ----------- A node's name must be a valid X.500 distinguished name. In order to be compatible with other implementations diff --git a/docs/source/permissioning.rst b/docs/source/permissioning.rst index ca4ed2ccb1..6546bd5224 100644 --- a/docs/source/permissioning.rst +++ b/docs/source/permissioning.rst @@ -15,6 +15,8 @@ Most production deployments will use an existing certificate authority or constr made available in the coming months. Until then, the documentation below can be used to create your own certificate authority. +.. note:: If you are looking for information on how to connect to the existing compatibility zone go to the section: `Connecting to a compatibility zone`_ + Certificate hierarchy --------------------- A Corda network has four types of certificate authorities (CAs): @@ -177,3 +179,39 @@ For each node, copy the following files to the node's certificate directory (``< 1. The node's ``nodekeystore.jks`` keystore 2. The node's ``sslkeystore.jks`` keystore 3. The root network CA's ``truststore.jks`` keystore + +Connecting to a compatibility zone +---------------------------------- +To connect to a compatibility zone you need to register with their certificate signing authority (doorman) by submitting +a certificate signing request (CSR) to obtain a valid identity for the zone. + +Before you can register, you must first have received the trust store file containing the root certificate from the zone +operator. Then run the following command: + +``java -jar corda.jar --initial-registration --network-root-truststore-password `` + +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. + +:emailAddress: e.g. "admin@company.com" + +:devMode: must be set to false + +:compatibilityZoneURL: Corda compatibility zone network management service root URL. + + 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. + +This process only is needed when the node connects to the network for the first time, or when the certificate expires.