Account Upgrade

This tutorial presents a scenario where a custodian offers its clients the option to voluntarily upgrade their “old” Account contracts to a “new” version. The focus is on demonstrating the process of such a voluntary upgrade.

We are going to:

  1. Introduce MyAccount, a custom account implementation for the custodian. It differs from the standard Daml Finance Account implementation in that it does not implement the Lockable interface, making it a non-freezable account.
  2. Prevent the custodian from creating old Account instances, by archiving its existing AccountFactory.
  3. Instantiate a new account factory, MyAccountFactory, which can create MyAccount instances.
  4. Provide a MyAccountUpgradeRule instance for clients, permitting them to upgrade their existing Account instances to new MyAccount instances.
  5. Upgrade the accounts for the clients.

Run the Script

You can run this tutorial using the runUpgradeAccount script found in the UpgradeAccount.daml module. Let us examine it step-by-step.

Setup

The script starts off with runSetupAccountsAndHoldings which sets up the necessary parties (a custodian Bank and its clients, Alice and Bob), an account factory (used for creating accounts) for the Bank, and accounts for both Alice and Bob. Additionally, it creates a holding for Alice. Since the holding refers to its account by key, which remains unchanged, it does not require an upgrade when the account is upgraded:

  SetupState
    { bank
    ; bankAccountFactoryCid
    ; alice
    ; aliceAccount
    ; bob
    ; bobAccount
    ; allClients
    } <- runSetupAccountsAndHoldings

Initially, the accounts and the account factory are of the old version. The new implementations, MyAccount and MyAccountFactory, can be found in the MyAccount.daml module.

Create a New Account Factory

To prevent the creation of accounts of the old implementation, the first step involves archiving the Bank’s existing account factory:

  submit bank do archiveCmd bankAccountFactoryCid

Next, we instantiate a MyAccountFactory responsible for creating MyAccount instances:

  submit bank do createCmd MyAccountFactory with provider = bank; observers = allClients

Provide an Upgrade Rule

To offer the clients to upgrade their existing account to a MyAccount instance, we instantiate a MyAccountUpgradeRule contract (which is also part of the MyAccount.daml module):

  cid <- submit bank do createCmd MyAccountUpgradeRule with custodian = bank; observers = allClients

Clients Upgrade

Following this, we let both Alice and Bob upgrade to the new account version:

  submit alice do exerciseCmd cid UpgradeToMyAccount with account = aliceAccount
  submit bob do exerciseCmd cid UpgradeToMyAccount with account = bobAccount

Summary

Upon completing this tutorial, you should have a solid understanding of how to manage voluntary upgrades. The essential steps include:

  • Replacing the old factory with a new, updated version.
  • Introduce a rule contract that enables users to transition from the old to the new version, provided they are willing to do so.

In our next tutorial, we’ll explore the process of upgrading holdings in a lazy manner.