diff --git a/docs/source/app-upgrade-notes.rst b/docs/source/app-upgrade-notes.rst index ff8489515f..a35bfac7b0 100644 --- a/docs/source/app-upgrade-notes.rst +++ b/docs/source/app-upgrade-notes.rst @@ -67,23 +67,34 @@ This is used by the Corda Gradle build plugin to populate your app JAR with usef .. important:: Watch out for the UK spelling of the word licence (with a c). -Name, vendor and licence can be set to any string you like, they don't have to be Corda identities. Target versioning is a new concept -introduced in Corda 4. Learn more by reading :doc:`versioning`. Setting a target version of 4 disables workarounds for various -bugs that may exist in your app, so by doing this you are promising that you have thoroughly tested your app on the new version. -Using a high target version is a good idea because some features and improvements are only available to apps that opt in. +Name, vendor and licence can be set to any string you like, they don't have to be Corda identities. -The new ``versionId`` number is used to block state downgrades: when a state constraint can be satisfied by multiple attachments, -the version is tracked in the ledger and cannot decrement. This ensures security fixes in CorDapps stick and can't be reversed by -downgrading states to an earlier version. See ":ref:`contract_non-downgrade_rule_ref`" for more information. In future, the version -attached to the workflow JAR will also be used to help implement smoother upgrade and migration features. If the "normal" version number -of your app as defined in your Gradle file follows the convention of always being a whole number starting from 1, you can just refer -to that variable directly to set the version id. +Target versioning is a new concept introduced in Corda 4. Learn more by reading :doc:`versioning`. +Setting a target version of 4 opts in to changes that might not be 100% backwards compatible, such as +API semantics changes or disabling workarounds for bugs that may be in your apps, so by doing this you +are promising that you have thoroughly tested your app on the new version. Using a high target version is +a good idea because some features and improvements are only available to apps that opt in. -The duplication between ``contract`` and ``workflow`` blocks exists because you should split your app into two separate JARs/modules, -one that contains on-ledger validation code like states and contracts, and one for the rest (called by convention the "workflows" -module although it can contain a lot more than just flows: services would also go here, for instance). For simplicity, here we -use one JAR for both, but this is in general an anti-pattern and can result in your flow logic code being sent over the network to -arbitrary third party peers, even though they don't need it. +The minimum platform version is just the (major) version number of the node that you require, so if you +start using new APIs and features in Corda 4, you should set this to 4. Unfortunately Corda 3 and below +do not know about this metadata and don't check it, so your app will still be loaded in such nodes and +then crash at runtime. However it's good to get in the habit of setting this properly for future releases. + +The new ``versionId`` number is a version code for **your** app, and is unrelated to Corda's own versions. +It is used to block state downgrades: when a state constraint can be satisfied +by multiple attachments, the version is tracked in the ledger and cannot decrement. This ensures security +fixes in CorDapps stick and can't be reversed by downgrading states to an earlier version. See +":ref:`contract_non-downgrade_rule_ref`" for more information. In future, the version attached to the +workflow JAR will also be used to help implement smoother upgrade and migration features. If the "normal" +version number of your app as defined in your Gradle file follows the convention of always being a whole +number starting from 1, you can just refer to that variable directly to set the version id. + +The duplication between ``contract`` and ``workflow`` blocks exists because you should split your app into +two separate JARs/modules, one that contains on-ledger validation code like states and contracts, and one +for the rest (called by convention the "workflows" module although it can contain a lot more than just flows: +services would also go here, for instance). For simplicity, here we use one JAR for both, but this is in +general an anti-pattern and can result in your flow logic code being sent over the network to arbitrary +third party peers, even though they don't need it. Step 3. Security: Upgrade your use of FinalityFlow -------------------------------------------------- @@ -92,10 +103,11 @@ The previous ``FinalityFlow`` API is insecure. It doesn't have a receive flow, s all signed transactions that are sent to it, without checks. It is **highly** recommended that existing CorDapps migrate away to the new API, as otherwise things like business network membership checks won't be reliably enforced. -This is a two step process: +This is a three step process: 1. Change the flow that calls ``FinalityFlow`` 2. Change or create the flow that will receive the finalised transaction. +3. Make sure your application's minimum and target version numbers are both set to 4 (see step 2). As an example, let's take a very simple flow that finalises a transaction without the involvement of a counterpart flow: diff --git a/docs/source/release-notes.rst b/docs/source/release-notes.rst index e826262f5b..248982f92b 100644 --- a/docs/source/release-notes.rst +++ b/docs/source/release-notes.rst @@ -186,6 +186,25 @@ into shared business logic, but it makes perfect sense to put into a user-specif If your flows could benefit from being extended in this way, read ":doc:`flow-overriding`" to learn more. +Target/minimum versions ++++++++++++++++++++++++ + +Applications can now specify a **target version** in their JAR manifest. The target version declares +which version of the platform the app was tested against. By incrementing the target version, app developers +can opt in to desirable changes that might otherwise not be entirely backwards compatible. For example +in a future release when the deterministic JVM is integrated and enabled, apps will need to opt in to +determinism by setting the target version to a high enough value. + +Target versioning has a proven track record in both iOS and Android of enabling platforms to preserve +strong backwards compatibility, whilst also moving forward with new features and bug fixes. We recommend +that maintained applications always try and target the latest version of the platform. Setting a target +version does not imply your app *requires* a node of that version, merely that it's been tested against +that version and can handle any opt-in changes. + +Applications may also specify a **minimum platform version**. If you try to install an app in a node that +is too old to satisfy this requirement, the app won't be loaded. App developers can set their min platform +version requirement if they start using new features and APIs. + Dependency upgrades +++++++++++++++++++