Immutability with database based domains

I have been asked the following with regard to a database based domain:

I understand the schema (ie data model) is proprietary. Is it blockchain like? I mean, are you storing blocks in tables, that are linked together using cryptographic method? The question behind is around immutability of the ledger, I’d like to understand how you can ensure that data stored in a database are never tempered. We all know how it works with blockchain, I’d like to understand better how you do it.

At the participant level, I can see from How Daml guarantees immutability in a centralized setup?, Canton - How to ensure distributed ledger is immutable? and from the docs that a dishonest participant could manipulate their local view of the ledger, but that this would be detected and rejected by other participants. I guess, similarly, a dishonest domain operator could manipulate their data but participants could detect this by replaying and comparing against actual state.

So is it fair to say that the ledger is immutable in that it would require all participants hosting the signatories of a given smart contract to act maliciously to to change it?

Do either participants or database based domains do any chaining together of data (for example when the mediator persists every received message)? Would there even be any point, or if that functionality is really required then should a decentralised domain be used?

To answer, we’ll start with a recap of how this works for blockchains generally, before addressing the specifics of Canton.

You have two sides to every blockchain system: the ledger (e.g. the blocks in the blockchain) and the resulting state (e.g. the Bitcoin balances). The state is derived from the ledger using a deterministic calculation. To be able to serve data efficiently, nodes store both the ledger and the state. Both of these types of data are immutable in the sense that tampering with that data can be detected and the truth can be recovered. However, it does take a proactive verification step to detect and repair changes to the immutable data. Since we have two types of data, we need two types of such tamper-proofing: state verification and ledger verification.

State verification is easy. If you are worried that the state was corrupted, you can recalculate it from the ledger. Some ecosystems and wallets like Bitcoin Core do exactly that. Other blockchains like Ethereum optimize that by including state hashes in their blocks, and allowing you to download state snapshots so you don’t need to recalculate from genesis. If you think you may have been corrupted, recalculate your state (or state hash) and compare.

Ledger verification has two pieces to it. Firstly, you need to determine whether you are on a valid ledger. Secondly, you need to figure out that you are on the same ledger as everyone else, or on a fork.

Ledger validation works the same as state verification. Go through the entire history from genesis and validate according to the blockchain’s rules. You can short-circuit this if you can obtain a block and corresponding state snapshot that you trust. In practice that’s usually done by asking a sufficient number of other nodes, where it’s really up to you to decide what you deem sufficient.

To detect whether you are on a fork, you have entirely different mechanisms in different blockchain systems. That’s what the consensus algorithms like proof of work, proof of stake, proof of authority and others are all about. Proof of authority (PoA) is the one most relevant to the Canton discussion. In PoA, you trust that a block is on the main branch if it is signed by some subset of privileged nodes. Note that most blockchains do not deal with malicious forks. Ie PoA algos fail if two conflicting blocks are signed. Even Ethereum 2.0 just stops dead should the PoS algo sign two conflicting epochs.

Note that none of these mechanisms prevent tampering with the local databases - e.g. your Ethereum Full Node’s local database. They only allow you to verify and/or rebuild your local database.

So now back to Canton and how it does state verification, ledger validation and fork detection. Canton offers the same kinds of tamperproofing mechanisms as other blockchains, though it does so at a more fine-grained level in order to be able to offer scalability and privacy.

Canton does not use blocks for performance and scalability reasons, but commits each transaction to the ledger individually. Transactions are linked to each other first and foremost through the UTXO ledger model in which each transaction references outputs from previous transactions.

The consensus algorithm is run at the participant level, not the domain level. A good analogy of the domain is Ethereum’s networking layer. All[1] the information needed for verification is contained on the participant nodes.

Furthermore, there is no one place where you have the global ledger in a form that you could verify it. That would be hard to reconcile with privacy or scalability. So verification is always done as a combination of local verification and bilateral processes between participants.

Since state verification and ledger validation are a local process, it works the same as in other blockchains. If in doubt, you reprocess the entire ledger. If it’s impractical to do it from genesis, you can do so from a recent snapshot that you trust - e.g. a backup. To add additional trust to backups, nodes frequently write “ACS commitments” to the ledger. These are signed state hashes of the state shared between two nodes. So you can restart your verification from a time when you have cryptographic proof that others agreed with you up to that point.

Forks are primarily prevented by the Canton protocol, which you can think of as a fine-grained dynamic proof of authority consensus protocol. Instead of a global set of signers for all transactions, Canton has a set of validators per transaction calculated from the signatory and controller annotations. Each transaction has to be confirmed with cryptographic signatures for it to be committed. Once you have all that cryptographic evidence, the existence of that transaction is irrefutable. The domain cannot fabricate transactions as they cannot forge the signatures.

Just like other proof of authority algorithms, Canton can be attacked if all validators of a transaction get together and sign two conflicting transactions. The other way in which Canton could be tampered with is deleting data from the domain - possibly selectively - so that some nodes see a message/transactions and others don’t.

Both of these attacks only matter if someone other than the attackers can observe them. Otherwise it’s a bit of a “if a tree falls in the woods…” situation. And if they are observable, there is enough cryptographic information in Canton to irrefutably establish the truth and find out who cheated.

There are fundamentally three types of attacks that you could try to run this way:

  1. Invalid transactions - commit transactions that do not comply to the Daml models
  2. Forks - get Alice and Bob into different states
  3. Double spends - consume the same contract twice

Invalid transactions are observable to all observers and can be dropped on the fly so that all nodes have a valid ledger at all times. If participants signed an invalid transaction, they are immediately identifiable as malicious.

Forks are detected either immediately the moment a participant on one side of the fork uses a contract that is unknown to a participant on the other side of the fork, or soon after the fact by comparing ACS commitments.

Double spends require all signatories of a contract to collude. They could just as well have created a second copy of the contract in the first place so this “attack” is somewhat explicit in Daml, unlike majority attacks in other blockchain systems. In Daml/Canton such an attack is considered malicious and like a 51% attack on Bitcoin cannot be prevented, but it is detectable and fairly harmless.

[1] There’s a small carveout from this: The mediator holds the Participants’ confirmations for privacy reasons.

4 Likes