This document attempts to formalize what it means for an IDL language (like Candid) to be sound, in the presence of service upgrades and (optional) host-language subtyping. It provides a framework that can be instantiated with various proposed rules for service type evolution.
In the interest of simplification, this framework combines the notion of “service type” and “function type” (as if we only had function types, or if each service had only one function).
An IDL language would instantiate these relations:
Parameter meta-variables:
t
: An argument or result types ::= t1 -> t2
: A service type
Parameter relations (to be instantated by a concrete solution):
t1 <: t2
: A value encoded att1
can be understood att2
s1 in t1 <: s2 in t2
: A value encoded att1
contains a service reference at types1
, which, when decoded att2
, has types2
.s1 ~> s2
: A service may evolve froms1
tos2
s1 <:h s2
: Host-language subtyping relation on service types (trivial reflexive relation in host languages without subtyping)
Further meta-variables:
A
,B
, …: A service identifierS : 𝒫(P)
: The global state, a set of assertionsP ::=
: AssertionsA : s
: ServiceA
has service types
A has B : s
: ServiceA
has a reference to serviceB
at types
Judgements:
-
S1 --> S2
: State transitions-
Services can be added
A fresh in S ───────────────────── S --> (A : s) ∪ S
-
Services can evolve
s1 ~> s2 ──────────────────────────────── { A : s1, S' } --> { A : s2, S'}
-
Services can learn about other services
A : s ∈ S ──────────────────────────── S --> (B has A : s) ∪ S
-
Services can send references to each other (uses auxillary judgments)
A has C at s1 ∈ S [S] A =(t1)=(t2)=> B s1 in t1 <: s2 in t2 ──────────────────────────────────────────────────────────────────── S --> (B has C : s2) ∪ S
-
Host-language subtyping may apply
A has B at s1 ∈ S s1 <:h s2 ────────────────────────────────── S --> (A has B : s2) ∪ S
-
-
[S] A =(t1)=(t2)=> B
: In stateS
,A
can send a message toB
at typet1
, andB
expects the message to be of typet2
.- Calls:
A has B : t1 -> _ ∈ S B : t1' -> _ ∈ S ────────────────────────────────────────────── [S] A =(t1)=(t1')=> B
- Replies
B has A : _ -> t1' ∈ S A : _ -> t1 ∈ S ────────────────────────────────────────────── [S] A =(t1)=(t1')=> B
- Calls:
A state S
is consistent if
Forall
[S] A =(t1)=(t2)=> B
we havet1 <: t2
.
An IDL language is sound if and only if:
Forall
{} -->* S
,S
is consistent.
A solution with canonical subtyping (transitive, contravariant) is sound.
Assume a reflexivie and transitive relation t1 <: t2
.
Define (t1' -> t2') <: (t1 -> t2) ⟺ (t1 <: t1') ∧ (t2' <: t2)
Assume that
s1 ~> s2
only ifs2 <: s1
(it can be more restrictive)- If
t1 <: t2
ands1 in t1 <: s2 in t2
thens1 <: s2
. s1 <:h s2
only ifs1 <: s2
(it can be more restrictive).
The following is obviously an invariant of -->
:
Every serivce
A
has at most one type, i.e. for a fixed{} --> * S
,A : s ∈ S
is a left-unique relation.
We prove that the following is an invariant of -->
:
If
A : s1 ∈ S
andB has A : s2 ∈ S
, thens1 <: s2
Consistency follows from this by inversion on [S] A =(t1)=(t2)=> B
(to figure
out who called whom):
- If
A has B : t1 -> _ ∈ S
andB : t1' -> _ ∈ S
thent1' -> _ <: t1 -> _
(by the invarinat) thust1 <: t2
- If
B has A : _ -> t1' ∈ S
andA : _ -> t1 ∈ S
then_ -> t1 <: _ -> t2
(by the invariant) thust1 <: t2
.
With S = {}
, the invariant holds trivially.
Assume S
satisfies the invariant, and consider the various state transitions
S -> S'
:
-
A service
C
gets added.Because
C
is fresh inS
, it cannot be in anyhas
relation, so the invariants continues to hold. -
A service
C
evolves froms3 ~> s4
If
A : s1 ∈ S'
andB has A : s2 ∈ S'
, then eitherC ≠ A
ands1 <: s2
follows from the invariant aboutS
.Or
A = C
, sos1 = s4
andA : s3 ∈ S
. We haves3 <: s2
by the invariant onS
ands4 <: s3
by the assumption on~>
, sos1 <: s2
by transitivity of<:
. -
Services can learn about other services
This adds
B has A : s
to the state, givenA : s ∈ S
. Sos <: s
by reflexitivity. -
A
sends a reference toC
toB
.This adds
B has C : s2
to the state, givenA has C at s1 ∈ S [S] A =(t1)=(t2)=> B s1 in t1 <: s2 in t2
Let
C : s3 ∈ S
. By the invariant onS
we learns3 <: s1
. By consistency ofS
we havet1 <: t2
. Withs1 in t1 <: s2 in t2
this yieldss1 <: s2
. Sos3 <: s2
, as required. -
Host-language subtyping may apply.
This adds
A has B : s
to the state, givenA has B at s1 ∈ S s1 <:h s2
Let
B : s3 ∈ S
. By the invariant onS
we learns3 <: s1
. The assumption on<:h
yieldss1 <: s2
. Sos3 <: s2
, as required.
Therefore, every {} -->* S
is consistent, and thus the IDL system is sound.