mirror of
https://github.com/corda/corda.git
synced 2025-06-19 15:43:52 +00:00
Merge pull request #352 from corda/colljos-merge-release3-dp-master
Merge from R3 Corda 3.0 Dev Preview release branch to master
This commit is contained in:
10
build.gradle
10
build.gradle
@ -4,7 +4,9 @@ buildscript {
|
|||||||
file("$projectDir/constants.properties").withInputStream { constants.load(it) }
|
file("$projectDir/constants.properties").withInputStream { constants.load(it) }
|
||||||
|
|
||||||
// Our version: bump this on release.
|
// Our version: bump this on release.
|
||||||
ext.corda_release_version = "3.0-ENT-snapshot"
|
ext.corda_release_version = "R3.CORDA-3.0-SNAPSHOT" // "CORDA-3.0-SNAPSHOT" for Corda (Open Source)
|
||||||
|
ext.corda_release_distribution = "com.r3.corda" // "net.corda" for Corda (Open Source)
|
||||||
|
|
||||||
// Increment this on any release that changes public APIs anywhere in the Corda platform
|
// Increment this on any release that changes public APIs anywhere in the Corda platform
|
||||||
ext.corda_platform_version = constants.getProperty("platformVersion")
|
ext.corda_platform_version = constants.getProperty("platformVersion")
|
||||||
ext.gradle_plugins_version = constants.getProperty("gradlePluginsVersion")
|
ext.gradle_plugins_version = constants.getProperty("gradlePluginsVersion")
|
||||||
@ -154,7 +156,7 @@ allprojects {
|
|||||||
attributes('Corda-Release-Version': corda_release_version)
|
attributes('Corda-Release-Version': corda_release_version)
|
||||||
attributes('Corda-Platform-Version': corda_platform_version)
|
attributes('Corda-Platform-Version': corda_platform_version)
|
||||||
attributes('Corda-Revision': corda_revision)
|
attributes('Corda-Revision': corda_revision)
|
||||||
attributes('Corda-Vendor': 'Corda Enterprise Edition')
|
attributes('Corda-Vendor': 'R3 Corda Edition')
|
||||||
attributes('Automatic-Module-Name': "net.corda.${task.project.name.replaceAll('-', '.')}")
|
attributes('Automatic-Module-Name': "net.corda.${task.project.name.replaceAll('-', '.')}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -191,7 +193,7 @@ allprojects {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
group 'com.r3.corda.enterprise'
|
group 'com.r3.corda'
|
||||||
version "$corda_release_version"
|
version "$corda_release_version"
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
@ -301,7 +303,7 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// User and key are commented out to prevent accidental pushes of Enterprise to public repos. DO NOT UNCOMMENT.
|
// User and key are commented out to prevent accidental pushes of R3 Corda to public repos. DO NOT UNCOMMENT.
|
||||||
bintrayConfig {
|
bintrayConfig {
|
||||||
// user = System.getenv('CORDA_BINTRAY_USER')
|
// user = System.getenv('CORDA_BINTRAY_USER')
|
||||||
// key = System.getenv('CORDA_BINTRAY_KEY')
|
// key = System.getenv('CORDA_BINTRAY_KEY')
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
gradlePluginsVersion=3.0.3
|
gradlePluginsVersion=3.0.3
|
||||||
kotlinVersion=1.1.60
|
kotlinVersion=1.1.60
|
||||||
platformVersion=1
|
platformVersion=3
|
||||||
guavaVersion=21.0
|
guavaVersion=21.0
|
||||||
bouncycastleVersion=1.57
|
bouncycastleVersion=1.57
|
||||||
typesafeConfigVersion=1.3.1
|
typesafeConfigVersion=1.3.1
|
||||||
|
@ -47,7 +47,8 @@ sealed class ByteSequence : Comparable<ByteSequence> {
|
|||||||
fun open() = ByteArrayInputStream(_bytes, offset, size)
|
fun open() = ByteArrayInputStream(_bytes, offset, size)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a sub-sequence backed by the same array.
|
* Create a sub-sequence of this sequence. A copy of the underlying array may be made, if a subclass overrides
|
||||||
|
* [bytes] to do so, as [OpaqueBytes] does.
|
||||||
*
|
*
|
||||||
* @param offset The offset within this sequence to start the new sequence. Note: not the offset within the backing array.
|
* @param offset The offset within this sequence to start the new sequence. Note: not the offset within the backing array.
|
||||||
* @param size The size of the intended sub sequence.
|
* @param size The size of the intended sub sequence.
|
||||||
@ -55,7 +56,8 @@ sealed class ByteSequence : Comparable<ByteSequence> {
|
|||||||
fun subSequence(offset: Int, size: Int): ByteSequence {
|
fun subSequence(offset: Int, size: Int): ByteSequence {
|
||||||
require(offset >= 0)
|
require(offset >= 0)
|
||||||
require(offset + size <= this.size)
|
require(offset + size <= this.size)
|
||||||
// Intentionally use bytes rather than _bytes, to mirror the copy-or-not behaviour of that property.
|
// Intentionally use bytes rather than _bytes, in case a subclass wants to prevent access to the original
|
||||||
|
// underlying array which could be revealed here (e.g. OpaqueBytes).
|
||||||
return if (offset == 0 && size == this.size) this else of(bytes, this.offset + offset, size)
|
return if (offset == 0 && size == this.size) this else of(bytes, this.offset + offset, size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,14 +1,3 @@
|
|||||||
{
|
{
|
||||||
"https://docs.corda.net/releases/release-M6.0": "M6.0",
|
"https://docs.corda.r3.com/releases/release-V3.0": "V3.0"
|
||||||
"https://docs.corda.net/releases/release-M7.0": "M7.0",
|
|
||||||
"https://docs.corda.net/releases/release-M8.2": "M8.2",
|
|
||||||
"https://docs.corda.net/releases/release-M9.2": "M9.2",
|
|
||||||
"https://docs.corda.net/releases/release-M10.1": "M10.1",
|
|
||||||
"https://docs.corda.net/releases/release-M11.2": "M11.2",
|
|
||||||
"https://docs.corda.net/releases/release-M12.1": "M12.1",
|
|
||||||
"https://docs.corda.net/releases/release-M13.0": "M13.0",
|
|
||||||
"https://docs.corda.net/releases/release-M14.0": "M14.0",
|
|
||||||
"https://docs.corda.net/releases/release-V1.0": "V1.0",
|
|
||||||
"https://docs.corda.net/releases/release-V2.0": "V2.0",
|
|
||||||
"https://docs.corda.net/head/": "Master"
|
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ API reference: <a href="api/kotlin/corda/index.html">Kotlin</a>/ <a href="api/ja
|
|||||||
{% block footer %}
|
{% block footer %}
|
||||||
<script>
|
<script>
|
||||||
// A synchronous request to retrieve all the Corda versions.
|
// A synchronous request to retrieve all the Corda versions.
|
||||||
$.getJSON("https://docs.corda.net/_static/versions", function(data) {
|
$.getJSON("https://docs.corda.r3.com/_static/versions", function(data) {
|
||||||
// Grab the current version.
|
// Grab the current version.
|
||||||
var version = $("#version").html();
|
var version = $("#version").html();
|
||||||
|
|
||||||
|
@ -145,6 +145,8 @@ which is then referenced within a custom flow:
|
|||||||
:start-after: DOCSTART TopupIssuer
|
:start-after: DOCSTART TopupIssuer
|
||||||
:end-before: DOCEND TopupIssuer
|
:end-before: DOCEND TopupIssuer
|
||||||
|
|
||||||
|
.. _database_migration_ref:
|
||||||
|
|
||||||
Database Migration
|
Database Migration
|
||||||
==================
|
==================
|
||||||
|
|
||||||
@ -232,7 +234,7 @@ Usage:
|
|||||||
Configurations:
|
Configurations:
|
||||||
|
|
||||||
- To enable migration at startup, set:
|
- To enable migration at startup, set:
|
||||||
- database.runMigration = true // false by default,
|
- ``database.runMigration = true`` // false by default,
|
||||||
|
|
||||||
Command line arguments:
|
Command line arguments:
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -18,6 +18,8 @@ an ongoing stream of updates from the node. More detail on how to use this is pr
|
|||||||
|
|
||||||
For a brief tutorial on how one can use the RPC API see :doc:`tutorial-clientrpc-api`.
|
For a brief tutorial on how one can use the RPC API see :doc:`tutorial-clientrpc-api`.
|
||||||
|
|
||||||
|
.. _rpc_security_mgmt_ref:
|
||||||
|
|
||||||
RPC permissions
|
RPC permissions
|
||||||
---------------
|
---------------
|
||||||
If a node's owner needs to interact with their node via RPC (e.g. to read the contents of the node's storage), they
|
If a node's owner needs to interact with their node via RPC (e.g. to read the contents of the node's storage), they
|
||||||
@ -68,6 +70,8 @@ Fine grained permissions allow a user to invoke a specific RPC operation, or to
|
|||||||
- to invoke a RPC operation: ``InvokeRpc.<rpc method name>`` e.g., ``InvokeRpc.nodeInfo``.
|
- to invoke a RPC operation: ``InvokeRpc.<rpc method name>`` e.g., ``InvokeRpc.nodeInfo``.
|
||||||
.. note:: Permission ``InvokeRpc.startFlow`` allows a user to initiate all flows.
|
.. note:: Permission ``InvokeRpc.startFlow`` allows a user to initiate all flows.
|
||||||
|
|
||||||
|
.. _authentication_ref:
|
||||||
|
|
||||||
RPC security management
|
RPC security management
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
|
@ -68,15 +68,7 @@ path to the node's base directory.
|
|||||||
|
|
||||||
.. note:: Longer term these keys will be managed in secure hardware devices.
|
.. note:: Longer term these keys will be managed in secure hardware devices.
|
||||||
|
|
||||||
:database: Database configuration:
|
.. _database_properties_ref:
|
||||||
|
|
||||||
:transactionIsolationLevel: Transaction isolation level as defined by the ``TRANSACTION_`` constants in
|
|
||||||
``java.sql.Connection``, but without the "TRANSACTION_" prefix. Defaults to REPEATABLE_READ.
|
|
||||||
:exportHibernateJMXStatistics: Whether to export Hibernate JMX statistics (caution: expensive run-time overhead)
|
|
||||||
|
|
||||||
: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.
|
|
||||||
|
|
||||||
:database: This section is used to configure JDBC and Hibernate related properties:
|
:database: This section is used to configure JDBC and Hibernate related properties:
|
||||||
|
|
||||||
@ -88,7 +80,11 @@ path to the node's base directory.
|
|||||||
:runMigration: Boolean on whether to run the database migration scripts. Defaults to true.
|
:runMigration: Boolean on whether to run the database migration scripts. Defaults to true.
|
||||||
|
|
||||||
:schema: (optional) some database providers require a schema name when generating DDL and SQL statements.
|
:schema: (optional) some database providers require a schema name when generating DDL and SQL statements.
|
||||||
(the value is passed to Hibernate property 'hibernate.hbm2ddl.auto').
|
(the value is passed to Hibernate property 'hibernate.default_schema').
|
||||||
|
|
||||||
|
: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.
|
||||||
|
|
||||||
:messagingServerAddress: The address of the ArtemisMQ broker instance. If not provided the node will run one locally.
|
:messagingServerAddress: The address of the ArtemisMQ broker instance. If not provided the node will run one locally.
|
||||||
|
|
||||||
@ -196,5 +192,7 @@ path to the node's base directory.
|
|||||||
:exportJMXTo: If set to ``http``, will enable JMX metrics reporting via the Jolokia HTTP/JSON agent.
|
:exportJMXTo: If set to ``http``, will enable JMX metrics reporting via the Jolokia HTTP/JSON agent.
|
||||||
Default Jolokia access url is http://127.0.0.1:7005/jolokia/
|
Default Jolokia access url is http://127.0.0.1:7005/jolokia/
|
||||||
|
|
||||||
|
.. _config_amqp_bridge:
|
||||||
|
|
||||||
:useAMQPBridges: Optionally can be set to ``false`` to use Artemis CORE Bridges for peer-to-peer communications.
|
:useAMQPBridges: Optionally can be set to ``false`` to use Artemis CORE Bridges for peer-to-peer communications.
|
||||||
Otherwise, defaults to ``true`` and the AMQP 1.0 protocol will be used for message transfer between nodes.
|
Otherwise, defaults to ``true`` and the AMQP 1.0 protocol will be used for message transfer between nodes.
|
@ -28,14 +28,12 @@ Setting your dependencies
|
|||||||
|
|
||||||
Choosing your Corda version
|
Choosing your Corda version
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
``ext.corda_release_version`` and ``ext.corda_gradle_plugins_version`` are used in the ``build.gradle`` to define the
|
The following three lines of the ``build.gradle`` file define the Corda version and distribution used to build your CorDapp:
|
||||||
versions of Corda and the Corda Gradle Plugins that are used to build your CorDapp.
|
|
||||||
|
|
||||||
For example, to use version 1.0 of Corda and version 1.0 of the Corda gradle plugins, you'd write:
|
|
||||||
|
|
||||||
.. sourcecode:: groovy
|
.. sourcecode:: groovy
|
||||||
|
|
||||||
ext.corda_release_version = '1.0.0'
|
ext.corda_release_version = '1.0.0'
|
||||||
|
ext.corda_release_distribution = 'net.corda'
|
||||||
ext.corda_gradle_plugins_version = '1.0.0'
|
ext.corda_gradle_plugins_version = '1.0.0'
|
||||||
|
|
||||||
You can find the latest published version of both here: https://bintray.com/r3/corda.
|
You can find the latest published version of both here: https://bintray.com/r3/corda.
|
||||||
@ -94,21 +92,21 @@ is already correctly configured and this is for reference only;
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
// Corda integration dependencies
|
// Corda integration dependencies
|
||||||
cordaCompile "net.corda:corda-core:$corda_release_version"
|
cordaCompile "$corda_release_distribution:corda-core:$corda_release_version"
|
||||||
cordaCompile "net.corda:corda-finance:$corda_release_version"
|
cordaCompile "$corda_release_distribution:corda-finance:$corda_release_version"
|
||||||
cordaCompile "net.corda:corda-jackson:$corda_release_version"
|
cordaCompile "$corda_release_distribution:corda-jackson:$corda_release_version"
|
||||||
cordaCompile "net.corda:corda-rpc:$corda_release_version"
|
cordaCompile "$corda_release_distribution:corda-rpc:$corda_release_version"
|
||||||
cordaCompile "net.corda:corda-node-api:$corda_release_version"
|
cordaCompile "$corda_release_distribution:corda-node-api:$corda_release_version"
|
||||||
cordaCompile "net.corda:corda-webserver-impl:$corda_release_version"
|
cordaCompile "$corda_release_distribution:corda-webserver-impl:$corda_release_version"
|
||||||
cordaRuntime "net.corda:corda:$corda_release_version"
|
cordaRuntime "$corda_release_distribution:corda:$corda_release_version"
|
||||||
cordaRuntime "net.corda:corda-webserver:$corda_release_version"
|
cordaRuntime "$corda_release_distribution:corda-webserver:$corda_release_version"
|
||||||
testCompile "net.corda:corda-test-utils:$corda_release_version"
|
testCompile "$corda_release_distribution:corda-test-utils:$corda_release_version"
|
||||||
|
|
||||||
// Corda Plugins: dependent flows and services
|
// Corda Plugins: dependent flows and services
|
||||||
// Identifying a CorDapp by its module in the same project.
|
// Identifying a CorDapp by its module in the same project.
|
||||||
cordapp project(":cordapp-contracts-states")
|
cordapp project(":cordapp-contracts-states")
|
||||||
// Identifying a CorDapp by its fully-qualified name.
|
// Identifying a CorDapp by its fully-qualified name.
|
||||||
cordapp "net.corda:bank-of-corda-demo:1.0"
|
cordapp "$corda_release_distribution:bank-of-corda-demo:1.0"
|
||||||
|
|
||||||
// Some other dependencies
|
// Some other dependencies
|
||||||
compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version"
|
compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version"
|
||||||
|
@ -88,7 +88,7 @@ nodes. Here is an example ``Cordform`` task called ``deployNodes`` that creates
|
|||||||
// No webport property, so no webserver will be created.
|
// No webport property, so no webserver will be created.
|
||||||
h2Port 10004
|
h2Port 10004
|
||||||
// Includes the corda-finance CorDapp on our node.
|
// Includes the corda-finance CorDapp on our node.
|
||||||
cordapps = ["net.corda:corda-finance:$corda_release_version"]
|
cordapps = ["$corda_release_distribution:corda-finance:$corda_release_version"]
|
||||||
}
|
}
|
||||||
node {
|
node {
|
||||||
name "O=PartyA,L=London,C=GB"
|
name "O=PartyA,L=London,C=GB"
|
||||||
@ -96,7 +96,7 @@ nodes. Here is an example ``Cordform`` task called ``deployNodes`` that creates
|
|||||||
rpcPort 10006
|
rpcPort 10006
|
||||||
webPort 10007
|
webPort 10007
|
||||||
h2Port 10008
|
h2Port 10008
|
||||||
cordapps = ["net.corda:corda-finance:$corda_release_version"]
|
cordapps = ["$corda_release_distribution:corda-finance:$corda_release_version"]
|
||||||
// Grants user1 all RPC permissions.
|
// Grants user1 all RPC permissions.
|
||||||
rpcUsers = [[ user: "user1", "password": "test", "permissions": ["ALL"]]]
|
rpcUsers = [[ user: "user1", "password": "test", "permissions": ["ALL"]]]
|
||||||
}
|
}
|
||||||
@ -106,7 +106,7 @@ nodes. Here is an example ``Cordform`` task called ``deployNodes`` that creates
|
|||||||
rpcPort 10010
|
rpcPort 10010
|
||||||
webPort 10011
|
webPort 10011
|
||||||
h2Port 10012
|
h2Port 10012
|
||||||
cordapps = ["net.corda:corda-finance:$corda_release_version"]
|
cordapps = ["$corda_release_distribution:corda-finance:$corda_release_version"]
|
||||||
// Grants user1 the ability to start the MyFlow flow.
|
// Grants user1 the ability to start the MyFlow flow.
|
||||||
rpcUsers = [[ user: "user1", "password": "test", "permissions": ["StartFlow.net.corda.flows.MyFlow"]]]
|
rpcUsers = [[ user: "user1", "password": "test", "permissions": ["StartFlow.net.corda.flows.MyFlow"]]]
|
||||||
}
|
}
|
||||||
|
@ -25,14 +25,14 @@ service.
|
|||||||
notary = [validating : true]
|
notary = [validating : true]
|
||||||
p2pPort 10002
|
p2pPort 10002
|
||||||
rpcPort 10003
|
rpcPort 10003
|
||||||
cordapps = ["net.corda:corda-finance:$corda_release_version"]
|
cordapps = ["$corda_release_distribution:corda-finance:$corda_release_version"]
|
||||||
}
|
}
|
||||||
node {
|
node {
|
||||||
name "O=PartyA,L=London,C=GB"
|
name "O=PartyA,L=London,C=GB"
|
||||||
p2pPort 10005
|
p2pPort 10005
|
||||||
rpcPort 10006
|
rpcPort 10006
|
||||||
webPort 10007
|
webPort 10007
|
||||||
cordapps = ["net.corda:corda-finance:$corda_release_version"]
|
cordapps = ["$corda_release_distribution:corda-finance:$corda_release_version"]
|
||||||
rpcUsers = [[ user: "user1", "password": "test", "permissions": ["ALL]]]
|
rpcUsers = [[ user: "user1", "password": "test", "permissions": ["ALL]]]
|
||||||
}
|
}
|
||||||
node {
|
node {
|
||||||
@ -41,7 +41,7 @@ service.
|
|||||||
rpcPort 10009
|
rpcPort 10009
|
||||||
webPort 10010
|
webPort 10010
|
||||||
sshdPort 10024
|
sshdPort 10024
|
||||||
cordapps = ["net.corda:corda-finance:$corda_release_version"]
|
cordapps = ["$corda_release_distribution:corda-finance:$corda_release_version"]
|
||||||
rpcUsers = [[ user: "user1", "password": "test", "permissions": ["ALL"]]]
|
rpcUsers = [[ user: "user1", "password": "test", "permissions": ["ALL"]]]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,6 +73,8 @@ Any database browsing tool that supports JDBC can be used, but if you have Intel
|
|||||||
a tool integrated with your IDE. Just open the database window and add an H2 data source with the above details.
|
a tool integrated with your IDE. Just open the database window and add an H2 data source with the above details.
|
||||||
You will now be able to browse the tables and row data within them.
|
You will now be able to browse the tables and row data within them.
|
||||||
|
|
||||||
|
.. _jolokia_ref:
|
||||||
|
|
||||||
Monitoring your node
|
Monitoring your node
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
|
@ -34,12 +34,14 @@ Standalone database
|
|||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
To run a node against a remote database modify node JDBC connection properties in `dataSourceProperties` entry
|
To run a node against a remote database modify node JDBC connection properties in `dataSourceProperties` entry
|
||||||
and Hibernate properties in `database` entry - see `:ref:`dataSourceProperties`.
|
and Hibernate properties in `database` entry - see :ref:`Node configuration <database_properties_ref>`.
|
||||||
|
|
||||||
|
.. _sql_server_ref:
|
||||||
|
|
||||||
SQL Azure and SQL Server
|
SQL Azure and SQL Server
|
||||||
````````````````````````
|
````````````````````````
|
||||||
Corda supports SQL Server 2017 (14.0.3006.16) and Azure SQL (12.0.2000.8).
|
Corda supports SQL Server 2017 (14.0.3006.16) and Azure SQL (12.0.2000.8).
|
||||||
The minimum transaction isolation level ``database.transactionIsolationLevel`` is 'readCommitted'.
|
The minimum transaction isolation level ``database.transactionIsolationLevel`` is 'READ_COMMITTED'.
|
||||||
The property ``database.schema`` is optional.
|
The property ``database.schema`` is optional.
|
||||||
Corda ships with Microsoft JDBC Driver 6.2 for SQLServer out-of-the-box.
|
Corda ships with Microsoft JDBC Driver 6.2 for SQLServer out-of-the-box.
|
||||||
|
|
||||||
@ -55,15 +57,19 @@ dataSourceProperties {
|
|||||||
dataSourceProperties.dataSource.password = [PASSWORD]
|
dataSourceProperties.dataSource.password = [PASSWORD]
|
||||||
}
|
}
|
||||||
database {
|
database {
|
||||||
transactionIsolationLevel = "readCommitted"
|
transactionIsolationLevel = READ_COMMITTED
|
||||||
schema = [SCHEMA]
|
schema = [SCHEMA]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.. _postgres_ref:
|
||||||
|
|
||||||
PostgreSQL
|
PostgreSQL
|
||||||
````````````````````````
|
````````````````````````
|
||||||
Corda supports PostgreSQL 9.6 database.
|
|
||||||
The property ``database.schema`` is optional. The value of ``database.schema`` is automatically wrapped in double quotes
|
Corda supports PostgreSQL 9.6 database preliminarily.
|
||||||
to preserve case-sensitivity (e.g. `AliceCorp` becomes `"AliceCorp"`, without quotes PostgresSQL would treat the value as `alicecorp`).
|
The property ``database.schema`` is optional. Currently only lowercase value is supported,
|
||||||
|
please ensure your database setup uses lowercase schema names (Corda sends an unquoted schema name
|
||||||
|
and PostgresSQL interprets the value as a lowercase one e.g. `AliceCorp` becomes `alicecorp`).
|
||||||
Corda ships with PostgreSQL JDBC Driver 42.1.4 out-of-the-box.
|
Corda ships with PostgreSQL JDBC Driver 42.1.4 out-of-the-box.
|
||||||
|
|
||||||
Example node configuration for PostgreSQL:
|
Example node configuration for PostgreSQL:
|
||||||
|
@ -29,7 +29,7 @@ parties on the network or to exit cash (for itself only).
|
|||||||
|
|
||||||
When connected to a *Participant* node a user can only execute cash transaction commands to move cash to other parties on the network.
|
When connected to a *Participant* node a user can only execute cash transaction commands to move cash to other parties on the network.
|
||||||
|
|
||||||
The Demo Nodes can be started in one of two modes:
|
The Demo Nodes can be started in one of three modes:
|
||||||
|
|
||||||
1. Normal
|
1. Normal
|
||||||
|
|
||||||
@ -60,14 +60,30 @@ The Demo Nodes can be started in one of two modes:
|
|||||||
|
|
||||||
./gradlew tools:explorer:runSimulationNodes
|
./gradlew tools:explorer:runSimulationNodes
|
||||||
|
|
||||||
|
.. _flow_triage:
|
||||||
|
|
||||||
|
3. Flow triage
|
||||||
|
|
||||||
|
Once again, building on the demonstration Corda network topology described above, this scenario mode triggers
|
||||||
|
an exception within a flow which can then be visualized using the "Flow Triage" panel within the Explorer.
|
||||||
|
The "Flow Triage" panel will be enhanced in the future to enable operators to take corrective actions upon flow failures
|
||||||
|
(eg. retry, terminate, amend and replay)
|
||||||
|
|
||||||
|
**Windows:**
|
||||||
|
|
||||||
|
gradlew.bat tools:explorer:runFlowTriageNodes
|
||||||
|
|
||||||
|
**Other:**
|
||||||
|
|
||||||
|
./gradlew tools:explorer:runFlowTriageNodes
|
||||||
|
|
||||||
.. note:: 5 Corda nodes will be created on the following port on localhost by default.
|
.. note:: 5 Corda nodes will be created on the following port on localhost by default.
|
||||||
|
|
||||||
* Notary -> 20003 (Does not accept logins)
|
* Notary -> 20001 (Does not accept logins)
|
||||||
* Alice -> 20006
|
* Alice -> 20004
|
||||||
* Bob -> 20009
|
* Bob -> 20007
|
||||||
* UK Bank Plc -> 20012 (*Issuer node*)
|
* UK Bank Plc -> 20010 (*Issuer node*)
|
||||||
* USA Bank Corp -> 20015 (*Issuer node*)
|
* USA Bank Corp -> 20013 (*Issuer node*)
|
||||||
|
|
||||||
Explorer login credentials to the Issuer nodes are defaulted to ``manager`` and ``test``.
|
Explorer login credentials to the Issuer nodes are defaulted to ``manager`` and ``test``.
|
||||||
Explorer login credentials to the Participants nodes are defaulted to ``user1`` and ``test``.
|
Explorer login credentials to the Participants nodes are defaulted to ``user1`` and ``test``.
|
||||||
|
@ -1,14 +1,8 @@
|
|||||||
Release notes
|
Release notes
|
||||||
=============
|
=============
|
||||||
|
|
||||||
Here are release notes for each snapshot release from M9 onwards.
|
|
||||||
|
|
||||||
Unreleased
|
Unreleased
|
||||||
----------
|
----------
|
||||||
* X.509 certificates now have an extension that specifies the Corda role the certificate is used for, and the role
|
|
||||||
hierarchy is now enforced in the validation code. This only has impact on those developing integrations with external
|
|
||||||
PKI solutions, in most cases it is managed transparently by Corda. A formal specification of the extension can be
|
|
||||||
found at see :doc:`permissioning-certificate-specification`.
|
|
||||||
|
|
||||||
* **Enum Class Evolution**
|
* **Enum Class Evolution**
|
||||||
With the addition of AMQP serialization Corda now supports enum constant evolution.
|
With the addition of AMQP serialization Corda now supports enum constant evolution.
|
||||||
@ -16,34 +10,162 @@ Unreleased
|
|||||||
That is the ability to alter an enum constant and, as long as certain rules are followed and the correct
|
That is the ability to alter an enum constant and, as long as certain rules are followed and the correct
|
||||||
annotations applied, have older and newer instances of that enumeration be understood.
|
annotations applied, have older and newer instances of that enumeration be understood.
|
||||||
|
|
||||||
* **AMQP Enabled**:
|
|
||||||
AMQP Serialization is now enabled for both peer to peer communication and the writing of states to the vault. This change
|
|
||||||
brings a stable format Corda can support internally throughout it's lifetime that meets the needs of Corda and our
|
|
||||||
users.
|
|
||||||
|
|
||||||
Details on the AMQP serialization framework can be found in the :doc:`serialization` document :ref:`here <amqp_ref>`.
|
R3 Corda 3.0 Developer Preview
|
||||||
This provides an introduction and overview of the framework whilst more specific details on object evolution as it relates to
|
------------------------------
|
||||||
serialization is similarly found in pages :doc:`serialization-default-evolution` and :doc:`serialization-enum-evolution`
|
This Developer Preview takes us towards the launch of R3 Corda, R3's commercially supported enterprise blockchain platform.
|
||||||
respectively. Recommendations on how best to code CorDapps using your own :ref:`custom types <amqp_custom_types_ref>`.
|
|
||||||
|
Whilst the recent major releases of **Corda** ("Open Source") - V1.0 and V2.0 - have focused on providing API stability and
|
||||||
|
functionality, **R3 Corda** has been primarily focused on non-functional aspects of the platform: performance, scalability,
|
||||||
|
robustness, security, configurability, manageability, supportability and upgradeability.
|
||||||
|
|
||||||
|
Here is a summary of some of the key new features in this preview, many of which will also appear in the next open
|
||||||
|
source release:
|
||||||
|
|
||||||
|
- support for :ref:`Azure SQL and SQL Server 2017 <sql_server_ref>` databases.
|
||||||
|
- integrated :ref:`database schema management <database_migration_ref>` tooling using `Liquibase <http://www.liquibase.org/>`_
|
||||||
|
- completely re-designed :doc:`network-map` Service.
|
||||||
|
- enabled :ref:`AMQP serialization <amqp_ref>` for peer to peer messaging, and vault transaction storage.
|
||||||
|
- pluggable :ref:`user authentication <authentication_ref>` and :ref:`fine-grained access control <rpc_security_mgmt_ref>`.
|
||||||
|
- re-designed Flow Framework manager in preparation for fully multi-threaded implementation.
|
||||||
|
- improvements to the Doorman certificate issuance process (including integration with HSMs).
|
||||||
|
- additional JMX metrics exported via :ref:`Jolokia for monitoring <jolokia_ref>` and pro-active alert management.
|
||||||
|
- a secure, remotely accessible, :ref:`SSH server <ssh_server>` in the node with built-in authorization and permissioning to enable remote
|
||||||
|
node administration without requiring console access to the underlying operating system.
|
||||||
|
- re-architected and re-designed Corda bridge management for secure P2P connectivity between participants.
|
||||||
|
- enhanced Explorer tool with new :ref:`flow triage <flow_triage>` user interface panel to visualize all currently running flows.
|
||||||
|
- preliminary implementation of Business Networks concept (a private sub group within a Corda Compatibility Zone).
|
||||||
|
|
||||||
|
We also continue to make improvements in usability of our Test Framework APIs in preparation for declaring the test
|
||||||
|
framework API stable (in addition to the already-stabilised core APIs).
|
||||||
|
|
||||||
|
Significant changes implemented in reaching this Developer Preview include:
|
||||||
|
|
||||||
|
* **AMQP**:
|
||||||
|
AMQP Serialization is now enabled for both peer to peer communication and the writing of states to the vault. This
|
||||||
|
change brings a serialisation format that will allow us to deliver enhanced security and wire stability. It is a key
|
||||||
|
prerequisite to enabling different Corda node versions to coexist on the same network and to enable easier upgrades.
|
||||||
|
|
||||||
|
Details on the AMQP serialization framework can be found :ref:`here <amqp_ref>`. This provides an introduction and
|
||||||
|
overview of the framework whilst more specific details on object evolution as it relates to serialization is similarly
|
||||||
|
found in :doc:`serialization-default-evolution` and :doc:`serialization-enum-evolution` respectively.
|
||||||
|
|
||||||
.. note:: This release delivers the bulk of our transition from Kryo serialisation to AMQP serialisation. This means that many of the restrictions
|
.. note:: This release delivers the bulk of our transition from Kryo serialisation to AMQP serialisation. This means that many of the restrictions
|
||||||
that were documented in previous versions of Corda are now enforced. (https://docs.corda.net/releases/release-V1.0/serialization.html).
|
that were documented in previous versions of Corda are now enforced.
|
||||||
|
|
||||||
In particular, you are advised to review the section titled "Custom Types". To aid with the transition, we have included support
|
In particular, you are advised to review the section titled :ref:`Custom Types <amqp_custom_types_ref>`.
|
||||||
in this release for default construction of objects and their instantiation through getters as well as objects with inaccessible
|
To aid with the transition, we have included support in this release for default construction and instantiation of
|
||||||
private fields but it is not guaranteed that this support will continue into future versions; the restrictions documented at the
|
objects with inaccessible private fields, but it is not guaranteed that this support will continue into future versions;
|
||||||
link above are the canonical source.
|
the restrictions documented at the link above are the canonical source.
|
||||||
|
|
||||||
* **Custom Serializers**
|
* **New Network Map Service**:
|
||||||
|
This release introduces the new network map architecture. The network map service has been completely redesigned and
|
||||||
|
implemented to enable future increased network scalability and redundancy, reduced runtime operational overhead,
|
||||||
|
support for multiple notaries, and administration of network compatibility zones (CZ) and business networks.
|
||||||
|
|
||||||
|
A Corda Compatibility Zone (CZ) is defined as a grouping of participants and services (notaries, oracles,
|
||||||
|
doorman, network map server) configured within an operational Corda network to be interoperable and compatible with
|
||||||
|
each other.
|
||||||
|
|
||||||
|
We introduce the concept of network parameters, which will be used in a future version of Corda to specify precisely
|
||||||
|
the set of constants (or ranges of constants) upon which a set of nodes need to agree in order to be assured of seamless
|
||||||
|
inter-operation. Additional security controls ensure that all network map data is now signed, thus reducing the power
|
||||||
|
of the network operator to tamper with the map.
|
||||||
|
|
||||||
|
This release also adds Hardware Security Module (HSM) support to the doorman service (certificate authority).
|
||||||
|
By integrating with external HSMs, we have further strengthened the security of issuing network certificates and
|
||||||
|
signing of network map related data.
|
||||||
|
|
||||||
|
Further information can be found in the :doc:`changelog` and :doc:`network-map` documentation.
|
||||||
|
|
||||||
|
* **Third party database support**:
|
||||||
|
R3 Corda has been tested against Azure SQL and SQL Server 2017 databases (in addition to the existing default support
|
||||||
|
of H2 for development mode). This preview adds preliminary support for :ref:`PostgreSQL 9.6 <postgres_ref>`.
|
||||||
|
Support for Oracle 11g RC02 and Oracle 12c is currently under development. All required database settings can be
|
||||||
|
specified in the node configuration file. For configuration details see :doc:`node-database`.
|
||||||
|
|
||||||
|
* **Integrated database migration tooling**:
|
||||||
|
We have adopted and integrated `Liquibase <http://www.liquibase.org/>`_ , an open source database-independent library
|
||||||
|
for tracking, managing and applying database schema changes in order to ease the evolution (creation and migration) of
|
||||||
|
CorDapp custom contract schemas and facilitate the operational administration of a Corda nodes database.
|
||||||
|
We provide tooling to export DDL and data (as SQL statements) to a file to be inspected and/or manually applied by a DBA.
|
||||||
|
Please see :ref:`database migration <database_migration_ref>` for further details.
|
||||||
|
|
||||||
|
* **Pluggable user authentication and fine-grained access control**:
|
||||||
|
All RPC functions are now subject to permission checks (previously these only applied when starting flows).
|
||||||
|
We have also included experimental support for external user credentials data source and password encryption using the
|
||||||
|
`Apache Shiro <https://shiro.apache.org>`_ framework. Please see :ref:`RPC security management <rpc_security_mgmt_ref>` for further details.
|
||||||
|
|
||||||
|
* **Preliminary preview of new bridge management functionality**:
|
||||||
|
The bridge manager component is responsible for dynamically establishing remote connectivity with participant nodes
|
||||||
|
in a Corda peer to peer network. A new Bridge manager has been designed and implemented to be used integrally
|
||||||
|
within a :ref:`Corda node <config_amqp_bridge>` or deployed (in the final R3 Corda 3.0 release) as a standalone component in DMZ operational deployments,
|
||||||
|
where security concerns require separation of infrastructure messaging subsystems.
|
||||||
|
|
||||||
|
* **Preliminary preview of flow triage functionality**:
|
||||||
|
The explorer GUI was extended with a panel similar to the ``flow watch`` CRaSH shell command. It provides users with a view of all
|
||||||
|
flows currently executed on the node, with information about success/failure. The "Flow Triage" panel will be enhanced in the future
|
||||||
|
to enable operators to take corrective actions upon flow failures (eg. retry, terminate, amend and replay).
|
||||||
|
|
||||||
|
* **Experimental preview of a new operational Corda network grouping concept: Business Networks**:
|
||||||
|
Business Networks are introduced as a way to partition the global population of nodes (a Compatibility Zone) into
|
||||||
|
independent, possibly overlapping, groups. A Business Network operator (BNO) will have control over which nodes will
|
||||||
|
be admitted into a Business Network. Some nodes may choose not to register themselves in the global Network Map, and
|
||||||
|
will therefore remain invisible to nodes outside of their Business Network. Further documentation will be forthcoming
|
||||||
|
by the final R3 Corda 3.0 release.
|
||||||
|
|
||||||
|
See the "Business Network reference implementation" prototype example in the Explorer tool (instructions in README.md).
|
||||||
|
|
||||||
|
In addition to enhancements focused on non-functional capabilities, this release encompasses a number of functional
|
||||||
|
improvements, including:
|
||||||
|
|
||||||
|
* Doorman Service
|
||||||
|
In order to automate a node's network joining process, a new Doorman service has been introduced with this release.
|
||||||
|
The Doorman's main purpose is to restrict network access only to those nodes whose identity has been confirmed and their network joining request approved.
|
||||||
|
It issues node-level certificates which are then used by other nodes in the network to confirm a nodes identity and network permissions.
|
||||||
|
More information on Doorman and how to run it can be found in :doc:`running-doorman`.
|
||||||
|
|
||||||
|
* Hardware Security Module (HSM) for Doorman
|
||||||
|
To allow for increased security, R3 Corda introduces HSM integration. Doorman certificates (together with their keys)
|
||||||
|
can now be stored on secured hardware constraining the way those certificates are accessed. Any usage of those certificates
|
||||||
|
(e.g. data signing or node-level certificate generation) falls into a restrictive process that is automatically audited
|
||||||
|
and can be configured to involve human-in-the-loop in order to prevent unauthorised access. The HSM integration is embodied
|
||||||
|
in our new Signing Service. More on this in :doc:`signing-service`.
|
||||||
|
|
||||||
|
* X.509 certificates now have an extension that specifies the Corda role the certificate is used for, and the role
|
||||||
|
hierarchy is now enforced in the validation code. This only has impact on those developing integrations with external
|
||||||
|
PKI solutions. In most cases it is managed transparently by Corda. A formal specification of the extension can be
|
||||||
|
found at see :doc:`permissioning-certificate-specification`.
|
||||||
|
|
||||||
|
* Custom Serializers
|
||||||
To allow interop with third party libraries that cannot be recompiled we add functionality that allows custom serializers
|
To allow interop with third party libraries that cannot be recompiled we add functionality that allows custom serializers
|
||||||
to be written for those classes. If needed, a proxy object can be created as an interim step that allows Corda's internal
|
to be written for those classes. If needed, a proxy object can be created as an interim step that allows Corda's internal
|
||||||
serializers to operate on those types.
|
serializers to operate on those types. A good example of this is the SIMM valuation demo which has a number of such
|
||||||
|
serializers defined in the plugin/custom serializers package
|
||||||
|
|
||||||
A good example of this is the SIMM valuation demo which has a number of such serializers defined in the plugin/customserializers package
|
Please refer to the :doc:`changelog` for detailed explanations of all new features.
|
||||||
|
|
||||||
Release 2.0
|
Finally, please note that although this developer preview has not yet been security audited, it is currently being subjected
|
||||||
----------
|
to a full external secure code review and penetration test.
|
||||||
|
|
||||||
|
As per previous major releases, we have provided a comprehensive upgrade notes (:doc:`upgrade-notes`) to ease the upgrade
|
||||||
|
of CorDapps to R3 Corda 3.0 Developer Preview. In line with our commitment to API stability, code level changes
|
||||||
|
are fairly minimal, and mostly related to improvements to our nearly API stable test framework.
|
||||||
|
|
||||||
|
From a build perspective, switching CorDapps built using Corda (the "Open Source" code) to R3 Corda is mostly effortless,
|
||||||
|
and simply requires setting two gradle build file variables:
|
||||||
|
|
||||||
|
.. sourcecode:: shell
|
||||||
|
|
||||||
|
ext.corda_release_version = 'R3.CORDA-3.0.0-DEV-PREVIEW'
|
||||||
|
ext.corda_release_distribution = 'com.r3.corda'
|
||||||
|
|
||||||
|
Please note this release is distributed under license and should not be used in a Production environment yet.
|
||||||
|
|
||||||
|
We look forward to hearing your feedback on this Developer Preview.
|
||||||
|
|
||||||
|
Corda 2.0
|
||||||
|
---------
|
||||||
Following quickly on the heels of the release of Corda 1.0, Corda version 2.0 consolidates
|
Following quickly on the heels of the release of Corda 1.0, Corda version 2.0 consolidates
|
||||||
a number of security updates for our dependent libraries alongside the reintroduction of the Observer node functionality.
|
a number of security updates for our dependent libraries alongside the reintroduction of the Observer node functionality.
|
||||||
This was absent from version 1 but based on user feedback its re-introduction removes the need for complicated "isRelevant()" checks.
|
This was absent from version 1 but based on user feedback its re-introduction removes the need for complicated "isRelevant()" checks.
|
||||||
@ -58,11 +180,11 @@ and via the versioning APIs.
|
|||||||
* **Observer Nodes**
|
* **Observer Nodes**
|
||||||
|
|
||||||
Adds the facility for transparent forwarding of transactions to some third party observer, such as a regulator. By having
|
Adds the facility for transparent forwarding of transactions to some third party observer, such as a regulator. By having
|
||||||
that entity simply run an Observer node they can simply recieve a stream of digitally signed, de-duplicated reports that
|
that entity simply run an Observer node they can simply receive a stream of digitally signed, de-duplicated reports that
|
||||||
can be used for reporting.
|
can be used for reporting.
|
||||||
|
|
||||||
Release 1.0
|
Corda 1.0
|
||||||
-----------
|
---------
|
||||||
Corda 1.0 is finally here!
|
Corda 1.0 is finally here!
|
||||||
|
|
||||||
This critical step in the Corda journey enables the developer community, clients, and partners to build on Corda with confidence.
|
This critical step in the Corda journey enables the developer community, clients, and partners to build on Corda with confidence.
|
||||||
@ -166,253 +288,3 @@ We have provided a comprehensive :doc:`upgrade-notes` to ease the transition of
|
|||||||
Upgrading to this release is strongly recommended, and you will be safe in the knowledge that core APIs will no longer break.
|
Upgrading to this release is strongly recommended, and you will be safe in the knowledge that core APIs will no longer break.
|
||||||
|
|
||||||
Thank you to all contributors for this release!
|
Thank you to all contributors for this release!
|
||||||
|
|
||||||
Milestone 14
|
|
||||||
------------
|
|
||||||
|
|
||||||
This release continues with the goal to improve API stability and developer friendliness. There have also been more
|
|
||||||
bug fixes and other improvements across the board.
|
|
||||||
|
|
||||||
The CorDapp template repository has been replaced with a specific repository for
|
|
||||||
`Java <https://github.com/corda/cordapp-template-java>`_ and `Kotlin <https://github.com/corda/cordapp-template-kotlin>`_
|
|
||||||
to improve the experience of starting a new project and to simplify the build system.
|
|
||||||
|
|
||||||
It is now possible to specify multiple IP addresses and legal identities for a single node, allowing node operators
|
|
||||||
more flexibility in setting up nodes.
|
|
||||||
|
|
||||||
A format has been introduced for CorDapp JARs that standardises the contents of CorDapps across nodes. This new format
|
|
||||||
now requires CorDapps to contain their own external dependencies. This paves the way for significantly improved
|
|
||||||
dependency management for CorDapps with the release of `Jigsaw (Java Modules) <http://openjdk.java.net/projects/jigsaw/>`_. For those using non-gradle build systems it is important
|
|
||||||
to read :doc:`cordapp-build-systems` to learn more. Those using our ``cordformation`` plugin simply need to update
|
|
||||||
to the latest version (``0.14.0``) to get the fixes.
|
|
||||||
|
|
||||||
We've now begun the process of demarcating which classes are part of our public API and which ones are internal.
|
|
||||||
Everything found in ``net.corda.core.internal`` and other packages in the ``net.corda`` namespace which has ``.internal`` in it are
|
|
||||||
considered internal and not for public use. In a future release any CorDapp using these packages will fail to load, and
|
|
||||||
when we migrate to Jigsaw these will not be exported.
|
|
||||||
|
|
||||||
The transaction finalisation flow (``FinalityFlow``) has had hooks added for alternative implementations, for example in
|
|
||||||
scenarios where no single participant in a transaction is aware of the well known identities of all parties.
|
|
||||||
|
|
||||||
DemoBench has a fix for a rare but inconvenient crash that can occur when sharing your display across multiple devices,
|
|
||||||
e.g. a projector while performing demonstrations in front of an audience.
|
|
||||||
|
|
||||||
Guava types are being removed because Guava does not have backwards compatibility across versions, which has serious
|
|
||||||
issues when multiple libraries depend on different versions of the library.
|
|
||||||
|
|
||||||
The identity service API has been tweaked, primarily so anonymous identity registration now takes in
|
|
||||||
AnonymousPartyAndPath rather than the individual components of the identity, as typically the caller will have
|
|
||||||
an AnonymousPartyAndPath instance. See change log for further detail.
|
|
||||||
|
|
||||||
Upgrading to this release is strongly recommended in order to keep up with the API changes, removal and additions.
|
|
||||||
|
|
||||||
Milestone 13
|
|
||||||
------------
|
|
||||||
|
|
||||||
Following our first public beta in M12, this release continues the work on API stability and user friendliness. Apart
|
|
||||||
from bug fixes and code refactoring, there are also significant improvements in the Vault Query and the
|
|
||||||
Identity Service (for more detailed information about what has changed, see :doc:`changelog`).
|
|
||||||
More specifically:
|
|
||||||
|
|
||||||
The long awaited new **Vault Query** service makes its debut in this release and provides advanced vault query
|
|
||||||
capabilities using criteria specifications (see ``QueryCriteria``), sorting, and pagination. Criteria specifications
|
|
||||||
enable selective filtering with and/or composition using multiple operator primitives on standard attributes stored in
|
|
||||||
Corda internal vault tables (eg. vault_states, vault_fungible_states, vault_linear_states), and also on custom contract
|
|
||||||
state schemas defined by CorDapp developers when modelling new contract types. Custom queries are specifiable using a
|
|
||||||
simple but sophisticated builder DSL (see ``QueryCriteriaUtils``). The new Vault Query service is usable by flows and by
|
|
||||||
RPC clients alike via two simple API functions: ``queryBy()`` and ``trackBy()``. The former provides point-in-time
|
|
||||||
snapshot queries whilst the later supplements the snapshot with dynamic streaming of updates.
|
|
||||||
See :doc:`api-vault-query` for full details.
|
|
||||||
|
|
||||||
We have written a comprehensive Hello, World! tutorial, showing developers how to build a CorDapp from start
|
|
||||||
to finish. The tutorial shows how the core elements of a CorDapp - states, contracts and flows - fit together
|
|
||||||
to allow your node to handle new business processes. It also explains how you can use our contract and
|
|
||||||
flow testing frameworks to massively reduce CorDapp development time.
|
|
||||||
|
|
||||||
Certificate checks have been enabled for much of the identity service. These are part of the confidential (anonymous)
|
|
||||||
identities work, and ensure that parties are actually who they claim to be by checking their certificate path back to
|
|
||||||
the network trust root (certificate authority).
|
|
||||||
|
|
||||||
To deal with anonymized keys, we've also implemented a deterministic key derivation function that combines logic
|
|
||||||
from the HMAC-based Extract-and-Expand Key Derivation Function (HKDF) protocol and the BIP32 hardened
|
|
||||||
parent-private-key -> child-private-key scheme. This function currently supports the following algorithms:
|
|
||||||
ECDSA secp256K1, ECDSA secpR1 (NIST P-256) and EdDSA ed25519. We are now very close to fully supporting anonymous
|
|
||||||
identities so as to increase privacy even against validating notaries.
|
|
||||||
|
|
||||||
We have further tightened the set of objects which Corda will attempt to serialise from the stack during flow
|
|
||||||
checkpointing. As flows are arbitrary code in which it is convenient to do many things, we ended up pulling in a lot of
|
|
||||||
objects that didn't make sense to put in a checkpoint, such as ``Thread`` and ``Connection``. To minimize serialization
|
|
||||||
cost and increase security by not allowing certain classes to be serialized, we now support class blacklisting
|
|
||||||
that will return an ``IllegalStateException`` if such a class is encountered during a checkpoint. Blacklisting supports
|
|
||||||
superclass and superinterface inheritance and always precedes ``@CordaSerializable`` annotation checking.
|
|
||||||
|
|
||||||
We've also started working on improving user experience when searching, by adding a new RPC to support fuzzy matching
|
|
||||||
of X.500 names.
|
|
||||||
|
|
||||||
Milestone 12 - First Public Beta
|
|
||||||
--------------------------------
|
|
||||||
|
|
||||||
One of our busiest releases, lots of changes that take us closer to API stability (for more detailed information about
|
|
||||||
what has changed, see :doc:`changelog`). In this release we focused mainly on making developers' lives easier. Taking
|
|
||||||
into account feedback from numerous training courses and meet-ups, we decided to add ``CollectSignaturesFlow`` which
|
|
||||||
factors out a lot of code which CorDapp developers needed to write to get their transactions signed.
|
|
||||||
The improvement is up to 150 fewer lines of code in each flow! To have your transaction signed by different parties, you
|
|
||||||
need only now call a subflow which collects the parties' signatures for you.
|
|
||||||
|
|
||||||
Additionally we introduced classpath scanning to wire-up flows automatically. Writing CorDapps has been made simpler by
|
|
||||||
removing boiler-plate code that was previously required when registering flows. Writing services such as oracles has also been simplified.
|
|
||||||
|
|
||||||
We made substantial RPC performance improvements (please note that this is separate to node performance, we are focusing
|
|
||||||
on that area in future milestones):
|
|
||||||
|
|
||||||
- 15-30k requests per second for a single client/server RPC connection.
|
|
||||||
* 1Kb requests, 1Kb responses, server and client on same machine, parallelism 8, measured on a Dell XPS 17(i7-6700HQ, 16Gb RAM)
|
|
||||||
- The framework is now multithreaded on both client and server side.
|
|
||||||
- All remaining bottlenecks are in the messaging layer.
|
|
||||||
|
|
||||||
Security of the key management service has been improved by removing support for extracting private keys, in order that
|
|
||||||
it can support use of a hardware security module (HSM) for key storage. Instead it exposes functionality for signing data
|
|
||||||
(typically transactions). The service now also supports multiple signature schemes (not just EdDSA).
|
|
||||||
|
|
||||||
We've added the beginnings of flow versioning. Nodes now reject flow requests if the initiating side is not using the same
|
|
||||||
flow version. In a future milestone release will add the ability to support backwards compatibility.
|
|
||||||
|
|
||||||
As with the previous few releases we have continued work extending identity support. There are major changes to the ``Party``
|
|
||||||
class as part of confidential identities, and how parties and keys are stored in transaction state objects.
|
|
||||||
See :doc:`changelog` for full details.
|
|
||||||
|
|
||||||
Added new Byzantine fault tolerant (BFT) decentralised notary demo, based on the `BFT-SMaRT protocol <https://bft-smart.github.io/library/>`_
|
|
||||||
For how to run the demo see: :ref:`notary-demo`
|
|
||||||
|
|
||||||
We continued to work on tools that enable diagnostics on the node. The newest addition to Corda Shell is ``flow watch`` command which
|
|
||||||
lets the administrator see all flows currently running with result or error information as well as who is the flow initiator.
|
|
||||||
Here is the view from DemoBench:
|
|
||||||
|
|
||||||
.. image:: resources/flowWatchCmd.png
|
|
||||||
|
|
||||||
We also started work on the strategic wire format (not integrated).
|
|
||||||
|
|
||||||
Milestone 11
|
|
||||||
------------
|
|
||||||
|
|
||||||
Special thank you to `Gary Rowe <https://github.com/gary-rowe>`_ for his contribution to Corda's Contracts DSL in M11.
|
|
||||||
|
|
||||||
Work has continued on confidential identities, introducing code to enable the Java standard libraries to work with
|
|
||||||
composite key signatures. This will form the underlying basis of future work to standardise the public key and signature
|
|
||||||
formats to enable interoperability with other systems, as well as enabling the use of composite signatures on X.509
|
|
||||||
certificates to prove association between transaction keys and identity keys.
|
|
||||||
|
|
||||||
The identity work will require changes to existing code and configurations, to replace party names with full X.500
|
|
||||||
distinguished names (see RFC 1779 for details on the construction of distinguished names). Currently this is not
|
|
||||||
enforced, however it will be in a later milestone.
|
|
||||||
|
|
||||||
* "myLegalName" in node configurations will need to be replaced, for example "Bank A" is replaced with
|
|
||||||
"CN=Bank A,O=Bank A,L=London,C=GB". Obviously organisation, location and country ("O", "L" and "C" respectively)
|
|
||||||
must be given values which are appropriate to the node, do not just use these example values.
|
|
||||||
* "networkMap" in node configurations must be updated to match any change to the legal name of the network map.
|
|
||||||
* If you are using mock parties for testing, try to standardise on the ``DUMMY_NOTARY``, ``DUMMY_BANK_A``, etc. provided
|
|
||||||
in order to ensure consistency.
|
|
||||||
|
|
||||||
We anticipate enforcing the use of distinguished names in node configurations from M12, and across the network from M13.
|
|
||||||
|
|
||||||
We have increased the maximum message size that we can send to Corda over RPC from 100 KB to 10 MB.
|
|
||||||
|
|
||||||
The Corda node now disables any use of ObjectInputStream to prevent Java deserialisation within flows. This is a security fix,
|
|
||||||
and prevents the node from deserialising arbitrary objects.
|
|
||||||
|
|
||||||
We've introduced the concept of platform version which is a single integer value which increments by 1 if a release changes
|
|
||||||
any of the public APIs of the entire Corda platform. This includes the node's public APIs, the messaging protocol,
|
|
||||||
serialisation, etc. The node exposes the platform version it's on and we envision CorDapps will use this to be able to
|
|
||||||
run on older versions of the platform to the one they were compiled against. Platform version borrows heavily from Android's
|
|
||||||
API Level.
|
|
||||||
|
|
||||||
We have revamped the DemoBench user interface. DemoBench will now also be installed as "Corda DemoBench" for both Windows
|
|
||||||
and MacOSX. The original version was installed as just "DemoBench", and so will not be overwritten automatically by the
|
|
||||||
new version.
|
|
||||||
|
|
||||||
Milestone 10
|
|
||||||
------------
|
|
||||||
|
|
||||||
Special thank you to `Qian Hong <https://github.com/fracting>`_, `Marek Skocovsky <https://github.com/marekdapps>`_,
|
|
||||||
`Karel Hajek <https://github.com/polybioz>`_, and `Jonny Chiu <https://github.com/johnnyychiu>`_ for their contributions
|
|
||||||
to Corda in M10.
|
|
||||||
|
|
||||||
A new interactive **Corda Shell** has been added to the node. The shell lets developers and node administrators
|
|
||||||
easily command the node by running flows, RPCs and SQL queries. It also provides a variety of commands to monitor
|
|
||||||
the node. The Corda Shell is based on the popular `CRaSH project <http://www.crashub.org/>`_ and new commands can
|
|
||||||
be easily added to the node by simply dropping Groovy or Java files into the node's ``shell-commands`` directory.
|
|
||||||
We have many enhancements planned over time including SSH access, more commands and better tab completion.
|
|
||||||
|
|
||||||
The new "DemoBench" makes it easy to configure and launch local Corda nodes. It is a standalone desktop app that can be
|
|
||||||
bundled with its own JRE and packaged as either EXE (Windows), DMG (MacOS) or RPM (Linux-based). It has the following
|
|
||||||
features:
|
|
||||||
|
|
||||||
#. New nodes can be added at the click of a button. Clicking "Add node" creates a new tab that lets you edit the most
|
|
||||||
important configuration properties of the node before launch, such as its legal name and which CorDapps will be loaded.
|
|
||||||
#. Each tab contains a terminal emulator, attached to the pseudoterminal of the node. This lets you see console output.
|
|
||||||
#. You can launch an Corda Explorer instance for each node at the click of a button. Credentials are handed to the Corda
|
|
||||||
Explorer so it starts out logged in already.
|
|
||||||
#. Some basic statistics are shown about each node, informed via the RPC connection.
|
|
||||||
#. Another button launches a database viewer in the system browser.
|
|
||||||
#. The configurations of all running nodes can be saved into a single ``.profile`` file that can be reloaded later.
|
|
||||||
|
|
||||||
Soft Locking is a new feature implemented in the vault to prevent a node constructing transactions that attempt to use the
|
|
||||||
same input(s) simultaneously. Such transactions would result in naturally wasted effort when the notary rejects them as
|
|
||||||
double spend attempts. Soft locks are automatically applied to coin selection (eg. cash spending) to ensure that no two
|
|
||||||
transactions attempt to spend the same fungible states.
|
|
||||||
|
|
||||||
The basic Amount API has been upgraded to have support for advanced financial use cases and to better integrate with
|
|
||||||
currency reference data.
|
|
||||||
|
|
||||||
We have added optional out-of-process transaction verification. Any number of external verifier processes may be attached
|
|
||||||
to the node which can handle loadbalanced verification requests.
|
|
||||||
|
|
||||||
We have also delivered the long waited Kotlin 1.1 upgrade in M10! The new features in Kotlin allow us to write even more
|
|
||||||
clean and easy to manage code, which greatly increases our productivity.
|
|
||||||
|
|
||||||
This release contains a large number of improvements, new features, library upgrades and bug fixes. For a full list of
|
|
||||||
changes please see :doc:`changelog`.
|
|
||||||
|
|
||||||
Milestone 9
|
|
||||||
-----------
|
|
||||||
|
|
||||||
This release focuses on improvements to resiliency of the core infrastructure, with highlights including a Byzantine
|
|
||||||
fault tolerant (BFT) decentralised notary, based on the BFT-SMaRT protocol and isolating the web server from the
|
|
||||||
Corda node.
|
|
||||||
|
|
||||||
With thanks to open source contributor Thomas Schroeter for providing the BFT notary prototype, Corda can now resist
|
|
||||||
malicious attacks by members of a distributed notary service. If your notary service cluster has seven members, two can
|
|
||||||
become hacked or malicious simultaneously and the system continues unaffected! This work is still in development stage,
|
|
||||||
and more features are coming in the next snapshot!
|
|
||||||
|
|
||||||
The web server has been split out of the Corda node as part of our ongoing hardening of the node. We now provide a Jetty
|
|
||||||
servlet container pre-configured to contact a Corda node as a backend service out of the box, which means individual
|
|
||||||
webapps can have their REST APIs configured for the specific security environment of that app without affecting the
|
|
||||||
others, and without exposing the sensitive core of the node to malicious Javascript.
|
|
||||||
|
|
||||||
We have launched a global training programme, with two days of classes from the R3 team being hosted in London, New York
|
|
||||||
and Singapore. R3 members get 5 free places and seats are going fast, so sign up today.
|
|
||||||
|
|
||||||
We've started on support for confidential identities, based on the key randomisation techniques pioneered by the Bitcoin
|
|
||||||
and Ethereum communities. Identities may be either anonymous when a transaction is a part of a chain of custody, or fully
|
|
||||||
legally verified when a transaction is with a counterparty. Type safety is used to ensure the verification level of a
|
|
||||||
party is always clear and avoid mistakes. Future work will add support for generating new identity keys and providing a
|
|
||||||
certificate path to show ownership by the well known identity.
|
|
||||||
|
|
||||||
There are even more privacy improvements when a non-validating notary is used; the Merkle tree algorithm is used to hide
|
|
||||||
parts of the transaction that a non-validating notary doesn't need to see, whilst still allowing the decentralised
|
|
||||||
notary service to sign the entire transaction.
|
|
||||||
|
|
||||||
The serialisation API has been simplified and improved. Developers now only need to tag types that will be placed in
|
|
||||||
smart contracts or sent between parties with a single annotation... and sometimes even that isn't necessary!
|
|
||||||
|
|
||||||
Better permissioning in the cash CorDapp, to allow node users to be granted different permissions depending on whether
|
|
||||||
they manage the issuance, movement or ledger exit of cash tokens.
|
|
||||||
|
|
||||||
We've continued to improve error handling in flows, with information about errors being fed through to observing RPC
|
|
||||||
clients.
|
|
||||||
|
|
||||||
There have also been dozens of bug fixes, performance improvements and usability tweaks. Upgrading is definitely
|
|
||||||
worthwhile and will only take a few minutes for most apps.
|
|
||||||
|
|
||||||
For a full list of changes please see :doc:`changelog`.
|
|
||||||
|
@ -64,3 +64,13 @@ To enable remote debugging of the node, run the following from the terminal wind
|
|||||||
``java -Dcapsule.jvm.args="-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005" -jar corda.jar``
|
``java -Dcapsule.jvm.args="-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005" -jar corda.jar``
|
||||||
|
|
||||||
This command line will start the debugger on port 5005 and pause the process awaiting debugger attachment.
|
This command line will start the debugger on port 5005 and pause the process awaiting debugger attachment.
|
||||||
|
|
||||||
|
Starting a node with JMX monitoring enabled
|
||||||
|
-------------------------------------------
|
||||||
|
To enable export of JMX metrics over HTTP via `Jolokia <https://jolokia.org/>`_, run the following from the terminal window:
|
||||||
|
|
||||||
|
``java -Dcapsule.jvm.args="-javaagent:drivers/jolokia-jvm-1.3.7-agent.jar=port=7005" -jar corda.jar``
|
||||||
|
|
||||||
|
This command line will start the node with JMX metrics accessible via HTTP on port 7005.
|
||||||
|
|
||||||
|
See :ref:`Monitoring your node <jolokia_ref>` for further details.
|
@ -37,7 +37,7 @@ Allowed parameters are:
|
|||||||
|
|
||||||
:databaseProperties: database properties
|
:databaseProperties: database properties
|
||||||
|
|
||||||
:dataSourceProperties: datasoruce properties
|
:dataSourceProperties: datasource properties
|
||||||
|
|
||||||
:jiraConfig: The Jira configuration
|
:jiraConfig: The Jira configuration
|
||||||
|
|
||||||
|
@ -46,6 +46,8 @@ It's reproduced here as an example of both ways you can do this for a couple of
|
|||||||
.. warning:: We will be replacing the use of Kryo in the serialization framework and so additional changes here are
|
.. warning:: We will be replacing the use of Kryo in the serialization framework and so additional changes here are
|
||||||
likely.
|
likely.
|
||||||
|
|
||||||
|
.. _amqp_ref:
|
||||||
|
|
||||||
AMQP
|
AMQP
|
||||||
====
|
====
|
||||||
|
|
||||||
@ -220,6 +222,8 @@ checked exceptions, or ``CordaRuntimeException``, for unchecked exceptions. Any
|
|||||||
not conform to ``CordaThrowable`` will be converted to a ``CordaRuntimeException`` with the original exception type
|
not conform to ``CordaThrowable`` will be converted to a ``CordaRuntimeException`` with the original exception type
|
||||||
and other properties retained within it.
|
and other properties retained within it.
|
||||||
|
|
||||||
|
.. _amqp_custom_types_ref:
|
||||||
|
|
||||||
Custom Types
|
Custom Types
|
||||||
------------
|
------------
|
||||||
|
|
||||||
|
@ -25,6 +25,8 @@ The shell via the local terminal
|
|||||||
In development mode, the shell will display in the node's terminal window. It may be disabled by passing the
|
In development mode, the shell will display in the node's terminal window. It may be disabled by passing the
|
||||||
``--no-local-shell`` flag when running the node.
|
``--no-local-shell`` flag when running the node.
|
||||||
|
|
||||||
|
.. _ssh_server:
|
||||||
|
|
||||||
The shell via SSH
|
The shell via SSH
|
||||||
-----------------
|
-----------------
|
||||||
The shell is also accessible via SSH.
|
The shell is also accessible via SSH.
|
||||||
|
@ -109,15 +109,10 @@ See more on plugins in :doc:`running-a-node`.
|
|||||||
Security
|
Security
|
||||||
--------
|
--------
|
||||||
RPC credentials associated with a Client must match the permission set configured on the server node.
|
RPC credentials associated with a Client must match the permission set configured on the server node.
|
||||||
This refers to both authentication (username and password) and role-based authorisation (a permissioned set of RPC operations an
|
This refers to both authentication (username and password) and authorisation (a permissioned set of RPC operations an
|
||||||
authenticated user is entitled to run).
|
authenticated user is entitled to run).
|
||||||
|
|
||||||
.. note:: Permissions are represented as *String's* to allow RPC implementations to add their own permissioning. Currently
|
In the instructions below the server node permissions are configured programmatically in the driver code:
|
||||||
the only permission type defined is *StartFlow*, which defines a list of whitelisted flows an authenticated use may
|
|
||||||
execute. An administrator user (or a developer) may also be assigned the ``ALL`` permission, which grants access to
|
|
||||||
any flow.
|
|
||||||
|
|
||||||
In the instructions above the server node permissions are configured programmatically in the driver code:
|
|
||||||
|
|
||||||
.. code-block:: text
|
.. code-block:: text
|
||||||
|
|
||||||
@ -125,7 +120,9 @@ In the instructions above the server node permissions are configured programmati
|
|||||||
val user = User("user", "password", permissions = setOf(startFlow<CashFlow>()))
|
val user = User("user", "password", permissions = setOf(startFlow<CashFlow>()))
|
||||||
val node = startNode("CN=Alice Corp,O=Alice Corp,L=London,C=GB", rpcUsers = listOf(user)).get()
|
val node = startNode("CN=Alice Corp,O=Alice Corp,L=London,C=GB", rpcUsers = listOf(user)).get()
|
||||||
|
|
||||||
When starting a standalone node using a configuration file we must supply the RPC credentials as follows:
|
When starting a standalone node using a configuration file we must supply the RPC credentials in the node configuration,
|
||||||
|
like illustrated in the sample configuration below, or indicate an external database storing user accounts (see
|
||||||
|
:doc:`clientrpc` for more details):
|
||||||
|
|
||||||
.. code-block:: text
|
.. code-block:: text
|
||||||
|
|
||||||
@ -133,6 +130,7 @@ When starting a standalone node using a configuration file we must supply the RP
|
|||||||
{ username=user, password=password, permissions=[ StartFlow.net.corda.finance.flows.CashFlow ] }
|
{ username=user, password=password, permissions=[ StartFlow.net.corda.finance.flows.CashFlow ] }
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
When using the gradle Cordformation plugin to configure and deploy a node you must supply the RPC credentials in a similar
|
When using the gradle Cordformation plugin to configure and deploy a node you must supply the RPC credentials in a similar
|
||||||
manner:
|
manner:
|
||||||
|
|
||||||
|
@ -9,27 +9,136 @@ first public Beta (:ref:`Milestone 12 <changelog_m12>`), to :ref:`V1.0 <changelo
|
|||||||
|
|
||||||
General rules
|
General rules
|
||||||
-------------
|
-------------
|
||||||
Always remember to update the version identifiers in your project gradle file:
|
Always remember to update the version identifiers in your project gradle file. For example, Corda V1.0 uses:
|
||||||
|
|
||||||
.. sourcecode:: shell
|
.. sourcecode:: shell
|
||||||
|
|
||||||
ext.corda_release_version = '1.0.0'
|
ext.corda_release_version = '1.0.0'
|
||||||
|
ext.corda_release_distribution = 'net.corda'
|
||||||
ext.corda_gradle_plugins_version = '1.0.0'
|
ext.corda_gradle_plugins_version = '1.0.0'
|
||||||
|
|
||||||
It may be necessary to update the version of major dependencies:
|
It may be necessary to update the version of major dependencies. Corda V1.0 uses:
|
||||||
|
|
||||||
.. sourcecode:: shell
|
.. sourcecode:: shell
|
||||||
|
|
||||||
ext.kotlin_version = '1.1.4'
|
ext.kotlin_version = '1.1.4'
|
||||||
ext.quasar_version = '0.7.9'
|
ext.quasar_version = '0.7.9'
|
||||||
|
ext.junit_version = '4.12'
|
||||||
|
|
||||||
Please consult the relevant release notes of the release in question. If not specified, you may assume the
|
Please consult the relevant release notes of the release in question. If not specified, you may assume the
|
||||||
versions you are currently using are still in force.
|
versions you are currently using are still in force.
|
||||||
|
|
||||||
We also strongly recommend cross referencing with the :doc:`changelog` to confirm changes.
|
We also strongly recommend cross referencing with the :doc:`changelog` to confirm changes.
|
||||||
|
|
||||||
UNRELEASED
|
V1.0 and V2.0 to R3 Corda V3.0 Developer Preview
|
||||||
----------
|
------------------------------------------------
|
||||||
|
|
||||||
|
Build
|
||||||
|
^^^^^
|
||||||
|
|
||||||
|
* Update the version identifiers in your project gradle file(s):
|
||||||
|
|
||||||
|
.. sourcecode:: shell
|
||||||
|
|
||||||
|
ext.corda_release_version = 'R3.CORDA-3.0.0-DEV-PREVIEW' // "CORDA-3.0.0-DEV-PREVIEW" (Open Source)
|
||||||
|
ext.corda_gradle_plugins_version = '3.0.3'
|
||||||
|
|
||||||
|
* Add a new release identifier to specify the R3 release of corda:
|
||||||
|
|
||||||
|
.. sourcecode:: shell
|
||||||
|
|
||||||
|
ext.corda_release_distribution = 'com.r3.corda' // "net.corda" for Corda (Open Source)
|
||||||
|
|
||||||
|
* Add an additional repository entry to point to the location of the R3 Corda distribution:
|
||||||
|
|
||||||
|
.. sourcecode:: shell
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
maven {
|
||||||
|
credentials {
|
||||||
|
username "r3-corda-dev-preview"
|
||||||
|
password "XXXXX"
|
||||||
|
}
|
||||||
|
url 'https://ci-artifactory.corda.r3cev.com/artifactory/r3-corda-releases'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
* Corda plugins have been modularised further so the following additional gradle entries are necessary:
|
||||||
|
|
||||||
|
.. sourcecode:: shell
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
classpath "net.corda.plugins:cordapp:$corda_gradle_plugins_version"
|
||||||
|
}
|
||||||
|
|
||||||
|
apply plugin: 'net.corda.plugins.cordapp'
|
||||||
|
|
||||||
|
The plugin needs to be applied in all gradle build files where there is a dependency on Corda using any of:
|
||||||
|
cordaCompile, cordaRuntime, cordapp
|
||||||
|
|
||||||
|
* Corda Gradle plugins require Gradle version 4.1 or above
|
||||||
|
|
||||||
|
* All gradle compile, test, and run-time dependencies (except gradle plugins) to Corda artifacts should now use the
|
||||||
|
``corda_release_distribution`` variable (was previously hardcoded to use ``net.corda``):
|
||||||
|
|
||||||
|
.. sourcecode:: shell
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
|
||||||
|
// Corda integration dependencies
|
||||||
|
cordaCompile "$corda_release_distribution:corda-core:$corda_release_version"
|
||||||
|
cordaCompile "$corda_release_distribution:corda-finance:$corda_release_version"
|
||||||
|
cordaCompile "$corda_release_distribution:corda-jackson:$corda_release_version"
|
||||||
|
cordaCompile "$corda_release_distribution:corda-rpc:$corda_release_version"
|
||||||
|
cordaCompile "$corda_release_distribution:corda-node-api:$corda_release_version"
|
||||||
|
cordaCompile "$corda_release_distribution:corda-webserver-impl:$corda_release_version"
|
||||||
|
cordaRuntime "$corda_release_distribution:corda:$corda_release_version"
|
||||||
|
cordaRuntime "$corda_release_distribution:corda-webserver:$corda_release_version"
|
||||||
|
|
||||||
|
testCompile "$corda_release_distribution:corda-node-driver:$corda_release_version"
|
||||||
|
}
|
||||||
|
|
||||||
|
* For existing contract ORM schemas that extend from `CommonSchemaV1.LinearState` or `CommonSchemaV1.FungibleState`,
|
||||||
|
you will need to explicitly map the `participants` collection to a database table. Previously this mapping was done in the
|
||||||
|
superclass, but that makes it impossible to properly configure the table name.
|
||||||
|
The required change is to add the ``override var participants: MutableSet<AbstractParty>? = null`` field to your class, and
|
||||||
|
add JPA mappings. For ex., see this example:
|
||||||
|
|
||||||
|
.. sourcecode:: kotlin
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "cash_states_v2",
|
||||||
|
indexes = arrayOf(Index(name = "ccy_code_idx2", columnList = "ccy_code")))
|
||||||
|
class PersistentCashState(
|
||||||
|
|
||||||
|
@ElementCollection
|
||||||
|
@Column(name = "participants")
|
||||||
|
@CollectionTable(name="cash_states_v2_participants", joinColumns = arrayOf(
|
||||||
|
JoinColumn(name = "output_index", referencedColumnName = "output_index"),
|
||||||
|
JoinColumn(name = "transaction_id", referencedColumnName = "transaction_id")))
|
||||||
|
override var participants: MutableSet<AbstractParty>? = null,
|
||||||
|
|
||||||
|
Configuration
|
||||||
|
^^^^^^^^^^^^^
|
||||||
|
Applies to both gradle deployNodes tasks and/or corda node configuration (node.conf).
|
||||||
|
|
||||||
|
* Remove any references to ``networkMap``.
|
||||||
|
|
||||||
|
.. sourcecode:: shell
|
||||||
|
|
||||||
|
networkMap "O=Agent,L=Dallas,C=US"
|
||||||
|
|
||||||
|
* Remove any references to ``advertisedServices`` (including notaries).
|
||||||
|
|
||||||
|
.. sourcecode:: shell
|
||||||
|
|
||||||
|
advertisedServices = ["corda.notary.validating"]
|
||||||
|
|
||||||
|
* Add an explicit notary definition in the Notary node configuration only:
|
||||||
|
|
||||||
|
.. sourcecode:: shell
|
||||||
|
|
||||||
|
notary = [validating : true]
|
||||||
|
|
||||||
* For existing contract ORM schemas that extend from `CommonSchemaV1.LinearState` or `CommonSchemaV1.FungibleState`,
|
* For existing contract ORM schemas that extend from `CommonSchemaV1.LinearState` or `CommonSchemaV1.FungibleState`,
|
||||||
you will need to explicitly map the `participants` collection to a database table. Previously this mapping was done in the
|
you will need to explicitly map the `participants` collection to a database table. Previously this mapping was done in the
|
||||||
@ -52,15 +161,237 @@ UNRELEASED
|
|||||||
override var participants: MutableSet<AbstractParty>? = null,
|
override var participants: MutableSet<AbstractParty>? = null,
|
||||||
|
|
||||||
Testing
|
Testing
|
||||||
~~~~~~~
|
^^^^^^^
|
||||||
|
|
||||||
|
Contract tests
|
||||||
|
~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
* You must now create a ``MockServices`` object.
|
||||||
|
|
||||||
|
``MockServices`` provides a mock identity, key and storage service. ``MockServices`` takes as its first argument a
|
||||||
|
list of the CorDapp packages to scan:
|
||||||
|
|
||||||
|
.. sourcecode:: kotlin
|
||||||
|
|
||||||
|
private val ledgerServices = MockServices(listOf("net.corda.examples.obligation", "net.corda.testing.contracts"))
|
||||||
|
|
||||||
|
``MockServices`` replaces the use of ``setCordappPackages`` and ``unsetCordappPackages``.
|
||||||
|
|
||||||
|
* ``ledger`` is now defined as a ``MockServices`` method. This means that:
|
||||||
|
|
||||||
|
.. sourcecode:: kotlin
|
||||||
|
|
||||||
|
ledger {
|
||||||
|
|
||||||
|
Becomes:
|
||||||
|
|
||||||
|
.. sourcecode:: kotlin
|
||||||
|
|
||||||
|
ledgerServices.ledger {
|
||||||
|
|
||||||
|
* Within a mock ledger transaction, ``ContractState`` instances are passed to ``input`` and ``output`` as objects
|
||||||
|
rather than lambdas. For example:
|
||||||
|
|
||||||
|
.. sourcecode:: kotlin
|
||||||
|
|
||||||
|
ledgerServices.ledger {
|
||||||
|
transaction {
|
||||||
|
input(OBLIGATION_CONTRACT_ID, DummyState())
|
||||||
|
output(OBLIGATION_CONTRACT_ID, oneDollarObligation)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
* Within a mock ledger transaction, ``CommandData`` instances are passed to ``input`` and ``output`` as objects
|
||||||
|
rather than lambdas, and the public keys must be passed as a list if there is more than one. For example:
|
||||||
|
|
||||||
|
.. sourcecode:: kotlin
|
||||||
|
|
||||||
|
ledgerServices.ledger {
|
||||||
|
transaction {
|
||||||
|
command(alice.publicKey, ObligationContract.Commands.Issue())
|
||||||
|
command(listOf(alice.publicKey, bob.publicKey), ObligationContract.Commands.Issue())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
* The predefined test identities (e.g. ``ALICE`` and ``MINI_CORP``) have been removed.
|
||||||
|
|
||||||
|
You must now define the test identities explicitly. For example:
|
||||||
|
|
||||||
|
.. sourcecode:: kotlin
|
||||||
|
|
||||||
|
val alice = TestIdentity(CordaX500Name(organisation = "Alice", locality = "TestLand", country = "GB"))
|
||||||
|
|
||||||
|
``TestIdentity`` exposes methods to get the ``name``, ``keyPair``, ``publicKey``, ``party`` and ``identity`` of the
|
||||||
|
underlying ``TestIdentity``
|
||||||
|
|
||||||
|
* Explicit invocation of transaction transformation (ie. using ``TransactionBuilder``) requires serialization engine
|
||||||
|
to be initialized. In unit test this can be achieved by using the following jUnit rule:
|
||||||
|
|
||||||
|
.. sourcecode:: kotlin
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
@JvmField
|
||||||
|
val testSerialization = SerializationEnvironmentRule()
|
||||||
|
|
||||||
|
Flow tests
|
||||||
|
~~~~~~~~~~
|
||||||
|
|
||||||
* The registration mechanism for CorDapps in ``MockNetwork`` unit tests has changed.
|
* The registration mechanism for CorDapps in ``MockNetwork`` unit tests has changed.
|
||||||
|
|
||||||
It is now done via the ``cordappPackages`` constructor parameter of MockNetwork.
|
It is now done via the ``cordappPackages`` constructor parameter of MockNetwork. This takes a list of ``String``
|
||||||
This takes a list of `String` values which should be the
|
values which should be the package names of the CorDapps containing the contract verification code you wish to load.
|
||||||
package names of the CorDapps containing the contract verification code you wish to load.
|
|
||||||
The ``unsetCordappPackages`` method is now redundant and has been removed.
|
The ``unsetCordappPackages`` method is now redundant and has been removed.
|
||||||
|
|
||||||
|
* Creation of Notaries in ``MockNetwork`` unit tests has changed.
|
||||||
|
|
||||||
|
Previously the API call ``createNotaryNode(legalName = CordaX500ame(...))`` would be used to create a notary:
|
||||||
|
|
||||||
|
.. sourcecode:: kotlin
|
||||||
|
|
||||||
|
val notary = mockNetwork.createNotaryNode(legalName = CordaX500Name("Notary", "London", "UK"))
|
||||||
|
|
||||||
|
Notaries are now defined as part of ``MockNetwork`` creation using ``notarySpecs``, as in the following example:
|
||||||
|
|
||||||
|
.. sourcecode:: kotlin
|
||||||
|
|
||||||
|
mockNetwork = MockNetwork(notarySpecs = listOf(MockNetwork.NotarySpec(CordaX500Name("Notary","London","UK"))))
|
||||||
|
|
||||||
|
* A notary is no longer specified when creating a standard node using the ``createPartyNode`` API call.
|
||||||
|
|
||||||
|
Previously:
|
||||||
|
|
||||||
|
.. sourcecode:: kotlin
|
||||||
|
|
||||||
|
mockNetwork.createPartyNode(notary.network.myAddress, CordaX500Name("Node", "Madrid", "ES"))
|
||||||
|
|
||||||
|
Becomes:
|
||||||
|
|
||||||
|
.. sourcecode:: kotlin
|
||||||
|
|
||||||
|
mockNetwork.createPartyNode(CordaX500Name("Node", "Madrid", "ES"))
|
||||||
|
|
||||||
|
* Utility node creation API method ``createSomeNodes(...)`` has been removed, and nodes must be created individually.
|
||||||
|
|
||||||
|
Previously:
|
||||||
|
|
||||||
|
.. sourcecode:: java
|
||||||
|
|
||||||
|
MockNetwork.BasketOfNodes nodes = net.createSomeNodes(3);
|
||||||
|
nodeA = nodes.getPartyNodes().get(0);
|
||||||
|
nodeB = nodes.getPartyNodes().get(1);
|
||||||
|
nodeC = nodes.getPartyNodes().get(2);
|
||||||
|
|
||||||
|
Becomes:
|
||||||
|
|
||||||
|
.. sourcecode:: java
|
||||||
|
|
||||||
|
nodeA = net.createNode(new MockNodeParameters());
|
||||||
|
nodeB = net.createNode(new MockNodeParameters());
|
||||||
|
nodeC = net.createNode(new MockNodeParameters());
|
||||||
|
List<StartedNode<MockNode>> nodes = Arrays.asList(nodeA, nodeB, nodeC);
|
||||||
|
|
||||||
|
* Flow framework instantiation of a flow has a slight variation in start syntax:
|
||||||
|
|
||||||
|
Previously:
|
||||||
|
|
||||||
|
.. sourcecode:: java
|
||||||
|
|
||||||
|
CordaFuture<SignedTransaction> future = nodeA.getServices().startFlow(flow).getResultFuture();
|
||||||
|
|
||||||
|
Becomes:
|
||||||
|
|
||||||
|
.. sourcecode:: java
|
||||||
|
|
||||||
|
CordaFuture<SignedTransaction> future = startFlow(nodeA.getServices(), flow).getResultFuture();
|
||||||
|
|
||||||
|
* ``StartedNodeServices.startFlow`` must now be imported from ``net.corda.testing.node``
|
||||||
|
|
||||||
|
* Do not use ``node.internals`` to register flows:
|
||||||
|
|
||||||
|
Previous code would often look as follows:
|
||||||
|
|
||||||
|
.. sourcecode:: kotlin
|
||||||
|
|
||||||
|
protected fun registerFlowsAndServices(node: StartedNode<MockNetwork.MockNode>) {
|
||||||
|
val mockNode = node.internals
|
||||||
|
mockNode.registerInitiatedFlow(MyCustomFlow::class.java)
|
||||||
|
}
|
||||||
|
|
||||||
|
Becomes:
|
||||||
|
|
||||||
|
.. sourcecode:: kotlin
|
||||||
|
|
||||||
|
protected fun registerFlowsAndServices(mockNode: StartedNode<MockNetwork.MockNode>) {
|
||||||
|
mockNode.registerInitiatedFlow(MyCustomFlow::class.java)
|
||||||
|
}
|
||||||
|
|
||||||
|
* Do not use ``node.internals`` to register Corda services
|
||||||
|
|
||||||
|
Previously:
|
||||||
|
|
||||||
|
.. sourcecode:: kotlin
|
||||||
|
|
||||||
|
node.internals.installCordaService(CustomService::class.java)
|
||||||
|
|
||||||
|
Becomes:
|
||||||
|
|
||||||
|
.. sourcecode:: kotlin
|
||||||
|
|
||||||
|
node.services.cordaService(CustomService::class.java)
|
||||||
|
|
||||||
|
Better yet, use node factory to organize both register flows and services, for example, create class as follows:
|
||||||
|
|
||||||
|
.. sourcecode:: kotlin
|
||||||
|
|
||||||
|
class PrimesOracleNode(args: MockNodeArgs) : MockNetwork.MockNode(args) {
|
||||||
|
override fun start() = super.start().apply {
|
||||||
|
registerInitiatedFlow(QueryHandler::class.java)
|
||||||
|
registerInitiatedFlow(SignHandler::class.java)
|
||||||
|
services.cordaService(net.corda.examples.oracle.service.service.Oracle::class.java)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
and then pass it to ``createNode``:
|
||||||
|
|
||||||
|
.. sourcecode:: kotlin
|
||||||
|
|
||||||
|
val oracle = mockNet.createNode(MockNodeParameters(legalName = CordaX500Name("Oracle", "New York", "US")), ::PrimesOracleNode)
|
||||||
|
|
||||||
|
Node driver
|
||||||
|
~~~~~~~~~~~
|
||||||
|
|
||||||
|
* ``User`` has been moved from ``net.corda.nodeapi.User`` to ``net.corda.nodeapi.internal.config.User``
|
||||||
|
|
||||||
|
* Notaries are defined by passing a list of ``NotarySpec`` objects to ``driver`` using the ``notarySpecs`` argument,
|
||||||
|
instead of being defined manually in the driver block.
|
||||||
|
|
||||||
|
``notarySpecs`` defaults to providing a single validating notary
|
||||||
|
|
||||||
|
* The ``waitForAllNodesToFinish`` function has been removed. It has been replaced with a ``waitForAllNodesToFinish``
|
||||||
|
argument to ``driver``
|
||||||
|
|
||||||
|
* No longer specify advertised services to the ``DriverDSL`` when starting nodes:
|
||||||
|
|
||||||
|
Previously:
|
||||||
|
|
||||||
|
.. sourcecode:: kotlin
|
||||||
|
|
||||||
|
driver {
|
||||||
|
startNode(providedName = CordaX500Name("Controller", "London", "GB"), advertisedServices = setOf(ServiceInfo(ValidatingNotaryService.type)))
|
||||||
|
|
||||||
|
Becomes:
|
||||||
|
|
||||||
|
.. sourcecode:: kotlin
|
||||||
|
|
||||||
|
driver {
|
||||||
|
startNode(providedName = CordaX500Name("Controller", "London", "GB")),
|
||||||
|
|
||||||
|
Finance
|
||||||
|
^^^^^^^
|
||||||
|
|
||||||
|
* ``CASH_PROGRAM_ID`` has been moved to ``Cash.PROGRAM_ID``, where ``Cash`` is defined in the
|
||||||
|
``import net.corda.finance.contracts.asset`` package
|
||||||
|
|
||||||
V1.0 to V2.0
|
V1.0 to V2.0
|
||||||
------------
|
------------
|
||||||
|
|
||||||
@ -83,14 +414,14 @@ Build
|
|||||||
|
|
||||||
* MockNetwork has moved.
|
* MockNetwork has moved.
|
||||||
|
|
||||||
A new test driver module dependency needs to be including in your project: `corda-node-driver`. To continue using the
|
A new test driver module dependency needs to be including in your project: ``corda-node-driver``. To continue using the
|
||||||
mock network for testing, add the following entry to your gradle build file:
|
mock network for testing, add the following entry to your gradle build file:
|
||||||
|
|
||||||
.. sourcecode:: shell
|
.. sourcecode:: shell
|
||||||
|
|
||||||
testCompile "net.corda:corda-node-driver:$corda_release_version"
|
testCompile "$corda_release_distribution:corda-node-driver:$corda_release_version"
|
||||||
|
|
||||||
.. note:: you may only need `testCompile "net.corda:corda-test-utils:$corda_release_version"` if not using the Driver DSL.
|
.. note:: you may only need `testCompile "$corda_release_distribution:corda-test-utils:$corda_release_version"` if not using the Driver DSL.
|
||||||
|
|
||||||
Configuration
|
Configuration
|
||||||
^^^^^^^^^^^^^
|
^^^^^^^^^^^^^
|
||||||
@ -111,7 +442,7 @@ Use the automatic imports feature of IntelliJ to intelligently resolve the new i
|
|||||||
|
|
||||||
* Missing imports for contract types.
|
* Missing imports for contract types.
|
||||||
|
|
||||||
CommercialPaper and Cash are now contained within the `finance` module, as are associated helpers functions.
|
CommercialPaper and Cash are now contained within the ``finance`` module, as are associated helpers functions.
|
||||||
For example:
|
For example:
|
||||||
``import net.corda.contracts.ICommercialPaperState`` becomes ``import net.corda.finance.contracts.ICommercialPaperState``
|
``import net.corda.contracts.ICommercialPaperState`` becomes ``import net.corda.finance.contracts.ICommercialPaperState``
|
||||||
|
|
||||||
@ -125,7 +456,7 @@ Use the automatic imports feature of IntelliJ to intelligently resolve the new i
|
|||||||
|
|
||||||
* Missing imports for utility functions.
|
* Missing imports for utility functions.
|
||||||
|
|
||||||
Many common types and helper methods have been consolidated into `net.corda.core.utilities` package.
|
Many common types and helper methods have been consolidated into ``net.corda.core.utilities`` package.
|
||||||
For example:
|
For example:
|
||||||
``import net.corda.core.crypto.commonName`` becomes ``import net.corda.core.utilities.commonName``
|
``import net.corda.core.crypto.commonName`` becomes ``import net.corda.core.utilities.commonName``
|
||||||
|
|
||||||
@ -190,7 +521,7 @@ Flow framework
|
|||||||
Node services (ServiceHub)
|
Node services (ServiceHub)
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
* VaultQueryService: unresolved reference to `vaultQueryService`.
|
* VaultQueryService: unresolved reference to ``vaultQueryService``.
|
||||||
|
|
||||||
Replace all references to ``<services>.vaultQueryService`` with ``<services>.vaultService``.
|
Replace all references to ``<services>.vaultQueryService`` with ``<services>.vaultService``.
|
||||||
Previously there were two vault APIs. Now there is a single unified API with the same functions: ``VaultService``.
|
Previously there were two vault APIs. Now there is a single unified API with the same functions: ``VaultService``.
|
||||||
@ -211,7 +542,7 @@ Node services (ServiceHub)
|
|||||||
RPC Client
|
RPC Client
|
||||||
^^^^^^^^^^
|
^^^^^^^^^^
|
||||||
|
|
||||||
* Missing API methods on `CordaRPCOps` interface.
|
* Missing API methods on ``CordaRPCOps`` interface.
|
||||||
|
|
||||||
* Calls to ``verifiedTransactionsFeed()`` and ``verifiedTransactions()`` have been replaced with:
|
* Calls to ``verifiedTransactionsFeed()`` and ``verifiedTransactions()`` have been replaced with:
|
||||||
``internalVerifiedTransactionsSnapshot()`` and ``internalVerifiedTransactionsFeed()`` respectively
|
``internalVerifiedTransactionsSnapshot()`` and ``internalVerifiedTransactionsFeed()`` respectively
|
||||||
@ -219,7 +550,7 @@ RPC Client
|
|||||||
This is in preparation for the planned integration of Intel SGX™, which will encrypt the transactions feed.
|
This is in preparation for the planned integration of Intel SGX™, which will encrypt the transactions feed.
|
||||||
Apps that use this API will not work on encrypted ledgers: you should probably be using the vault query API instead.
|
Apps that use this API will not work on encrypted ledgers: you should probably be using the vault query API instead.
|
||||||
|
|
||||||
* Accessing the `networkMapCache` via ``services.nodeInfo().legalIdentities`` returns a list of identities.
|
* Accessing the ``networkMapCache`` via ``services.nodeInfo().legalIdentities`` returns a list of identities.
|
||||||
The first element in the list is the Party object referring to a node's single identity.
|
The first element in the list is the Party object referring to a node's single identity.
|
||||||
|
|
||||||
This is in preparation for allowing a node to host multiple separate identities in future.
|
This is in preparation for allowing a node to host multiple separate identities in future.
|
||||||
@ -227,15 +558,15 @@ RPC Client
|
|||||||
Testing
|
Testing
|
||||||
^^^^^^^
|
^^^^^^^
|
||||||
|
|
||||||
Please note that `Clauses` have been removed completely as of V1.0.
|
Please note that ``Clauses`` have been removed completely as of V1.0.
|
||||||
We will be revisiting this capability in a future release.
|
We will be revisiting this capability in a future release.
|
||||||
|
|
||||||
* CorDapps must be explicitly registered in ``MockNetwork`` unit tests.
|
* CorDapps must be explicitly registered in ``MockNetwork`` unit tests.
|
||||||
|
|
||||||
This is done by calling ``setCordappPackages``, an extension helper function in the ``net.corda.testing`` package,
|
This is done by calling ``setCordappPackages``, an extension helper function in the ``net.corda.testing`` package,
|
||||||
on the first line of your `@Before` method. This takes a variable number of `String` arguments which should be the
|
on the first line of your ``@Before`` method. This takes a variable number of ``String`` arguments which should be the
|
||||||
package names of the CorDapps containing the contract verification code you wish to load.
|
package names of the CorDapps containing the contract verification code you wish to load.
|
||||||
You should unset CorDapp packages in your `@After` method by using ``unsetCordappPackages()`` after `stopNodes()`.
|
You should unset CorDapp packages in your ``@After`` method by using ``unsetCordappPackages()`` after ``stopNodes()``.
|
||||||
|
|
||||||
* CorDapps must be explicitly registered in ``DriverDSL`` and ``RPCDriverDSL`` integration tests.
|
* CorDapps must be explicitly registered in ``DriverDSL`` and ``RPCDriverDSL`` integration tests.
|
||||||
|
|
||||||
@ -245,7 +576,7 @@ We will be revisiting this capability in a future release.
|
|||||||
Finance
|
Finance
|
||||||
^^^^^^^
|
^^^^^^^
|
||||||
|
|
||||||
* `FungibleAsset` interface simplification.
|
* ``FungibleAsset`` interface simplification.
|
||||||
|
|
||||||
The ``FungibleAsset`` interface has been made simpler. The ``Commands`` grouping interface
|
The ``FungibleAsset`` interface has been made simpler. The ``Commands`` grouping interface
|
||||||
that included the ``Move``, ``Issue`` and ``Exit`` interfaces have all been removed, while the ``move`` function has
|
that included the ``Move``, ``Issue`` and ``Exit`` interfaces have all been removed, while the ``move`` function has
|
||||||
@ -253,10 +584,10 @@ Finance
|
|||||||
|
|
||||||
The following errors may be reported:
|
The following errors may be reported:
|
||||||
|
|
||||||
* override nothing (FungibleAsset): `move`
|
* override nothing (FungibleAsset): ``move``
|
||||||
* not a subtype of overridden FungibleAsset: `withNewOwner`
|
* not a subtype of overridden FungibleAsset: ``withNewOwner``
|
||||||
* no longer need to override `override val contractHash: SecureHash? = null`
|
* no longer need to override ``override val contractHash: SecureHash? = null``
|
||||||
* need to override `override val contract: Class<out Contract>? = null`
|
* need to override ``override val contract: Class<out Contract>? = null``
|
||||||
|
|
||||||
|
|
||||||
Miscellaneous
|
Miscellaneous
|
||||||
@ -286,7 +617,7 @@ Gotchas
|
|||||||
Core data structures
|
Core data structures
|
||||||
^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
* `TransactionBuilder` changes.
|
* ``TransactionBuilder`` changes.
|
||||||
|
|
||||||
Use convenience class ``StateAndContract`` instead of ``TransactionBuilder.withItems()`` for passing
|
Use convenience class ``StateAndContract`` instead of ``TransactionBuilder.withItems()`` for passing
|
||||||
around a state and its contract.
|
around a state and its contract.
|
||||||
@ -294,7 +625,7 @@ Core data structures
|
|||||||
* Transaction building DSL changes:
|
* Transaction building DSL changes:
|
||||||
|
|
||||||
* now need to explicitly pass the ContractClassName into all inputs and outputs.
|
* now need to explicitly pass the ContractClassName into all inputs and outputs.
|
||||||
* `ContractClassName` refers to the class containing the “verifier” method.
|
* ``ContractClassName`` refers to the class containing the “verifier” method.
|
||||||
|
|
||||||
* Contract verify method signature change.
|
* Contract verify method signature change.
|
||||||
|
|
||||||
@ -364,15 +695,15 @@ Build
|
|||||||
|
|
||||||
* Gradle dependency reference changes.
|
* Gradle dependency reference changes.
|
||||||
|
|
||||||
Module name has changed to include `corda` in the artifacts jar name:
|
Module name has changed to include ``corda`` in the artifacts jar name:
|
||||||
|
|
||||||
.. sourcecode:: shell
|
.. sourcecode:: shell
|
||||||
|
|
||||||
compile "net.corda:core:$corda_release_version" -> compile "net.corda:corda-core:$corda_release_version"
|
compile "$corda_release_distribution:core:$corda_release_version" -> compile "$corda_release_distribution:corda-core:$corda_release_version"
|
||||||
compile "net.corda:finance:$corda_release_version" -> compile "net.corda:corda-finance:$corda_release_version"
|
compile "$corda_release_distribution:finance:$corda_release_version" -> compile "$corda_release_distribution:corda-finance:$corda_release_version"
|
||||||
compile "net.corda:jackson:$corda_release_version" -> compile "net.corda:corda-jackson:$corda_release_version"
|
compile "$corda_release_distribution:jackson:$corda_release_version" -> compile "$corda_release_distribution:corda-jackson:$corda_release_version"
|
||||||
compile "net.corda:node:$corda_release_version" -> compile "net.corda:corda-node:$corda_release_version"
|
compile "$corda_release_distribution:node:$corda_release_version" -> compile "$corda_release_distribution:corda-node:$corda_release_version"
|
||||||
compile "net.corda:rpc:$corda_release_version" -> compile "net.corda:corda-rpc:$corda_release_version"
|
compile "$corda_release_distribution:rpc:$corda_release_version" -> compile "$corda_release_distribution:corda-rpc:$corda_release_version"
|
||||||
|
|
||||||
Node services (ServiceHub)
|
Node services (ServiceHub)
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
@ -387,10 +718,10 @@ Finance
|
|||||||
|
|
||||||
* Financial asset contracts (Cash, CommercialPaper, Obligations) are now a standalone CorDapp within the **finance** module.
|
* Financial asset contracts (Cash, CommercialPaper, Obligations) are now a standalone CorDapp within the **finance** module.
|
||||||
|
|
||||||
Need to import from respective package within `finance` module:
|
Need to import from respective package within ``finance`` module:
|
||||||
eg. ``net.corda.finance.contracts.asset.Cash``
|
eg. ``net.corda.finance.contracts.asset.Cash``
|
||||||
|
|
||||||
Likewise, need to import associated asset flows from respective package within `finance` module:
|
Likewise, need to import associated asset flows from respective package within ``finance`` module:
|
||||||
eg. ``net.corda.finance.flows.CashIssueFlow``
|
eg. ``net.corda.finance.flows.CashIssueFlow``
|
||||||
``net.corda.finance.flows.CashIssueAndPaymentFlow``
|
``net.corda.finance.flows.CashIssueAndPaymentFlow``
|
||||||
``net.corda.finance.flows.CashExitFlow``
|
``net.corda.finance.flows.CashExitFlow``
|
||||||
@ -398,4 +729,4 @@ Finance
|
|||||||
* Moved ``finance`` gradle project files into a ``net.corda.finance`` package namespace.
|
* Moved ``finance`` gradle project files into a ``net.corda.finance`` package namespace.
|
||||||
|
|
||||||
This may require adjusting imports of Cash flow references and also of ``StartFlow`` permission in ``gradle.build`` files.
|
This may require adjusting imports of Cash flow references and also of ``StartFlow`` permission in ``gradle.build`` files.
|
||||||
Associated flows (`Cash*Flow`, `TwoPartyTradeFlow`, `TwoPartyDealFlow`) must now be imported from this package.
|
Associated flows (``Cash*Flow``, ``TwoPartyTradeFlow``, ``TwoPartyDealFlow``) must now be imported from this package.
|
||||||
|
@ -60,9 +60,9 @@ class CordappPlugin : Plugin<Project> {
|
|||||||
excludes.none { exclude -> (exclude["group"] == dep.group) && (exclude["name"] == dep.name) }
|
excludes.none { exclude -> (exclude["group"] == dep.group) && (exclude["name"] == dep.name) }
|
||||||
}
|
}
|
||||||
filteredDeps.forEach {
|
filteredDeps.forEach {
|
||||||
// net.corda or com.r3.corda.enterprise may be a core dependency which shouldn't be included in this cordapp so give a warning
|
// net.corda or com.r3.corda may be a core dependency which shouldn't be included in this cordapp so give a warning
|
||||||
val group = it.group?.toString() ?: ""
|
val group = it.group?.toString() ?: ""
|
||||||
if (group.startsWith("net.corda.") || group.startsWith("com.r3.corda.enterprise.")) {
|
if (group.startsWith("net.corda.") || group.startsWith("com.r3.corda.")) {
|
||||||
project.logger.warn("You appear to have included a Corda platform component ($it) using a 'compile' or 'runtime' dependency." +
|
project.logger.warn("You appear to have included a Corda platform component ($it) using a 'compile' or 'runtime' dependency." +
|
||||||
"This can cause node stability problems. Please use 'corda' instead." +
|
"This can cause node stability problems. Please use 'corda' instead." +
|
||||||
"See http://docs.corda.net/cordapp-build-systems.html")
|
"See http://docs.corda.net/cordapp-build-systems.html")
|
||||||
|
@ -38,7 +38,7 @@ class Cordformation : Plugin<Project> {
|
|||||||
fun verifyAndGetRuntimeJar(project: Project, jarName: String): File {
|
fun verifyAndGetRuntimeJar(project: Project, jarName: String): File {
|
||||||
val releaseVersion = project.rootProject.ext<String>("corda_release_version")
|
val releaseVersion = project.rootProject.ext<String>("corda_release_version")
|
||||||
val maybeJar = project.configuration("runtime").filter {
|
val maybeJar = project.configuration("runtime").filter {
|
||||||
"$jarName-$releaseVersion.jar" in it.toString() || "$jarName-enterprise-$releaseVersion.jar" in it.toString()
|
"$jarName-$releaseVersion.jar" in it.toString() || "$jarName-r3-$releaseVersion.jar" in it.toString()
|
||||||
}
|
}
|
||||||
if (maybeJar.isEmpty) {
|
if (maybeJar.isEmpty) {
|
||||||
throw IllegalStateException("No $jarName JAR found. Have you deployed the Corda project to Maven? Looked for \"$jarName-$releaseVersion.jar\"")
|
throw IllegalStateException("No $jarName JAR found. Have you deployed the Corda project to Maven? Looked for \"$jarName-$releaseVersion.jar\"")
|
||||||
@ -55,7 +55,8 @@ class Cordformation : Plugin<Project> {
|
|||||||
override fun apply(project: Project) {
|
override fun apply(project: Project) {
|
||||||
Utils.createCompileConfiguration("cordapp", project)
|
Utils.createCompileConfiguration("cordapp", project)
|
||||||
Utils.createRuntimeConfiguration(CORDFORMATION_TYPE, project)
|
Utils.createRuntimeConfiguration(CORDFORMATION_TYPE, project)
|
||||||
val jolokiaVersion = project.rootProject.ext<String>("jolokia_version")
|
// TODO: improve how we re-use existing declared external variables from root gradle.build
|
||||||
|
val jolokiaVersion = try { project.rootProject.ext<String>("jolokia_version") } catch (e: Exception) { "1.3.7" }
|
||||||
project.dependencies.add(CORDFORMATION_TYPE, "org.jolokia:jolokia-jvm:$jolokiaVersion:agent")
|
project.dependencies.add(CORDFORMATION_TYPE, "org.jolokia:jolokia-jvm:$jolokiaVersion:agent")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -128,7 +128,8 @@ class Node(private val project: Project) : CordformNode() {
|
|||||||
* Installs the jolokia monitoring agent JAR to the node/drivers directory
|
* Installs the jolokia monitoring agent JAR to the node/drivers directory
|
||||||
*/
|
*/
|
||||||
private fun installAgentJar() {
|
private fun installAgentJar() {
|
||||||
val jolokiaVersion = project.rootProject.ext<String>("jolokia_version")
|
// TODO: improve how we re-use existing declared external variables from root gradle.build
|
||||||
|
val jolokiaVersion = try { project.rootProject.ext<String>("jolokia_version") } catch (e: Exception) { "1.3.7" }
|
||||||
val agentJar = project.configuration("runtime").files {
|
val agentJar = project.configuration("runtime").files {
|
||||||
(it.group == "org.jolokia") &&
|
(it.group == "org.jolokia") &&
|
||||||
(it.name == "jolokia-jvm") &&
|
(it.name == "jolokia-jvm") &&
|
||||||
|
@ -33,7 +33,7 @@ java -jar capsule-hsm/build/libs/hsm-<version>.jar --config-file hsm.conf
|
|||||||
|
|
||||||
For a list of options the HSM signing server takes, run with the `--help` option:
|
For a list of options the HSM signing server takes, run with the `--help` option:
|
||||||
```
|
```
|
||||||
java -jar capsule-hsm/build/libs/hsm-3.0-<version>.jar --help
|
java -jar capsule-hsm/build/libs/hsm-<version>.jar --help
|
||||||
```
|
```
|
||||||
|
|
||||||
#Configuring network management service
|
#Configuring network management service
|
||||||
|
@ -7,8 +7,6 @@ import net.corda.core.crypto.random63BitValue
|
|||||||
import net.corda.core.internal.CertRole
|
import net.corda.core.internal.CertRole
|
||||||
import net.corda.core.internal.reader
|
import net.corda.core.internal.reader
|
||||||
import net.corda.core.internal.writer
|
import net.corda.core.internal.writer
|
||||||
import net.corda.core.identity.CordaX500Name
|
|
||||||
import net.corda.core.internal.*
|
|
||||||
import net.corda.core.utilities.days
|
import net.corda.core.utilities.days
|
||||||
import net.corda.core.utilities.millis
|
import net.corda.core.utilities.millis
|
||||||
import org.bouncycastle.asn1.*
|
import org.bouncycastle.asn1.*
|
||||||
|
@ -6,7 +6,7 @@ apply plugin: 'net.corda.plugins.publish-utils'
|
|||||||
apply plugin: 'us.kirchmeier.capsule'
|
apply plugin: 'us.kirchmeier.capsule'
|
||||||
apply plugin: 'com.jfrog.artifactory'
|
apply plugin: 'com.jfrog.artifactory'
|
||||||
|
|
||||||
description 'Corda Enterprise'
|
description 'R3 Corda'
|
||||||
|
|
||||||
configurations {
|
configurations {
|
||||||
runtimeArtifacts.extendsFrom runtime
|
runtimeArtifacts.extendsFrom runtime
|
||||||
@ -28,7 +28,7 @@ targetCompatibility = 1.6
|
|||||||
|
|
||||||
task buildCordaJAR(type: FatCapsule, dependsOn: project(':node').compileJava) {
|
task buildCordaJAR(type: FatCapsule, dependsOn: project(':node').compileJava) {
|
||||||
applicationClass 'net.corda.node.Corda'
|
applicationClass 'net.corda.node.Corda'
|
||||||
archiveName "corda-enterprise-${corda_release_version}.jar"
|
archiveName "corda-r3-${corda_release_version}.jar"
|
||||||
applicationSource = files(
|
applicationSource = files(
|
||||||
project(':node').configurations.runtime,
|
project(':node').configurations.runtime,
|
||||||
project(':node').jar,
|
project(':node').jar,
|
||||||
|
@ -17,9 +17,10 @@ import net.corda.node.services.config.NotaryConfig
|
|||||||
import net.corda.nodeapi.internal.DevIdentityGenerator
|
import net.corda.nodeapi.internal.DevIdentityGenerator
|
||||||
import net.corda.nodeapi.internal.network.NetworkParametersCopier
|
import net.corda.nodeapi.internal.network.NetworkParametersCopier
|
||||||
import net.corda.nodeapi.internal.network.NotaryInfo
|
import net.corda.nodeapi.internal.network.NotaryInfo
|
||||||
import net.corda.testing.*
|
import net.corda.testing.chooseIdentity
|
||||||
import net.corda.testing.common.internal.testNetworkParameters
|
import net.corda.testing.common.internal.testNetworkParameters
|
||||||
import net.corda.testing.contracts.DummyContract
|
import net.corda.testing.contracts.DummyContract
|
||||||
|
import net.corda.testing.dummyCommand
|
||||||
import net.corda.testing.internal.IntegrationTest
|
import net.corda.testing.internal.IntegrationTest
|
||||||
import net.corda.testing.internal.IntegrationTestSchemas
|
import net.corda.testing.internal.IntegrationTestSchemas
|
||||||
import net.corda.testing.node.MockNetwork
|
import net.corda.testing.node.MockNetwork
|
||||||
@ -27,7 +28,10 @@ import net.corda.testing.node.MockNodeParameters
|
|||||||
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
|
import net.corda.testing.node.MockServices.Companion.makeTestDataSourceProperties
|
||||||
import net.corda.testing.node.inMemoryH2DataSourceConfig
|
import net.corda.testing.node.inMemoryH2DataSourceConfig
|
||||||
import net.corda.testing.node.startFlow
|
import net.corda.testing.node.startFlow
|
||||||
import org.junit.*
|
import org.junit.After
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.ClassRule
|
||||||
|
import org.junit.Test
|
||||||
import java.math.BigInteger
|
import java.math.BigInteger
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
@ -17,6 +17,11 @@ import net.corda.node.internal.StartedNode
|
|||||||
import net.corda.node.services.messaging.MessagingService
|
import net.corda.node.services.messaging.MessagingService
|
||||||
import net.corda.node.services.messaging.ReceivedMessage
|
import net.corda.node.services.messaging.ReceivedMessage
|
||||||
import net.corda.node.services.messaging.send
|
import net.corda.node.services.messaging.send
|
||||||
|
import net.corda.node.services.transactions.RaftValidatingNotaryService
|
||||||
|
import net.corda.testing.*
|
||||||
|
import net.corda.node.services.messaging.*
|
||||||
|
import net.corda.testing.ALICE_NAME
|
||||||
|
import net.corda.testing.chooseIdentity
|
||||||
import net.corda.testing.ALICE_NAME
|
import net.corda.testing.ALICE_NAME
|
||||||
import net.corda.testing.chooseIdentity
|
import net.corda.testing.chooseIdentity
|
||||||
import net.corda.testing.driver.DriverDSL
|
import net.corda.testing.driver.DriverDSL
|
||||||
|
@ -284,6 +284,9 @@ open class Node(configuration: NodeConfiguration,
|
|||||||
printBasicNodeInfo("Database connection url is", "jdbc:h2:$url/node")
|
printBasicNodeInfo("Database connection url is", "jdbc:h2:$url/node")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (databaseUrl != null) {
|
||||||
|
printBasicNodeInfo("Database connection url is", databaseUrl)
|
||||||
|
}
|
||||||
return super.initialiseDatabasePersistence(schemaService, identityService, insideTransaction)
|
return super.initialiseDatabasePersistence(schemaService, identityService, insideTransaction)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
package net.corda.node.services.config
|
package net.corda.node.services.config
|
||||||
|
|
||||||
import com.typesafe.config.*
|
|
||||||
import net.corda.core.crypto.Crypto
|
|
||||||
import net.corda.core.crypto.SignatureScheme
|
|
||||||
import com.typesafe.config.Config
|
import com.typesafe.config.Config
|
||||||
import com.typesafe.config.ConfigFactory
|
import com.typesafe.config.ConfigFactory
|
||||||
import com.typesafe.config.ConfigParseOptions
|
import com.typesafe.config.ConfigParseOptions
|
||||||
|
@ -8,7 +8,8 @@ import net.corda.nodeapi.internal.persistence.NODE_DATABASE_PREFIX
|
|||||||
import org.hibernate.Session
|
import org.hibernate.Session
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
import java.util.Date
|
import java.time.LocalDateTime
|
||||||
|
import java.time.temporal.ChronoField
|
||||||
import java.util.concurrent.ScheduledExecutorService
|
import java.util.concurrent.ScheduledExecutorService
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import java.util.concurrent.atomic.AtomicBoolean
|
import java.util.concurrent.atomic.AtomicBoolean
|
||||||
@ -47,7 +48,7 @@ class RunOnceService(private val database: CordaPersistence, private val machine
|
|||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = TABLE)
|
@Table(name = TABLE)
|
||||||
class MutualExclusion(machineNameInit: String, pidInit: String) {
|
class MutualExclusion(machineNameInit: String, pidInit: String, timeStampInit: LocalDateTime) {
|
||||||
@Column(name = ID, insertable = false, updatable = false)
|
@Column(name = ID, insertable = false, updatable = false)
|
||||||
@Id
|
@Id
|
||||||
val id: Char = 'X'
|
val id: Char = 'X'
|
||||||
@ -59,8 +60,7 @@ class RunOnceService(private val database: CordaPersistence, private val machine
|
|||||||
val pid = pidInit
|
val pid = pidInit
|
||||||
|
|
||||||
@Column(name = TIMESTAMP)
|
@Column(name = TIMESTAMP)
|
||||||
@Temporal(TemporalType.TIMESTAMP)
|
val timestamp = timeStampInit
|
||||||
val timestamp: Date? = null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun start() {
|
fun start() {
|
||||||
@ -130,7 +130,7 @@ class RunOnceService(private val database: CordaPersistence, private val machine
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun updateTimestamp(session: Session, mutualExclusion: MutualExclusion): Boolean {
|
private fun updateTimestamp(session: Session, mutualExclusion: MutualExclusion): Boolean {
|
||||||
val minWaitTime = simpleDateFormat.format(Date(mutualExclusion.timestamp!!.time + waitInterval))
|
val minWaitTime = mutualExclusion.timestamp.plus(waitInterval, ChronoField.MILLI_OF_SECOND.baseUnit)
|
||||||
val query = session.createNativeQuery("UPDATE $TABLE SET $MACHINE_NAME = :machineName, $TIMESTAMP = CURRENT_TIMESTAMP, $PID = :pid " +
|
val query = session.createNativeQuery("UPDATE $TABLE SET $MACHINE_NAME = :machineName, $TIMESTAMP = CURRENT_TIMESTAMP, $PID = :pid " +
|
||||||
"WHERE $ID = 'X' AND " +
|
"WHERE $ID = 'X' AND " +
|
||||||
|
|
||||||
|
@ -167,11 +167,7 @@ class InMemoryIdentityServiceTests {
|
|||||||
val issuerKeyPair = generateKeyPair()
|
val issuerKeyPair = generateKeyPair()
|
||||||
val issuer = getTestPartyAndCertificate(x500Name, issuerKeyPair.public)
|
val issuer = getTestPartyAndCertificate(x500Name, issuerKeyPair.public)
|
||||||
val txKeyPair = Crypto.generateKeyPair()
|
val txKeyPair = Crypto.generateKeyPair()
|
||||||
val txCert = X509Utilities.createCertificate(
|
val txCert = X509Utilities.createCertificate(CertificateType.CONFIDENTIAL_LEGAL_IDENTITY, issuer.certificate, issuerKeyPair, x500Name.x500Principal,
|
||||||
CertificateType.CONFIDENTIAL_LEGAL_IDENTITY,
|
|
||||||
issuer.certificate,
|
|
||||||
issuerKeyPair,
|
|
||||||
x500Name.x500Principal,
|
|
||||||
txKeyPair.public)
|
txKeyPair.public)
|
||||||
val txCertPath = X509CertificateFactory().generateCertPath(listOf(txCert) + issuer.certPath.certificates)
|
val txCertPath = X509CertificateFactory().generateCertPath(listOf(txCert) + issuer.certPath.certificates)
|
||||||
return Pair(issuer, PartyAndCertificate(txCertPath))
|
return Pair(issuer, PartyAndCertificate(txCertPath))
|
||||||
|
@ -14,7 +14,7 @@ import org.junit.Before
|
|||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.contrib.java.lang.system.ExpectedSystemExit
|
import org.junit.contrib.java.lang.system.ExpectedSystemExit
|
||||||
import java.util.*
|
import java.time.LocalDateTime
|
||||||
import java.util.concurrent.ScheduledExecutorService
|
import java.util.concurrent.ScheduledExecutorService
|
||||||
import java.util.concurrent.ScheduledFuture
|
import java.util.concurrent.ScheduledFuture
|
||||||
import javax.persistence.Query
|
import javax.persistence.Query
|
||||||
@ -64,7 +64,9 @@ class RunOnceServiceTest {
|
|||||||
fun `row updated when change of master node`() {
|
fun `row updated when change of master node`() {
|
||||||
runOnceServiceMachine1.start()
|
runOnceServiceMachine1.start()
|
||||||
|
|
||||||
var firstTimestamp: Date? = null
|
var secondTimestamp = LocalDateTime.now()
|
||||||
|
var firstTimestamp = LocalDateTime.now()
|
||||||
|
|
||||||
database.transaction {
|
database.transaction {
|
||||||
val query = session.createNativeQuery(selectQuery, RunOnceService.MutualExclusion::class.java)
|
val query = session.createNativeQuery(selectQuery, RunOnceService.MutualExclusion::class.java)
|
||||||
val result = machine1RowCheck(query)
|
val result = machine1RowCheck(query)
|
||||||
@ -76,14 +78,13 @@ class RunOnceServiceTest {
|
|||||||
|
|
||||||
runOnceServiceMachine2.start()
|
runOnceServiceMachine2.start()
|
||||||
|
|
||||||
var secondTimestamp: Date? = null
|
|
||||||
database.transaction {
|
database.transaction {
|
||||||
val query = session.createNativeQuery(selectQuery, RunOnceService.MutualExclusion::class.java)
|
val query = session.createNativeQuery(selectQuery, RunOnceService.MutualExclusion::class.java)
|
||||||
val result = machine2RowCheck(query)
|
val result = machine2RowCheck(query)
|
||||||
secondTimestamp = result.timestamp
|
secondTimestamp = result.timestamp
|
||||||
}
|
}
|
||||||
|
|
||||||
assertTrue(secondTimestamp!!.toInstant().isAfter(firstTimestamp!!.toInstant()))
|
assertTrue(secondTimestamp.isAfter(firstTimestamp))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -105,7 +106,9 @@ class RunOnceServiceTest {
|
|||||||
fun `row updated when last run was same machine`() {
|
fun `row updated when last run was same machine`() {
|
||||||
runOnceServiceMachine1.start()
|
runOnceServiceMachine1.start()
|
||||||
|
|
||||||
var firstTimestamp: Date? = null
|
var secondTimestamp = LocalDateTime.now()
|
||||||
|
var firstTimestamp = LocalDateTime.now()
|
||||||
|
|
||||||
database.transaction {
|
database.transaction {
|
||||||
val query = session.createNativeQuery(selectQuery, RunOnceService.MutualExclusion::class.java)
|
val query = session.createNativeQuery(selectQuery, RunOnceService.MutualExclusion::class.java)
|
||||||
val result = machine1RowCheck(query)
|
val result = machine1RowCheck(query)
|
||||||
@ -117,14 +120,13 @@ class RunOnceServiceTest {
|
|||||||
|
|
||||||
runOnceServiceMachine1.start()
|
runOnceServiceMachine1.start()
|
||||||
|
|
||||||
var secondTimestamp: Date? = null
|
|
||||||
database.transaction {
|
database.transaction {
|
||||||
val query = session.createNativeQuery(selectQuery, RunOnceService.MutualExclusion::class.java)
|
val query = session.createNativeQuery(selectQuery, RunOnceService.MutualExclusion::class.java)
|
||||||
val result = machine1RowCheck(query)
|
val result = machine1RowCheck(query)
|
||||||
secondTimestamp = result.timestamp
|
secondTimestamp = result.timestamp
|
||||||
}
|
}
|
||||||
|
|
||||||
assertTrue(secondTimestamp!!.toInstant().isAfter(firstTimestamp!!.toInstant()))
|
assertTrue(secondTimestamp.isAfter(firstTimestamp))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -132,7 +134,9 @@ class RunOnceServiceTest {
|
|||||||
whenever(mockUpdateExecutor.scheduleAtFixedRate(any(), any(), any(), any())).thenAnswer { invocation ->
|
whenever(mockUpdateExecutor.scheduleAtFixedRate(any(), any(), any(), any())).thenAnswer { invocation ->
|
||||||
val runnable = invocation.arguments[0] as Runnable
|
val runnable = invocation.arguments[0] as Runnable
|
||||||
|
|
||||||
var firstTimestamp: Date? = null
|
var secondTimestamp = LocalDateTime.now()
|
||||||
|
var firstTimestamp = LocalDateTime.now()
|
||||||
|
|
||||||
database.transaction {
|
database.transaction {
|
||||||
val query = session.createNativeQuery(selectQuery, RunOnceService.MutualExclusion::class.java)
|
val query = session.createNativeQuery(selectQuery, RunOnceService.MutualExclusion::class.java)
|
||||||
val result = machine1RowCheck(query)
|
val result = machine1RowCheck(query)
|
||||||
@ -141,14 +145,13 @@ class RunOnceServiceTest {
|
|||||||
|
|
||||||
runnable.run()
|
runnable.run()
|
||||||
|
|
||||||
var secondTimestamp: Date? = null
|
|
||||||
database.transaction {
|
database.transaction {
|
||||||
val query = session.createNativeQuery(selectQuery, RunOnceService.MutualExclusion::class.java)
|
val query = session.createNativeQuery(selectQuery, RunOnceService.MutualExclusion::class.java)
|
||||||
val result = machine1RowCheck(query)
|
val result = machine1RowCheck(query)
|
||||||
secondTimestamp = result.timestamp
|
secondTimestamp = result.timestamp
|
||||||
}
|
}
|
||||||
|
|
||||||
assertTrue(secondTimestamp!!.toInstant().isAfter(firstTimestamp!!.toInstant()))
|
assertTrue(secondTimestamp.isAfter(firstTimestamp))
|
||||||
|
|
||||||
mock<ScheduledFuture<*>>()
|
mock<ScheduledFuture<*>>()
|
||||||
}
|
}
|
||||||
@ -228,7 +231,7 @@ class RunOnceServiceTest {
|
|||||||
assertEquals('X', result.id)
|
assertEquals('X', result.id)
|
||||||
assertEquals("machine1", result.machineName)
|
assertEquals("machine1", result.machineName)
|
||||||
assertEquals("123", result.pid)
|
assertEquals("123", result.pid)
|
||||||
assertTrue(result.timestamp is Date)
|
assertTrue(result.timestamp is LocalDateTime)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,7 +241,7 @@ class RunOnceServiceTest {
|
|||||||
assertEquals('X', result.id)
|
assertEquals('X', result.id)
|
||||||
assertEquals("machine2", result.machineName)
|
assertEquals("machine2", result.machineName)
|
||||||
assertEquals("789", result.pid)
|
assertEquals("789", result.pid)
|
||||||
assertTrue(result.timestamp is Date)
|
assertTrue(result.timestamp is LocalDateTime)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -8,9 +8,9 @@ import net.corda.core.utilities.NetworkHostAndPort
|
|||||||
import net.corda.node.services.config.NotaryConfig
|
import net.corda.node.services.config.NotaryConfig
|
||||||
import net.corda.node.services.config.RaftConfig
|
import net.corda.node.services.config.RaftConfig
|
||||||
import net.corda.nodeapi.internal.DevIdentityGenerator
|
import net.corda.nodeapi.internal.DevIdentityGenerator
|
||||||
import net.corda.testing.node.internal.demorun.*
|
|
||||||
import net.corda.testing.ALICE_NAME
|
import net.corda.testing.ALICE_NAME
|
||||||
import net.corda.testing.BOB_NAME
|
import net.corda.testing.BOB_NAME
|
||||||
|
import net.corda.testing.node.internal.demorun.*
|
||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
|
|
||||||
fun main(args: Array<String>) = RaftNotaryCordform().deployNodes()
|
fun main(args: Array<String>) = RaftNotaryCordform().deployNodes()
|
||||||
|
@ -52,7 +52,7 @@ allprojects {
|
|||||||
systemProperties["attestation.home"] = "$buildDir/logs"
|
systemProperties["attestation.home"] = "$buildDir/logs"
|
||||||
}
|
}
|
||||||
|
|
||||||
group 'com.r3.corda.enterprise'
|
group 'com.r3.corda'
|
||||||
version '1.0-SNAPSHOT'
|
version '1.0-SNAPSHOT'
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
|
@ -110,6 +110,9 @@ Now choose `File/Open` from the main menu, and select the profile that you have
|
|||||||
just saved. DemoBench should close the two existing tabs and then relaunch the
|
just saved. DemoBench should close the two existing tabs and then relaunch the
|
||||||
Notary and Bank nodes.
|
Notary and Bank nodes.
|
||||||
|
|
||||||
|
If you want to edit the content, please make sure that when zipping content back,
|
||||||
|
the notary node is the first directory (ZIP files content is ordered)
|
||||||
|
|
||||||
## Exiting DemoBench
|
## Exiting DemoBench
|
||||||
|
|
||||||
Close DemoBench as a normal application on your platform; it should close any
|
Close DemoBench as a normal application on your platform; it should close any
|
||||||
|
@ -10,6 +10,7 @@ import net.corda.nodeapi.internal.config.User
|
|||||||
import net.corda.nodeapi.internal.config.toConfig
|
import net.corda.nodeapi.internal.config.toConfig
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.nio.file.StandardCopyOption
|
import java.nio.file.StandardCopyOption
|
||||||
|
import java.util.Properties
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a subset of FullNodeConfiguration, containing only those configs which we need. The node uses reference.conf
|
* This is a subset of FullNodeConfiguration, containing only those configs which we need. The node uses reference.conf
|
||||||
@ -25,7 +26,10 @@ data class NodeConfig(
|
|||||||
val h2port: Int,
|
val h2port: Int,
|
||||||
val rpcUsers: List<User> = listOf(defaultUser),
|
val rpcUsers: List<User> = listOf(defaultUser),
|
||||||
/** This is an extra config used by the Cash app. */
|
/** This is an extra config used by the Cash app. */
|
||||||
val issuableCurrencies: List<String> = emptyList()
|
val issuableCurrencies: List<String> = emptyList(),
|
||||||
|
/** Pass-through for generating node.conf with external DB */
|
||||||
|
val dataSourceProperties: Properties? = null,
|
||||||
|
val database: Properties? = null
|
||||||
) {
|
) {
|
||||||
companion object {
|
companion object {
|
||||||
val renderOptions: ConfigRenderOptions = ConfigRenderOptions.defaults().setOriginComments(false)
|
val renderOptions: ConfigRenderOptions = ConfigRenderOptions.defaults().setOriginComments(false)
|
||||||
|
@ -10,10 +10,10 @@ import net.corda.core.internal.noneOrSingle
|
|||||||
import net.corda.core.utilities.NetworkHostAndPort
|
import net.corda.core.utilities.NetworkHostAndPort
|
||||||
import net.corda.demobench.plugin.CordappController
|
import net.corda.demobench.plugin.CordappController
|
||||||
import net.corda.demobench.pty.R3Pty
|
import net.corda.demobench.pty.R3Pty
|
||||||
|
import net.corda.nodeapi.internal.DevIdentityGenerator
|
||||||
import net.corda.nodeapi.internal.network.NetworkParameters
|
import net.corda.nodeapi.internal.network.NetworkParameters
|
||||||
import net.corda.nodeapi.internal.network.NetworkParametersCopier
|
import net.corda.nodeapi.internal.network.NetworkParametersCopier
|
||||||
import net.corda.nodeapi.internal.network.NotaryInfo
|
import net.corda.nodeapi.internal.network.NotaryInfo
|
||||||
import net.corda.nodeapi.internal.DevIdentityGenerator
|
|
||||||
import tornadofx.*
|
import tornadofx.*
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.lang.management.ManagementFactory
|
import java.lang.management.ManagementFactory
|
||||||
|
@ -34,16 +34,44 @@ The Participant nodes are only able to spend cash (eg. move cash).
|
|||||||
|
|
||||||
**These Corda nodes will be created on the following port on localhost.**
|
**These Corda nodes will be created on the following port on localhost.**
|
||||||
|
|
||||||
* Notary -> 20003 (Does not accept logins)
|
* Notary -> 20001 (Does not accept logins)
|
||||||
* Alice -> 20006
|
* Alice -> 20004
|
||||||
* Bob -> 20009
|
* Bob -> 20007
|
||||||
* UK Bank Plc -> 20012 (*Issuer node*)
|
* UK Bank Plc -> 20010 (*Issuer node*)
|
||||||
* USA Bank Corp -> 20015 (*Issuer node*)
|
* USA Bank Corp -> 20013 (*Issuer node*)
|
||||||
|
|
||||||
Explorer login credentials to the Issuer nodes are defaulted to ``manager`` and ``test``.
|
Explorer login credentials to the Issuer nodes are defaulted to ``manager`` and ``test``.
|
||||||
Explorer login credentials to the Participants nodes are defaulted to ``user1`` and ``test``.
|
Explorer login credentials to the Participant nodes are defaulted to ``user1`` and ``test``.
|
||||||
Please note you are not allowed to login to the notary.
|
Please note you are not allowed to login to the notary.
|
||||||
|
|
||||||
|
## Running Simulation Nodes
|
||||||
|
|
||||||
|
Building on the demonstration Corda network topology described above, simulation mode performs continuous
|
||||||
|
issue, move and exit cash operations across all participant nodes.
|
||||||
|
|
||||||
|
**Windows:**
|
||||||
|
|
||||||
|
gradlew.bat tools:explorer:runSimulationNodes
|
||||||
|
|
||||||
|
**Other:**
|
||||||
|
|
||||||
|
./gradlew tools:explorer:runSimulationNodes
|
||||||
|
|
||||||
|
## Running Flow Triage scenario
|
||||||
|
|
||||||
|
Once again, building on the demonstration Corda network topology described above, this scenario mode triggers
|
||||||
|
an exception within a flow which can then be visualized using the "Flow Triage" panel within the Explorer.
|
||||||
|
The "Flow Triage" panel will be enhanced in the future to enable operators to take corrective actions upon flow failures
|
||||||
|
(eg. retry, terminate, amend and replay)
|
||||||
|
|
||||||
|
**Windows:**
|
||||||
|
|
||||||
|
gradlew.bat tools:explorer:runFlowTriageNodes
|
||||||
|
|
||||||
|
**Other:**
|
||||||
|
|
||||||
|
./gradlew tools:explorer:runFlowTriageNodes
|
||||||
|
|
||||||
## Business Network reference implementation
|
## Business Network reference implementation
|
||||||
|
|
||||||
An additional "IOU" panel is now visible in the main Explorer dashboard to demonstrate the new Business Networks concept using a sample IOU product.
|
An additional "IOU" panel is now visible in the main Explorer dashboard to demonstrate the new Business Networks concept using a sample IOU product.
|
||||||
|
@ -65,11 +65,11 @@ class Main : App(MainView::class) {
|
|||||||
if (!isLoggedIn) {
|
if (!isLoggedIn) {
|
||||||
stage.hide()
|
stage.hide()
|
||||||
loginView.login()
|
loginView.login()
|
||||||
|
}
|
||||||
addOptionalViews()
|
addOptionalViews()
|
||||||
(find(primaryView) as MainView).initializeControls()
|
(find(primaryView) as MainView).initializeControls()
|
||||||
stage.show()
|
stage.show()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private fun addOptionalViews() {
|
private fun addOptionalViews() {
|
||||||
val iouView = find<IOUViewer>()
|
val iouView = find<IOUViewer>()
|
||||||
|
Reference in New Issue
Block a user