This document contains information about the deployment of smart contracts.

1. Deployment via CoreAPI

The first option how to deploy smart contracts and related resources to Thought machine environment is using the CoreAPI. For each resource you need to create / deploy, you can find an example of CREATE request in the API documentation and follow the request scheme to deploy your product.

However, downside of this approach is that when having multiple TM resources with inter-product dependencies, this approach is not scalable well enough and creates a great overhead on handling duplicates, dependencies and migrations of existing resource instances. For this reason we recommend to opt in for the next approach.

2. Deployment using CLU (configuration layer utility by Thought Machine)

Thought machine created a custom deployment utility, which takes resource definitions as inputs and produces a deployment pipeline, which then deploys all required resources to the TM environment.

It is able to handle dependencies between resources, automatically skips resources that haven’t changed and verifies the correctness of resources before deployment. Basically the only disadvantage of using CLU are their not-so-thought-through logs, but although there aren’t many logs, they still provide all the needed information regarding the deployment process. For us, this is the way to go when deploying smart contracts and that’s why we built a deployment pipeline around the CLU, which is currently able to deploy all the resources we need for SaFI:

  • smart contracts

  • supervisor smart contracts

  • global parameters / global parameter values updates

  • internal accounts

  • workflows

  • postings api clients

The CLU pipeline along with its source code can be found here: https://github.com/SafiBank/SaFiMono/tree/main/tm-contracts/deploy .

There is also a README.md file which contains more in depth explanation for the CLU pipeline configuration (with step by step how to setup and use the CLU pipeline), and a video-recorded workshop of brand new TM env deployment using the CLU pipeline and another workshop recording to explain the code base and functioning of the deployment pipeline.

There is also an official manual for CLU by Thought machine:

Resources deployment flow

When you run the deployment pipeline, following steps are being performed:

  1. Current deployed versions of products are fetched from TM API

  2. All smart contract codes are rendered and workflow definition codes gathered

  3. Resource configuration yaml files containing details about each “to-be-deployed” resources are collected and templated by prefixes (see README for more details)

  4. Resource configurations are validated

  5. Resources are deployed (or updated or skipped if unchanged)

  6. If smart contracts or supervisor smart contracts were among the deployed / updated resources, accounts and plans migrations are run

Accounts and plans migrations

If a smart contract of supervisor smart contract is updated, existing accounts are not migrated automatically (our preferred migration strategy is set to PRODUCT_VERSION_MIGRATION_STRATEGY_ADD_VERSION_AUTO_MIGRATE_USERS`).

This is mostly due to main and pocket account. Since these accounts are being used under plans with debt manager supervisor, they usually need to be migrated to their newer versions together with the whole plan being migrated to a newer supervisor version. This is due to fact that each supervisor version is strictly mapped to a selected main account product version - and when the account updates, the product version changes and therefore the migration will fail because the plan will contain unsupported product versions.

To handle this and be able to update and migrate accounts, bridge supervisor plan updates are being used and the process is as following:

  1. verify, if either main account or pocket account was upgraded (if a new version was deployed) - and therefore if we need account migrations

    1. if no, then go to step 5

    2. else continue with step 2

  2. if main / pocket account was upgraded, then first create a bridge supervisor, with supports both old and new version of main / pocket accounts

  3. migrate all existing plans to the bridge supervisor version

  4. migrate all main / pocket accounts to the new main / pocket account version

  5. if also supervisor was updated (in case main / pocket account were updated supervisor needs to be updated always to reference new account versions and move from bridge to final supervisor, if main / pocket was not updated, we still might want to just update the supervisor), migrate the plans to the new supervisor version, which now supports the version of accounts currently in the plans

3. Good practices / what to avoid

Be careful when upgrading existing accounts in plans

If an account migration to a newer deployed version fails, there is no way to know just from the logs / api responses that you get within the CLU pipeline. You have to verify that the accounts and plans were really upgraded by fetching the migration statuses via Core API (the migration itself is an asynchronous job). However, good thing about this is that if an account / plan migration fails, it should be transactional - so in the end the account / plan is kept at previous working versions and state.

Always bump the supervisor version when upgrading anything related to it

Even when you only update the supervisee (main / pocket accounts) and not the supervisor itself, you still NEED to update the supervisor version. If you do not do this, the supervisor deployment will fail, because TM does not allow you to create a new supervisor with version set to same or lower than the previous highest deployed version.

History of instance parameter changes is removed at account upgrade

When upgrading (migrating) an account to a newer version, if you changed the values of its instance parameters multiple times before the upgrade, the history gets unfortunately removed at the time of upgrade (and only one, the most recent value is kept as the current value of the instance parameter of the upgraded account).

In case you need to keep the history of instance parameters after account upgrade, you have to perform these additional steps:

  • first create backups of whole history of instance parameters for every existing account that is about to be migrated

  • then migrate the accounts

  • then fill the instance parameter history of the upgraded account with the backed up historical value changes

This workaround is not implemented yet as a part of CLU deployment pipeline. More info here SM-7711 - History of instance parameters gets removed with account upgrade Done .

Attachments: