mirror of
https://github.com/corda/corda.git
synced 2024-12-18 20:47:57 +00:00
CORDA-2456: Documentation around explicit upgrades (#4783)
* Documentation around explicit upgrades Small changes Fix merge * Address review comments
This commit is contained in:
parent
a8861fd18d
commit
09ba5c2652
@ -14,6 +14,8 @@ Release new CorDapp versions
|
||||
|
||||
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
|
||||
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.
|
||||
@ -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
|
||||
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
|
||||
* A state is upgraded while the contract stays the same
|
||||
* The state and the contract are updated simultaneously
|
||||
.. warning:: In Corda 4 we've introduced the Signature Constraint (see :doc:`api-contract-constraints`). States created or migrated to
|
||||
the Signature Constraint can't be explicitly upgraded using the Contract upgrade transaction. This feature might be added in a future version.
|
||||
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
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
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
|
||||
old state and contract definitions on their node's classpath for the duration of the upgrade
|
||||
.. note:: This requirement will go away in a future version of Corda. In Corda 4, the contract-code-as-attachment feature was implemented
|
||||
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
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
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:
|
||||
|
||||
.. sourcecode:: kotlin
|
||||
@ -307,11 +309,20 @@ upgraded contracts must implement the ``UpgradedContract`` interface. This inter
|
||||
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
|
||||
upgraded, the same state type can be used for both the old and new state type parameters.
|
||||
The ``upgrade`` method describes how the old state type is upgraded to the new state type.
|
||||
|
||||
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:
|
||||
|
||||
.. 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
|
||||
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
|
||||
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
|
||||
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
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
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
|
||||
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
|
||||
and/or state objects
|
||||
* 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
|
||||
^^^^^^^^^
|
||||
* All nodes need to run the contract upgrade authorisation flow to upgrade the contract and/or state objects
|
||||
|
Loading…
Reference in New Issue
Block a user