mirror of
https://github.com/corda/corda.git
synced 2025-05-31 22:50:53 +00:00
* Documentation around explicit upgrades Small changes Fix merge * Address review comments (cherry picked from commit 09ba5c2652b6ab5f57f9f639d2128d372de9659e)
This commit is contained in:
parent
43e3755c6f
commit
0ba7b65ee8
@ -14,6 +14,8 @@ Release new CorDapp versions
|
|||||||
|
|
||||||
CorDapp versioning
|
CorDapp versioning
|
||||||
------------------
|
------------------
|
||||||
|
.. UPDATE - This is no longer accurate! Needs to talk about the different types of artifacts ( kernel, workflows) each versioned independently
|
||||||
|
|
||||||
The Corda platform does not mandate a version number on a per-CorDapp basis. Different elements of a CorDapp are
|
The Corda platform does not mandate a version number on a per-CorDapp basis. Different elements of a CorDapp are
|
||||||
allowed to evolve separately. Sometimes, however, a change to one element will require changes to other elements. For
|
allowed to evolve separately. Sometimes, however, a change to one element will require changes to other elements. For
|
||||||
example, changing a shared data structure may require flow changes that are not backwards-compatible.
|
example, changing a shared data structure may require flow changes that are not backwards-compatible.
|
||||||
@ -279,25 +281,25 @@ Performing explicit contract and state upgrades
|
|||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
In an explicit upgrade, contracts and states can be changed in arbitrary ways, if and only if all of the state's
|
In an explicit upgrade, contracts and states can be changed in arbitrary ways, if and only if all of the state's
|
||||||
participants agree to the proposed upgrade. The following combinations of upgrades are possible:
|
participants agree to the proposed upgrade. To ensure the continuity of the chain the upgraded contract needs to declare the contract and
|
||||||
|
constraint of the states it's allowed to replace.
|
||||||
|
|
||||||
* A contract is upgraded while the state definition remains the same
|
.. warning:: In Corda 4 we've introduced the Signature Constraint (see :doc:`api-contract-constraints`). States created or migrated to
|
||||||
* A state is upgraded while the contract stays the same
|
the Signature Constraint can't be explicitly upgraded using the Contract upgrade transaction. This feature might be added in a future version.
|
||||||
* The state and the contract are updated simultaneously
|
Given the nature of the Signature constraint there should be little need to create a brand new contract to fix issues in the old contract.
|
||||||
|
|
||||||
1. Preserve the existing state and contract definitions
|
1. Preserve the existing state and contract definitions
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
Currently, all nodes must **permanently** keep **all** old state and contract definitions on their node's classpath
|
Currently, all nodes must **permanently** keep **all** old state and contract definitions on their node's classpath if the explicit upgrade
|
||||||
|
process was used on them.
|
||||||
|
|
||||||
.. note:: Once the contract-code-as-an-attachment feature has been implemented, nodes will only be required to keep the
|
.. note:: This requirement will go away in a future version of Corda. In Corda 4, the contract-code-as-attachment feature was implemented
|
||||||
old state and contract definitions on their node's classpath for the duration of the upgrade
|
only for "normal" transactions. ``Contract Upgrade`` and ``Notary Change`` transactions will still be executed within the node classpath.
|
||||||
|
|
||||||
Changing a state or contract's package constitutes a definition change. If you want to move a state or contract
|
|
||||||
definition to a new package, you must also preserve the definition in the old package
|
|
||||||
|
|
||||||
2. Write the new state and contract definitions
|
2. Write the new state and contract definitions
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
Update the contract and/or state definitions. There are no restrictions on how states are updated. However,
|
Update the contract and state definitions. There are no restrictions on how states are updated. However,
|
||||||
upgraded contracts must implement the ``UpgradedContract`` interface. This interface is defined as:
|
upgraded contracts must implement the ``UpgradedContract`` interface. This interface is defined as:
|
||||||
|
|
||||||
.. sourcecode:: kotlin
|
.. sourcecode:: kotlin
|
||||||
@ -307,11 +309,20 @@ upgraded contracts must implement the ``UpgradedContract`` interface. This inter
|
|||||||
fun upgrade(state: OldState): NewState
|
fun upgrade(state: OldState): NewState
|
||||||
}
|
}
|
||||||
|
|
||||||
The ``upgrade`` method describes how the old state type is upgraded to the new state type. When the state isn't being
|
The ``upgrade`` method describes how the old state type is upgraded to the new state type.
|
||||||
upgraded, the same state type can be used for both the old and new state type parameters.
|
|
||||||
|
|
||||||
By default this new contract will only be able to upgrade legacy states which are constrained by the zone whitelist (see :doc:`api-contract-constraints`).
|
By default this new contract will only be able to upgrade legacy states which are constrained by the zone whitelist (see :doc:`api-contract-constraints`).
|
||||||
If hash or other constraint types are used, the new contract should implement ``UpgradedContractWithLegacyConstraint``
|
|
||||||
|
|
||||||
|
.. note:: The requirement for a ``legacyContractConstraint`` arises from the fact that when a transaction chain is verified and a ``Contract Upgrade`` is
|
||||||
|
encountered on the back chain, the verifier wants to know that a legitimate state was transformed into the new contract. The ``legacyContractConstraint`` is
|
||||||
|
the mechanism by which this is enforced. Using it, the new contract is able to narrow down what constraint the states it is upgrading should have.
|
||||||
|
If a malicious party would create a fake ``com.megacorp.MegaToken`` state, he would not be able to use the usual ``MegaToken`` code as his
|
||||||
|
fake token will not validate because the constraints will not match. The ``com.megacorp.SuperMegaToken`` would know that it is a fake state and thus refuse to upgrade it.
|
||||||
|
It is safe to omit the ``legacyContractConstraint`` for the zone whitelist constraint, because the chain of trust is ensured by the Zone operator
|
||||||
|
who would have whitelisted both contracts and checked them.
|
||||||
|
|
||||||
|
If the hash constraint is used, the new contract should implement ``UpgradedContractWithLegacyConstraint``
|
||||||
instead, and specify the constraint explicitly:
|
instead, and specify the constraint explicitly:
|
||||||
|
|
||||||
.. sourcecode:: kotlin
|
.. sourcecode:: kotlin
|
||||||
@ -342,8 +353,8 @@ Have each node operator stop their node. If you are also changing flow definitio
|
|||||||
:ref:`node drain <draining_the_node>` first to avoid the definition of states or contracts changing whilst a flow is
|
:ref:`node drain <draining_the_node>` first to avoid the definition of states or contracts changing whilst a flow is
|
||||||
in progress.
|
in progress.
|
||||||
|
|
||||||
6. Re-run the network bootstrapper
|
6. Re-run the network bootstrapper (only if you want to whitelist the new contract)
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
If you're using the network bootstrapper instead of a network map server and have defined any new contracts, you need to
|
If you're using the network bootstrapper instead of a network map server and have defined any new contracts, you need to
|
||||||
re-run the network bootstrapper to whitelist the new contracts. See :doc:`network-bootstrapper`.
|
re-run the network bootstrapper to whitelist the new contracts. See :doc:`network-bootstrapper`.
|
||||||
|
|
||||||
@ -378,29 +389,22 @@ contract upgrade.
|
|||||||
One the flow ends successfully, all the participants of the old state object should have the upgraded state object
|
One the flow ends successfully, all the participants of the old state object should have the upgraded state object
|
||||||
which references the new contract code.
|
which references the new contract code.
|
||||||
|
|
||||||
|
10. Migrate the new upgraded state to the Signature Constraint from the zone constraint
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
Follow the guide in :doc:`api-contract-constraints`.
|
||||||
|
|
||||||
Points to note
|
Points to note
|
||||||
~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Capabilities of the contract upgrade flows
|
Capabilities of the contract upgrade flows
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
* Despite its name, the ``ContractUpgradeFlow`` also handles the update of state object definitions
|
* Despite its name, the ``ContractUpgradeFlow`` handles the update of both state object definitions and contract logic
|
||||||
* The state can completely change as part of an upgrade! For example, it is possible to transmute a ``Cat`` state into
|
* The state can completely change as part of an upgrade! For example, it is possible to transmute a ``Cat`` state into
|
||||||
a ``Dog`` state, provided that all participants in the ``Cat`` state agree to the change
|
a ``Dog`` state, provided that all participants in the ``Cat`` state agree to the change
|
||||||
* Equally, the state doesn't have to change at all
|
|
||||||
* If a node has not yet run the contract upgrade authorisation flow, they will not be able to upgrade the contract
|
* If a node has not yet run the contract upgrade authorisation flow, they will not be able to upgrade the contract
|
||||||
and/or state objects
|
and/or state objects
|
||||||
* State schema changes are handled separately
|
* State schema changes are handled separately
|
||||||
|
|
||||||
Writing new states and contracts
|
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
* If a property is removed from a state, any references to it must be removed from the contract code. Otherwise, you
|
|
||||||
will not be able to compile your contract code. It is generally not advisable to remove properties from states. Mark
|
|
||||||
them as deprecated instead
|
|
||||||
* When adding properties to a state, consider how the new properties will affect transaction validation involving this
|
|
||||||
state. If the contract is not updated to add constraints over the new properties, they will be able to take on any
|
|
||||||
value
|
|
||||||
* Updated state objects can use the old contract code as long as there is no requirement to update it
|
|
||||||
|
|
||||||
Logistics
|
Logistics
|
||||||
^^^^^^^^^
|
^^^^^^^^^
|
||||||
* All nodes need to run the contract upgrade authorisation flow to upgrade the contract and/or state objects
|
* All nodes need to run the contract upgrade authorisation flow to upgrade the contract and/or state objects
|
||||||
|
Loading…
x
Reference in New Issue
Block a user