Why does the ledger canister need to maintain a blockchain on top of the subnet's blockchain instead of only storing balances?

At the end of this talk, @bogdanwarinschi mentions that the ledger canister is essentially maintaining a ledger on top of the subnets ledger by storing all the transactions and linking them together. Why is that necessary? Couldn’t the subnet simply maintain a list of account identifiers with corresponding ICP balances instead?

I guess it has to do with the asynchronous nature of the IC. It seems that I have generally not fully comprehended yet how execution works on a particular subnet. As far as I understand, execution within a particular canister always happens synchronously. And on the other extreme, communication across subnets obviously is asynchronous. What about execution within a particular subnet? My intuition always was that this more or less works similar to other Blockchains namely synchronously. Am I mistaken about that? How would it even not be synchronous?

If the reason for running a ledger on top of a ledger has nothing to do with that, then it would be great to understand the reasoning behind that design choice.

Thanks in advance for any help!

Why is that necessary? Couldn’t the subnet simply maintain a list of account identifiers with corresponding ICP balances instead?

I think it’s for extra security so that the NNS cannot willy nilly change ICP balances in a proposal. (Almost everything else is modifiable by the NNS.)

As far as I understand, execution within a particular canister always happens synchronously. And on the other extreme, communication across subnets obviously is asynchronous. What about execution within a particular subnet?

The Internet Computer operates under a partially synchronous communication model.

This means that the IC assumes that messages sent between replicas within the same subnet are delivered within some finite time bound―but only periodically for short intervals of time. This assumption is needed only for “liveness” (i.e. the consensus protocol makes progress) but not for “safety” (i.e. consensus is correct).

Note that Bitcoin cannot guarantee safety in an asynchronous communication network. The IC, on the other hand, can.

See this whitepaper for details.

My intuition always was that this more or less works similar to other Blockchains namely synchronously.

The word ‘synchronous’ is highly overloaded IMO. Communication in the real world is not usually synchronous; sometimes, malicious actors can delay messages for arbitrarily long periods of time.

I think you are referring to the fact that transactions in Ethereum are atomic, even when one smart contract calls another. If that’s the case, then the execution model of the IC is fundamentally different than that of Ethereum. Both inter-subnet and intra-subnet canister-to-canister calls cause the originating canister to commit its state up until the point where it make the inter-canister call. The entire transaction (or update call, in IC lingo) is not atomic.

Because IC is a computing platform and not a crypto currency. On a subnet level there is no notion of “ICP transactions” - there are only messages and actors which process these messages and change their state (which is just a blob of bytes for a subnet).

Also, transactions (messages) on a subnet level are not stored forever but only for a small portion of time. There is no blockchain in a classical sense, there is a temporary window of blocks that always moves forward. Chain Key cryptography guarantees security of this process. Since a subnet state that is signed signed with the chain key could only be forged by following the protocol, there is no need in storing all the blocks.

This is why you have to implement your own ledger inside a canister each time you need a history of some events and ICP ledger canister does exactly that.

1 Like

I think it at the very least offers a form of verifiability. All blockchains require some degree of trust, but they should also offer the ability to verify if data (and history of data) is indeed correct with respect to user inputs. IC does not require blocks to be kept indefinitely in order to function, but the history of ICP transactions is also important for verification purpose, and keeping them in a chain structure strengthens that.

BTW, you might be interested in reading a related discussion Why should I trust NNS Ledger, seriously?

2 Likes

Thank you very much for the help! That is all very helpful. I’d love to understand all of that once and for all so I hope it’s ok if I keep asking. It seems like there are 3 different things that I don’t fully understand.

Terminology

Lately, I started to read more about how Ethereum is aiming to implement sharding in order to get a better understanding of what issues both protocols face and where exactly the differences lie. That helped me a lot to finally understand the issues around atomicity. What I find really confusing there is, as you mentioned, how the term synchronous and atomic relate to each other. I found this thread of Vitalik. Under “What does sharding change?” he describes how “yanking” could be used to allow for atomic transactions (across shards) as the execution would ultimately happen synchronously in one shard. Let’s not get into yanking but I think he meant that a contract can be transferred to a different shard, and then everything that is on there would then be executed within the same block and thus be atomic.
So he seems to be using the term synchronous to describe that the execution is not waiting on something but is happening at once, thus atomic. As you said that makes it pretty confusing, especially when we talk about the IC.

Communication assumptions

So that I can better differentiate between the assumptions around the IC’s communication model and atomicity could you give me the intuition of what the partially-synchronous assumptions practically imply? I mean Bitcoin seems to work reasonably well under the synchronous communication assumption, so what are the practical problems the IC solves exactly by not relying on synchronous communication? I mean I more or less understand that communication could be interrupted for some time without affecting safety but is that a significant problem for Blockchains such as Bitcoin? What would an attack for example look like on BTC that cannot happen to the IC?

Intra-subnet transactions

I think you are referring to the fact that transactions in Ethereum are atomic , even when one smart contract calls another. If that’s the case, then the execution model of the IC is fundamentally different than that of Ethereum. Both inter-subnet and intra-subnet canister-to-canister calls cause the originating canister to commit its state up until the point where it makes the inter-canister call. The entire transaction (or update call, in IC lingo) is not atomic.

I find it intuitive that inter-subnet transactions are not atomic, that is what Ethereum is also struggling with and is coming up with things like yanking to work around it (which comes with its own issues it seems). But if you have a specific subnet that is updated with each block, then why are the transactions within a specific block not atomic? So far I have always assumed this to be the case, even though of course the actor model seems to be applied even for transactions occurring within a particular subnet. But wouldn’t we want to have atomic transactions wherever we can get them? Doesn’t it make sense to have atomic transactions within the same subnet? I don’t fully get that. In relation to that, what exactly did you mean by the following:

Both inter-subnet and intra-subnet canister-to-canister calls cause the originating canister to commit its state up until the point where it make the inter-canister call.

Thanks again for the help.

Thanks for the help!

State

Because IC is a computing platform and not a cryptocurrency. On a subnet level, there is no notion of “ICP transactions” - there are only messages and actors which process these messages and change their state (which is just a blob of bytes for a subnet).

Would you mind elaborating on what you mean by that? On Ethereum you do have the notion of transactions that are related to some specific part of the overall state by specifying the address of a specific contract that you call. Generally, a token contract only stores the mapping of addresses with balances, not really any blocks as part of its state. I assumed this works in a similar way with canisters. Maybe I need to read up on that.

Storing blocks

If blocks are not stored forever, it does make sense that the canister stores the transactions. But at the same time, it sort of implies that not storing the blocks reduces the overall security, so it is a bit of a contradiction potentially.

I understand how chain key works generally but would you mind elaborating why it allows getting rid of old blocks:

Chain Key cryptography guarantees security of this process. Since a subnet state that is signed signed with the chain key could only be forged by following the protocol, there is no need in storing all the blocks.

In addition to that, honestly to this day I never fully understood why Blockchains generally need to store every block. Couldn’t a cut-off point simply be defined after which everyone simply agrees on a new initial state?
That makes it even harder to understand why the IC can get rid of old blocks while other blockchains don’t seem to be able to do so. Or even more confusing, Ethereum differentiates between archive nodes and others, so not everyone is storing all the blocks. I never deeply understood the design choices behind that. Of course, starting from nobody having any balances is sort of a social reference point that requires no state at all to be stored by anyone, which might be the reason for it, but is that all?

Yes, this is the same for the IC. That part of my comment was related to “why ICP token for IC network is not the same that ETH token for Ethereum network”.

On Ethereum (and other blockchains) an outside observer can’t say for sure whether some particular isolated block is the part of the global blockchain or not. You need the whole chain in order to validate it. This is because each block is signed only by the validator’s signature, but the network is permissionless - there is no notion of “approved validator set”. So this signature is only used to identify the validator.

On IC all the blocks literally signed with the same single key. You can take any isolated block and validate that this is indeed a valid block from the IC blockchain (because otherwise there would be no signature). This implies, that you don’t have to store a complete blockchain since it’s just useless - the chain key signature already gives all the proofs you need.

1 Like

Thank you very much! Nice, I’ve seen the thread before but hopefully understand the arguments better by now.
It does kind of make sense with the blocks but I still don’t fully understand it all, see my other response.

Wow, you just blew my mind! Makes total sense, I should have seen this. I was aware that people can use a single public key to verify that messages are coming from the IC but it seems like I did not fully comprehend the implications. I’ll think more about this. Thank you very much.

And yes true, I was briefly thinking of ICP being equivalent to ETH, which is obviously not the case. Rather cycles but the reverse gas model plays into it.

Both inter-subnet and intra-subnet canister-to-canister calls cause the originating canister to commit its state up until the point where it make the inter-canister call.

I mean that as soon as a canister makes an inter-canister call, the original call that the canister was executing is no longer atomic. See the docs for details. It’s part of the programming model, and differs starkly from Ethereum AFAIK.

I mean Bitcoin seems to work reasonably well under the synchronous communication assumption, so what are the practical problems the IC solves exactly by not relying on synchronous communication?

I find it intuitive that inter-subnet transactions are not atomic, that is what Ethereum is also struggling with and is coming up with things like yanking to work around it (which comes with its own issues it seems). But if you have a specific subnet that is updated with each block, then why are the transactions within a specific block not atomic?

These are good questions that I don’t have the answers for. @PaulLiu @diegop Would either of you happen to know?

1 Like