From 0ce7a602fa920374e22855a87a8306ae722e38d9 Mon Sep 17 00:00:00 2001 From: Tudor Malene Date: Fri, 18 Jan 2019 15:57:33 +0000 Subject: [PATCH 1/5] CORDA-2465 Document the whitelist to signature constraint migration process. --- docs/source/api-contract-constraints.rst | 53 +++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/docs/source/api-contract-constraints.rst b/docs/source/api-contract-constraints.rst index 1d80cd6cd6..fe2f15590d 100644 --- a/docs/source/api-contract-constraints.rst +++ b/docs/source/api-contract-constraints.rst @@ -316,7 +316,7 @@ For example: - For upgradeable constraints like the ``WhitelistedByZoneAttachmentConstraint``, the output states will inherit the same, and the selected attachment will be the latest version installed on the node. -- A more complex case is when for ``MyContract``, one input state is constrained by the ``HashAttachmentConstraint``, while another +- A more complex and unlikely case is when for ``MyContract``, one input state is constrained by the ``HashAttachmentConstraint``, while another state by the ``WhitelistedByZoneAttachmentConstraint``. To respect the rule from above, if the hash of the ``HashAttachmentConstraint`` is whitelisted by the network, then the output states will inherit the ``HashAttachmentConstraint``, as it is more restrictive. If the hash was not whitelisted, then the builder will fail as it is unable to select a correct constraint. @@ -330,6 +330,57 @@ For example: For Contracts that are annotated with ``@NoConstraintPropagation``, the platform requires that the Transaction Builder specifies an actual constraint for the output states (the ``AutomaticPlaceholderConstraint`` can't be used) . + +How to use the ``SignatureAttachmentConstraint`` if states were already created on the network with the ``WhitelistedByZoneAttachmentConstraint`` +------------------------------------------------------------------------------------------------------------------------------------------------- + +1. As the original developer of the Cordapp, the first step is to sign the latest version of the JAR that was released. The key used for signing will be used +to sign all subsequent releases, so it should be stored appropriately. The JAR can be signed by multiple keys owned by different parties and it will be +expressed as a ``CompositeKey`` in the ``SignatureAttachmentConstraint`` (See :doc:`api-core-types`). + +2. Next step is to whitelist this newly signed JAR with the Zone operator. The Zone operator should check that the JAR is signed and not allow any +more versions of it to be whitelisted in the future. From now on the developer(s) who signed the JAR are responsible for new versions. + +3. Any flows that build transactions using this Cordapp will have the responsibility of transitioning states to the ``SignatureAttachmentConstraint``. + This is done explicitly in the code by setting the constraint of the output states to signers of the latest version of the whitelisted jar. + +4. As a node operator you need to add the new signed version of the cordapp to the "cordapps" folder together with the latest version of the flows jar +that will contain code like: + +.. container:: codeset + + .. sourcecode:: kotlin + + // This will read the signers for the deployed cordapp. + val attachment = this.serviceHub.cordappProvider.getContractAttachmentID(contractClass) + val signers = this.serviceHub.attachments.openAttachment(attachment!!)!!.signerKeys + + // Create the key that will have to pass for all future versions. + // Could be as simple as: val ownersKey = signers.first() + val ownersKey = CompositeKey.Builder().addKeys(signers).build() + + val txBuilder = TransactionBuilder(notary) + // Set the Signature constraint on the cordapp. + .addOutputState(outputState, constraint = SignatureAttachmentConstraint(ownersKey)) + ... + + .. sourcecode:: java + + // This will read the signers for the deployed cordapp. + SecureHash attachment = this.getServiceHub().getCordappProvider().getContractAttachmentID(IOUContract.ID); + List signers = this.getServiceHub().getAttachments().openAttachment(attachment).getSignerKeys(); + + // Create the key that will have to pass for all future versions. + // Could be as simple as: PublicKey ownersKey = signers.get(0) . + PublicKey ownersKey = new CompositeKey.Builder().addKeys(signers).build(null); + + PublicKey ownerPublicKey = fetchPublicKey() // Read the public key from + TransactionBuilder txBuilder = new TransactionBuilder(notary) + // Set the Signature constraint on the new state to migrate away from the WhitelistConstraint. + .addOutputState(outputState, myContract, new SignatureAttachmentConstraint(ownersKey)) + ... + + Debugging --------- If an attachment constraint cannot be resolved, a ``MissingContractAttachments`` exception is thrown. There are two From c3f0dfd8a7e54417f20dcb90a6f3c6cfc175b84b Mon Sep 17 00:00:00 2001 From: Tudor Malene Date: Tue, 29 Jan 2019 16:48:01 +0000 Subject: [PATCH 2/5] Address code review comments. --- docs/source/api-contract-constraints.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/source/api-contract-constraints.rst b/docs/source/api-contract-constraints.rst index fe2f15590d..e57985a278 100644 --- a/docs/source/api-contract-constraints.rst +++ b/docs/source/api-contract-constraints.rst @@ -334,11 +334,11 @@ an actual constraint for the output states (the ``AutomaticPlaceholderConstraint How to use the ``SignatureAttachmentConstraint`` if states were already created on the network with the ``WhitelistedByZoneAttachmentConstraint`` ------------------------------------------------------------------------------------------------------------------------------------------------- -1. As the original developer of the Cordapp, the first step is to sign the latest version of the JAR that was released. The key used for signing will be used -to sign all subsequent releases, so it should be stored appropriately. The JAR can be signed by multiple keys owned by different parties and it will be -expressed as a ``CompositeKey`` in the ``SignatureAttachmentConstraint`` (See :doc:`api-core-types`). +1. As the original developer of the corDapp, the first step is to sign the latest version of the JAR that was released (see :doc:`cordapp-build-systems`). +The key used for signing will be used to sign all subsequent releases, so it should be stored appropriately. The JAR can be signed by multiple keys owned +by different parties and it will be expressed as a ``CompositeKey`` in the ``SignatureAttachmentConstraint`` (See :doc:`api-core-types`). -2. Next step is to whitelist this newly signed JAR with the Zone operator. The Zone operator should check that the JAR is signed and not allow any +2. Whitelist this newly signed JAR with the Zone operator. The Zone operator should check that the JAR is signed and not allow any more versions of it to be whitelisted in the future. From now on the developer(s) who signed the JAR are responsible for new versions. 3. Any flows that build transactions using this Cordapp will have the responsibility of transitioning states to the ``SignatureAttachmentConstraint``. From bb0ceda8d038848391a6fa291154ab12396db74f Mon Sep 17 00:00:00 2001 From: szymonsztuka Date: Tue, 5 Feb 2019 11:49:30 +0000 Subject: [PATCH 3/5] Addressing PR comments - added links to jarSigner and corda-gradle-plugins signing and explain which one to use. --- docs/source/api-contract-constraints.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/source/api-contract-constraints.rst b/docs/source/api-contract-constraints.rst index e57985a278..f3a8af7ab7 100644 --- a/docs/source/api-contract-constraints.rst +++ b/docs/source/api-contract-constraints.rst @@ -337,6 +337,8 @@ How to use the ``SignatureAttachmentConstraint`` if states were already created 1. As the original developer of the corDapp, the first step is to sign the latest version of the JAR that was released (see :doc:`cordapp-build-systems`). The key used for signing will be used to sign all subsequent releases, so it should be stored appropriately. The JAR can be signed by multiple keys owned by different parties and it will be expressed as a ``CompositeKey`` in the ``SignatureAttachmentConstraint`` (See :doc:`api-core-types`). +Use `JAR signing and verification tool `_ to sign the existing JAR. +The signing capability of :ref:`corda-gradle-plugins ` cannot be used in this context as it signs the JAR while building it from source. 2. Whitelist this newly signed JAR with the Zone operator. The Zone operator should check that the JAR is signed and not allow any more versions of it to be whitelisted in the future. From now on the developer(s) who signed the JAR are responsible for new versions. From e4ae1a2aaafc52130fc73487a6356b5f653f4c61 Mon Sep 17 00:00:00 2001 From: Tudor Malene Date: Wed, 13 Feb 2019 15:27:02 +0000 Subject: [PATCH 4/5] CORDA-2465 Address code review comments. --- docs/source/api-contract-constraints.rst | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/docs/source/api-contract-constraints.rst b/docs/source/api-contract-constraints.rst index 840adb4560..b53d1605cc 100644 --- a/docs/source/api-contract-constraints.rst +++ b/docs/source/api-contract-constraints.rst @@ -191,7 +191,8 @@ The signing capability of :ref:`corda-gradle-plugins signers = this.getServiceHub().getAttachments().openAttachment(attachment).getSignerKeys(); // Create the key that will have to pass for all future versions. - // Could be as simple as: PublicKey ownersKey = signers.get(0) . - PublicKey ownersKey = new CompositeKey.Builder().addKeys(signers).build(null); + PublicKey ownersKey = signers.get(0); - PublicKey ownerPublicKey = fetchPublicKey() // Read the public key from TransactionBuilder txBuilder = new TransactionBuilder(notary) // Set the Signature constraint on the new state to migrate away from the WhitelistConstraint. .addOutputState(outputState, myContract, new SignatureAttachmentConstraint(ownersKey)) From 34184ca1eac00ca5e305c89453fabad3886893f7 Mon Sep 17 00:00:00 2001 From: Tudor Malene Date: Wed, 13 Feb 2019 15:51:57 +0000 Subject: [PATCH 5/5] CORDA-2465 Address code review comments. --- docs/source/api-contract-constraints.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/api-contract-constraints.rst b/docs/source/api-contract-constraints.rst index b53d1605cc..accaa912a5 100644 --- a/docs/source/api-contract-constraints.rst +++ b/docs/source/api-contract-constraints.rst @@ -194,7 +194,7 @@ more versions of it to be whitelisted in the future. From now on the developer(s This is done explicitly in the code by setting the constraint of the output states to signers of the latest version of the whitelisted jar. In the near future we will make this transition automatic if we detect that the previous 2 steps were executed. -4. As a node operator you need to add the new signed version of the cordapp to the "cordapps" folder together with the latest version of the flows jar +4. As a node operator you need to add the new signed version of the contracts cordapp to the "cordapps" folder together with the latest version of the flows jar that will contain code like: .. container:: codeset