Closed afck closed 8 months ago
Say chain C was closed at height hc
. Chain A, at height ha
later sends message m to C.
A's outbox for C now contains an entry ha
, and a cross-chain message goes to the worker responsible for C.
C is considered to have sent a SystemMessage::ChainClosed(BlockHeight)
to all other chains at height hc
; the argument is the lowest next expected block height from the recipient of that message, i.e. in A's case something ≤ ha
. However, this message is treated specially, and only actually delivered to those chains that send a message to C that was not received at any height < hc
(i.e. either at hc
or not at all).
C's worker finds that C has been closed, and C's outbox for receiver A doesn't have an entry at height ≥ hc
. So it puts hc
into it; it does not put anything in C's inbox. When it sends the outgoing messages for A, it finds that entry and sends a cross-chain message with ChainClosed
.
When A's worker receives that, it sets a closed
flag in its own outbox for C, and takes all remaining messages from heights ≥ ha
(and all future messages instead of putting them into the outbox); in this example m. It puts them into its own inbox from C, as "bounced".
In Event
, height
and index
are replaced by a single cursor
field. The Cursor
becomes an enum
:
enum Cursor {
/// The other chain is active; the `height` and `index` refer to the other chain.
Active { height: BlockHeight, index: u32 },
/// The other chain has been closed; `height` and `index` refer to our chain.
/// This is only used for bounced messages that were not received before the chain
/// was closed. All `Closed` values are considered to be greater than `Active` values.
Closed { height: BlockHeight, index: u32 },
}
If we eventually fully purge (or archive) the chain state, we'd also remove C's outbox from storage, so this would no longer work, and messages would fail to bounce. That may be okay, if we make the client handle bounced messages from closed chains with sufficient care: E.g. if we purge chains two weeks after closing, clients should never propose fast blocks that receive bounced messages older than one week from closed chains.
Chains cannot be fully closed immediately, only handed over to the validators. The validators will keep adding blocks bouncing all messages in the future, for some period. (Like two weeks?)
This requires fewer exceptions in the message and inbox/outbox logic, but creates much more work for the validators. The purging issue is the same as in proposal 1.
As discussed, we will change what it means to close a chain instead:
The owners are not removed; instead, a closed
flag is set that disallows all operations, and only allows bouncing (but not accepting) messages.
Also required for to https://github.com/linera-io/linera-protocol/issues/305.