Corda is a very interesting case study from the perspective of backwards compatibility.

In a distributed system, the various nodes of the system might be running different versions of the software. In many cases, the software is deployed incrementally to them and not in a single step. There is an additional challenge in a decentralized system because different organizations now control the various nodes of the systems so that these discrepancies might last longer.

Corda provides a lot of different mechanisms to preserve backwards compatibility in different areas, so let’s explore some of them.

API & ABI backwards compatibility

Corda provides API & ABI backwards compatibility for all the public APIs available to CorDapps. It means that any CorDapp should run in future versions of the platform without any change or re-compilation.

Similar to other applications, CorDapps are expected to evolve, which might involve:

  • Changing the structure of data exchanged between nodes
  • Changing the structure of data stored in the ledger (e.g., states)

Changing the structure of data exchanged between nodes

The serialization framework provides some support for the evolution of this case.

Example: Adding nullable properties

Nullable properties can be added to a class, and the framework will take care of the associated conversions. A node running an older version of the CorDapp will ignore this new property if data is sent from a node running a newer version of the CorDapp. A node running a newer version of the CorDapp will populate the property with null when receiving data from a node running the older version of the CorDapp.

Example: Removing nullable properties and adding non-nullable properties

Removing nullable properties and adding a non-nullable property is also possible by providing a default value. However, the serialization framework does not allow this form of data loss for data that persisted in the ledger, such as states and commands.

Since states can evolve and the ledger might contain states from many earlier versions of a CorDapp, newer versions of a contract need to contain appropriate logic that can process states from earlier versions of the CorDapp.

The contract logic for handling states from version viv_i of the CorDapp can be removed by a subsequent release of the CorDapp only after all unspent states in the ledger are from version vjv_j of the CorDapp, where j>ij > i.

New backwards incompatible feature

In some cases, the platform might introduce a new feature that is not backward compatible. The older versions of the platform cannot understand it . This feature can be problematic for two reasons:

  • Two nodes running different versions of the platform might reach different conclusions with regards to the validity of a transaction.

  • When validating a transaction, nodes are also supposed to validate previous transactions involved in the chain of the provenance of the states consumed in the current transaction.

This means that a node running an older version of the platform might fail to validate a transaction that was valid in the past simply because the transaction uses a feature introduced in a newer version of the platform.

Corda solving multiple versioning problem

Corda solves the multiple versioning problem with the use of the network minimum platform version.

Minimum platform version

Every network comes with a set of parameters that every node participating in the network needs to agree on and use to interoperate with each other correctly. This set contains a parameter called minimumPlatformVersion, which determines the minimum platform version that the nodes must be running. Any node which is below this will not be able to start.

Any platform feature that is not backwards compatible and requires a minimum version of the platform can check this parameter and be enabled only when the network is over a specific platform version. In this way, the nodes of a network can start using a feature only after they can be certain all other nodes will also be able to use it.

This process establishes a balance between nodes in a network that are keen on using a new feature and nodes that are risk-averse and are not willing to upgrade to a new version of the platform.

Note: However, this process applies only to features that have network-wide implications, e.g., ones that determine how data are stored on the ledger.

Features that do not affect the whole network

There are features that do not affect the whole network. For example changes to how two nodes interact during the execution of a flow or even how a single node executes some part of a CorDapp locally.

Multiple versioning levers provided by Corda

Corda provides multiple versioning levers for more fine-grained control. CorDapps provide two version numbers for this purpose: minimumPlatformVersion and targetPlatformVersion.

  • minimumPlatformVersion indicates the minimum platform version the node must have for the CorDapp to function properly, which is essentially determined based on the necessary features to the CorDapp and the platform version they were introduced in.

  • targetPlatformVersion indicates the highest version the CorDapp has been tested against and helps the platform disable backwards compatibility codePaths that might make the CorDapp less efficient or secure.

Note: These two versions only have implications on the node running the CorDapp, instead of the whole network.

Another example is the fact that flows in a CorDapp can be versioned to evolve while maintaining backwards compatibility. In this way, a flow can behave differently depending on the deployed version of the CorDapp on the counterparty node. This makes it possible to upgrade a CorDapp incrementally across various nodes, instead of all of them having to do it in lockstep.

Get hands-on with 1400+ tech skills courses.