Regen docsite with new JavaDoc format API reference

This commit is contained in:
Mike Hearn 2017-01-19 18:11:18 +01:00
parent 4e65200a04
commit 2ec31781c1
5409 changed files with 2546 additions and 152709 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,4 +1,4 @@
# Sphinx build info version 1
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
config: e2be8594fe6e220577145a401ac3e5b5
config: caa85c0cfb7660f75ff8985c07fa3b0c
tags: 645f666f9bcd5a90fca523b33c5a78b7

View File

@ -81,7 +81,7 @@
<br>
<a href="api/index.html">API reference</a>
API reference: <a href="api/kotlin/corda/index.html">Kotlin</a>/ <a href="api/javadoc/index.html">JavaDoc</a>
<br>
<a href="https://discourse.corda.net">Discourse Forums</a>
<br>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 274 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

View File

@ -37,7 +37,7 @@ When writing a contract you need to override the contract's ``verify`` function
there is a check if all of transaction's commands were matched. If not, then an exception is raised. This is done to
enforce that spurious commands cannot be included in a transaction, ensuring that the transaction is as clear as
possible. As an example imagine a transaction with two commands: ``Move`` and ``Issue`` included, with verification written
using ``FirstComposition`` on clauses that require single command set. Thus only one of transaction's commands will match
using ``FirstOf`` on clauses that require single command set. Thus only one of transaction's commands will match
leaving the second unprocessed. It should raise an error - we want to ensure that commands set is minimal to simplify
analysis of intent of a transaction.
@ -47,14 +47,14 @@ An example ``verify`` from ``Obligation`` contract:
.. sourcecode:: kotlin
override fun verify(tx: TransactionForContract) = verifyClause<Commands>(tx, FirstComposition<ContractState, Commands, Unit>(
override fun verify(tx: TransactionForContract) = verifyClause<Commands>(tx, FirstOf<ContractState, Commands, Unit>(
Clauses.Net<Commands, P>(),
Clauses.Group<P>()
), tx.commands.select<Obligation.Commands>())
It takes transaction to be verified, and passes it along with a top-level clause and commands to the ``verifyClause``
function. As you can see above we have used ``FirstComposition`` which is a special type of clause, which extends the
``CompositeClause`` abstract class (in that particular case, it ensures that either ``Net`` or ``Group`` will run - for explanation see `FirstComposition`_).
function. As you can see above we have used ``FirstOf`` which is a special type of clause, which extends the
``CompositeClause`` abstract class (in that particular case, it ensures that either ``Net`` or ``Group`` will run - for explanation see `FirstOf`_).
It's a type of clause that adds support for encapsulating multiple clauses and defines common behaviour for that composition.
There is also a ``GroupClauseVerifier`` special clause, which specifies how to group transaction input/output states
together and passes them to adequate clause for further processing.
@ -66,37 +66,37 @@ One of the most important concepts of clauses - composition clauses which extend
providing a range of ways of assembling clauses together. They define a logic of verification execution specifying which clauses
will be run.
AllComposition
~~~~~~~~~~~~~~
AllOf
~~~~~
**Description**
Composes a number of clauses, such that all of the clauses must run for verification to pass.
.. image:: resources/allCompositionChart.png
.. image:: resources/allOfChart.png
Short description:
- ``AllComposition`` holds clauses *Cl1,..,Cl5*.
- Check if all clauses that compose ``AllComposition`` have associated commands in a command set - if not, verification fails.
- ``AllOf`` holds clauses *Cl1,..,Cl5*.
- Check if all clauses that compose ``AllOf`` have associated commands in a command set - if not, verification fails.
- After successful check runs verification logic specific for every clause *Cl1,..,Cl5* from that composition.
**Usage**
See code in `GroupClauseVerifier`_.
AnyComposition
~~~~~~~~~~~~~~
AnyOf
~~~~~
**Description**
Composes a number of clauses, such that 0 or more of the clauses can be run.
Composes a number of clauses, such that 1 or more of the clauses can be run.
.. image:: resources/anyCompositionChart.png
.. image:: resources/anyOfChart.png
Short description:
- Checks if zero or more clauses that compose AnyComposition have associated commands in a command set.
- Checks if one or more clauses that compose AnyOf have associated commands in a command set.
- After success runs verification logic specific for every *matched* (in this case *Cl2, Cl4, Cl5*) clause from composition.
**Usage**
@ -108,7 +108,7 @@ Example from ``CommercialPaper.kt``:
.. sourcecode:: kotlin
class Group : GroupClauseVerifier<State, Commands, Issued<Terms>>(
AnyComposition(
AnyOf(
Redeem(),
Move(),
Issue())) {
@ -116,14 +116,14 @@ Example from ``CommercialPaper.kt``:
= tx.groupStates<State, Issued<Terms>> { it.token }
}
FirstComposition
~~~~~~~~~~~~~~~~
FirstOf
~~~~~~~
**Description**
Composes a number of clauses, such that the first match is run, and it errors if none is run.
.. image:: resources/firstCompositionChart.png
.. image:: resources/firstOfChart.png
Short description:
@ -168,13 +168,13 @@ grouped input and output states with a grouping key used for each group. Example
.. sourcecode:: kotlin
class Group<P> : GroupClauseVerifier<State<P>, Commands, Issued<Terms<P>>>(
AllComposition(
AllOf(
NoZeroSizedOutputs<State<P>, Commands, Terms<P>>(),
FirstComposition(
FirstOf(
SetLifecycle<P>(),
AllComposition(
AllOf(
VerifyLifecycle<State<P>, Commands, Issued<Terms<P>>, P>(),
FirstComposition(
FirstOf(
Settle<P>(),
Issue(),
ConserveAmount()

View File

@ -92,5 +92,5 @@ This will require some familiarity with Kryo. An example is shown in :doc:`tuto
.. warning:: We will be replacing the use of Kryo in RPC with a stable message format and this will mean that this plugin
customisation point will either go away completely or change.
.. _CordaRPCClient: api/net.corda.client/-corda-r-p-c-client/index.html
.. _CordaRPCOps: api/net.corda.node.services.messaging/-corda-r-p-c-ops/index.html
.. _CordaRPCClient: api/kotlin/corda/net.corda.client/-corda-r-p-c-client/index.html
.. _CordaRPCOps: api/kotlin/corda/net.corda.node.services.messaging/-corda-r-p-c-ops/index.html

View File

@ -46,8 +46,8 @@ Multiple notaries
More than one notary can exist in the network. This gives the following benefits:
* **Custom behaviour**. We can have both validating and privacy preserving Notaries -- parties can make a choice based on their specific requirements
* **Load balancing**. Spreading the transaction load over multiple Notaries will allow higher transaction throughput in the platform overall
* **Custom behaviour**. We can have both validating and privacy preserving notaries -- parties can make a choice based on their specific requirements
* **Load balancing**. Spreading the transaction load over multiple notaries will allow higher transaction throughput in the platform overall
* **Low latency**. Latency could be minimised by choosing a notary physically closer the transacting parties
A transaction should only be signed by a notary if all of its input states point to it.

View File

@ -4,13 +4,16 @@ Node configuration
File location
-------------
The Corda all-in-one ``corda.jar`` file is generated by the ``gradle buildCordaJAR`` task and defaults to reading configuration from a ``node.conf`` file in the present working directory.
This behaviour can be overidden using the ``--config-file`` command line option to target configuration files with different names, or different file location (relative paths are relative to the current working directory).
Also, the ``--base-directory`` command line option alters the Corda node workspace location and if specified a ``node.conf`` configuration file is then expected in the root of the workspace.
The Corda all-in-one ``corda.jar`` file is generated by the ``gradle buildCordaJAR`` task and defaults to reading configuration
from a ``node.conf`` file in the present working directory. This behaviour can be overidden using the ``--config-file``
command line option to target configuration files with different names, or different file location (relative paths are
relative to the current working directory). Also, the ``--base-directory`` command line option alters the Corda node
workspace location and if specified a ``node.conf`` configuration file is then expected in the root of the workspace.
The configuration file templates used for the ``gradle deployNodes`` task are to be found in the ``/config/dev`` folder. Also note that there is a basic set of defaults loaded from
the built in resource file ``/node/src/main/resources/reference.conf`` of the ``:node`` gradle module. All properties in this can be overidden in the file configuration
and for rarely changed properties this defaulting allows the property to be excluded from the configuration file.
The configuration file templates used for the ``gradle deployNodes`` task are to be found in the ``/config/dev`` folder.
Also note that there is a basic set of defaults loaded from the built in resource file ``/node/src/main/resources/reference.conf``
of the ``:node`` gradle module. All properties in this can be overidden in the file configuration and for rarely changed
properties this defaulting allows the property to be excluded from the configuration file.
Format
------
@ -31,7 +34,6 @@ NetworkMapService plus Simple Notary configuration file.
.. parsed-literal::
basedir : "./nameserver"
myLegalName : "Notary Service"
nearestCity : "London"
keyStorePassword : "cordacadevpass"
@ -47,9 +49,8 @@ NetworkMapService plus Simple Notary configuration file.
Fields
------
:basedir: This specifies the node workspace folder either as an absolute path, or relative to the current working directory.
It can be overridden by the ``--base-directory`` command line option, in which case the value in the file is ignored
and a ``node.conf`` file is expected in that workspace directory as the configuration source.
The available config fields are listed below. ``basedir`` is available as a substitution value, containing the absolute
path to the node's base directory.
:myLegalName: The legal identity of the node acts as a human readable alias to the node's public key and several demos use
this to lookup the NodeInfo.

View File

@ -1,115 +0,0 @@
The Corda Configuration File
============================
Configuration File Location
---------------------------
The Corda all-in-one ``corda.jar`` file is generated by the ``gradle buildCordaJAR`` task and defaults to reading configuration from a ``node.conf`` file in the present working directory.
This behaviour can be overidden using the ``--config-file`` command line option to target configuration files with different names, or different file location (relative paths are relative to the current working directory).
Also, the ``--base-directory`` command line option alters the Corda node workspace location and if specified a ``node.conf`` configuration file is then expected in the root of the workspace.
The configuration file templates used for the ``gradle deployNodes`` task are to be found in the ``/config/dev`` folder. Also note that there is a basic set of defaults loaded from
the built in resource file ``/node/src/main/resources/reference.conf`` of the ``:node`` gradle module. All properties in this can be overidden in the file configuration
and for rarely changed properties this defaulting allows the property to be excluded from the configuration file.
Configuration File Format
-------------------------
Corda uses the Typesafe configuration library to parse the configuration see the `typesafe config on Github <https://github.com/typesafehub/config/>`_ the format of the configuration files can be simple JSON, but for the more powerful substitution features
uses HOCON format see `HOCON documents <https://github.com/typesafehub/config/blob/master/HOCON.md>`_
Configuration File Examples
---------------------------
General node configuration file for hosting the IRSDemo services.
.. code-block:: text
basedir : "./nodea"
myLegalName : "Bank A"
nearestCity : "London"
keyStorePassword : "cordacadevpass"
trustStorePassword : "trustpass"
dataSourceProperties : {
dataSourceClassName : org.h2.jdbcx.JdbcDataSource
"dataSource.url" : "jdbc:h2:"${basedir}"/persistence"
"dataSource.user" : sa
"dataSource.password" : ""
}
artemisAddress : "localhost:31337"
webAddress : "localhost:31339"
extraAdvertisedServiceIds: "corda.interest_rates"
networkMapAddress : "localhost:12345"
useHTTPS : false
rpcUsers : [
{ user=user1, password=letmein, permissions=[ cash ] }
]
NetworkMapService plus Simple Notary configuration file.
.. code-block:: text
basedir : "./nameserver"
myLegalName : "Notary Service"
nearestCity : "London"
keyStorePassword : "cordacadevpass"
trustStorePassword : "trustpass"
artemisAddress : "localhost:12345"
webAddress : "localhost:12346"
extraAdvertisedServiceIds: ""
useHTTPS : false
Configuration File Fields
-------------------------
:basedir: This specifies the node workspace folder either as an absolute path, or relative to the current working directory. It can be overidden by the ``--base-directory`` command line option, in which case the the value in the file is ignored and a ``node.conf`` file is expected in that workspace directory as the configuration source.
:myLegalName: The legal identity of the node acts as a human readable alias to the node's public key and several demos use this to lookup the NodeInfo.
:nearestCity: The location of the node as used to locate coordinates on the world map when running the network simulator demo. See :doc:`network-simulator`.
:keyStorePassword:
The password to unlock the KeyStore file (``<workspace>/certificates/sslkeystore.jks``) containing the 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.
:trustStorePassword:
The password to unlock the Trust store file (``<workspace>/certificates/truststore.jks``) containing the R3 Corda root certificate. This is the non-secret value for the development certificates automatically generated during the first node run.
.. note:: Longer term these keys will be managed in secure hardware devices.
:dataSourceProperties:
This section is used to configure the jdbc connection and database driver used for the nodes persistence. Currently the defaults in ``/node/src/main/resources/reference.conf`` are as shown in the first example. This is currently the only configuration that has been tested, although in the future full support for other storage layers will be validated.
:artemisAddress:
The host and port on which the node is available for protocol operations over ArtemisMQ.
.. note:: In practice the ArtemisMQ messaging services bind to all local addresses on the specified port. However, note that the host is the included as the advertised entry in the NetworkMapService. As a result the value listed here must be externally accessible when running nodes across a cluster of machines.
:messagingServerAddress:
The address of the ArtemisMQ broker instance. If not provided the node will run one locally.
:webAddress:
The host and port on which the node is available for web operations.
.. note:: If HTTPS is enabled then the browser security checks will require that the accessing url host name is one of either the machine name, fully qualified machine name, or server IP address to line up with the Subject Alternative Names contained within the development certificates. This is addition to requiring the ``/config/dev/corda_dev_ca.cer`` root certificate be installed as a Trusted CA.
:extraAdvertisedServiceIds: A list of ServiceType id strings to be advertised to the NetworkMapService and thus be available when other nodes query the NetworkMapCache for supporting nodes. This can also include plugin services loaded from .jar files in the plugins folder.
:notaryNodeAddress: The host and port to which to bind the embedded Raft server. Required only when running a distributed notary service. A group of Corda nodes can run a distributed notary service by each running an embedded Raft server and joining them to the same cluster to replicate the committed state log. Note that the Raft cluster uses a separate transport layer for communication that does not integrate with ArtemisMQ messaging services.
:notaryClusterAddresses: List of Raft cluster member addresses used to joining the cluster. At least one of the specified members must be active and be able to communicate with the cluster leader for joining. If empty, a new cluster will be bootstrapped. Required only when running a distributed notary service.
:networkMapAddress: If `null`, or missing the node is declaring itself as the NetworkMapService host. Otherwise the configuration value is the remote HostAndPort string for the ArtemisMQ service on the hosting node.
:useHTTPS: If false the node's web server will be plain HTTP. If true the node will use the same certificate and private key from the ``<workspace>/certificates/sslkeystore.jks`` file as the ArtemisMQ port for HTTPS. If HTTPS is enabled then unencrypted HTTP traffic to the node's **webAddress** port is not supported.
:rpcUsers:
A list of users who are authorised to access the RPC system. Each user in the list is a config object with the
following fields:
:user: Username consisting only of word characters (a-z, A-Z, 0-9 and _)
:password: The password
:permissions: A list of permission strings which RPC methods can use to control access
If this field is absent or an empty list then RPC is effectively locked down.

View File

@ -36,9 +36,8 @@ This will output the node JAR to ``build/libs/corda.jar`` and several sample/sta
node setups to ``build/nodes``. For now you can use the ``build/nodes/nodea`` configuration as a template.
Each node server by default must have a ``node.conf`` file in the current working directory. After first
execution of the node server there will be many other configuration and persistence files created in a node
workspace directory. This is specified as the basedir property of the node.conf file, or else can be overidden
using ``--base-directory=<workspace>``.
execution of the node server there will be many other configuration and persistence files created in this
workspace directory. The directory can be overridden by the ``--base-directory=<workspace>`` command line argument.
.. note:: Outside of development environments do not store your node directories in the build folder.
@ -69,7 +68,7 @@ The configuration file and workspace paths can be overidden on the command line
``java -jar corda.jar --config-file=test.conf --base-directory=/opt/r3corda/nodes/test``.
Otherwise the workspace folder for the node is created based upon the ``basedir`` property in the ``node.conf`` file and if this is relative it is applied relative to the current working path.
Otherwise the workspace folder for the node is the current working path.
Debugging your node
-------------------
@ -92,9 +91,9 @@ The user name and password for the login are as per the node data source configu
The name and column layout of the internal node tables is in a state of flux and should not be relied upon to remain static
at the present time, and should certainly be treated as read-only.
.. _CordaPluginRegistry: api/net.corda.core.node/-corda-plugin-registry/index.html
.. _PluginServiceHub: api/net.corda.core.node/-plugin-service-hub/index.html
.. _ServiceHub: api/net.corda.core.node/-service-hub/index.html
.. _CordaPluginRegistry: api/kotlin/corda/net.corda.core.node/-corda-plugin-registry/index.html
.. _PluginServiceHub: api/kotlin/corda/net.corda.core.node/-plugin-service-hub/index.html
.. _ServiceHub: api/kotlin/corda/net.corda.core.node/-service-hub/index.html
Building against Corda
----------------------
@ -212,7 +211,6 @@ is a three node example;
networkMap "Controller" // The artemis address of the node named here will be used as the networkMapService.address on all other nodes.
node {
name "Controller"
dirName "controller"
nearestCity "London"
advertisedServices = [ "corda.notary.validating" ]
artemisPort 12345
@ -221,7 +219,6 @@ is a three node example;
}
node {
name "NodeA"
dirName "nodea"
nearestCity "London"
advertisedServices = []
artemisPort 31337
@ -230,7 +227,6 @@ is a three node example;
}
node {
name "NodeB"
dirName "nodeb"
nearestCity "New York"
advertisedServices = []
artemisPort 31338

View File

@ -80,4 +80,4 @@ valid) inside a ``databaseTransaction``. All node flows run within a database t
but any time we need to use the database directly from a unit test, you need to provide a database transaction as shown
here.
And that's it: you can explore the documentation for the `MockNetwork API <api/net.corda.testing.node/-mock-network/index.html>`_ here.
And that's it: you can explore the documentation for the `MockNetwork API <api/kotlin/corda/net.corda.testing.node/-mock-network/index.html>`_ here.

View File

@ -2,26 +2,39 @@ Welcome to the Corda documentation!
===================================
.. warning:: This build of the docs is from the "|version|" branch, not a milestone release. It may not reflect the
current state of the code. `Read the docs for M7 <https://docs.corda.net/releases/release-M7.0/>`_.
current state of the code. `Read the docs for milestone release M7 <https://docs.corda.net/releases/release-M7.0/>`_.
This is the developer guide for Corda, a proposed architecture for distributed ledgers. Here are the sources
of documentation you may find useful, from highest level to lowest:
`Corda <https://www.corda.net/>`_ is an open-source distributed ledger platform. The latest *milestone* (i.e. stable)
release is M7. The codebase is on `GitHub <https://github.com/corda>`_, and our community can be found on
`Slack <https://slack.corda.net/>`_ and in our `forum <https://discourse.corda.net/>`_.
1. The `Introductory white paper`_ describes the motivating vision and background of the project. It is the kind
of document your boss should read. It describes why the project exists and briefly compares it to alternative
systems on the market.
2. The `Technical white paper`_ describes the entire intended design from beginning to end. It is the kind of
document that you should read, or at least, read parts of. Note that because the technical white paper
describes the intended end state, it does not always align with the implementation.
3. This user guide. It describes *how* to use the system to write apps, as currently implemented. It assumes
you already have read the relevant sections of the technology white paper and now wish to learn how to use it.
4. The `API docs`_.
If you're new to Corda, you should start by learning about its motivating vision and architecture. A good introduction
is the `Introduction to Corda webinar <https://vimeo.com/192757743/c2ec39c1e1>`_ and the `Introductory white paper`_. As
they become more familiar with Corda, readers with a technical background will also want to dive into the `Technical white paper`_,
which describes the platform's envisioned end-state.
Corda is designed so that developers can easily extend its functionality by writing CorDapps
(**Cor**\ da **D**\ istributed **App**\ lication\ **s**\ ). An example CorDapp is available on
`Github <https://github.com/corda/cordapp-template>`_. To get it running, follow the instructions in the
`readme <https://github.com/corda/cordapp-template/blob/master/README.md>`_, or watch the
`Corda Developers Tutorial <https://vimeo.com/192797322/aab499b152>`_.
Additional CorDapp samples are available in the Corda repo's `samples <https://github.com/corda/corda/tree/master/samples>`_
directory. These are sophisticated CorDapps that implement more complex functionality. You can find directions for
running these samples `here <https://docs.corda.net/running-the-demos.html>`_.
From there, you'll be in a position to start extending the example CorDapp yourself (e.g. by writing new states, contracts,
and/or flows). For this, you'll want to refer to this docsite, and to the `tutorials <https://docs.corda.net/#tutorials>`_
in particular. If you get stuck, get in touch on `Slack <https://slack.corda.net/>`_ or the `forum <https://discourse.corda.net/>`_.
Once you're familiar with Corda and CorDapp development, we'd encourage you to get involved in the development of the
platform itself. Find out more about `contributing to Corda <https://github.com/corda/corda/wiki/Corda's-Open-Source-Approach>`_.
.. _`Introductory white paper`: _static/corda-introductory-whitepaper.pdf
.. _`Technical white paper`: _static/corda-technical-whitepaper.pdf
.. _`API docs`: api/index.html
Read on to learn:
Documentation Contents:
=======================
.. toctree::
:maxdepth: 2

View File

@ -1,73 +0,0 @@
Initial margin agreements
=========================
This app is a demonstration of how Corda can be used for the real world requirement of initial margin calculation and
agreement; featuring the integration of complex and industry proven third party libraries into Corda nodes.
SIMM introduction
-----------------
SIMM is an acronym for "Standard Initial Margin Model". It is effectively the calculation of a "margin" that is paid
by one party to another when they agree a trade on certain types of transaction. This margin is
paid such that, in the event of one of the counterparties suffering a credit event
(a financial term and a polite way to say defaulting, not paying the debts that are due, or potentially even bankruptcy),
then the party that is owed any sum already has some of the amount that it should have been paid. This payment to the
receiving party is a preventative measure in order to reduce the risk of a potentially catastrophic default domino
effect that caused the `Great Financial Crisis <https://en.wikipedia.org/wiki/Financial_crisis_of_2007%E2%80%932008>`_,
as it means that they can be assured that if they need to pay another party, they will have a proportion of the funds
that they have been relying on.
To enact this, in September 2016, the ISDA committee - with full backing from various governing bodies -
`issued a ruling on what is known as the ISDA SIMM ™ model <http://www2.isda.org/news/isda-simm-deployed-today-new-industry-standard-for-calculating-initial-margin-widely-adopted-by-market-participants>`_,
a way of fairly and consistently calculating this margin. Any parties wishing to trade a financial product that is
covered under this ruling would, independently, use this model and calculate their margin payment requirement,
agree it with their trading counterparty and then pay (or receive, depending on the results of this calculation)
this amount. In the case of disagreement that is not resolved in a timely fashion, this payment would increase
and so therefore it is in the parties interest to reach agreement in a short as time frame as possible.
To be more accurate, the SIMM calculation is not performed on just one trade - it is calculated on an aggregate of
intermediary values (which in this model are sensitivities to risk factors) from a portfolio of trades; therefore
the input to a SIMM is actually this data, not the individual trades itself.
Also note that implementations of the SIMM are actually protected and subject to license restrictions by ISDA
(this is due to the model itself being protected). We were fortunate enough to technically partner with
`OpenGamma <http://www.opengamma.com>`_ who allowed us to demonstrate the SIMM process using their proprietary model.
In the source code released, we have replaced their analytics engine with very simple stub functions that allow
the process to run and can easily be swapped out in place for their real libraries.
Process steps
-------------
Preliminaries
- Ensure that there are a number of live trades with another party financial products that are covered under the
ISDA SIMM agreement (if none, then use the demo to enter some simple trades as described below).
Initial Margin Agreement Process
- Agree that one will be performing the margining calculation against a portfolio of trades with another party, and agree the trades in that portfolio. In practice, one node will start the flow but it does not matter which node does.
- Individually (at the node level), identify the data (static, reference etc) one will need in order to be able to calculate the metrics on those trades
- Confirm with the other counterparty the dataset from the above set
- Calculate any intermediary steps and values needed for the margin calculation (ie sensitivities to risk factors)
- Agree on the results of these steps
- Calculate the initial margin
- Agree on the calculation of the above with the other party
- In practice, pay (or receive) this margin (omitted for the sake of complexity for this example)
Running the app
---------------
The demonstration can be run in two ways - via IntelliJ (which will allow you to add breakpoints, debug, etc), or via gradle and the command line.
Run with IntelliJ::
1. Open the `cordapp-samples` project with IntelliJ
2. Run the shared run configuration "SIMM Valuation Demo"
3. Browse to http://localhost:10005/web/simmvaluationdemo
Run via CLI::
1. Navigate to the `cordapp-samples` directory in your shell
2. Run the gradle target `deployNodes` (ie; ./gradlew deployNodes for Unix or gradlew.bat on Windows)
1. Unix: `cd simm-valuation-demo/build/nodes && ./runnodes`.
2. Windows: `cd simm-valuation-demo/build/nodes & runnodes.bat`
4. Browse to http://localhost:10005/web/simmvaluationdemo

View File

@ -1,73 +0,0 @@
Initial Margin Agreements
=========================
This app is a demonstration of how Corda can be used for the real world requirement of initial margin calculation and
agreement; featuring the integration of complex and industry proven third party libraries into Corda nodes.
SIMM Introduction
-----------------
SIMM is an acronym for "Standard Initial Margin Model". It is effectively the calculation of a "margin" that is paid
by one party to another when they agree a trade on certain types of transaction. This margin is
paid such that, in the event of one of the counterparties suffering a credit event
(a financial term and a polite way to say defaulting, not paying the debts that are due, or potentially even bankruptcy),
then the party that is owed any sum already has some of the amount that it should have been paid. This payment to the
receiving party is a preventative measure in order to reduce the risk of a potentially catastrophic default domino
effect that caused the `Great Financial Crisis <https://en.wikipedia.org/wiki/Financial_crisis_of_2007%E2%80%932008>`_,
as it means that they can be assured that if they need to pay another party, they will have a proportion of the funds
that they have been relying on.
To enact this, in September 2016, the ISDA committee - with full backing from various governing bodies -
`issued a ruling on what is known as the ISDA SIMM ™ model <http://www2.isda.org/news/isda-simm-deployed-today-new-industry-standard-for-calculating-initial-margin-widely-adopted-by-market-participants>`_,
a way of fairly and consistently calculating this margin. Any parties wishing to trade a financial product that is
covered under this ruling would, independently, use this model and calculate their margin payment requirement,
agree it with their trading counterparty and then pay (or receive, depending on the results of this calculation)
this amount. In the case of disagreement that is not resolved in a timely fashion, this payment would increase
and so therefore it is in the parties interest to reach agreement in a short as time frame as possible.
To be more accurate, the SIMM calculation is not performed on just one trade - it is calculated on an aggregate of
intermediary values (which in this model are sensitivities to risk factors) from a portfolio of trades; therefore
the input to a SIMM is actually this data, not the individual trades itself.
Also note that implementations of the SIMM are actually protected and subject to license restrictions by ISDA
(this is due to the model itself being protected). We were fortunate enough to technically partner with
`OpenGamma <http://www.opengamma.com>`_ who allowed us to demonstrate the SIMM process using their proprietary model.
In the source code released, we have replaced their analytics engine with very simple stub functions that allow
the process to run and can easily be swapped out in place for their real libraries.
Process steps
-------------
Preliminaries
- Ensure that there are a number of live trades with another party financial products that are covered under the
ISDA SIMM agreement (if none, then use the demo to enter some simple trades as described below).
Initial Margin Agreement Process
- Agree that one will be performing the margining calculation against a portfolio of trades with another party, and agree the trades in that portfolio. In practice, one node will start the protocol but it does not matter which node does.
- Individually (at the node level), identify the data (static, reference etc) one will need in order to be able to calculate the metrics on those trades
- Confirm with the other counterparty the dataset from the above set
- Calculate any intermediary steps and values needed for the margin calculation (ie sensitivities to risk factors)
- Agree on the results of these steps
- Calculate the initial margin
- Agree on the calculation of the above with the other party
- In practice, pay (or receive) this margin (omitted for the sake of complexity for this example)
Running the app
---------------
The demonstration can be run in two ways - via IntelliJ (which will allow you to add breakpoints, debug, etc), or via gradle and the command line.
Run with IntelliJ::
1. Open the `cordapp-samples` project with IntelliJ
2. Run the shared run configuration "SIMM Valuation Demo"
3. Browse to http://localhost:10005/web/simmvaluationdemo
Run via CLI::
1. Navigate to the `cordapp-samples` directory in your shell
2. Run the gradle target `deployNodes` (ie; ./gradlew deployNodes for Unix or gradlew.bat on Windows)
1. Unix: `cd simm-valuation-demo/build/nodes && ./runnodes`.
2. Windows: `cd simm-valuation-demo/build/nodes & runnodes.bat`
4. Browse to http://localhost:10005/web/simmvaluationdemo

View File

@ -56,9 +56,28 @@ Here are a few ways to build dashboards and extract monitoring data for a node:
* *Java Mission Control* is a desktop app that can connect to a target JVM that has the right command line flags set
(or always, if running locally). You can explore what data is available, create graphs of those metrics, and invoke
management operations like forcing a garbage collection.
* *VisualVM* is another desktop app that can do fine grained JVM monitoring and sampling. Very useful during development.
* Cloud metrics services like New Relic also understand JMX, typically, by providing their own agent that uploads the
data to their service on a regular schedule.
Memory usage and tuning
-----------------------
All garbage collected programs can run faster if you give them more memory, as they need to collect less
frequently. As a default JVM will happily consume all the memory on your system if you let it, Corda is
configured with a relatively small 200mb Java heap by default. When other overheads are added, this yields
a total memory usage of about 500mb for a node (the overheads come from things like compiled code, metadata,
off-heap buffers, thread stacks, etc).
If you want to make your node go faster and profiling suggests excessive GC overhead is the cause, or if your
node is running out of memory, you can give it more by running the node like this:
``java -Xmx1024m -jar corda.jar``
The example command above would give a 1 gigabyte Java heap.
.. note:: Unfortunately the JVM does not let you limit the total memory usage of Java program, just the heap size.
Uploading and downloading attachments
-------------------------------------

View File

@ -1,694 +0,0 @@
.. highlight:: kotlin
.. raw:: html
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/codesets.js"></script>
Protocol state machines
=======================
This article explains our experimental approach to modelling financial protocols in code. It explains how the
platform's state machine framework is used, and takes you through the code for a simple 2-party asset trading protocol
which is included in the source.
Introduction
------------
Shared distributed ledgers are interesting because they allow many different, mutually distrusting parties to
share a single source of truth about the ownership of assets. Digitally signed transactions are used to update that
shared ledger, and transactions may alter many states simultaneously and atomically.
Blockchain systems such as Bitcoin support the idea of building up a finished, signed transaction by passing around
partially signed invalid transactions outside of the main network, and by doing this you can implement
*delivery versus payment* such that there is no chance of settlement failure, because the movement of cash and the
traded asset are performed atomically by the same transaction. To perform such a trade involves a multi-step protocol
in which messages are passed back and forth privately between parties, checked, signed and so on.
Despite how useful these protocols are, platforms such as Bitcoin and Ethereum do not assist the developer with the rather
tricky task of actually building them. That is unfortunate. There are many awkward problems in their implementation
that a good platform would take care of for you, problems like:
* Avoiding "callback hell" in which code that should ideally be sequential is turned into an unreadable mess due to the
desire to avoid using up a thread for every protocol instantiation.
* Surviving node shutdowns/restarts that may occur in the middle of the protocol without complicating things. This
implies that the state of the protocol must be persisted to disk.
* Error handling.
* Message routing.
* Serialisation.
* Catching type errors, in which the developer gets temporarily confused and expects to receive/send one type of message
when actually they need to receive/send another.
* Unit testing of the finished protocol.
Actor frameworks can solve some of the above but they are often tightly bound to a particular messaging layer, and
we would like to keep a clean separation. Additionally, they are typically not type safe, and don't make persistence or
writing sequential code much easier.
To put these problems in perspective, the *payment channel protocol* in the bitcoinj library, which allows bitcoins to
be temporarily moved off-chain and traded at high speed between two parties in private, consists of about 7000 lines of
Java and took over a month of full time work to develop. Most of that code is concerned with the details of persistence,
message passing, lifecycle management, error handling and callback management. Because the business logic is quite
spread out the code can be difficult to read and debug.
As small contract-specific trading protocols are a common occurence in finance, we provide a framework for the
construction of them that automatically handles many of the concerns outlined above.
Theory
------
A *continuation* is a suspended stack frame stored in a regular object that can be passed around, serialised,
unserialised and resumed from where it was suspended. This concept is sometimes referred to as "fibers". This may
sound abstract but don't worry, the examples below will make it clearer. The JVM does not natively support
continuations, so we implement them using a library called Quasar which works through behind-the-scenes
bytecode rewriting. You don't have to know how this works to benefit from it, however.
We use continuations for the following reasons:
* It allows us to write code that is free of callbacks, that looks like ordinary sequential code.
* A suspended continuation takes far less memory than a suspended thread. It can be as low as a few hundred bytes.
In contrast a suspended Java thread stack can easily be 1mb in size.
* It frees the developer from thinking (much) about persistence and serialisation.
A *state machine* is a piece of code that moves through various *states*. These are not the same as states in the data
model (that represent facts about the world on the ledger), but rather indicate different stages in the progression
of a multi-stage protocol. Typically writing a state machine would require the use of a big switch statement and some
explicit variables to keep track of where you're up to. The use of continuations avoids this hassle.
A two party trading protocol
----------------------------
We would like to implement the "hello world" of shared transaction building protocols: a seller wishes to sell some
*asset* (e.g. some commercial paper) in return for *cash*. The buyer wishes to purchase the asset using his cash. They
want the trade to be atomic so neither side is exposed to the risk of settlement failure. We assume that the buyer
and seller have found each other and arranged the details on some exchange, or over the counter. The details of how
the trade is arranged isn't covered in this article.
Our protocol has two parties (B and S for buyer and seller) and will proceed as follows:
1. S sends a ``StateAndRef`` pointing to the state they want to sell to B, along with info about the price they require
B to pay.
2. B sends to S a ``SignedTransaction`` that includes the state as input, B's cash as input, the state with the new
owner key as output, and any change cash as output. It contains a single signature from B but isn't valid because
it lacks a signature from S authorising movement of the asset.
3. S signs it and hands the now finalised ``SignedTransaction`` back to B.
You can find the implementation of this protocol in the file ``finance/src/main/kotlin/net.corda.protocols/TwoPartyTradeProtocol.kt``.
Assuming no malicious termination, they both end the protocol being in posession of a valid, signed transaction that
represents an atomic asset swap.
Note that it's the *seller* who initiates contact with the buyer, not vice-versa as you might imagine.
We start by defining a wrapper that namespaces the protocol code, two functions to start either the buy or sell side
of the protocol, and two classes that will contain the protocol definition. We also pick what data will be used by
each side.
.. note:: The code samples in this tutorial are only available in Kotlin, but you can use any JVM language to
write them and the approach is the same.
.. container:: codeset
.. sourcecode:: kotlin
object TwoPartyTradeProtocol {
class UnacceptablePriceException(val givenPrice: Amount<Currency>) : Exception("Unacceptable price: $givenPrice")
class AssetMismatchException(val expectedTypeName: String, val typeName: String) : Exception() {
override fun toString() = "The submitted asset didn't match the expected type: $expectedTypeName vs $typeName"
}
// This object is serialised to the network and is the first protocol message the seller sends to the buyer.
data class SellerTradeInfo(
val assetForSale: StateAndRef<OwnableState>,
val price: Amount<Currency>,
val sellerOwnerKey: PublicKey
)
data class SignaturesFromSeller(val sellerSig: DigitalSignature.WithKey,
val notarySig: DigitalSignature.LegallyIdentifiable)
open class Seller(val otherSide: Party,
val notaryNode: NodeInfo,
val assetToSell: StateAndRef<OwnableState>,
val price: Amount<Currency>,
val myKeyPair: KeyPair,
override val progressTracker: ProgressTracker = Seller.tracker()) : ProtocolLogic<SignedTransaction>() {
@Suspendable
override fun call(): SignedTransaction {
TODO()
}
}
open class Buyer(val otherSide: Party,
val notary: Party,
val acceptablePrice: Amount<Currency>,
val typeToBuy: Class<out OwnableState>) : ProtocolLogic<SignedTransaction>() {
@Suspendable
override fun call(): SignedTransaction {
TODO()
}
}
}
This code defines several classes nested inside the main ``TwoPartyTradeProtocol`` singleton. Some of the classes are
simply protocol messages or exceptions. The other two represent the buyer and seller side of the protocol.
Going through the data needed to become a seller, we have:
- ``otherSide: Party`` - the party with which you are trading.
- ``notaryNode: NodeInfo`` - the entry in the network map for the chosen notary. See ":doc:`consensus`" for more
information on notaries.
- ``assetToSell: StateAndRef<OwnableState>`` - a pointer to the ledger entry that represents the thing being sold.
- ``price: Amount<Currency>`` - the agreed on price that the asset is being sold for (without an issuer constraint).
- ``myKeyPair: KeyPair`` - the key pair that controls the asset being sold. It will be used to sign the transaction.
And for the buyer:
- ``acceptablePrice: Amount<Currency>`` - the price that was agreed upon out of band. If the seller specifies
a price less than or equal to this, then the trade will go ahead.
- ``typeToBuy: Class<out OwnableState>`` - the type of state that is being purchased. This is used to check that the
sell side of the protocol isn't trying to sell us the wrong thing, whether by accident or on purpose.
Alright, so using this protocol shouldn't be too hard: in the simplest case we can just create a Buyer or Seller
with the details of the trade, depending on who we are. We then have to start the protocol in some way. Just
calling the ``call`` function ourselves won't work: instead we need to ask the framework to start the protocol for
us. More on that in a moment.
Suspendable functions
---------------------
The ``call`` function of the buyer/seller classes is marked with the ``@Suspendable`` annotation. What does this mean?
As mentioned above, our protocol framework will at points suspend the code and serialise it to disk. For this to work,
any methods on the call stack must have been pre-marked as ``@Suspendable`` so the bytecode rewriter knows to modify
the underlying code to support this new feature. A protocol is suspended when calling either ``receive``, ``send`` or
``sendAndReceive`` which we will learn more about below. For now, just be aware that when one of these methods is
invoked, all methods on the stack must have been marked. If you forget, then in the unit test environment you will
get a useful error message telling you which methods you didn't mark. The fix is simple enough: just add the annotation
and try again.
.. note:: Java 9 is likely to remove this pre-marking requirement completely.
Starting your protocol
----------------------
The ``StateMachineManager`` is the class responsible for taking care of all running protocols in a node. It knows
how to register handlers with the messaging system (see ":doc:`messaging`") and iterate the right state machine
when messages arrive. It provides the send/receive/sendAndReceive calls that let the code request network
interaction and it will save/restore serialised versions of the fiber at the right times.
Protocols can be invoked in several ways. For instance, they can be triggered by scheduled events,
see ":doc:`event-scheduling`" to learn more about this. Or they can be triggered via the HTTP API. Or they can
be triggered directly via the Java-level node APIs from your app code.
You request a protocol to be invoked by using the ``ServiceHub.invokeProtocolAsync`` method. This takes a
Java reflection ``Class`` object that describes the protocol class to use (in this case, either ``Buyer`` or ``Seller``).
It also takes a set of arguments to pass to the constructor. Because it's possible for protocol invocations to
be requested by untrusted code (e.g. a state that you have been sent), the types that can be passed into the
protocol are checked against a whitelist, which can be extended by apps themselves at load time.
The process of starting a protocol returns a ``ListenableFuture`` that you can use to either block waiting for
the result, or register a callback that will be invoked when the result is ready.
In a two party protocol only one side is to be manually started using ``ServiceHub.invokeProtocolAsync``. The other side
has to be registered by its node to respond to the initiating protocol via ``ServiceHubInternal.registerProtocolInitiator``.
In our example it doesn't matter which protocol is the initiator and which is the initiated. For example, if we are to
take the seller as the initiator then we would register the buyer as such:
.. container:: codeset
.. sourcecode:: kotlin
val services: ServiceHubInternal = TODO()
services.registerProtocolInitiator(Seller::class) { otherParty ->
val notary = services.networkMapCache.notaryNodes[0]
val acceptablePrice = TODO()
val typeToBuy = TODO()
Buyer(otherParty, notary, acceptablePrice, typeToBuy)
}
This is telling the buyer node to fire up an instance of ``Buyer`` (the code in the lambda) when the initiating protocol
is a seller (``Seller::class``).
Implementing the seller
-----------------------
Let's implement the ``Seller.call`` method. This will be run when the protocol is invoked.
.. container:: codeset
.. sourcecode:: kotlin
@Suspendable
override fun call(): SignedTransaction {
val partialTX: SignedTransaction = receiveAndCheckProposedTransaction()
val ourSignature: DigitalSignature.WithKey = computeOurSignature(partialTX)
val allPartySignedTx = partialTX + ourSignature
val notarySignature = getNotarySignature(allPartySignedTx)
val result: SignedTransaction = sendSignatures(allPartySignedTx, ourSignature, notarySignature)
return result
}
Here we see the outline of the procedure. We receive a proposed trade transaction from the buyer and check that it's
valid. The buyer has already attached their signature before sending it. Then we calculate and attach our own signature so that the transaction is
now signed by both the buyer and the seller. We then send this request to a notary to assert with another signature that the
timestamp in the transaction (if any) is valid and there are no double spends, and send back both
our signature and the notaries signature. Note we should not send to the notary until all other required signatures have been appended
as the notary may validate the signatures as well as verifying for itself the transactional integrity.
Finally, we hand back to the code that invoked the protocol the finished transaction.
Let's fill out the ``receiveAndCheckProposedTransaction()`` method.
.. container:: codeset
.. sourcecode:: kotlin
@Suspendable
private fun receiveAndCheckProposedTransaction(): SignedTransaction {
// Make the first message we'll send to kick off the protocol.
val hello = SellerTradeInfo(assetToSell, price, myKeyPair.public)
val maybeSTX = sendAndReceive<SignedTransaction>(otherSide, hello)
maybeSTX.unwrap {
// Check that the tx proposed by the buyer is valid.
val missingSigs: Set<PublicKey> = it.verifySignatures(throwIfSignaturesAreMissing = false)
val expected = setOf(myKeyPair.public, notaryNode.identity.owningKey)
if (missingSigs != expected)
throw SignatureException("The set of missing signatures is not as expected: ${missingSigs.toStringsShort()} vs ${expected.toStringsShort()}")
val wtx: WireTransaction = it.tx
logger.trace { "Received partially signed transaction: ${it.id}" }
// Download and check all the things that this transaction depends on and verify it is contract-valid,
// even though it is missing signatures.
subProtocol(ResolveTransactionsProtocol(wtx, otherSide))
if (wtx.outputs.map { it.data }.sumCashBy(myKeyPair.public).withoutIssuer() != price)
throw IllegalArgumentException("Transaction is not sending us the right amount of cash")
return it
}
}
Let's break this down. We fill out the initial protocol message with the trade info, and then call ``sendAndReceive``.
This function takes a few arguments:
- The party on the other side.
- The thing to send. It'll be serialised and sent automatically.
- Finally a type argument, which is the kind of object we're expecting to receive from the other side. If we get
back something else an exception is thrown.
Once ``sendAndReceive`` is called, the call method will be suspended into a continuation and saved to persistent
storage. If the node crashes or is restarted, the protocol will effectively continue as if nothing had happened. Your
code may remain blocked inside such a call for seconds, minutes, hours or even days in the case of a protocol that
needs human interaction!
.. note:: There are a couple of rules you need to bear in mind when writing a class that will be used as a continuation.
The first is that anything on the stack when the function is suspended will be stored into the heap and kept alive by
the garbage collector. So try to avoid keeping enormous data structures alive unless you really have to.
The second is that as well as being kept on the heap, objects reachable from the stack will be serialised. The state
of the function call may be resurrected much later! Kryo doesn't require objects be marked as serialisable, but even so,
doing things like creating threads from inside these calls would be a bad idea. They should only contain business
logic and only do I/O via the methods exposed by the protocol framework.
It's OK to keep references around to many large internal node services though: these will be serialised using a
special token that's recognised by the platform, and wired up to the right instance when the continuation is
loaded off disk again.
The buyer is supposed to send us a transaction with all the right inputs/outputs/commands in response to the opening
message, with their cash put into the transaction and their signature on it authorising the movement of the cash.
You get back a simple wrapper class, ``UntrustworthyData<SignedTransaction>``, which is just a marker class that reminds
us that the data came from a potentially malicious external source and may have been tampered with or be unexpected in
other ways. It doesn't add any functionality, but acts as a reminder to "scrub" the data before use.
Our "scrubbing" has three parts:
1. Check that the expected signatures are present and correct. At this point we expect our own signature to be missing,
because of course we didn't sign it yet, and also the signature of the notary because that must always come last.
2. We resolve the transaction, which we will cover below.
3. We verify that the transaction is paying us the demanded price.
Subprotocols
------------
Protocols can be composed via nesting. Invoking a sub-protocol looks similar to an ordinary function call:
.. container:: codeset
.. sourcecode:: kotlin
@Suspendable
private fun getNotarySignature(stx: SignedTransaction): DigitalSignature.LegallyIdentifiable {
progressTracker.currentStep = NOTARY
return subProtocol(NotaryProtocol.Client(stx))
}
In this code snippet we are using the ``NotaryProtocol.Client`` to request notarisation of the transaction.
We simply create the protocol object via its constructor, and then pass it to the ``subProtocol`` method which
returns the result of the protocol's execution directly. Behind the scenes all this is doing is wiring up progress
tracking (discussed more below) and then running the objects ``call`` method. Because this little helper method can
be on the stack when network IO takes place, we mark it as ``@Suspendable``.
Going back to the previous code snippet, we use a subprotocol called ``ResolveTransactionsProtocol``. This is
responsible for downloading and checking all the dependencies of a transaction, which in Corda are always retrievable
from the party that sent you a transaction that uses them. This protocol returns a list of ``LedgerTransaction``
objects, but we don't need them here so we just ignore the return value.
.. note:: Transaction dependency resolution assumes that the peer you got the transaction from has all of the
dependencies itself. It must do, otherwise it could not have convinced itself that the dependencies were themselves
valid. It's important to realise that requesting only the transactions we require is a privacy leak, because if
we don't download a transaction from the peer, they know we must have already seen it before. Fixing this privacy
leak will come later.
After the dependencies, we check the proposed trading transaction for validity by running the contracts for that as
well (but having handled the fact that some signatures are missing ourselves).
Here's the rest of the code:
.. container:: codeset
.. sourcecode:: kotlin
open fun computeOurSignature(partialTX: SignedTransaction) = myKeyPair.signWithECDSA(partialTX.txBits)
@Suspendable
private fun sendSignatures(allPartySignedTX: SignedTransaction, ourSignature: DigitalSignature.WithKey,
notarySignature: DigitalSignature.LegallyIdentifiable): SignedTransaction {
val fullySigned = allPartySignedTX + notarySignature
logger.trace { "Built finished transaction, sending back to secondary!" }
send(otherSide, SignaturesFromSeller(ourSignature, notarySignature))
return fullySigned
}
It's all pretty straightforward from now on. Here ``txBits`` is the raw byte array representing the serialised
transaction, and we just use our private key to calculate a signature over it. As a reminder, in Corda signatures do
not cover other signatures: just the core of the transaction data.
In ``sendSignatures``, we take the two signatures we obtained and add them to the partial transaction we were sent.
There is an overload for the + operator so signatures can be added to a SignedTransaction easily. Finally, we wrap the
two signatures in a simple wrapper message class and send it back. The send won't block waiting for an acknowledgement,
but the underlying message queue software will retry delivery if the other side has gone away temporarily.
You can also see that every protocol instance has a logger (using the SLF4J API) which you can use to log progress
messages.
.. warning:: This sample code is **not secure**. Other than not checking for all possible invalid constructions, if the
seller stops before sending the finalised transaction to the buyer, the seller is left with a valid transaction
but the buyer isn't, so they can't spend the asset they just purchased! This sort of thing will be fixed in a
future version of the code.
Implementing the buyer
----------------------
OK, let's do the same for the buyer side:
.. container:: codeset
.. sourcecode:: kotlin
@Suspendable
override fun call(): SignedTransaction {
val tradeRequest = receiveAndValidateTradeRequest()
val (ptx, cashSigningPubKeys) = assembleSharedTX(tradeRequest)
val stx = signWithOurKeys(cashSigningPubKeys, ptx)
val signatures = swapSignaturesWithSeller(stx)
logger.trace { "Got signatures from seller, verifying ... " }
val fullySigned = stx + signatures.sellerSig + signatures.notarySig
fullySigned.verifySignatures()
logger.trace { "Signatures received are valid. Trade complete! :-)" }
return fullySigned
}
@Suspendable
private fun receiveAndValidateTradeRequest(): SellerTradeInfo {
// Wait for a trade request to come in from the other side
val maybeTradeRequest = receive<SellerTradeInfo>(otherParty)
maybeTradeRequest.unwrap {
// What is the seller trying to sell us?
val asset = it.assetForSale.state.data
val assetTypeName = asset.javaClass.name
logger.trace { "Got trade request for a $assetTypeName: ${it.assetForSale}" }
if (it.price > acceptablePrice)
throw UnacceptablePriceException(it.price)
if (!typeToBuy.isInstance(asset))
throw AssetMismatchException(typeToBuy.name, assetTypeName)
// Check the transaction that contains the state which is being resolved.
// We only have a hash here, so if we don't know it already, we have to ask for it.
subProtocol(ResolveTransactionsProtocol(setOf(it.assetForSale.ref.txhash), otherSide))
return it
}
}
@Suspendable
private fun swapSignaturesWithSeller(stx: SignedTransaction): SignaturesFromSeller {
progressTracker.currentStep = SWAPPING_SIGNATURES
logger.trace { "Sending partially signed transaction to seller" }
// TODO: Protect against the seller terminating here and leaving us in the lurch without the final tx.
return sendAndReceive<SignaturesFromSeller>(otherSide, stx).unwrap { it }
}
private fun signWithOurKeys(cashSigningPubKeys: List<PublicKey>, ptx: TransactionBuilder): SignedTransaction {
// Now sign the transaction with whatever keys we need to move the cash.
for (k in cashSigningPubKeys) {
val priv = serviceHub.keyManagementService.toPrivate(k)
ptx.signWith(KeyPair(k, priv))
}
return ptx.toSignedTransaction(checkSufficientSignatures = false)
}
private fun assembleSharedTX(tradeRequest: SellerTradeInfo): Pair<TransactionBuilder, List<PublicKey>> {
val ptx = TransactionType.General.Builder(notary)
// Add input and output states for the movement of cash, by using the Cash contract to generate the states.
val wallet = serviceHub.walletService.currentWallet
val cashStates = wallet.statesOfType<Cash.State>()
val cashSigningPubKeys = Cash().generateSpend(ptx, tradeRequest.price, tradeRequest.sellerOwnerKey, cashStates)
// Add inputs/outputs/a command for the movement of the asset.
ptx.addInputState(tradeRequest.assetForSale)
// Just pick some new public key for now. This won't be linked with our identity in any way, which is what
// we want for privacy reasons: the key is here ONLY to manage and control ownership, it is not intended to
// reveal who the owner actually is. The key management service is expected to derive a unique key from some
// initial seed in order to provide privacy protection.
val freshKey = serviceHub.keyManagementService.freshKey()
val (command, state) = tradeRequest.assetForSale.state.data.withNewOwner(freshKey.public)
ptx.addOutputState(state, tradeRequest.assetForSale.state.notary)
ptx.addCommand(command, tradeRequest.assetForSale.state.data.owner)
// And add a request for timestamping: it may be that none of the contracts need this! But it can't hurt
// to have one.
val currentTime = serviceHub.clock.instant()
ptx.setTime(currentTime, 30.seconds)
return Pair(ptx, cashSigningPubKeys)
}
This code is longer but no more complicated. Here are some things to pay attention to:
1. We do some sanity checking on the received message to ensure we're being offered what we expected to be offered.
2. We create a cash spend in the normal way, by using ``Cash().generateSpend``. See the contracts tutorial if this
part isn't clear.
3. We access the *service hub* when we need it to access things that are transient and may change or be recreated
whilst a protocol is suspended, things like the wallet or the network map.
4. Finally, we send the unfinished, invalid transaction to the seller so they can sign it. They are expected to send
back to us a ``SignaturesFromSeller``, which once we verify it, should be the final outcome of the trade.
As you can see, the protocol logic is straightforward and does not contain any callbacks or network glue code, despite
the fact that it takes minimal resources and can survive node restarts.
.. warning:: In the current version of the platform, exceptions thrown during protocol execution are not propagated
back to the sender. A thorough error handling and exceptions framework will be in a future version of the platform.
Progress tracking
-----------------
Not shown in the code snippets above is the usage of the ``ProgressTracker`` API. Progress tracking exports information
from a protocol about where it's got up to in such a way that observers can render it in a useful manner to humans who
may need to be informed. It may be rendered via an API, in a GUI, onto a terminal window, etc.
A ``ProgressTracker`` is constructed with a series of ``Step`` objects, where each step is an object representing a
stage in a piece of work. It is therefore typical to use singletons that subclass ``Step``, which may be defined easily
in one line when using Kotlin. Typical steps might be "Waiting for response from peer", "Waiting for signature to be
approved", "Downloading and verifying data" etc.
Each step exposes a label. By default labels are fixed, but by subclassing ``RelabelableStep``
you can make a step that can update its label on the fly. That's useful for steps that want to expose non-structured
progress information like the current file being downloaded. By defining your own step types, you can export progress
in a way that's both human readable and machine readable.
Progress trackers are hierarchical. Each step can be the parent for another tracker. By altering the
``ProgressTracker.childrenFor[step] = tracker`` map, a tree of steps can be created. It's allowed to alter the hierarchy
at runtime, on the fly, and the progress renderers will adapt to that properly. This can be helpful when you don't
fully know ahead of time what steps will be required. If you _do_ know what is required, configuring as much of the
hierarchy ahead of time is a good idea, as that will help the users see what is coming up.
Every tracker has not only the steps given to it at construction time, but also the singleton
``ProgressTracker.UNSTARTED`` step and the ``ProgressTracker.DONE`` step. Once a tracker has become ``DONE`` its
position may not be modified again (because e.g. the UI may have been removed/cleaned up), but until that point, the
position can be set to any arbitrary set both forwards and backwards. Steps may be skipped, repeated, etc. Note that
rolling the current step backwards will delete any progress trackers that are children of the steps being reversed, on
the assumption that those subtasks will have to be repeated.
Trackers provide an `Rx observable <http://reactivex.io/>`_ which streams changes to the hierarchy. The top level
observable exposes all the events generated by its children as well. The changes are represented by objects indicating
whether the change is one of position (i.e. progress), structure (i.e. new subtasks being added/removed) or some other
aspect of rendering (i.e. a step has changed in some way and is requesting a re-render).
The protocol framework is somewhat integrated with this API. Each ``ProtocolLogic`` may optionally provide a tracker by
overriding the ``protocolTracker`` property (``getProtocolTracker`` method in Java). If the
``ProtocolLogic.subProtocol`` method is used, then the tracker of the sub-protocol will be made a child of the current
step in the parent protocol automatically, if the parent is using tracking in the first place. The framework will also
automatically set the current step to ``DONE`` for you, when the protocol is finished.
Because a protocol may sometimes wish to configure the children in its progress hierarchy _before_ the sub-protocol
is constructed, for sub-protocols that always follow the same outline regardless of their parameters it's conventional
to define a companion object/static method (for Kotlin/Java respectively) that constructs a tracker, and then allow
the sub-protocol to have the tracker it will use be passed in as a parameter. This allows all trackers to be built
and linked ahead of time.
In future, the progress tracking framework will become a vital part of how exceptions, errors, and other faults are
surfaced to human operators for investigation and resolution.
Unit testing
------------
A protocol can be a fairly complex thing that interacts with many services and other parties over the network. That
means unit testing one requires some infrastructure to provide lightweight mock implementations. The MockNetwork
provides this testing infrastructure layer; you can find this class in the node module
A good example to examine for learning how to unit test protocols is the ``ResolveTransactionsProtocol`` tests. This
protocol takes care of downloading and verifying transaction graphs, with all the needed dependencies. We start
with this basic skeleton:
.. container:: codeset
.. sourcecode:: kotlin
class ResolveTransactionsProtocolTest {
lateinit var net: MockNetwork
lateinit var a: MockNetwork.MockNode
lateinit var b: MockNetwork.MockNode
lateinit var notary: Party
@Before
fun setup() {
net = MockNetwork()
val nodes = net.createSomeNodes()
a = nodes.partyNodes[0]
b = nodes.partyNodes[1]
notary = nodes.notaryNode.info.identity
net.runNetwork()
}
@After
fun tearDown() {
net.stopNodes()
}
}
We create a mock network in our ``@Before`` setup method and create a couple of nodes. We also record the identity
of the notary in our test network, which will come in handy later. We also tidy up when we're done.
Next, we write a test case:
.. container:: codeset
.. sourcecode:: kotlin
@Test
fun resolveFromTwoHashes() {
val (stx1, stx2) = makeTransactions()
val p = ResolveTransactionsProtocol(setOf(stx2.id), a.info.identity)
val future = b.services.startProtocol("resolve", p)
net.runNetwork()
val results = future.get()
assertEquals(listOf(stx1.id, stx2.id), results.map { it.id })
assertEquals(stx1, b.storage.validatedTransactions.getTransaction(stx1.id))
assertEquals(stx2, b.storage.validatedTransactions.getTransaction(stx2.id))
}
We'll take a look at the ``makeTransactions`` function in a moment. For now, it's enough to know that it returns two
``SignedTransaction`` objects, the second of which spends the first. Both transactions are known by node A
but not node B.
The test logic is simple enough: we create the protocol, giving it node A's identity as the target to talk to.
Then we start it on node B and use the ``net.runNetwork()`` method to bounce messages around until things have
settled (i.e. there are no more messages waiting to be delivered). All this is done using an in memory message
routing implementation that is fast to initialise and use. Finally, we obtain the result of the protocol and do
some tests on it. We also check the contents of node B's database to see that the protocol had the intended effect
on the node's persistent state.
Here's what ``makeTransactions`` looks like:
.. container:: codeset
.. sourcecode:: kotlin
private fun makeTransactions(): Pair<SignedTransaction, SignedTransaction> {
// Make a chain of custody of dummy states and insert into node A.
val dummy1: SignedTransaction = DummyContract.generateInitial(MEGA_CORP.ref(1), 0, notary).let {
it.signWith(MEGA_CORP_KEY)
it.signWith(DUMMY_NOTARY_KEY)
it.toSignedTransaction(false)
}
val dummy2: SignedTransaction = DummyContract.move(dummy1.tx.outRef(0), MINI_CORP_PUBKEY).let {
it.signWith(MEGA_CORP_KEY)
it.signWith(DUMMY_NOTARY_KEY)
it.toSignedTransaction()
}
a.services.recordTransactions(dummy1, dummy2)
return Pair(dummy1, dummy2)
}
We're using the ``DummyContract``, a simple test smart contract which stores a single number in its states, along
with ownership and issuer information. You can issue such states, exit them and re-assign ownership (move them).
It doesn't do anything else. This code simply creates a transaction that issues a dummy state (the issuer is
``MEGA_CORP``, a pre-defined unit test identity), signs it with the test notary and MegaCorp keys and then
converts the builder to the final ``SignedTransaction``. It then does so again, but this time instead of issuing
it re-assigns ownership instead. The chain of two transactions is finally committed to node A by sending them
directly to the ``a.services.recordTransaction`` method (note that this method doesn't check the transactions are
valid).
And that's it: you can explore the documentation for the `MockNode API <api/net.corda.node.internal.testing/-mock-network/index.html>`_ here.
Versioning
----------
Fibers involve persisting object-serialised stack frames to disk. Although we may do some R&D into in-place upgrades
in future, for now the upgrade process for protocols is simple: you duplicate the code and rename it so it has a
new set of class names. Old versions of the protocol can then drain out of the system whilst new versions are
initiated. When enough time has passed that no old versions are still waiting for anything to happen, the previous
copy of the code can be deleted.
Whilst kind of ugly, this is a very simple approach that should suffice for now.
.. warning:: Protocols are not meant to live for months or years, and by implication they are not meant to implement entire deal
lifecycles. For instance, implementing the entire life cycle of an interest rate swap as a single protocol - whilst
technically possible - would not be a good idea. The platform provides a job scheduler tool that can invoke
protocols for this reason (see ":doc:`event-scheduling`")
Future features
---------------
The protocol framework is a key part of the platform and will be extended in major ways in future. Here are some of
the features we have planned:
* Identity based addressing
* Exposing progress trackers to local (inside the firewall) clients using message queues and/or WebSockets
* Exception propagation and management, with a "protocol hospital" tool to manually provide solutions to unavoidable
problems (e.g. the other side doesn't know the trade)
* Being able to interact with internal apps and tools via HTTP and similar
* Being able to interact with people, either via some sort of external ticketing system, or email, or a custom UI.
For example to implement human transaction authorisations.
* A standard library of protocols that can be easily sub-classed by local developers in order to integrate internal
reporting logic, or anything else that might be required as part of a communications lifecycle.

View File

@ -3,6 +3,45 @@ Release notes
Here are brief summaries of what's changed between each snapshot release.
Milestone 7
-----------
* With thanks to `Thomas Schroeter <https://github.com/thschroeter>`_ ``NotaryFlow`` is now idempotent.
* Explorer:
* The GUI for the explorer now shows other nodes on the network map and the transactions between them.
* Map resolution increased and allows zooming and panning.
* `Video demonstration <https://www.corda.net/2017/01/03/the-node-explorer/>`_ of the Node Explorer.
* The CorDapp template now has a Java example that parallels the Kotlin one for developers more comfortable with Java.
ORM support added to the Kotlin example.
* Demos:
* Added the Bank of Corda demo - a demo showing a node (Bank of Corda) acting as an issuer of Cash, and a client
driver providing both Web and RPC access to request issuance of cash.
* Demos now use RPC to communicate with the node from the webserver. This brings the demos more in line with how
interaction with nodes is expected to be. The demos now treat their webservers like clients. This will also allow
for the splitting of the webserver from the node for milestone 8.
* Added a SIMM valuation demo integration test to catch regressions.
* Security:
* MQ broker of the node now requires authentication which means that third parties cannot connect to and
listen to queues on the Node. RPC and P2P between nodes is now authenticated as a result of this change.
This also means that nodes or RPC users cannot pretend to be other nodes or RPC users.
* The node now does host verification of any node that connects to it and prevents man in the middle attacks.
* Improvements:
* Vault updates now contain full ``StateAndRef`` which allows subscribers to check whether the update contains
relevant states.
* Cash balances are calculated using aggregate values to prevent iterating through all states in the vault, which
improves performance.
* Multi-party services, such as notaries, are now load balanced and represented as a single ``Party`` object.
* The Notary Change flow now supports encumbrances.
Milestone 6
-----------

View File

@ -7,7 +7,7 @@ These provide a common language for states and contracts.
Amount
------
The `Amount <api/net.corda.core.contracts/-amount/index.html>`_ class is used to represent an amount of some
The `Amount <api/kotlin/corda/net.corda.core.contracts/-amount/index.html>`_ class is used to represent an amount of some
fungible asset. It is a generic class which wraps around a type used to define the underlying product, called
the *token*. For instance it can be the standard JDK type ``Currency``, or an ``Issued`` instance, or this can be
a more complex type such as an obligation contract issuance definition (which in turn contains a token definition
@ -203,4 +203,4 @@ The ``SecureHash`` class represents a secure hash of unknown algorithm. We curre
``SecureHash.SHA256``. There are utility methods to create them, parse them and so on.
We also provide some mathematical utilities, in particular a set of interpolators and classes for working with
splines. These can be found in the `maths package <api/net.corda.core.math/index.html>`_.
splines. These can be found in the `maths package <api/kotlin/corda/net.corda.core.math/index.html>`_.

View File

@ -7,50 +7,59 @@
Writing a contract using clauses
================================
This tutorial will take you through restructuring the commercial paper contract to use clauses. You should have
In this tutorial, we will restructure the commercial paper contract to use clauses. You should have
already completed ":doc:`tutorial-contract`".
As before, the example is focused on basic implementation of commercial paper, which is essentially a simpler version of a corporate
bond. A company issues CP with a particular face value, say $100, but sells it for less, say $90. The paper can be redeemed
for cash at a given date in the future. Thus this example would have a 10% interest rate with a single repayment.
Whole Kotlin code can be found in ``CommercialPaper.kt``.
What are clauses and why to use them?
-------------------------------------
As before, this example is focused on a basic implementation of commercial paper (CP), which is essentially a simpler version of a corporate
bond. A company issues commercial paper with a particular face value, say $100, but sells it for less, say $90. The paper can be redeemed
for cash at a given future date. In our example, the commercial paper has a 10% interest rate, with a single repayment.
The full Kotlin code can be found in ``CommercialPaper.kt``.
What are clauses and why use them?
----------------------------------
Clauses are essentially micro-contracts which contain independent verification logic, and can be logically composed
together to form a contract. Clauses are designed to enable re-use of common verification parts, for example issuing state objects
is generally the same for all fungible contracts, so a common issuance clause can be inherited for each contract's
to form a complete contract. Clauses are designed to enable re-use of common verification parts. For example, issuing state objects
is generally the same for all fungible contracts, so a common issuance clause can be used for each contract's
issue clause. This cuts down on scope for error, and improves consistency of behaviour. By splitting verification logic
into smaller chunks, they can also be readily tested in isolation.
into smaller chunks, these can also be readily tested in isolation.
How clauses work?
-----------------
How do clauses work?
--------------------
We have different types of clauses, the most basic are the ones that define verification logic for particular command set.
We will see them later as elementary building blocks that commercial paper consist of - ``Move``, ``Issue`` and ``Redeem``.
As a developer you need to identify reusable parts of your contract and decide how they should be combined. It is where
composite clauses become useful. They gather many clause subcomponents and resolve how and which of them should be checked.
There are different types of clauses. The most basic are those that define the verification logic for a single command
(e.g. ``Move``, ``Issue`` and ``Redeem``, in the case of commercial paper), or even run without any commands at all (e.g. ``Timestamp``).
For example, assume that we want to verify a transaction using all constraints defined in separate clauses. We need to
wrap classes that define them into ``AllComposition`` composite clause. It assures that all clauses from that combination
match with commands in a transaction - only then verification logic can be executed.
It may be a little confusing, but composite clause is also a clause and you can even wrap it in the special grouping clause.
In ``CommercialPaper`` it looks like that:
These basic clauses can then be combined using a ``CompositeClause``. The goal of composite clauses is to determine
which individual clauses need to be matched and verified for a given transaction
to be considered valid. We refer to a clause as being "matched" when the transaction has the required commands present for the clause
in question to trigger. Meanwhile, we talk about a clause "verifying" when its ``verify()`` function returns ``True``.
As an example, let's say we want a transaction to be valid only when every single one of its clauses matches and verifies. We implement this
by wrapping the individual clauses into an ``AllOf`` composite clause, which ensures that a transaction is
only considered valid if all of its clauses are both matched and verify.
There are two other basic composite clauses that you should be aware of:
* ``AnyOf``, whereby 1 or more clauses may match, and every matched clause must verify
* ``FirstOf``, whereby at least one clause must match, and the first such clause must verify
In turn, composite clauses are themselves ``Clause`` s, and can, for example, be wrapped in the special ``GroupClauseVerifier`` grouping clause.
For ``CommercialPaper``, this would look as follows:
.. image:: resources/commPaperClauses.png
The most basic types of composite clauses are ``AllComposition``, ``AnyComposition`` and ``FirstComposition``.
In this tutorial we will use ``GroupClauseVerifier`` and ``AnyComposition``. It's important to understand how they work.
Charts showing execution and more detailed information can be found in :doc:`clauses`.
For this tutorial, we will be using ``GroupClauseVerifier`` and ``AnyOf``. Since it's important to understand how these work,
charts showing their execution and other details can be found in :doc:`clauses`.
.. _verify_ref:
Commercial paper class
----------------------
We start from defining ``CommercialPaper`` class. As in previous tutorial we need some elementary parts: ``Commands`` interface,
``generateMove``, ``generateIssue``, ``generateRedeem`` - so far so good that stays the same. The new part is verification and
``Clauses`` interface (you will see them later in code). Let's start from the basic structure:
We start by defining the ``CommercialPaper`` class. As in the previous tutorial, we need some elementary parts: a ``Commands`` interface,
``generateMove``, ``generateIssue``, ``generateRedeem``. So far, so good - these stay the same. The new part is verification and the
``Clauses`` interface (which we will see later in code). Let's start from the basic structure:
.. container:: codeset
@ -97,18 +106,18 @@ We start from defining ``CommercialPaper`` class. As in previous tutorial we nee
}
}
As you can see we used ``verifyClause`` function with ``Clauses.Group()`` in place of previous verification.
As you can see, we used ``verifyClause`` function with ``Clauses.Group()`` in place of our previous verification logic.
It's an entry point to running clause logic. ``verifyClause`` takes the transaction, a clause (usually a composite one)
to verify, and a collection of commands the clause is expected to handle all of. This list of commands is important because
``verifyClause`` checks that none of the commands are left unprocessed at the end, and raises an error if they are.
to verify, and all of the commands the clause is expected to handle. This list of commands is important because
``verifyClause`` checks that none of the commands are left unprocessed at the end, raising an error if they are.
Simple Clauses
--------------
Let's move to constructing contract logic in terms of clauses language. Commercial paper contract has three commands and
Let's move to constructing contract logic in terms of clauses. The commercial paper contract has three commands and
three corresponding behaviours: ``Issue``, ``Move`` and ``Redeem``. Each of them has a specific set of requirements that must be satisfied -
perfect material for defining clauses. For brevity we will show only ``Move`` clause, rest is constructed in similar manner
and included in the ``CommercialPaper.kt`` code.
perfect material for defining clauses. For brevity, we will only show the ``Move`` clause. The rest is constructed in similar manner,
and is included in the ``CommercialPaper.kt`` code.
.. container:: codeset
@ -172,50 +181,51 @@ and included in the ``CommercialPaper.kt`` code.
}
...
We took part of code for ``Command.Move`` verification from previous tutorial and put it into the verify function
We took part of the code for ``Command.Move`` verification from the previous tutorial and put it into the verify function
of ``Move`` class. Notice that this class must extend the ``Clause`` abstract class, which defines
the ``verify`` function, and the ``requiredCommands`` property used to determine the conditions under which a clause
is triggered. In the above example it means that the clause will run verification when the ``Commands.Move`` is present in a transaction.
the ``verify`` function and the ``requiredCommands`` property used to determine the conditions under which a clause
is triggered. In the above example, this means that the clause will run its verification logic when ``Commands.Move`` is present in a transaction.
.. note:: Notice that commands refer to all input and output states in a transaction. For clause to be executed, transaction has
to include all commands from ``requiredCommands`` set.
.. note:: Notice that commands refer to all input and output states in a transaction. For a clause to be executed, the transaction has
to include all commands from the ``requiredCommands`` set.
Few important changes:
A few important changes:
- ``verify`` function returns the set of commands which it has processed. Normally this returned set is identical to the
``requiredCommands`` used to trigger the clause, however in some cases the clause may process further optional commands
- The ``verify`` function returns the set of commands which it has processed. Normally this set is identical to the
``requiredCommands`` used to trigger the clause. However, in some cases, the clause may process further optional commands
which it needs to report that it has handled.
- Verification takes new parameters. Usually inputs and outputs are some subset of the original transaction entries
passed to the clause by outer composite or grouping clause. ``groupingKey`` is a key used to group original states.
As a simple example imagine input states:
As a simple example, imagine the following input states:
1. 1000 GBP issued by Bank of England
2. 500 GBP issued by Bank of England
3. 1000 GBP issued by Bank of Scotland
We will group states by Issuer so in the first group we have inputs 1 and 2, in second group input number 3. Grouping keys are:
We will group states by Issuer, meaning that we have inputs 1 and 2 in one group, and input 3 in another group. The grouping keys are
'GBP issued by Bank of England' and 'GBP issued by Bank of Scotland'.
How the states can be grouped and passed in that form to the ``Move`` clause? That leads us to the concept of ``GroupClauseVerifier``.
How are the states grouped and passed in this form to the ``Move`` clause? Answering that question leads us to the concept of
``GroupClauseVerifier``.
Group clause
------------
We may have a transaction with similar but unrelated state evolutions which need to be validated independently. It
makes sense to check ``Move`` command on groups of related inputs and outputs (see example above). Thus, we need to collect
makes sense to check the ``Move`` command on groups of related inputs and outputs (see example above). Thus, we need to collect
relevant states together.
For this we extend the standard ``GroupClauseVerifier`` and specify how to group input/output states, as well as the top-level
clause to run on each group. In our example a top-level is a composite clause - ``AnyCompostion`` that delegates verification to
it's subclasses (wrapped move, issue, redeem). Any in this case means that it will take 0 or more clauses that match transaction commands.
For this, we extend the standard ``GroupClauseVerifier`` and specify how to group input/output states, as well as the top-level
clause to run on each group. In our example, the top level is a composite clause - ``AnyCompostion`` - that delegates verification to
its subclauses (wrapped move, issue, redeem). "Any" in this case means that it will take 0 or more clauses that match the transaction commands.
.. container:: codeset
.. sourcecode:: kotlin
class Group : GroupClauseVerifier<State, Commands, Issued<Terms>>(
AnyComposition(
AnyOf(
Redeem(),
Move(),
Issue())) {
@ -227,7 +237,7 @@ it's subclasses (wrapped move, issue, redeem). Any in this case means that it wi
class Group extends GroupClauseVerifier<State, Commands, State> {
public Group() {
super(new AnyComposition<>(
super(new AnyOf<>(
new Clauses.Redeem(),
new Clauses.Move(),
new Clauses.Issue()
@ -242,16 +252,16 @@ it's subclasses (wrapped move, issue, redeem). Any in this case means that it wi
}
For the ``CommercialPaper`` contract, ``Group`` is the main clause for the contract, and is passed directly into
``verifyClause`` (see the example code at the top of this tutorial). We used ``groupStates`` function here, it's worth reminding
how it works: :ref:`state_ref`.
``verifyClause`` (see the example code at the top of this tutorial). We also used ``groupStates`` function here - it
may be worth reminding yourself how it works here: :ref:`state_ref`.
Summary
-------
In summary the top level contract ``CommercialPaper`` specifies a single grouping clause of type
``CommercialPaper.Clauses.Group`` which in turn specifies ``GroupClause`` implementations for each type of command
(``Redeem``, ``Move`` and ``Issue``). This reflects the flow of verification: in order to verify a ``CommercialPaper``
we first group states, check which commands are specified, and run command-specific verification logic accordingly.
In summary, the top-level contract ``CommercialPaper`` specifies a single grouping clause of type
``CommercialPaper.Clauses.Group``, which in turn specifies ``GroupClause`` implementations for each type of command
(``Redeem``, ``Move`` and ``Issue``). This reflects the verification flow: in order to verify ``CommercialPaper``,
we first group states, then we check which commands are specified, and finally we run command-specific verification logic accordingly.
.. image:: resources/commPaperExecution.png

View File

@ -804,7 +804,6 @@ like to deploy for testing. See further details below:
networkMap "Controller" // The artemis address of the node to be used as the network map.
node {
name "Controller" // Artemis name of node to be deployed.
dirName "controller" // Directory to which the node will
nearestCity "London" // For use with the network visualiser.
advertisedServices = ["corda.notary.validating"] // A list of services you wish the node to offer.
artemisPort 10002
@ -813,7 +812,6 @@ like to deploy for testing. See further details below:
}
node { // Create an additional node.
name "NodeA"
dirName "nodea"
nearestCity "London"
advertisedServices = []
artemisPort 10004

View File

@ -1,69 +0,0 @@
.. highlight:: kotlin
.. raw:: html
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/codesets.js"></script>
Where to start
==============
So you want to start experimenting with Corda. Where do you begin? Although Corda is still very early and missing
large chunks of important functionality, this article will hopefully put you on the right place.
An experiment with Corda is started by picking a *scenario* and then turning it into a *demo*. It is important to
understand that at this stage in its life, Corda does not have a single unified server that loads everything
dynamically. Instead, Corda provides an object oriented API which is then used by a *driver* program, with one driver
per scenario. You can see the existing demo apps in action by :doc:`running-the-demos`.
In future this design will change and there will be a single server that does everything. But for now, there isn't.
A scenario contains:
* A set of participating nodes and their roles.
* Some business process you wish to automate (typically simplified from the real thing).
* The smart contracts and flows that will automate that process.
It may also specify a REST/JSON API, but this is optional.
Here's are two example scenarios included in the box:
1. Bank A wishes to buy some commercial paper in return for cash. Bank B wants to issue and sell some CP to Bank A.
This is probably the simplest scenario in Corda that still does something interesting. It's like the buttered
bread of finance.
2. Bank A and Bank B want to enter into an interest rate swap and evolve it through its lifecycle.
The process of implementing a scenario looks like this:
1. First of all, design your states and transaction types. Read about the :doc:`data-model` if you aren't sure what that
involves.
2. Now, create a new file in the finance/src/main directory. You can either any JVM language but we only provide examples
in Java and Kotlin. The file should define your state classes and your contract class, which will define the
allowable state transitions. You can learn how these are constructed by reading the ":doc:`tutorial-contract`" tutorial.
3. It isn't enough to just define static data and logic that controls what's allowed. You must also orchestrate the
business process. This is the job of the flow framework. You can learn how to author these by reading
":doc:`flow-state-machines`".
4. Once you have created your states, transactions and flows, you need a way to demonstrate them (outside of the
unit tests, of course). This topic is covered below.
The trader demo
---------------
Until Corda has a unified server that can dynamically load every aspect of an application (i.e. software implementing a scenario),
we have to do a bit of copy/paste wiring ourselves.
The trader demo is a good place to start understanding this, which can be found in src/main/kotlin/demos/TraderDemo.kt
The idea of a driver program is that it starts a node in one of several roles, according to a command line flag. The
driver may step through some pre-programmed scenario automatically or it may register an API to be exported via HTTP.
You would then have to drive the node externally for your demo.
The best way to create your own scenario is not to write a driver from scratch but to copy the existing trader or IRS
demo drivers and then customise them, as much of the code would end up being shared (like for command line parsing).
Things you will want to adjust:
1. The name of the grouping directory each node role will create its private directory under.
2. The demo flows that just wrap the real business process in some kind of fake trading logic.
The IRS driver program registers REST APIs, but as this is seriously in flux right now and the APIs will change a lot,
we do not recommend you try this as part of your initial explorations unless you are feeling adventurous.

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -1,280 +0,0 @@
<HTML>
<HEAD>
<title></title>
<link rel="stylesheet" href="style.css">
</HEAD>
<BODY>
<br/>
<br/>
<h3>Packages</h3>
<table>
<tbody>
<tr>
<td>
<a href="net.corda.client.fxutils/index.html">net.corda.client.fxutils</a></td>
<td>
</td>
</tr>
<tr>
<td>
<a href="net.corda.client.mock/index.html">net.corda.client.mock</a></td>
<td>
</td>
</tr>
<tr>
<td>
<a href="net.corda.client.model/index.html">net.corda.client.model</a></td>
<td>
</td>
</tr>
<tr>
<td>
<a href="net.corda.contracts/index.html">net.corda.contracts</a></td>
<td>
</td>
</tr>
<tr>
<td>
<a href="net.corda.contracts.asset/index.html">net.corda.contracts.asset</a></td>
<td>
</td>
</tr>
<tr>
<td>
<a href="net.corda.contracts.clause/index.html">net.corda.contracts.clause</a></td>
<td>
</td>
</tr>
<tr>
<td>
<a href="net.corda.contracts.testing/index.html">net.corda.contracts.testing</a></td>
<td>
</td>
</tr>
<tr>
<td>
<a href="net.corda.core/index.html">net.corda.core</a></td>
<td>
</td>
</tr>
<tr>
<td>
<a href="net.corda.core.contracts/index.html">net.corda.core.contracts</a></td>
<td>
</td>
</tr>
<tr>
<td>
<a href="net.corda.core.contracts.clauses/index.html">net.corda.core.contracts.clauses</a></td>
<td>
</td>
</tr>
<tr>
<td>
<a href="net.corda.core.crypto/index.html">net.corda.core.crypto</a></td>
<td>
</td>
</tr>
<tr>
<td>
<a href="net.corda.core.flows/index.html">net.corda.core.flows</a></td>
<td>
</td>
</tr>
<tr>
<td>
<a href="net.corda.core.math/index.html">net.corda.core.math</a></td>
<td>
</td>
</tr>
<tr>
<td>
<a href="net.corda.core.messaging/index.html">net.corda.core.messaging</a></td>
<td>
</td>
</tr>
<tr>
<td>
<a href="net.corda.core.node/index.html">net.corda.core.node</a></td>
<td>
</td>
</tr>
<tr>
<td>
<a href="net.corda.core.node.services/index.html">net.corda.core.node.services</a></td>
<td>
</td>
</tr>
<tr>
<td>
<a href="net.corda.core.schemas/index.html">net.corda.core.schemas</a></td>
<td>
</td>
</tr>
<tr>
<td>
<a href="net.corda.core.serialization/index.html">net.corda.core.serialization</a></td>
<td>
</td>
</tr>
<tr>
<td>
<a href="net.corda.core.testing/index.html">net.corda.core.testing</a></td>
<td>
</td>
</tr>
<tr>
<td>
<a href="net.corda.core.transactions/index.html">net.corda.core.transactions</a></td>
<td>
</td>
</tr>
<tr>
<td>
<a href="net.corda.core.utilities/index.html">net.corda.core.utilities</a></td>
<td>
</td>
</tr>
<tr>
<td>
<a href="net.corda.flows/index.html">net.corda.flows</a></td>
<td>
</td>
</tr>
<tr>
<td>
<a href="net.corda.node/index.html">net.corda.node</a></td>
<td>
</td>
</tr>
<tr>
<td>
<a href="net.corda.node.api/index.html">net.corda.node.api</a></td>
<td>
</td>
</tr>
<tr>
<td>
<a href="net.corda.node.driver/index.html">net.corda.node.driver</a></td>
<td>
</td>
</tr>
<tr>
<td>
<a href="net.corda.node.internal/index.html">net.corda.node.internal</a></td>
<td>
</td>
</tr>
<tr>
<td>
<a href="net.corda.node.serialization/index.html">net.corda.node.serialization</a></td>
<td>
</td>
</tr>
<tr>
<td>
<a href="net.corda.node.services/index.html">net.corda.node.services</a></td>
<td>
</td>
</tr>
<tr>
<td>
<a href="net.corda.node.services.api/index.html">net.corda.node.services.api</a></td>
<td>
</td>
</tr>
<tr>
<td>
<a href="net.corda.node.services.config/index.html">net.corda.node.services.config</a></td>
<td>
</td>
</tr>
<tr>
<td>
<a href="net.corda.node.services.events/index.html">net.corda.node.services.events</a></td>
<td>
</td>
</tr>
<tr>
<td>
<a href="net.corda.node.services.identity/index.html">net.corda.node.services.identity</a></td>
<td>
</td>
</tr>
<tr>
<td>
<a href="net.corda.node.services.keys/index.html">net.corda.node.services.keys</a></td>
<td>
</td>
</tr>
<tr>
<td>
<a href="net.corda.node.services.messaging/index.html">net.corda.node.services.messaging</a></td>
<td>
</td>
</tr>
<tr>
<td>
<a href="net.corda.node.services.network/index.html">net.corda.node.services.network</a></td>
<td>
</td>
</tr>
<tr>
<td>
<a href="net.corda.node.services.persistence/index.html">net.corda.node.services.persistence</a></td>
<td>
</td>
</tr>
<tr>
<td>
<a href="net.corda.node.services.schema/index.html">net.corda.node.services.schema</a></td>
<td>
</td>
</tr>
<tr>
<td>
<a href="net.corda.node.services.statemachine/index.html">net.corda.node.services.statemachine</a></td>
<td>
</td>
</tr>
<tr>
<td>
<a href="net.corda.node.services.transactions/index.html">net.corda.node.services.transactions</a></td>
<td>
</td>
</tr>
<tr>
<td>
<a href="net.corda.node.services.vault/index.html">net.corda.node.services.vault</a></td>
<td>
</td>
</tr>
<tr>
<td>
<a href="net.corda.node.servlets/index.html">net.corda.node.servlets</a></td>
<td>
</td>
</tr>
<tr>
<td>
<a href="net.corda.node.utilities/index.html">net.corda.node.utilities</a></td>
<td>
</td>
</tr>
<tr>
<td>
<a href="net.corda.node.utilities.certsigning/index.html">net.corda.node.utilities.certsigning</a></td>
<td>
</td>
</tr>
<tr>
<td>
<a href="net.corda.schemas/index.html">net.corda.schemas</a></td>
<td>
</td>
</tr>
</tbody>
</table>
<h3>Index</h3>
<a href="alltypes/index.html">All Types</a></BODY>
</HTML>

View File

@ -2,10 +2,10 @@
<!-- NewPage -->
<html lang="en">
<head>
<!-- Generated by javadoc (1.8.0_102) on Wed Jan 18 13:37:15 CET 2017 -->
<!-- Generated by javadoc (1.8.0_102) on Thu Jan 19 18:07:20 CET 2017 -->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>All Classes</title>
<meta name="date" content="2017-01-18">
<meta name="date" content="2017-01-19">
<link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style">
<script type="text/javascript" src="script.js"></script>
</head>

View File

@ -2,10 +2,10 @@
<!-- NewPage -->
<html lang="en">
<head>
<!-- Generated by javadoc (1.8.0_102) on Wed Jan 18 13:37:15 CET 2017 -->
<!-- Generated by javadoc (1.8.0_102) on Thu Jan 19 18:07:20 CET 2017 -->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>All Classes</title>
<meta name="date" content="2017-01-18">
<meta name="date" content="2017-01-19">
<link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style">
<script type="text/javascript" src="script.js"></script>
</head>

View File

@ -2,10 +2,10 @@
<!-- NewPage -->
<html lang="en">
<head>
<!-- Generated by javadoc (1.8.0_102) on Wed Jan 18 13:37:06 CET 2017 -->
<!-- Generated by javadoc (1.8.0_102) on Thu Jan 19 18:07:12 CET 2017 -->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Constant Field Values</title>
<meta name="date" content="2017-01-18">
<meta name="date" content="2017-01-19">
<link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style">
<script type="text/javascript" src="script.js"></script>
</head>

View File

@ -2,10 +2,10 @@
<!-- NewPage -->
<html lang="en">
<head>
<!-- Generated by javadoc (1.8.0_102) on Wed Jan 18 13:37:15 CET 2017 -->
<!-- Generated by javadoc (1.8.0_102) on Thu Jan 19 18:07:20 CET 2017 -->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Deprecated List</title>
<meta name="date" content="2017-01-18">
<meta name="date" content="2017-01-19">
<link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style">
<script type="text/javascript" src="script.js"></script>
</head>

View File

@ -2,10 +2,10 @@
<!-- NewPage -->
<html lang="en">
<head>
<!-- Generated by javadoc (1.8.0_102) on Wed Jan 18 13:37:15 CET 2017 -->
<!-- Generated by javadoc (1.8.0_102) on Thu Jan 19 18:07:20 CET 2017 -->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>API Help</title>
<meta name="date" content="2017-01-18">
<meta name="date" content="2017-01-19">
<link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style">
<script type="text/javascript" src="script.js"></script>
</head>

View File

@ -2,10 +2,10 @@
<!-- NewPage -->
<html lang="en">
<head>
<!-- Generated by javadoc (1.8.0_102) on Wed Jan 18 13:37:15 CET 2017 -->
<!-- Generated by javadoc (1.8.0_102) on Thu Jan 19 18:07:19 CET 2017 -->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Index</title>
<meta name="date" content="2017-01-18">
<meta name="date" content="2017-01-19">
<link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style">
<script type="text/javascript" src="script.js"></script>
</head>

View File

@ -2,7 +2,7 @@
<!-- NewPage -->
<html lang="en">
<head>
<!-- Generated by javadoc (1.8.0_102) on Wed Jan 18 13:37:15 CET 2017 -->
<!-- Generated by javadoc (1.8.0_102) on Thu Jan 19 18:07:20 CET 2017 -->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Generated Documentation (Untitled)</title>
<script type="text/javascript">

View File

@ -2,10 +2,10 @@
<!-- NewPage -->
<html lang="en">
<head>
<!-- Generated by javadoc (1.8.0_102) on Wed Jan 18 13:36:54 CET 2017 -->
<!-- Generated by javadoc (1.8.0_102) on Thu Jan 19 18:07:01 CET 2017 -->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>AggregatedList</title>
<meta name="date" content="2017-01-18">
<meta name="date" content="2017-01-19">
<meta name="keywords" content="net.corda.client.fxutils.AggregatedList class">
<meta name="keywords" content="get()">
<meta name="keywords" content="getSourceIndex()">

View File

@ -2,10 +2,10 @@
<!-- NewPage -->
<html lang="en">
<head>
<!-- Generated by javadoc (1.8.0_102) on Wed Jan 18 13:36:54 CET 2017 -->
<!-- Generated by javadoc (1.8.0_102) on Thu Jan 19 18:07:01 CET 2017 -->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>AmountBindings</title>
<meta name="date" content="2017-01-18">
<meta name="date" content="2017-01-19">
<meta name="keywords" content="net.corda.client.fxutils.AmountBindings class">
<meta name="keywords" content="INSTANCE">
<meta name="keywords" content="sum()">

View File

@ -2,10 +2,10 @@
<!-- NewPage -->
<html lang="en">
<head>
<!-- Generated by javadoc (1.8.0_102) on Wed Jan 18 13:36:55 CET 2017 -->
<!-- Generated by javadoc (1.8.0_102) on Thu Jan 19 18:07:01 CET 2017 -->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>AssociatedList</title>
<meta name="date" content="2017-01-18">
<meta name="date" content="2017-01-19">
<meta name="keywords" content="net.corda.client.fxutils.AssociatedList class">
<meta name="keywords" content="getSourceList()">
<link rel="stylesheet" type="text/css" href="../../../../stylesheet.css" title="Style">

View File

@ -2,10 +2,10 @@
<!-- NewPage -->
<html lang="en">
<head>
<!-- Generated by javadoc (1.8.0_102) on Wed Jan 18 13:36:55 CET 2017 -->
<!-- Generated by javadoc (1.8.0_102) on Thu Jan 19 18:07:01 CET 2017 -->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>ChosenList</title>
<meta name="date" content="2017-01-18">
<meta name="date" content="2017-01-19">
<meta name="keywords" content="net.corda.client.fxutils.ChosenList class">
<meta name="keywords" content="get()">
<meta name="keywords" content="getSize()">

View File

@ -2,10 +2,10 @@
<!-- NewPage -->
<html lang="en">
<head>
<!-- Generated by javadoc (1.8.0_102) on Wed Jan 18 13:36:55 CET 2017 -->
<!-- Generated by javadoc (1.8.0_102) on Thu Jan 19 18:07:01 CET 2017 -->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>ConcatenatedList</title>
<meta name="date" content="2017-01-18">
<meta name="date" content="2017-01-19">
<meta name="keywords" content="net.corda.client.fxutils.ConcatenatedList class">
<meta name="keywords" content="sourceChanged()">
<meta name="keywords" content="getSize()">

View File

@ -2,10 +2,10 @@
<!-- NewPage -->
<html lang="en">
<head>
<!-- Generated by javadoc (1.8.0_102) on Wed Jan 18 13:36:55 CET 2017 -->
<!-- Generated by javadoc (1.8.0_102) on Thu Jan 19 18:07:01 CET 2017 -->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>FlattenedList.WrappedObservableValue</title>
<meta name="date" content="2017-01-18">
<meta name="date" content="2017-01-19">
<meta name="keywords" content="net.corda.client.fxutils.FlattenedList.WrappedObservableValue class">
<meta name="keywords" content="getObservableValue()">
<link rel="stylesheet" type="text/css" href="../../../../stylesheet.css" title="Style">

View File

@ -2,10 +2,10 @@
<!-- NewPage -->
<html lang="en">
<head>
<!-- Generated by javadoc (1.8.0_102) on Wed Jan 18 13:36:55 CET 2017 -->
<!-- Generated by javadoc (1.8.0_102) on Thu Jan 19 18:07:01 CET 2017 -->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>FlattenedList</title>
<meta name="date" content="2017-01-18">
<meta name="date" content="2017-01-19">
<meta name="keywords" content="net.corda.client.fxutils.FlattenedList class">
<meta name="keywords" content="getIndexMap()">
<meta name="keywords" content="sourceChanged()">

View File

@ -2,10 +2,10 @@
<!-- NewPage -->
<html lang="en">
<head>
<!-- Generated by javadoc (1.8.0_102) on Wed Jan 18 13:36:55 CET 2017 -->
<!-- Generated by javadoc (1.8.0_102) on Thu Jan 19 18:07:01 CET 2017 -->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>LeftOuterJoinedMap</title>
<meta name="date" content="2017-01-18">
<meta name="date" content="2017-01-19">
<meta name="keywords" content="net.corda.client.fxutils.LeftOuterJoinedMap class">
<meta name="keywords" content="getLeftTable()">
<meta name="keywords" content="getRightTable()">

Some files were not shown because too many files have changed in this diff Show More