I’m working on the migration process of DAML contracts. I have already made the templates, the script to create the proposals and the trigger, now I need to collect the signatures of all participants to migrate the contracts, I have seen that the proposed solution is that “use a Daml script to accept the proposal, this step will often be exposed as part of a web UI”, but I would like to know if there is a way to collect all the signatures before to start process. Sometimes my contracts have interaction with contracts of the same type, for that reason I have to migrate all my contracts at once, otherwise these dependencies could be pointing to old contracts.
I’m not entirely sure I understand your question correctly, but, yes, in principle, you can collect all the signatures before you upgrade any contract, and then upgrade all the contracts at once, for a given subset of users. Just create a separate template “CollectSignaturesForUpgrades” and have that contract take a list of other contracts to upgrade.
That way you can keep all the old contracts unchanged while you collect signatures, and then upgrade all of them at once (with a choice on that
CollectSignaturesForUpgrades contract). This may scale poorly depending on how intricate your web of contracts-to-upgrade is and how many parties are involved, I suppose.
For a concrete example, you can take a look at the DAVL upgrade process. Once the
UpgradeAgreement contract is signed, the company can upgrade all contracts; there is no need for having an intermediate state where some contracts are upgraded and some are not (for a given set of parties). In this case contracts are upgraded one at a time, but nothing would prevent you from writing a choice that takes a list of contract IDs instead of one at a time.
Thanks for your response,
Yes, exactly what I need is something like CollectSignaturesForUpgrades contract that you mention, because I need to collect previously those signatures, Is there a way to do the same but more scalable?
I can’t answer that without knowing more about what you’re doing. If whatever state your ledger is in requires collecting a million signatures before upgrading tens of millions of contracts in a single transaction, that’s not going to work very well. If you have a system like DAVL where you can make do with two signatures and one contract at a time, there should not be any issue. For all the in-betweens, it will depend heavily on many things, like how your DAML code is structured, what is the actual “shape” of the relationships between contracts (not templates) on the ledger, which storage layer you’re using, how big the machines you’re using are, etc.
@DavidBelinchon have you looked at some of the resources that are available on upgrading?
Those should cover your question. If not, maybe you could restate your question around one of those. As @Gary_Verhaegen said, it’s difficult to help without some more contextual information.
Edit: I should also mention that we have improved upgrading features on our roadmap, aiming to improve both the UX as well as the scalability.
yes we already looked at the documentation available and implemented a migration process following the guide. During the development of the migration process we encounter the following issues:
- All parties in DAML have to sign the ‘migration’ contract so that it can be updated to the newest version. In our system we will have many users and some of them will not sign in time.
- In the case where parties do not sign in time we understand that we can ‘freeze’ these contracts to be signed at a later moment. But here come our questions:
- What happen with contracts that are related to each other, on contract is updated to version 2 but the other is still in version 1?
- We have to maintain all versions of contracts not signed already?
There is a natural tension in multi-party applications between wanting to give users ownership and control over their data and processes, and wanting to retain control of applications as the author - for example to do upgrades.
The more you decentralise ownership, the harder upgrades get for the exact reason you lay out: you need everyone’s agreement.
On one extreme end of the spectrum, you have traditional centralised applications, where the operator owns all data and processes and can upgrade unilaterally. You can model this in Daml by making a single party the only signatory on all contracts. You still get the synchronization, authorization and auditability benefits form Daml and its underlying platform, but you would be explicitly saying “this application is owned and operated by David, and David can change the rules without notice”.
At the other hand of the spectrum are public chain applications, where everyone co-owns everything. The usual solution to upgrading is to just abandon an old version and start a new one. Ie upgrades amount to forking the application, just like upgrades to chain infrastructure tend to fork the chain. Ie every user decides whether they continue operating on the old version or switch to the new. That’s the “nuclear” approach to upgrading which is obviously not practical for most business applications.
In between you have a whole spectrum of options.
One approach you can try to take is to say “I want users to (co-)own the data, but I as the application operator own the rules”. You can make that happen by having completely separate templates for data and rules. Data is signed by both you and the relevant users, rules are signed only by you. When you want to change the rules, you can do so unilaterally. The minimum you can achieve this way is that if users don’t sign the upgrade, they go into a “read-only” mode, which gives them a strong incentive to sign up.
Next, you can design your application to be sufficiently sharded by parties. Ie see whether you can partition your contracts in such a way that each set only involves a small group of parties. Then you can do a rolling upgrade, upgrading each shard as all its stakeholders have signed the upgrade contract.
This last technique goes hand in hand with a pattern @simon recently described in a blog post as well. In that pattern, you do the upgrade in two distinct phases: First you upgrade client applications (which usually have single party ownership) to be able to work on processes of both the old and new version. Once a sufficient volume of participants has done that, participants can safely start operating in the new version.
On your second question, it really depends what those references are and how they are used. Daml does not itself enforce referential integrity. Ie a contract can reference a non-existent (or archived) ContractId, or a Contract Key that is not allocated. Generally, if I sign a contract C1 that references a contract C2 which I have not signed, I accept the possibility that the signatories of C2 archive that contract and my contract C1 ends up with a dangling reference.
Whether you accept dangling references during an upgrade really depends on what impact that has on the users that have not yet upgraded, and whether that impact is acceptable.