pub trait NotificationImpliesPersistedChange: CorrectValidator + StorageAtomicity { }Expand description
Lemma (A correct validator’s notification reports a change that is already persisted). If a
client receives a Notification from a correct validator, the state change it names is in
that validator’s storage. Nothing is claimed about a faulty validator’s notifications, which by
CorrectValidator may report anything at all.
Proof. Notifications are not sent where they are built. Each is pushed onto the
notifications field of a NetworkActions value which the handler returns, and every
handler that changes state calls save() before returning it — a failed save propagates with
?, so the actions are dropped and nothing is dispatched. Site by site:
Reason::NewBlockandReason::NewEventsare pushed inChainWorkerState::execute_contiguous_blockbefore itsself.save()?, so a save that fails discards them along with the actions that carry them.Reason::NewEventsis pushed again inpreprocess_certified_block, there after the save rather than before it, which reaches the same conclusion more directly.Reason::NewRoundis built insidecreate_network_actionsfromChainManager::current_round, and travels out in the same returned value.Reason::NewIncomingBundleis pushed inWorkerState::handle_cross_chain_requestonly onceprocess_cross_chain_updatehas returnedCrossChainUpdateResult::Updated, and that result crosses achain_writebatch, which takes the lock and saves once before replying.
The caller dispatches through Notifier::notify_chain on the returned value alone, so no path
reaches a client without a completed save. By StorageAtomicity that save is all or nothing,
so a client is never told about a half-written change. ∎
A notification carries no evidence. Notification is a chain_id and a Reason: no
signature, no certificate, not even a field naming the sender. Validators are not asked to sign
them.
Knowing who sent one is a deployment matter rather than a protocol one. Under
NetworkProtocol::Grpc(TlsConfig::Tls) the transport authenticates which validator the stream
came from, so a third party cannot inject notifications into it; TlsConfig::ClearText is an
equally valid configuration, so the specification cannot assume even that. And where it does
hold it authenticates the origin, never the content, and only to the client holding the
connection — a client cannot show anyone else what a validator told it. A notification is
therefore never evidence in the sense the accountability results use: none is convictable, and
none can be forwarded as proof of anything.
So the qualifier above is not a technicality a client can discharge by inspection. A fabricated
notification is indistinguishable by content from a sound one, and the only way to learn
whether the change happened is to ask. What a client may take from one is that it is worth
querying now, and never what the answer will be. That the named block is the block at that
height, rather than one validator’s idea of it, is CommitAgreement’s and not this lemma’s.