Merge pull request #832 from corda/mike-merge-ea81548d6

Merge to ea81548d6
This commit is contained in:
Mike Hearn 2018-05-11 21:44:59 +02:00 committed by GitHub
commit eea7ae3a67
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
43 changed files with 265 additions and 312 deletions

View File

@ -46,7 +46,7 @@ sealed class ByteSequence(private val _bytes: ByteArray, val offset: Int, val si
* @param offset The offset within this sequence to start the new sequence. Note: not the offset within the backing array.
* @param size The size of the intended sub sequence.
*/
@Suppress("MemberVisibilityCanPrivate")
@Suppress("MemberVisibilityCanBePrivate")
fun subSequence(offset: Int, size: Int): ByteSequence {
require(offset >= 0)
require(offset + size <= this.size)
@ -176,7 +176,7 @@ open class OpaqueBytes(bytes: ByteArray) : ByteSequence(bytes, 0, bytes.size) {
* compiler is ever able to optimise away the clone. In which case we may need to revisit
* this later.
*/
override final val bytes: ByteArray = bytes
final override val bytes: ByteArray = bytes
get() = field.clone()
}

View File

@ -128,7 +128,7 @@ class ProgressTracker(vararg steps: Step) {
if (currentStep == value) return
val index = steps.indexOf(value)
require(index != -1)
require(index != -1, { "Step ${value.label} not found in progress tracker." })
if (index < stepIndex) {
// We are going backwards: unlink and unsubscribe from any child nodes that we're rolling back

View File

@ -1,13 +1,26 @@
## The following requirements were added by pip freeze:
alabaster==0.7.8
Babel==2.3.4
certifi==2018.4.16
chardet==3.0.4
docutils==0.12
idna==2.6
imagesize==0.7.1
Jinja2==2.8
MarkupSafe==0.23
Pygments==2.1.3
packaging==17.1
pdfrw==0.4
Pillow==5.1.0
Pygments==2.2.0
pyparsing==2.2.0
pytz==2016.4
reportlab==3.4.0
requests==2.18.4
rst2pdf==0.93
six==1.10.0
snowballstemmer==1.2.1
Sphinx==1.4.4
Sphinx==1.7.4
sphinx-rtd-theme==0.1.9
rst2pdf==0.93
sphinxcontrib-websupport==1.0.1
typing==3.6.4
urllib3==1.22

View File

@ -20,6 +20,8 @@ Any object that needs to be identified by its hash should implement the ``NamedB
``SecureHash`` is a sealed class that only defines a single subclass, ``SecureHash.SHA256``. There are utility methods
to create and parse ``SecureHash.SHA256`` objects.
.. _composite_keys:
CompositeKey
------------
Corda supports scenarios where more than one signature is required to authorise a state object transition. For example:

View File

@ -265,10 +265,11 @@ In order to create a communication session between your initiator flow and the r
* Sends the ``payload`` object and receives an object of type ``receiveType`` back
In addition ``FlowLogic`` provides functions that batch receives:
* ``receiveAllMap(sessions: Map<FlowSession, Class<out Any>>): Map<FlowSession, UntrustworthyData<Any>>``
* Receives from all ``FlowSession``s specified in the passed in map. The received types may differ.
Receives from all ``FlowSession`` objects specified in the passed in map. The received types may differ.
* ``receiveAll(receiveType: Class<R>, sessions: List<FlowSession>): List<UntrustworthyData<R>>``
* Receives from all ``FlowSession``s specified in the passed in list. The received types must be the same.
Receives from all ``FlowSession`` objects specified in the passed in list. The received types must be the same.
The batched functions are implemented more efficiently by the flow framework.

View File

@ -124,7 +124,7 @@ JDBC connection (session) as described by the `Java SQL Connection API <https://
Use the ``ServiceHub`` ``jdbcSession`` function to obtain a JDBC connection as illustrated in the following example:
.. literalinclude:: ../../node/src/test/kotlin/net/corda/node/services/database/HibernateConfigurationTest.kt
.. literalinclude:: ../../node/src/test/kotlin/net/corda/node/services/persistence/HibernateConfigurationTest.kt
:language: kotlin
:start-after: DOCSTART JdbcSession
:end-before: DOCEND JdbcSession

View File

@ -377,7 +377,7 @@ Track unconsumed cash states:
:language: kotlin
:start-after: DOCSTART VaultQueryExample15
:end-before: DOCEND VaultQueryExample15
:dedent: 20
:dedent: 12
Track unconsumed linear states:
@ -385,7 +385,7 @@ Track unconsumed linear states:
:language: kotlin
:start-after: DOCSTART VaultQueryExample16
:end-before: DOCEND VaultQueryExample16
:dedent: 20
:dedent: 12
.. note:: This will return both ``DealState`` and ``LinearState`` states.
@ -395,7 +395,7 @@ Track unconsumed deal states:
:language: kotlin
:start-after: DOCSTART VaultQueryExample17
:end-before: DOCEND VaultQueryExample17
:dedent: 20
:dedent: 12
.. note:: This will return only ``DealState`` states.

View File

@ -1,20 +1,20 @@
Building a Corda VM from the AWS Marketplace
============================================
To help you design, build and test applications on Corda, called CorDapps, a Corda network AMI can be deployed from the `AWS Marketplace <https://aws.amazon.com/marketplace/pp/B077PG9SP5>`_. Instructions on running Corda nodes can be found `here <https://docs.corda.net/deploying-a-node.html>`_.
To help you design, build and test applications on Corda, called CorDapps, a Corda network AMI can be deployed from the `AWS Marketplace <https://aws.amazon.com/marketplace/pp/B077PG9SP5>`__. Instructions on running Corda nodes can be found `here <https://docs.corda.net/deploying-a-node.html>`_.
This Corda network offering builds a pre-configured network of Corda nodes as Ubuntu virtual machines (VM). The network consists of a Notary node and three Corda nodes using version 1 of Corda. The following guide will also show you how to load one of four `Corda Sample apps <https://www.corda.net/samples>`_ which demonstrates the basic principles of Corda. When you are ready to go further with developing on Corda and start making contributions to the project head over to the `Corda.net <https://www.corda.net/>`_.
Pre-requisites
--------------
* Ensure you have a registered AWS account which can create virtual machines under your subscription(s) and you are logged on to the `AWS portal <https://console.aws.amazon.com>`_
* It is recommended you generate a private-public SSH key pair (see `here <https://www.digitalocean.com/community/tutorials/how-to-set-up-ssh-keys--2/>`_)
* It is recommended you generate a private-public SSH key pair (see `here <https://www.digitalocean.com/community/tutorials/how-to-set-up-ssh-keys--2/>`__)
Deploying a Corda Network
---------------------------
Browse to the `AWS Marketplace <https://aws.amazon.com/marketplace>`_ and search for Corda.
Browse to the `AWS Marketplace <https://aws.amazon.com/marketplace>`__ and search for Corda.
Follow the instructions to deploy the AMI to an instance of EC2 which is in a region near to your location.
@ -59,7 +59,7 @@ Then start the Corda webserver
find ~/dev/cordapp-example/kotlin-source/ -name corda-webserver.jar -execdir sh -c 'java -jar {} &' \;
You can now interact with your running CorDapp. See the instructions `here <https://docs.corda.net/tutorial-cordapp.html#via-http>`_
You can now interact with your running CorDapp. See the instructions `here <https://docs.corda.net/tutorial-cordapp.html#via-http>`__.
Next Steps
----------

View File

@ -8,7 +8,7 @@ This Corda network offering builds a pre-configured network of Corda nodes as Ub
Pre-requisites
--------------
* Ensure you have a registered Microsoft Azure account which can create virtual machines under your subscription(s) and you are logged on to the Azure portal (portal.azure.com)
* It is recommended you generate a private-public SSH key pair (see `here <https://www.digitalocean.com/community/tutorials/how-to-set-up-ssh-keys--2/>`_)
* It is recommended you generate a private-public SSH key pair (see `here <https://www.digitalocean.com/community/tutorials/how-to-set-up-ssh-keys--2/>`__)
Deploying the Corda Network

View File

@ -7,7 +7,7 @@ against the unstable Master branch if you are using a very recent feature, or ar
To work against the Master branch, proceed as follows:
1. Open a terminal window in the folder where you cloned the Corda repository
(available `here <https://github.com/corda/corda>`_)
(available `here <https://github.com/corda/corda>`_)
2. Use the following command to check out the latest master branch:

View File

@ -6,9 +6,9 @@ release, see :doc:`upgrade-notes`.
Unreleased
==========
* Fixed an error thrown by NodeVaultService upon recording a transaction with a number of inputs greater than the default page size.
* Node will now gracefully fail to start if one of the required ports is already in use.
* Fixed incorrect computation of ``totalStates`` from ``otherResults`` in ``NodeVaultService``.
* Node will now gracefully fail to start if ``devMode`` is true and ``compatibilityZoneURL`` is specified.
* Changes to the JSON/YAML serialisation format from ``JacksonSupport``, which also applies to the node shell:
@ -20,48 +20,33 @@ Unreleased
* ``PartyAndCertificate`` is serialised as an object containing the name and owning key
* ``SignedTransaction`` can now be serialized to JSON and deserialized back into an object.
* Several members of ``JacksonSupport`` have been deprecated to highlight that they are internal and not to be used
* Several members of ``JacksonSupport`` have been deprecated to highlight that they are internal and not to be used.
* Refactor AMQP Serializer to pass context object down the serialization call hierarchy. Will allow per thread
extensions to be set and used by the RPC work (Observable Context Key)
* The Vault Criteria API has been extended to take a more precise specification of which class contains a field. This
primarily impacts Java users; Kotlin users need take no action. The old methods have been deprecated but still work -
the new methods avoid bugs that can occur when JPA schemas inherit from each other.
* Refactor RPC Server Kryo observable serializer into it's own sub module
* The Vault Criteria API has been extended to take a more precise specification of which class contains a field. This primarily impacts Java users; Kotlin users need take no action. The old methods have been deprecated but still work - the new methods avoid bugs that can occur when JPA schemas inherit from each other.
* Refactor RPC Client Kryo observable serializer into it's own sub module
* Fix CORDA-1403 where a property of a class that implemented a generic interface could not be deserialized in
a factory without a serializer as the subtype check for the class instance failed. Fix is to compare the raw
type.
* Due to ongoing work the experimental interfaces for defining custom notary services have been moved to the internal package.
CorDapps implementing custom notary services will need to be updated, see ``samples/notary-demo`` for an example.
Further changes may be required in the future.
* Fixed incorrect exception handling in ``NodeVaultService._query()``.
* Avoided a memory leak deriving from incorrect MappedSchema caching strategy.
* Configuration file changes:
* Added program line argument ``on-unknown-config-keys`` to allow specifying behaviour on unknown node configuration property keys.
Values are: [FAIL, WARN, IGNORE], default to FAIL if unspecified.
* Added program line argument ``on-unknown-config-keys`` to allow specifying behaviour on unknown node configuration property keys.
Values are: [FAIL, WARN, IGNORE], default to FAIL if unspecified.
* Introduced a placeholder for custom properties within ``node.conf``; the property key is "custom".
* The deprecated web server now has its own ``web-server.conf`` file, separate from ``node.conf``.
* Property keys with double quotes (e.g. `"key"`) in ``node.conf`` are no longer allowed, for rationale refer to :doc:`corda-configuration-file`.
* Fix CORDA-1229. Setter-based serialization was broken with generic types when the property was stored
as the raw type, List for example.
* More types can be serialized now: java.security.cert.CRLReason, java.security.cert.X509CRL, java.math.BigInteger
* java.security.cert.CRLReason added to the default Whitelist.
* java.security.cert.X509CRL serialization support added.
* Replaced the ``PersistentMap`` in ``NodeSchedulerService`` with an implementation that only loads the next scheduled
state from the database into memory, rather than them all.
* Upgraded H2 to v1.4.197.
* Upgraded H2 to v1.4.197
* Shell (embedded available only in dev mode or via SSH) connects to the node via RPC instead of using the ``CordaRPCOps`` object directly.
To enable RPC connectivity ensure nodes ``rpcSettings.address`` and ``rpcSettings.adminAddress`` settings are present.
* Changes to the network bootstrapper:
* The whitelist.txt file is no longer needed. The existing network parameters file is used to update the current contracts
whitelist.
* The CorDapp jars are also copied to each nodes' `cordapps` directory.
@ -72,20 +57,10 @@ Unreleased
framework. Prior to this change it didn't work, but the error thrown was opaque (complaining about too few arguments
to a constructor). Whilst this was possible in the older Kryo implementation (Kryo passing null as the synthesised
reference to the outer class) as per the Java documentation `here <https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html>`_
we are disallowing this as the paradigm in general makes little sense for Contract States
* Fix CORDA-1258. Custom serializers were spuriously registered every time a serialization factory was fetched from the cache rather than
only once when it was created. Whilst registering serializers that already exist is essentially a no-op, it's a performance overhead for
a very frequent operation that hits a synchronisation point (and is thus flagged as contended by our perfomance suite)
we are disallowing this as the paradigm in general makes little sense for contract states.
* Update the fast-classpath-scanner dependent library version from 2.0.21 to 2.12.3
.. note:: Whilst this is not the latest version of this library, that being 2.18.1 at time of writing, versions later
than 2.12.3 (including 2.12.4) exhibit a different issue.
* Fixed node's behaviour on startup when there is no connectivity to network map. Node continues to work normally if it has
all the needed network data, waiting in the background for network map to become available.
* Added `database.hibernateDialect` node configuration option
.. _changelog_r3_v3:
@ -95,11 +70,6 @@ R3 Corda 3.0 Developer Preview
* Fix CORDA-1229. Setter-based serialization was broken with generic types when the property was stored as the raw type, List for example.
* Update the fast-classpath-scanner dependent library version from 2.0.21 to 2.12.3
.. note:: Whilst this is not the latest version of this library, that being 2.18.1 at time of writing, versions later
than 2.12.3 (including 2.12.4) exhibit a different issue.
* Fixed security vulnerability when using the ``HashAttachmentConstraint``. Added strict check that the contract JARs
referenced in a transaction were deployed on the node.
@ -188,7 +158,7 @@ than 2.12.3 (including 2.12.4) exhibit a different issue.
* To support local and test deployments, the node polls the ``additional-node-infos`` directory for these signed ``NodeInfo``
objects which are stored in its local cache. On startup the node generates its own signed file with the filename format
"nodeInfo-*". This can be copied to every node's ``additional-node-infos`` directory that is part of the network.
"nodeInfo-\*". This can be copied to every node's ``additional-node-infos`` directory that is part of the network.
* Cordform (which is the ``deployNodes`` gradle task) does this copying automatically for the demos. The ``NetworkMap``
parameter is no longer needed.
@ -300,13 +270,13 @@ than 2.12.3 (including 2.12.4) exhibit a different issue.
* The ``ReceiveTransactionFlow`` can now be told to record the transaction at the same time as receiving it. Using this
feature, better support for observer/regulator nodes has been added. See :doc:`tutorial-observer-nodes`.
* Added an overload of ``TransactionWithSignatures.verifySignaturesExcept`` which takes in a collection of ``PublicKey``s.
* Added an overload of ``TransactionWithSignatures.verifySignaturesExcept`` which takes in a collection of ``PublicKey`` s.
* ``DriverDSLExposedInterface`` has been renamed to ``DriverDSL`` and the ``waitForAllNodesToFinish()`` method has instead
become a parameter on driver creation.
* Values for the ``database.transactionIsolationLevel`` config now follow the ``java.sql.Connection`` int constants but
without the "TRANSACTION_" prefix, i.e. "NONE", "READ_UNCOMMITTED", etc.
without the "TRANSACTION" prefix, i.e. "NONE", "READ_UNCOMMITTED", etc.
* Peer-to-peer communications is now via AMQP 1.0 as default.
Although the legacy Artemis CORE bridging can still be used by setting the ``useAMQPBridges`` configuration property to false.
@ -477,7 +447,7 @@ Corda 1.0
* Vault query soft locking enhancements and deprecations
* removed original ``VaultService`` ``softLockedStates` query mechanism.
* removed original ``VaultService`` ``softLockedStates`` query mechanism.
* introduced improved ``SoftLockingCondition`` filterable attribute in ``VaultQueryCriteria`` to enable specification of different soft locking retrieval behaviours (exclusive of soft locked states, soft locked states only, specified by set of lock ids)
* Trader demo now issues cash and commercial paper directly from the bank node, rather than the seller node self-issuing

View File

@ -21,6 +21,7 @@ between the TLS and Node Identity certificates.
Certificate hierarchy
---------------------
A Corda network has 8 types of keys and a regular node requires 4 of them:
* The **root network CA** key
@ -52,51 +53,51 @@ underlying HSM device, but the default for dev-mode is Pure EdDSA (ed25519).
The following table presents the 5 signature schemes currently supported by Corda. The TLS column shows which of them
are compatible with TLS 1.2, while the default scheme per key type is also shown.
+-------------------------+-------------------------------------------------------------+-----+-----------------------+
| Cipher suite | Description | TLS | Default for |
+=========================+=============================================================|=====+=======================+
| Pure EdDSA using the | EdDSA represents the current state of the art in mainstream | NO | node identity |
| ed25519 curve | cryptography. It implements elliptic curve cryptography | | confidential identity |
| and SHA-512 | with deterministic signatures a fast implementation, | | network map (dev) |
| | explained constants, side channel resistance and many other | | |
| | desirable characteristics. However, it is relatively new | | |
| | and not widely supported, for example, you can't use it in | | |
| | TLS yet (a draft RFC exists but is not standardised yet). | | |
+-------------------------+-------------------------------------------------------------+-----+-----------------------+
| ECDSA using the | This is the default choice for most systems that support | YES | root network CA |
| NIST P-256 curve | elliptic curve cryptography today and is recommended by | | doorman CA |
| (secp256r1) | NIST. It is also supported by the majority of the HSM | | node CA |
| and SHA-256 | vendors. | | tls |
| | | | network map (CN) |
+-------------------------+-------------------------------------------------------------+-----+-----------------------+
| ECDSA using the | secp256k1 is the curve adopted by Bitcoin and as such there | YES | |
| Koblitz k1 curve | is a wealth of infrastructure, code and advanced algorithms | | |
| (secp256k1) | designed for use with it. This curve is standardised by | | |
| and SHA-256 | NIST as part of the "Suite B" cryptographic algorithms and | | |
| | as such is more widely supported than ed25519. By | | |
| | supporting it we gain access to the ecosystem of advanced | | |
| | cryptographic techniques and devices pioneered by the | | |
| | Bitcoin community. | | |
+-------------------------+-------------------------------------------------------------+-----+-----------------------+
| RSA (3072bit) PKCS#1 | RSA is well supported by any sort of hardware or software | YES | |
| and SHA-256 | as a signature algorithm no matter how old, for example, | | |
| | legacy HSMs will support this along with obsolete operating | | |
| | systems. RSA is using bigger keys than ECDSA and thus it is | | |
| | recommended for inclusion only for its backwards | | |
| | compatibility properties, and only for usage where legacy | | |
| | constraints or government regulation forbids the usage of | | |
| | more modern approaches. | | |
+-------------------------+-------------------------------------------------------------+-----+-----------------------+
| SPHINCS-256 | SPHINCS-256 is a post-quantum secure algorithm that relies | NO | |
| and SHA-512 | only on hash functions. It is included as a hedge against | | |
| | the possibility of a malicious adversary obtaining a | | |
| | quantum computer capable of running Shor's algorithm in | | |
| | future. SPHINCS is based ultimately on a clever usage of | | |
| | Merkle hash trees. Hash functions are a very heavily | | |
| | studied and well understood area of cryptography. Thus, it | | |
| | is assumed that there is a much lower chance of | | |
| | breakthrough attacks on the underlying mathematical | | |
| | problems. However, SPHINCS uses relatively big public keys, | | |
| | it is slower and outputs bigger signatures than EdDSA, | | |
| | ECDSA and RSA algorithms. | | |
+-------------------------+-------------------------------------------------------------+-----+-----------------------+
+-------------------------+---------------------------------------------------------------+-----+-------------------------+
| Cipher suite | Description | TLS | Default for |
+=========================+===============================================================+=====+=========================+
| | Pure EdDSA using the | | EdDSA represents the current state of the art in mainstream | NO | - node identity |
| | ed25519 curve | | cryptography. It implements elliptic curve cryptography | | - confidential identity |
| | and SHA-512 | | with deterministic signatures a fast implementation, | | - network map (dev) |
| | | explained constants, side channel resistance and many other | | |
| | | desirable characteristics. However, it is relatively new | | |
| | | and not widely supported, for example, you can't use it in | | |
| | | TLS yet (a draft RFC exists but is not standardised yet). | | |
+-------------------------+---------------------------------------------------------------+-----+-------------------------+
| | ECDSA using the | | This is the default choice for most systems that support | YES | - root network CA |
| | NIST P-256 curve | | elliptic curve cryptography today and is recommended by | | - doorman CA |
| | (secp256r1) | | NIST. It is also supported by the majority of the HSM | | - node CA |
| | and SHA-256 | | vendors. | | - tls |
| | | | - network map (CN) |
+-------------------------+---------------------------------------------------------------+-----+-------------------------+
| | ECDSA using the | | secp256k1 is the curve adopted by Bitcoin and as such there | YES | |
| | Koblitz k1 curve | | is a wealth of infrastructure, code and advanced algorithms | | |
| | (secp256k1) | | designed for use with it. This curve is standardised by | | |
| | and SHA-256 | | NIST as part of the "Suite B" cryptographic algorithms and | | |
| | | as such is more widely supported than ed25519. By | | |
| | | supporting it we gain access to the ecosystem of advanced | | |
| | | cryptographic techniques and devices pioneered by the | | |
| | | Bitcoin community. | | |
+-------------------------+---------------------------------------------------------------+-----+-------------------------+
| | RSA (3072bit) PKCS#1 | | RSA is well supported by any sort of hardware or software | YES | |
| | and SHA-256 | | as a signature algorithm no matter how old, for example, | | |
| | | legacy HSMs will support this along with obsolete operating | | |
| | | systems. RSA is using bigger keys than ECDSA and thus it is | | |
| | | recommended for inclusion only for its backwards | | |
| | | compatibility properties, and only for usage where legacy | | |
| | | constraints or government regulation forbids the usage of | | |
| | | more modern approaches. | | |
+-------------------------+---------------------------------------------------------------+-----+-------------------------+
| | SPHINCS-256 | | SPHINCS-256 is a post-quantum secure algorithm that relies | NO | |
| | and SHA-512 | | only on hash functions. It is included as a hedge against | | |
| | | the possibility of a malicious adversary obtaining a | | |
| | | quantum computer capable of running Shor's algorithm in | | |
| | | future. SPHINCS is based ultimately on a clever usage of | | |
| | | Merkle hash trees. Hash functions are a very heavily | | |
| | | studied and well understood area of cryptography. Thus, it | | |
| | | is assumed that there is a much lower chance of | | |
| | | breakthrough attacks on the underlying mathematical | | |
| | | problems. However, SPHINCS uses relatively big public keys, | | |
| | | it is slower and outputs bigger signatures than EdDSA, | | |
| | | ECDSA and RSA algorithms. | | |
+-------------------------+---------------------------------------------------------------+-----+-------------------------+

View File

@ -197,7 +197,7 @@ of ``INMEMORY`` type:
an exception at node startup.
Authentication/authorisation data
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The ``dataSource`` structure defines the data provider supplying credentials and permissions for users. There exist two
supported types of such data source, identified by the ``dataSource.type`` field:
@ -218,7 +218,7 @@ supported types of such data source, identified by the ``dataSource.type`` field
in each table alongside the expected ones.
Password encryption
^^^^^^^^^^^^^^^^^^^
~~~~~~~~~~~~~~~~~~~
Storing passwords in plain text is discouraged in applications where security is critical. Passwords are assumed
to be in plain format by default, unless a different format is specified by the ``passwordEncryption`` field, like:
@ -235,7 +235,7 @@ it is currently the only non-plain password hash-encryption format supported. Ha
format can be produced by using the `Apache Shiro Hasher command line tool <https://shiro.apache.org/command-line-hasher.html>`_.
Caching user accounts data
^^^^^^^^^^^^^^^^^^^^^^^^^^
~~~~~~~~~~~~~~~~~~~~~~~~~~
A cache layer on top of the external data source of users credentials and permissions can significantly improve
performances in some cases, with the disadvantage of causing a (controllable) delay in picking up updates to the underlying data.

View File

@ -44,7 +44,7 @@ Here's the workflow for contract upgrades:
9. The ``Initiator`` node sends the proposed transaction, along with details of the new contract upgrade path that it
is proposing, to all participants of the state object
10. Each counterparty (the ``Acceptor``s) verifies the proposal, signs or rejects the state reissuance accordingly, and
10. Each counterparty (the ``Acceptor`` s) verifies the proposal, signs or rejects the state reissuance accordingly, and
sends a signature or rejection notification back to the initiating node
11. If signatures are received from all parties, the ``Initiator`` assembles the complete signed transaction and sends

View File

@ -112,7 +112,7 @@ absolute path to the node's base directory.
:messageRedeliveryDelay: The initial retry delay, e.g. `30 seconds`.
:maxRetryCount: How many retries to attempt.
:backoffBase: The base of the exponential backoff, :math:`t_{wait} = messageRedeliveryDelay * backoffBase^{retryCount}`.
:backoffBase: The base of the exponential backoff, `t_{wait} = messageRedeliveryDelay * backoffBase^{retryCount}`.
:rpcAddress: The address of the RPC system on which RPC requests can be made to the node. If not provided then the node will run without RPC. This is now deprecated in favour of the ``rpcSettings`` block.
@ -241,9 +241,8 @@ Examples
General node configuration file for hosting the IRSDemo services:
.. literalinclude:: example-code/src/main/resources/example-node.conf
:language: javascript
Simple notary configuration file:
Simple notary configuration file:
.. parsed-literal::
@ -292,7 +291,7 @@ path to the node's base directory.
node certificate and private key.
.. note:: This is the non-secret value for the development certificates automatically generated during the first node run.
Longer term these keys will be managed in secure hardware devices.
Longer term these keys will be managed in secure hardware devices.
:trustStorePassword: The password to unlock the Trust store file (``<workspace>/certificates/truststore.jks``) containing
the Corda network root certificate. This is the non-secret value for the development certificates automatically
@ -324,5 +323,5 @@ Longer term these keys will be managed in secure hardware devices.
:password: The password
:permissions: A list of permissions for starting flows via RPC. To give the user the permission to start the flow
``foo.bar.FlowClass``, add the string ``StartFlow.foo.bar.FlowClass`` to the list. If the list
contains the string ``ALL``, the user can start any flow via RPC. This value is intended for administrator
users and for development.
contains the string ``ALL``, the user can start any flow via RPC. This value is intended for administrator
users and for development.

View File

@ -17,21 +17,20 @@ Custom serializer classes should follow the rules for including classes found in
Writing a Custom Serializer
---------------------------
Serializers must
* Inherit from ``net.corda.core.serialization.SerializationCustomSerializer``
* Provide a proxy class to transform the object to and from
* Implement the ``toProxy`` and ``fromProxy`` methods
* Be either included into CorDapp Jar or made known to the running process via ``amqp.custom.serialization.scanSpec``
system property.
This system property may be necessary to be able to discover custom serializer in the classpath. At a minimum the value
of the property should include comma separated set of packages where custom serializers located. Full syntax includes
scanning specification as defined by: `<http://github.com/lukehutch/fast-classpath-scanner/wiki/2.-Constructor#scan-spec>`
system property. This system property may be necessary to be able to discover custom serializer in the classpath. At a minimum the value
of the property should include comma separated set of packages where custom serializers located. Full syntax includes
scanning specification as defined by: `<http://github.com/lukehutch/fast-classpath-scanner/wiki/2.-Constructor#scan-spec>`
Serializers inheriting from ``SerializationCustomSerializer`` have to implement two methods and two types.
Example
-------
Consider this example class
Consider this example class:
.. sourcecode:: java

View File

@ -33,9 +33,7 @@ handling, and ensures the Corda service is run at boot.
5. Create a directory called ``cordapps`` in ``/opt/corda`` and save your CorDapp jar file to it. Alternatively, download one of
our `sample CorDapps <https://www.corda.net/samples/>`_ to the ``cordapps`` directory
6. Save the below as ``/opt/corda/node.conf``. See :doc:`corda-configuration-file` for a description of these options
.. code-block:: json
6. Save the below as ``/opt/corda/node.conf``. See :doc:`corda-configuration-file` for a description of these options::
basedir : "/opt/corda"
p2pAddress : "example.com:10002"
@ -192,9 +190,7 @@ at boot, and means the Corda service stays running with no users connected to th
* Oracle Java 8. The supported versions are listed in :doc:`getting-set-up`
1. Create a Corda directory and download the Corda jar. Replace ``VERSION_NUMBER`` with the desired version. Here's an
example using PowerShell:
.. code-block:: PowerShell
example using PowerShell::
mkdir C:\Corda
wget http://jcenter.bintray.com/net/corda/corda/VERSION_NUMBER/corda-VERSION_NUMBER.jar -OutFile C:\Corda\corda.jar
@ -202,9 +198,7 @@ at boot, and means the Corda service stays running with no users connected to th
2. Create a directory called ``cordapps`` in ``C:\Corda\`` and save your CorDapp jar file to it. Alternatively,
download one of our `sample CorDapps <https://www.corda.net/samples/>`_ to the ``cordapps`` directory
3. Save the below as ``C:\Corda\node.conf``. See :doc:`corda-configuration-file` for a description of these options
.. code-block:: json
3. Save the below as ``C:\Corda\node.conf``. See :doc:`corda-configuration-file` for a description of these options::
basedir : "C:\\Corda"
p2pAddress : "example.com:10002"

View File

@ -419,7 +419,7 @@ the other counterparties. Instead they will be informed the flow has terminated
generic exception.
.. note:: A future version will extend this to give the node administrator more control on what to do with such erroring
flows.
flows.
Throwing a ``FlowException`` enables a flow to reject a piece of data it has received back to the sender. This is typically
done in the ``unwrap`` method of the received ``UntrustworthyData``. In the above example the seller checks the price

View File

@ -39,9 +39,9 @@ any issues, please consult the :doc:`troubleshooting` page, or reach out on `Sla
The set-up instructions are available for the following platforms:
* :ref:`windows-label` (or `in video form <https://vimeo.com/217462250>`_)
* :ref:`windows-label` (or `in video form <https://vimeo.com/217462250>`__)
* :ref:`mac-label` (or `in video form <https://vimeo.com/217462230>`_)
* :ref:`mac-label` (or `in video form <https://vimeo.com/217462230>`__)
.. _windows-label:
@ -171,8 +171,8 @@ The best way to check that everything is working fine is by taking a deeper look
Next, you should read through :doc:`Corda Key Concepts <key-concepts>` to understand how Corda works.
By then, you'll be ready to start writing your own CorDapps. Learn how to do this in the
:doc:`Hello, World tutorial <hello-world-introduction>`. You may want to refer to the :doc:`API docs <api-index>`, the
:doc:`Hello, World tutorial <hello-world-introduction>`. You may want to refer to the API documentation, the
:doc:`flow cookbook <flow-cookbook>` and the `samples <https://www.corda.net/samples/>`_ along the way.
If you encounter any issues, please see the :doc:`troubleshooting` page, or get in touch with us on the
`forums <https://discourse.corda.net/>`_ or via `slack <http://slack.corda.net/>`_.
If you encounter any issues, please see the :doc:`troubleshooting` page, or ask on
`Stack Overflow <https://stackoverflow.com/questions/tagged/corda>`_ or via `our Slack channels <http://slack.corda.net/>`_.

View File

@ -124,7 +124,7 @@ If the flow worked, it should have recorded a new IOU in the vaults of both Part
We can check the contents of each node's vault by running:
.. code-block:: base
.. code-block:: bash
run vaultQuery contractStateType: com.template.IOUState

View File

@ -39,7 +39,7 @@ Corda also uses several other techniques to maximize privacy on the network:
* **Transaction tear-offs**: Transactions are structured in a way that allows them to be digitally signed without
disclosing the transaction's contents. This is achieved using a data structure called a Merkle tree. You can read
more about this technique in :doc:`merkle-trees`.
more about this technique in :doc:`tutorial-tear-offs`.
* **Key randomisation**: The parties to a transaction are identified only by their public keys, and fresh keypairs are
generated for each transaction. As a result, an onlooker cannot identify which parties were involved in a given
transaction.

View File

@ -95,8 +95,10 @@ Each required signers should only sign the transaction if the following two cond
* **Transaction validity**: For both the proposed transaction, and every transaction in the chain of transactions
that created the current proposed transaction's inputs:
* The transaction is digitally signed by all the required parties
* The transaction is *contractually valid* (see :doc:`key-concepts-contracts`)
* **Transaction uniqueness**: There exists no other committed transaction that has consumed any of the inputs to
our proposed transaction (see :doc:`key-concepts-consensus`)

View File

@ -54,7 +54,7 @@ for maintenance and other minor purposes.
:``internal.peers.$identity``:
These are a set of private queues only available to the node which it uses to route messages destined to other peers.
The queue name ends in the base 58 encoding of the peer's identity key. There is at most one queue per peer. The broker
creates a bridge from this queue to the peer's ``p2p.inbound.$identity`` queue, using the network map service to lookup the
creates a bridge from this queue to the peer's ``p2p.inbound.$identity`` queue, using the network map service to lookup the
peer's network address.
:``internal.services.$identity``:

View File

@ -1,4 +1,4 @@
Network permissioning
Network permissioning
=====================
.. contents::

View File

@ -132,4 +132,4 @@ and simply requires setting two Gradle build file variables:
Please note this release is distributed under the evaluation license and should not be used in a Production environment yet.
We look forward to hearing your feedback on this release!
We look forward to hearing your feedback on this release!

View File

@ -1,15 +1,15 @@
Running a notary service
------------------------
At present we have several prototype notary implementations:
At present we have several notary implementations:
1. ``SimpleNotaryService`` (single node) -- commits the provided transaction input states without any validation.
2. ``ValidatingNotaryService`` (single node) -- retrieves and validates the whole transaction history
(including the given transaction) before committing.
3. ``RaftNonValidatingNotaryService`` (distributed) -- functionally equivalent to ``SimpleNotaryService``, but stores
the committed states in a distributed collection replicated and persisted in a Raft cluster. For the consensus layer
we are using the `Copycat <http://atomix.io/copycat/>`_ framework
4. ``RaftValidatingNotaryService`` (distributed) -- as above, but performs validation on the transactions received
we are using the `Copycat <http://atomix.io/copycat/>`_ framework.
4. ``RaftValidatingNotaryService`` (distributed) -- as above, but performs validation on the transactions received.
To have a node run a notary service, you need to set appropriate ``notary`` configuration before starting it
(see :doc:`corda-configuration-file` for reference).

View File

@ -94,7 +94,7 @@ tests in ``FxTransactionBuildTutorialTest.kt`` and
part of a simulated in-memory network of nodes.
.. note:: Before creating the IntelliJ run configurations for these unit tests
go to Run -> Edit |nbsp| Configurations -> Defaults -> JUnit, add
go to Run -> Edit Configurations -> Defaults -> JUnit, add
``-javaagent:lib/quasar.jar``
to the VM options, and set Working directory to ``$PROJECT_DIR$``
so that the ``Quasar`` instrumentation is correctly configured.
@ -301,4 +301,4 @@ overall transaction id is still provable from the
not expose that data to the other node directly. A full example of this
can be found in the ``NodeInterestRates`` Oracle code from the
``irs-demo`` project which interacts with the ``RatesFixFlow`` flow.
Also, refer to the :doc:`merkle-trees` documentation.
Also, refer to the :doc:`tutorial-tear-offs`.

View File

@ -156,11 +156,13 @@ The key files and directories are as follows:
about which version is required
* **lib** contains the Quasar jar which rewrites our CorDapp's flows to be checkpointable
* **kotlin-source** contains the source code for the example CorDapp written in Kotlin
* **kotlin-source/src/main/kotlin** contains the source code for the example CorDapp
* **kotlin-source/src/main/resources** contains the certificate store, some static web content to be served by the
nodes and the WebServerPluginRegistry file
* **kotlin-source/src/test/kotlin** contains unit tests for the contracts and flows, and the driver to run the nodes
via IntelliJ
* **kotlin-source/src/main/kotlin** contains the source code for the example CorDapp
* **kotlin-source/src/main/resources** contains the certificate store, some static web content to be served by the
nodes and the WebServerPluginRegistry file
* **kotlin-source/src/test/kotlin** contains unit tests for the contracts and flows, and the driver to run the nodes
via IntelliJ
* **java-source** contains the same source code, but written in Java. CorDapps can be developed in any language
targeting the JVM

View File

@ -53,6 +53,6 @@ The following code snippet is taken from ``NodeInterestRates.kt`` and implements
components (leaves). However, it can happen that having transaction with multiple commands one party reveals only subset of them to the Oracle.
As signing is done now over the Merkle root hash, the service signs all commands of given type, even though it didn't see
all of them. In the case however where all of the commands should be visible to an Oracle, one can type ``ftx.checkAllComponentsVisible(COMMANDS_GROUP)`` before invoking ``ftx.verify``.
``checkAllComponentsVisible`` is using a sophisticated underlying partial Merkle tree check to guarantee that all of
the components of a particular group that existed in the original ``WireTransaction`` are included in the received
``FilteredTransaction``.
``checkAllComponentsVisible`` is using a sophisticated underlying partial Merkle tree check to guarantee that all of
the components of a particular group that existed in the original ``WireTransaction`` are included in the received
``FilteredTransaction``.

View File

@ -28,13 +28,19 @@ project so that they do not bloat the CorDapp at build time.
.. _cordapp-structure:
Structure
---------
You should base the structure of your project on the Java or Kotlin templates:
Structure and dependencies
--------------------------
You should base your project on the Java template (for CorDapps written in Java) or the Kotlin template (for CorDapps
written in Kotlin):
* `Java Template CorDapp <https://github.com/corda/cordapp-template-java>`_
* `Kotlin Template CorDapp <https://github.com/corda/cordapp-template-kotlin>`_
Please checkout the branch of the template that corresponds to the version of Corda you are using. For example, someone
building a CorDapp on Corda 3 should use the ``release-V3`` branch of the template.
The required dependencies are defined by the ``build.gradle`` file in the root directory of the template.
The project should be split into two modules:
* A ``cordapp-contracts-states`` module containing classes such as contracts and states that will be sent across the
@ -135,14 +141,12 @@ These are for testing purposes and would be removed in a production CorDapp.
Resources
---------
In writing a CorDapp, you should consult the following resources:
In writing a CorDapp, these pages may be particularly helpful:
* :doc:`Getting Set Up </getting-set-up>` to set up your development environment
* The :doc:`Hello, World! tutorial </hello-world-index>` to write your first CorDapp
* :doc:`Building a CorDapp </cordapp-build-systems>` to build and run your CorDapp
* The :doc:`API docs </api-index>` to read about the API available in developing CorDapps
* There is also a :doc:`cheatsheet </cheat-sheet>` recapping the key types
* The :doc:`Flow cookbook </flow-cookbook>` to see code examples of how to perform common flow tasks
* `Sample CorDapps <https://www.corda.net/samples/>`_ showing various parts of Corda's functionality
* :doc:`getting-set-up`, to set up your development environment.
* The :doc:`hello-world-introduction` tutorial to write your first CorDapp.
* :doc:`cordapp-build-systems` to build and run your CorDapp.
* The `API docs </api/javadoc/index.html>`_ to read about the API available in developing CorDapps.
* There is also a :doc:`cheat-sheet` recapping the key types.
* The :doc:`flow-cookbook` to see code examples of how to perform common flow tasks.
* `Sample CorDapps <https://www.corda.net/samples/>`_ showing various parts of Corda's functionality.

View File

@ -35,9 +35,7 @@ object CashSchemaV1 : MappedSchema(
override val migrationResource = "cash.changelog-master"
@Entity
@Table(name = "contract_cash_states",
indexes = arrayOf(Index(name = "ccy_code_idx", columnList = "ccy_code"),
Index(name = "pennies_idx", columnList = "pennies")))
@Table(name = "contract_cash_states", indexes = [Index(name = "ccy_code_idx", columnList = "ccy_code"), Index(name = "pennies_idx", columnList = "pennies")])
class PersistentCashState(
/** X500Name of owner party **/
@Column(name = "owner_name")

View File

@ -38,10 +38,7 @@ object CommercialPaperSchemaV1 : MappedSchema(
override val migrationResource = "commercial-paper.changelog-master"
@Entity
@Table(name = "cp_states",
indexes = arrayOf(Index(name = "ccy_code_index", columnList = "ccy_code"),
Index(name = "maturity_index", columnList = "maturity_instant"),
Index(name = "face_value_index", columnList = "face_value")))
@Table(name = "cp_states", indexes = [Index(name = "ccy_code_index", columnList = "ccy_code"), Index(name = "maturity_index", columnList = "maturity_instant"), Index(name = "face_value_index", columnList = "face_value")])
class PersistentCommercialPaperState(
@Column(name = "issuance_key_hash", length = MAX_HASH_HEX_SIZE)
var issuancePartyHash: String,

View File

@ -34,9 +34,7 @@ object SampleCashSchemaV1 : MappedSchema(schemaFamily = CashSchema.javaClass, ve
override val migrationResource = "sample-cash-v1.changelog-init"
@Entity
@Table(name = "contract_cash_states_v1",
indexes = arrayOf(Index(name = "ccy_code_idx", columnList = "ccy_code"),
Index(name = "pennies_idx", columnList = "pennies")))
@Table(name = "contract_cash_states_v1", indexes = [Index(name = "ccy_code_idx", columnList = "ccy_code"), Index(name = "pennies_idx", columnList = "pennies")])
class PersistentCashState(
@Column(name = "owner_key_hash", length = MAX_HASH_HEX_SIZE)
var ownerHash: String,

View File

@ -35,10 +35,7 @@ object SampleCommercialPaperSchemaV1 : MappedSchema(schemaFamily = CommercialPap
override val migrationResource = "sample-cp-v1.changelog-init"
@Entity
@Table(name = "cp_states_v1",
indexes = arrayOf(Index(name = "ccy_code_index", columnList = "ccy_code"),
Index(name = "maturity_index", columnList = "maturity_instant"),
Index(name = "face_value_index", columnList = "face_value")))
@Table(name = "cp_states_v1", indexes = [Index(name = "ccy_code_index", columnList = "ccy_code"), Index(name = "maturity_index", columnList = "maturity_instant"), Index(name = "face_value_index", columnList = "face_value")])
class PersistentCommercialPaperState(
@Column(name = "issuance_key_hash", length = MAX_HASH_HEX_SIZE)
var issuancePartyHash: String,

View File

@ -30,8 +30,7 @@ object SampleCommercialPaperSchemaV2 : MappedSchema(schemaFamily = CommercialPap
override val migrationResource = "sample-cp-v2.changelog-init"
@Entity
@Table(name = "cp_states_v2",
indexes = [Index(name = "ccy_code_index2", columnList = "ccy_code"), Index(name = "maturity_index2", columnList = "maturity_instant")])
@Table(name = "cp_states_v2", indexes = [Index(name = "ccy_code_index2", columnList = "ccy_code"), Index(name = "maturity_index2", columnList = "maturity_instant")])
class PersistentCommercialPaperState(
@Column(name = "maturity_instant")
var maturity: Instant,

View File

@ -11,14 +11,22 @@
package net.corda.node.services.network
import net.corda.cordform.CordformNode
import net.corda.core.concurrent.CordaFuture
import net.corda.core.crypto.random63BitValue
import net.corda.core.internal.*
import net.corda.core.identity.CordaX500Name
import net.corda.core.internal.bufferUntilSubscribed
import net.corda.core.internal.concurrent.transpose
import net.corda.core.internal.div
import net.corda.core.internal.exists
import net.corda.core.internal.list
import net.corda.core.internal.readObject
import net.corda.core.messaging.ParametersUpdateInfo
import net.corda.core.node.NodeInfo
import net.corda.core.serialization.serialize
import net.corda.core.utilities.getOrThrow
import net.corda.core.utilities.seconds
import net.corda.node.services.config.configureDevKeyAndTrustStores
import net.corda.nodeapi.internal.config.NodeSSLConfiguration
import net.corda.nodeapi.internal.network.NETWORK_PARAMS_FILE_NAME
import net.corda.nodeapi.internal.network.NETWORK_PARAMS_UPDATE_FILE_NAME
import net.corda.nodeapi.internal.network.SignedNetworkParameters
@ -31,6 +39,7 @@ import net.corda.testing.internal.IntegrationTest
import net.corda.testing.internal.IntegrationTestSchemas
import net.corda.testing.internal.toDatabaseSchemaName
import net.corda.testing.node.internal.CompatibilityZoneParams
import net.corda.testing.node.internal.DriverDSLImpl
import net.corda.testing.node.internal.internalDriver
import net.corda.testing.node.internal.network.NetworkMapServer
import org.assertj.core.api.Assertions.assertThat
@ -82,7 +91,7 @@ class NetworkMapTest : IntegrationTest() {
initialiseSerialization = false,
notarySpecs = emptyList()
) {
val alice = startNode(providedName = ALICE_NAME).getOrThrow() as NodeHandleInternal
val alice = startNode(providedName = ALICE_NAME, devMode = false).getOrThrow() as NodeHandleInternal
val nextParams = networkMapServer.networkParameters.copy(epoch = 3, modifiedTime = Instant.ofEpochMilli(random63BitValue()))
val nextHash = nextParams.serialize().hash
val snapshot = alice.rpc.networkParametersFeed().snapshot
@ -129,7 +138,7 @@ class NetworkMapTest : IntegrationTest() {
initialiseSerialization = false,
notarySpecs = emptyList()
) {
val alice = startNode(providedName = ALICE_NAME).getOrThrow()
val alice = startNode(providedName = ALICE_NAME, devMode = false).getOrThrow()
val networkParameters = (alice.baseDirectory / NETWORK_PARAMS_FILE_NAME)
.readObject<SignedNetworkParameters>()
.verified()
@ -144,17 +153,16 @@ class NetworkMapTest : IntegrationTest() {
internalDriver(
portAllocation = portAllocation,
compatibilityZone = compatibilityZone,
initialiseSerialization = false
initialiseSerialization = false,
notarySpecs = emptyList()
) {
val (aliceNode, bobNode, notaryNode) = listOf(
startNode(providedName = ALICE_NAME),
startNode(providedName = BOB_NAME),
defaultNotaryNode
val (aliceNode, bobNode) = listOf(
startNode(providedName = ALICE_NAME, devMode = false),
startNode(providedName = BOB_NAME, devMode = false)
).transpose().getOrThrow()
notaryNode.onlySees(notaryNode.nodeInfo, aliceNode.nodeInfo, bobNode.nodeInfo)
aliceNode.onlySees(notaryNode.nodeInfo, aliceNode.nodeInfo, bobNode.nodeInfo)
bobNode.onlySees(notaryNode.nodeInfo, aliceNode.nodeInfo, bobNode.nodeInfo)
aliceNode.onlySees(aliceNode.nodeInfo, bobNode.nodeInfo)
bobNode.onlySees(aliceNode.nodeInfo, bobNode.nodeInfo)
}
}
@ -163,24 +171,20 @@ class NetworkMapTest : IntegrationTest() {
internalDriver(
portAllocation = portAllocation,
compatibilityZone = compatibilityZone,
initialiseSerialization = false
initialiseSerialization = false,
notarySpecs = emptyList()
) {
val (aliceNode, notaryNode) = listOf(
startNode(providedName = ALICE_NAME),
defaultNotaryNode
).transpose().getOrThrow()
val aliceNode = startNode(providedName = ALICE_NAME, devMode = false).getOrThrow()
notaryNode.onlySees(notaryNode.nodeInfo, aliceNode.nodeInfo)
aliceNode.onlySees(notaryNode.nodeInfo, aliceNode.nodeInfo)
aliceNode.onlySees(aliceNode.nodeInfo)
val bobNode = startNode(providedName = BOB_NAME).getOrThrow()
val bobNode = startNode(providedName = BOB_NAME, devMode = false).getOrThrow()
// Wait for network map client to poll for the next update.
Thread.sleep(cacheTimeout.toMillis() * 2)
bobNode.onlySees(notaryNode.nodeInfo, aliceNode.nodeInfo, bobNode.nodeInfo)
notaryNode.onlySees(notaryNode.nodeInfo, aliceNode.nodeInfo, bobNode.nodeInfo)
aliceNode.onlySees(notaryNode.nodeInfo, aliceNode.nodeInfo, bobNode.nodeInfo)
bobNode.onlySees(aliceNode.nodeInfo, bobNode.nodeInfo)
aliceNode.onlySees(aliceNode.nodeInfo, bobNode.nodeInfo)
}
}
@ -189,25 +193,23 @@ class NetworkMapTest : IntegrationTest() {
internalDriver(
portAllocation = portAllocation,
compatibilityZone = compatibilityZone,
initialiseSerialization = false
initialiseSerialization = false,
notarySpecs = emptyList()
) {
val (aliceNode, bobNode, notaryNode) = listOf(
startNode(providedName = ALICE_NAME),
startNode(providedName = BOB_NAME),
defaultNotaryNode
val (aliceNode, bobNode) = listOf(
startNode(providedName = ALICE_NAME, devMode = false),
startNode(providedName = BOB_NAME, devMode = false)
).transpose().getOrThrow()
notaryNode.onlySees(notaryNode.nodeInfo, aliceNode.nodeInfo, bobNode.nodeInfo)
aliceNode.onlySees(notaryNode.nodeInfo, aliceNode.nodeInfo, bobNode.nodeInfo)
bobNode.onlySees(notaryNode.nodeInfo, aliceNode.nodeInfo, bobNode.nodeInfo)
aliceNode.onlySees(aliceNode.nodeInfo, bobNode.nodeInfo)
bobNode.onlySees(aliceNode.nodeInfo, bobNode.nodeInfo)
networkMapServer.removeNodeInfo(aliceNode.nodeInfo)
// Wait for network map client to poll for the next update.
Thread.sleep(cacheTimeout.toMillis() * 2)
notaryNode.onlySees(notaryNode.nodeInfo, bobNode.nodeInfo)
bobNode.onlySees(notaryNode.nodeInfo, bobNode.nodeInfo)
bobNode.onlySees(bobNode.nodeInfo)
}
}
@ -237,3 +239,19 @@ class NetworkMapTest : IntegrationTest() {
assertThat(rpc.networkMapSnapshot()).containsOnly(*nodes)
}
}
private fun DriverDSLImpl.startNode(providedName: CordaX500Name, devMode: Boolean): CordaFuture<NodeHandle> {
var customOverrides = emptyMap<String, String>()
if (!devMode) {
val nodeDir = baseDirectory(providedName)
val nodeSslConfig = object : NodeSSLConfiguration {
override val baseDirectory = nodeDir
override val keyStorePassword = "cordacadevpass"
override val trustStorePassword = "trustpass"
override val crlCheckSoftFail = true
}
nodeSslConfig.configureDevKeyAndTrustStores(providedName)
customOverrides = mapOf("devMode" to "false")
}
return startNode(providedName = providedName, customOverrides = customOverrides)
}

View File

@ -11,6 +11,7 @@
package net.corda.node.internal
import com.jcabi.manifests.Manifests
import io.netty.channel.unix.Errors
import net.corda.core.crypto.Crypto
import net.corda.core.cordapp.Cordapp
import net.corda.core.internal.Emoji
@ -134,6 +135,10 @@ open class NodeStartup(val args: Array<String>) {
cmdlineOptions.baseDirectory.createDirectories()
startNode(conf, versionInfo, startTime, cmdlineOptions)
} catch (e: Exception) {
if (e is Errors.NativeIoException && e.message?.contains("Address already in use") == true) {
logger.error("One of the ports required by the Corda node is already in use.")
return false
}
if (e.message?.startsWith("Unknown named curve:") == true) {
logger.error("Exception during node startup - ${e.message}. " +
"This is a known OpenJDK issue on some Linux distributions, please use OpenJDK from zulu.org or Oracle JDK.")
@ -169,7 +174,7 @@ open class NodeStartup(val args: Array<String>) {
if (conf.shouldStartLocalShell()) {
startedNode.internals.startupComplete.then {
try {
InteractiveShell.runLocalShell( {startedNode.dispose()} )
InteractiveShell.runLocalShell({ startedNode.dispose() })
} catch (e: Throwable) {
logger.error("Shell failed to start", e)
}
@ -266,7 +271,6 @@ open class NodeStartup(val args: Array<String>) {
// twice with the same directory: that's a user error and we should bail out.
val pidFile = (baseDirectory / "process-id").toFile()
pidFile.createNewFile()
pidFile.deleteOnExit()
val pidFileRw = RandomAccessFile(pidFile, "rw")
val pidFileLock = pidFileRw.channel.tryLock()
if (pidFileLock == null) {
@ -274,6 +278,7 @@ open class NodeStartup(val args: Array<String>) {
println("Shut that other node down and try again. It may have process ID ${pidFile.readText()}")
System.exit(1)
}
pidFile.deleteOnExit()
// Avoid the lock being garbage collected. We don't really need to release it as the OS will do so for us
// when our process shuts down, but we try in stop() anyway just to be nice.
addShutdownHook {
@ -369,11 +374,7 @@ open class NodeStartup(val args: Array<String>) {
""" / ____/ _________/ /___ _""").newline().a(
""" / / __ / ___/ __ / __ `/ """).fgBrightBlue().a(msg1).newline().fgBrightRed().a(
"""/ /___ /_/ / / / /_/ / /_/ / """).fgBrightBlue().a(msg2).newline().fgBrightRed().a(
"""\____/ /_/ \__,_/\__,_/""").reset().newline().newline().fgBrightDefault().bold().
a("--- ${versionInfo.vendor} ${versionInfo.releaseVersion} (${versionInfo.revision.take(7)}) -----------------------------------------------").
newline().
newline().
reset())
"""\____/ /_/ \__,_/\__,_/""").reset().newline().newline().fgBrightDefault().bold().a("--- ${versionInfo.vendor} ${versionInfo.releaseVersion} (${versionInfo.revision.take(7)}) -----------------------------------------------").newline().newline().reset())
}
}
}

View File

@ -242,6 +242,7 @@ data class NodeConfigurationImpl(
override fun validate(): List<String> {
val errors = mutableListOf<String>()
errors += validateDevModeOptions()
errors += validateRpcOptions(rpcOptions)
return errors
}
@ -256,6 +257,16 @@ data class NodeConfigurationImpl(
return errors
}
private fun validateDevModeOptions(): List<String> {
val errors = mutableListOf<String>()
if (devMode) {
compatibilityZoneURL?.let {
errors += "'compatibilityZoneURL': present. Property cannot be set when 'devMode' is true."
}
}
return errors
}
override val transactionCacheSizeBytes: Long
get() = transactionCacheSizeMegaBytes?.MB ?: super.transactionCacheSizeBytes
override val attachmentContentCacheSizeBytes: Long

View File

@ -85,8 +85,7 @@ class NodeAttachmentService(
}
@Entity
@Table(name = "${NODE_DATABASE_PREFIX}attachments",
indexes = arrayOf(Index(name = "att_id_idx", columnList = "att_id")))
@Table(name = "${NODE_DATABASE_PREFIX}attachments", indexes = [Index(name = "att_id_idx", columnList = "att_id")])
class DBAttachment(
@Id
@Column(name = "att_id")

View File

@ -41,9 +41,7 @@ object VaultSchemaV1 : MappedSchema(schemaFamily = VaultSchema.javaClass, versio
override val migrationResource = "vault-schema.changelog-master"
@Entity
@Table(name = "vault_states",
indexes = arrayOf(Index(name = "state_status_idx", columnList = "state_status"),
Index(name = "lock_id_idx", columnList = "lock_id, state_status")))
@Table(name = "vault_states", indexes = [Index(name = "state_status_idx", columnList = "state_status"), Index(name = "lock_id_idx", columnList = "lock_id, state_status")])
class VaultStates(
/** NOTE: serialized transaction state (including contract state) is now resolved from transaction store */
// TODO: create a distinct table to hold serialized state data (once DBTransactionStore is encrypted)
@ -79,9 +77,7 @@ object VaultSchemaV1 : MappedSchema(schemaFamily = VaultSchema.javaClass, versio
) : PersistentState()
@Entity
@Table(name = "vault_linear_states",
indexes = arrayOf(Index(name = "external_id_index", columnList = "external_id"),
Index(name = "uuid_index", columnList = "uuid")))
@Table(name = "vault_linear_states", indexes = [Index(name = "external_id_index", columnList = "external_id"), Index(name = "uuid_index", columnList = "uuid")])
class VaultLinearStates(
/** [ContractState] attributes */
@ -163,9 +159,7 @@ object VaultSchemaV1 : MappedSchema(schemaFamily = VaultSchema.javaClass, versio
}
@Entity
@Table(name = "vault_transaction_notes",
indexes = arrayOf(Index(name = "seq_no_index", columnList = "seq_no"),
Index(name = "transaction_id_index", columnList = "transaction_id")))
@Table(name = "vault_transaction_notes", indexes = [Index(name = "seq_no_index", columnList = "seq_no"), Index(name = "transaction_id_index", columnList = "transaction_id")])
class VaultTxnNote(
@Id
@GeneratedValue

View File

@ -18,8 +18,10 @@ import net.corda.core.utilities.seconds
import net.corda.testing.core.ALICE_NAME
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
import net.corda.tools.shell.SSHDConfiguration
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatThrownBy
import org.junit.Test
import java.net.URI
import java.nio.file.Paths
import java.util.*
import kotlin.test.assertEquals
@ -84,6 +86,15 @@ class NodeConfigurationImplTest {
assertFalse { testConfiguration.copy(noLocalShell = true, sshd = null).shouldInitCrashShell() }
}
@Test
fun `validation has error when compatibilityZoneURL is present and devMode is true`() {
val configuration = testConfiguration.copy(devMode = true, compatibilityZoneURL = URI.create("https://r3.com").toURL())
val errors = configuration.validate()
assertThat(errors).hasOnlyOneElementSatisfying { error -> error.contains("compatibilityZoneURL") && error.contains("devMode") }
}
private fun configDebugOptions(devMode: Boolean, devModeOptions: DevModeOptions?): NodeConfiguration {
return testConfiguration.copy(devMode = devMode, devModeOptions = devModeOptions)
}

View File

@ -10,59 +10,17 @@
package net.corda.node.services.vault
import net.corda.core.contracts.Amount
import net.corda.core.contracts.ContractState
import net.corda.core.contracts.FungibleAsset
import net.corda.core.contracts.LinearState
import net.corda.core.contracts.PartyAndReference
import net.corda.core.contracts.StateAndRef
import net.corda.core.contracts.StateRef
import net.corda.core.crypto.Crypto
import net.corda.core.crypto.SecureHash
import net.corda.core.crypto.SignatureMetadata
import net.corda.core.crypto.generateKeyPair
import net.corda.core.crypto.toStringShort
import net.corda.core.contracts.*
import net.corda.core.crypto.*
import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party
import net.corda.core.internal.packageName
import net.corda.core.node.services.IdentityService
import net.corda.core.node.services.Vault
import net.corda.core.node.services.VaultQueryException
import net.corda.core.node.services.VaultService
import net.corda.core.node.services.queryBy
import net.corda.core.node.services.trackBy
import net.corda.core.node.services.vault.BinaryComparisonOperator
import net.corda.core.node.services.vault.ColumnPredicate
import net.corda.core.node.services.vault.DEFAULT_PAGE_NUM
import net.corda.core.node.services.vault.DEFAULT_PAGE_SIZE
import net.corda.core.node.services.vault.MAX_PAGE_SIZE
import net.corda.core.node.services.vault.PageSpecification
import net.corda.core.node.services.vault.QueryCriteria
import net.corda.core.node.services.vault.QueryCriteria.FungibleAssetQueryCriteria
import net.corda.core.node.services.vault.QueryCriteria.LinearStateQueryCriteria
import net.corda.core.node.services.vault.QueryCriteria.SoftLockingCondition
import net.corda.core.node.services.vault.QueryCriteria.SoftLockingType
import net.corda.core.node.services.vault.QueryCriteria.TimeCondition
import net.corda.core.node.services.vault.QueryCriteria.TimeInstantType
import net.corda.core.node.services.vault.QueryCriteria.VaultCustomQueryCriteria
import net.corda.core.node.services.vault.QueryCriteria.VaultQueryCriteria
import net.corda.core.node.services.vault.Sort
import net.corda.core.node.services.vault.SortAttribute
import net.corda.core.node.services.vault.builder
import net.corda.core.node.services.*
import net.corda.core.node.services.vault.*
import net.corda.core.node.services.vault.QueryCriteria.*
import net.corda.core.transactions.TransactionBuilder
import net.corda.core.utilities.NonEmptySet
import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.days
import net.corda.core.utilities.seconds
import net.corda.core.utilities.toHexString
import net.corda.finance.AMOUNT
import net.corda.finance.CHF
import net.corda.finance.DOLLARS
import net.corda.finance.GBP
import net.corda.finance.POUNDS
import net.corda.finance.SWISS_FRANCS
import net.corda.finance.USD
import net.corda.finance.`issued by`
import net.corda.core.utilities.*
import net.corda.finance.*
import net.corda.finance.contracts.CommercialPaper
import net.corda.finance.contracts.Commodity
import net.corda.finance.contracts.DealState
@ -77,18 +35,7 @@ import net.corda.node.internal.configureDatabase
import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.nodeapi.internal.persistence.DatabaseConfig
import net.corda.nodeapi.internal.persistence.DatabaseTransaction
import net.corda.testing.core.ALICE_NAME
import net.corda.testing.core.BOB_NAME
import net.corda.testing.core.BOC_NAME
import net.corda.testing.core.CHARLIE_NAME
import net.corda.testing.core.DUMMY_NOTARY_NAME
import net.corda.testing.core.SerializationEnvironmentRule
import net.corda.testing.core.TestIdentity
import net.corda.testing.core.dummyCommand
import net.corda.testing.core.expect
import net.corda.testing.core.expectEvents
import net.corda.testing.core.sequence
import net.corda.testing.core.singleIdentityAndCert
import net.corda.testing.core.*
import net.corda.testing.internal.TEST_TX_TIME
import net.corda.testing.internal.rigorousMock
import net.corda.testing.internal.vault.DUMMY_LINEAR_CONTRACT_PROGRAM_ID
@ -2037,7 +1984,7 @@ abstract class VaultQueryTestsBase : VaultQueryParties {
val updates = database.transaction {
val updates =
// DOCSTART VaultQueryExample15
vaultService.trackBy<Cash.State>().updates // UNCONSUMED default
vaultService.trackBy<Cash.State>().updates // UNCONSUMED default
// DOCEND VaultQueryExample15
vaultFiller.fillWithSomeTestCash(100.DOLLARS, notaryServices, 5, DUMMY_CASH_ISSUER)
@ -2221,9 +2168,7 @@ abstract class VaultQueryTestsBase : VaultQueryParties {
@Test
fun trackDealStates() {
val updates = database.transaction {
// DOCSTART VaultQueryExample17
val (snapshot, updates) = vaultService.trackBy<DealState>()
// DOCEND VaultQueryExample17
@ -2282,7 +2227,7 @@ abstract class VaultQueryTestsBase : VaultQueryParties {
}
@Test
fun `unconsumedCashStatesForSpending_single_issuer_reference_not_matching`() {
fun `unconsumedCashStatesForSpending single issuer reference not matching`() {
database.transaction {
vaultFiller.fillWithSomeTestCash(1000.DOLLARS, notaryServices, 1, DUMMY_CASH_ISSUER)

View File

@ -33,9 +33,7 @@ object DummyLinearStateSchemaV1 : MappedSchema(schemaFamily = DummyLinearStateSc
override val migrationResource = "dummy-linear-v1.changelog-init"
@Entity
@Table(name = "dummy_linear_states",
indexes = arrayOf(Index(name = "external_id_idx", columnList = "external_id"),
Index(name = "uuid_idx", columnList = "uuid")))
@Table(name = "dummy_linear_states", indexes = [Index(name = "external_id_idx", columnList = "external_id"), Index(name = "uuid_idx", columnList = "uuid")])
class PersistentDummyLinearState(
/** [ContractState] attributes */