Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Basic packet flow in TLA+ #248

Merged
merged 8 commits into from
Sep 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
138 changes: 107 additions & 31 deletions docs/spec/relayer/Chain.tla → docs/spec/relayer/tla/Chain.tla
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---------------------------- MODULE Chain ----------------------------

EXTENDS Integers, FiniteSets, RelayerDefinitions,
ClientHandlers, ConnectionHandlers, ChannelHandlers
ClientHandlers, ConnectionHandlers, ChannelHandlers, PacketHandlers

CONSTANTS MaxHeight, \* maximal chain height
ChainID, \* chain identifier
Expand All @@ -10,9 +10,12 @@ CONSTANTS MaxHeight, \* maximal chain height

VARIABLES chainStore, \* chain store, containing client heights, a connection end, a channel end
incomingDatagrams, \* set of incoming datagrams
history \* history variable
incomingPacketDatagrams, \* sequence of incoming packet datagrams
history, \* history variable
packetLog, \* packet log
appPacketSeq \* packet sequence number from the application on the chain

vars == <<chainStore, incomingDatagrams, history>>
vars == <<chainStore, incomingDatagrams, incomingPacketDatagrams, history, packetLog, appPacketSeq>>
Heights == 1..MaxHeight \* set of possible heights of the chains in the system

(***************************************************************************
Expand Down Expand Up @@ -78,12 +81,34 @@ ChannelUpdate(chainID, store, datagrams) ==

chanCloseConfirmStore

(***************************************************************************
Packet update operators
***************************************************************************)
\* Update the chain store of the chain with chainID and the packet log,
\* using the packet datagrams generated by the relayer
\* (Handler operators defined in PacketHandlers.tla)
PacketUpdate(chainID, store, packetDatagrams, log) ==
\* if the sequence of packet datagrams is not empty
IF packetDatagrams /= AsSeqPacketDatagrams(<<>>)
THEN \* process the packet datagram at the head of the sequence
LET packetDatagram == AsPacketDatagram(Head(packetDatagrams)) IN
LET packet == packetDatagram.packet IN
\* get the new updated store and packet log entry
LET newStoreAndLog ==
IF packetDatagram.type = "PacketRecv"
THEN HandlePacketRecv(chainID, store, packetDatagram, log)
ELSE IF packetDatagram.type = "PacketAck"
THEN HandlePacketAck(chainID, store, packetDatagram, log)
ELSE [chainStore|-> store, packetLogEntry |-> log] IN
newStoreAndLog
ELSE [chainStore |-> store, packetLog |->log]

(***************************************************************************
Chain update operators
***************************************************************************)
\* Update chainID with the received datagrams
\* Supports ICS2 (Clients), ICS3 (Connections), and ICS4 (Channels).
UpdateChainStore(chainID, datagrams) ==
\* Supports ICS2 (Clients), ICS3 (Connections), and ICS4 (Channels & Packets).
UpdateChainStoreAndPacketLog(chainID, datagrams, packetDatagrams, log) ==

\* ICS 002: Client updates
LET clientUpdatedStore == LightClientUpdate(chainID, chainStore, datagrams) IN
Expand All @@ -94,15 +119,20 @@ UpdateChainStore(chainID, datagrams) ==
\* ICS 003: Channel updates
LET channelUpdatedStore == ChannelUpdate(chainID, connectionUpdatedStore, datagrams) IN

\* ICS 004: Packet transmission
LET packetUpdatedStoreAndLogEntry == PacketUpdate(chainID, channelUpdatedStore, packetDatagrams, log) IN
LET packetUpdatedStore == packetUpdatedStoreAndLogEntry.chainStore IN

\* update height
LET updatedChainStore ==
IF /\ chainStore /= channelUpdatedStore
IF /\ chainStore /= packetUpdatedStore
/\ chainStore.height + 1 \in Heights
THEN [channelUpdatedStore EXCEPT !.height = chainStore.height + 1]
ELSE channelUpdatedStore
THEN [packetUpdatedStore EXCEPT !.height = chainStore.height + 1]
ELSE packetUpdatedStore
IN
updatedChainStore

[chainStore |-> updatedChainStore,
packetLog |-> packetUpdatedStoreAndLogEntry.packetLog]

(***************************************************************************
Chain actions
Expand All @@ -111,29 +141,68 @@ UpdateChainStore(chainID, datagrams) ==
AdvanceChain ==
/\ chainStore.height + 1 \in Heights
/\ chainStore' = [chainStore EXCEPT !.height = chainStore.height + 1]
/\ UNCHANGED <<incomingDatagrams, history>>
/\ UNCHANGED <<incomingDatagrams, incomingPacketDatagrams, history>>
/\ UNCHANGED <<packetLog, appPacketSeq>>

\* Send a packet
SendPacket ==
\* enabled if appPacketSeq is not bigger than MaxPacketSeq
/\ appPacketSeq <= MaxPacketSeq
\* Create a packet: Abstract away from packet data, ports, and timestamp.
\* Assume timeoutHeight is MaxHeight + 1
/\ LET packet == AsPacket([
sequence |-> appPacketSeq,
timeoutHeight |-> MaxHeight + 1,
srcChannelID |-> GetChannelID(ChainID),
dstChannelID |-> GetChannelID(GetCounterpartyChainID(ChainID))]) IN
\* update chain store with packet committment
/\ chainStore' = WritePacketCommitment(chainStore, packet)
\* log sent packet
/\ packetLog' = Append(packetLog, AsPacketLogEntry(
[type |-> "PacketSend",
srcChainID |-> ChainID,
sequence |-> packet.sequence ,
timeoutHeight |-> packet.timeoutHeight]))
\* increase application packet sequence
/\ appPacketSeq' = appPacketSeq + 1
/\ UNCHANGED <<incomingDatagrams, incomingPacketDatagrams, history>>

\* write a packet acknowledgement on the packet log and chain store
AcknowledgePacket ==
/\ chainStore.packetsToAcknowledge /= AsSeqPacket(<<>>)
/\ chainStore' = WriteAcknowledgement(chainStore, Head(chainStore.packetsToAcknowledge))
/\ packetLog' = LogAcknowledgement(ChainID, chainStore, packetLog, Head(chainStore.packetsToAcknowledge))
/\ UNCHANGED <<incomingDatagrams, incomingPacketDatagrams, history>>
/\ UNCHANGED appPacketSeq

\* Handle the datagrams and update the chain state
HandleIncomingDatagrams ==
/\ incomingDatagrams /= AsSetDatagrams({})
/\ chainStore' = UpdateChainStore(ChainID, AsSetDatagrams(incomingDatagrams))
/\ incomingDatagrams' = AsSetDatagrams({})
/\ history' = CASE chainStore'.connectionEnd.state = "INIT"
-> [history EXCEPT !.connInit = TRUE]
[] chainStore'.connectionEnd.state = "TRYOPEN"
-> [history EXCEPT !.connTryOpen = TRUE]
[] chainStore'.connectionEnd.state = "OPEN"
-> [history EXCEPT !.connOpen = TRUE]
[] chainStore'.connectionEnd.channelEnd.state = "INIT"
-> [history EXCEPT !.chanInit = TRUE]
[] chainStore'.connectionEnd.channelEnd.state = "TRYOPEN"
-> [history EXCEPT !.chanTryOpen = TRUE]
[] chainStore'.connectionEnd.channelEnd.state = "OPEN"
-> [history EXCEPT !.chanOpen = TRUE]
[] chainStore'.connectionEnd.channelEnd.state = "CLOSED"
-> [history EXCEPT !.chanClosed = TRUE]
[] OTHER
-> history
/\ \/ incomingDatagrams /= AsSetDatagrams({})
\/ incomingPacketDatagrams /= AsSeqPacketDatagrams(<<>>)
/\ LET updatedChainStoreAndPacketLog == UpdateChainStoreAndPacketLog(ChainID, incomingDatagrams, incomingPacketDatagrams, packetLog) IN
/\ chainStore' = updatedChainStoreAndPacketLog.chainStore
/\ packetLog' = updatedChainStoreAndPacketLog.packetLog
/\ incomingDatagrams' = AsSetDatagrams({})
/\ incomingPacketDatagrams' = IF incomingPacketDatagrams /= AsSeqPacketDatagrams(<<>>)
THEN Tail(incomingPacketDatagrams)
ELSE incomingPacketDatagrams
/\ history' = CASE chainStore'.connectionEnd.state = "INIT"
-> [history EXCEPT !.connInit = TRUE]
[] chainStore'.connectionEnd.state = "TRYOPEN"
-> [history EXCEPT !.connTryOpen = TRUE]
[] chainStore'.connectionEnd.state = "OPEN"
-> [history EXCEPT !.connOpen = TRUE]
[] chainStore'.connectionEnd.channelEnd.state = "INIT"
-> [history EXCEPT !.chanInit = TRUE]
[] chainStore'.connectionEnd.channelEnd.state = "TRYOPEN"
-> [history EXCEPT !.chanTryOpen = TRUE]
[] chainStore'.connectionEnd.channelEnd.state = "OPEN"
-> [history EXCEPT !.chanOpen = TRUE]
[] chainStore'.connectionEnd.channelEnd.state = "CLOSED"
-> [history EXCEPT !.chanClosed = TRUE]
[] OTHER
-> history
/\ UNCHANGED appPacketSeq

(***************************************************************************
Specification
Expand All @@ -146,16 +215,21 @@ HandleIncomingDatagrams ==
Init ==
/\ chainStore = InitChainStore(ChannelOrdering)
/\ incomingDatagrams = AsSetDatagrams({})
/\ incomingPacketDatagrams = AsSeqDatagrams(<<>>)
/\ history = InitHistory
/\ appPacketSeq = AsInt(1)

\* Next state action
\* The chain either
\* - advances its height
\* - receives datagrams and updates its state
\* - sends a packet (TODO)
\* - sends a packet if the appPacketSeq is not bigger than MaxPacketSeq
\* - acknowledges a packet
Next ==
\/ AdvanceChain
\/ HandleIncomingDatagrams
\/ SendPacket
\/ AcknowledgePacket
\/ UNCHANGED vars

Fairness ==
Expand All @@ -171,6 +245,8 @@ TypeOK ==
/\ chainStore \in ChainStores(MaxHeight, ChannelOrdering, MaxPacketSeq)
/\ incomingDatagrams \in SUBSET Datagrams(MaxHeight, MaxPacketSeq)
/\ history \in Histories
/\ appPacketSeq \in 1..MaxPacketSeq
/\ packetLog \in SUBSET Packets(MaxHeight, MaxPacketSeq)

(***************************************************************************
Properties
Expand All @@ -182,5 +258,5 @@ HeightDoesntDecrease ==

=============================================================================
\* Modification History
\* Last modified Thu Sep 10 15:43:42 CEST 2020 by ilinastoilkovska
\* Last modified Wed Sep 30 13:47:16 CEST 2020 by ilinastoilkovska
\* Created Fri Jun 05 16:56:21 CET 2020 by ilinastoilkovska
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
-------------------------- MODULE ICS18Environment --------------------------

EXTENDS Integers, FiniteSets, RelayerDefinitions
EXTENDS Integers, FiniteSets, Sequences, RelayerDefinitions

CONSTANTS MaxHeight, \* maximal height of all the chains in the system
MaxPacketSeq, \* maximal packet sequence number (will be used later)
Expand All @@ -16,24 +16,34 @@ VARIABLES chainAstore, \* store of ChainA
chainBstore, \* store of ChainB
incomingDatagramsChainA, \* set of datagrams incoming to ChainA
incomingDatagramsChainB, \* set of datagrams incoming to ChainB
incomingPacketDatagramsChainA, \* sequence of packet datagrams incoming to ChainA
incomingPacketDatagramsChainB, \* sequence of packet datagrams incoming to ChainB
relayer1Heights, \* the client heights of Relayer1
relayer2Heights, \* the client heights of Relayer2
outgoingDatagrams, \* sets of datagrams outgoing of the relayers
outgoingPacketDatagrams, \* sequences of packet datagrams outgoing of the relayers
closeChannelA, \* flag that triggers closing of the channel end at ChainA
closeChannelB, \* flag that triggers closing of the channel end at ChainB
historyChainA, \* history variables for ChainA
historyChainB \* history variables for ChainB
historyChainB, \* history variables for ChainB
packetLog, \* a set of packets sent by both chains
appPacketSeqChainA, \* packet sequence number from the application on ChainA
appPacketSeqChainB \* packet sequence number from the application on ChainA

vars == <<chainAstore, chainBstore,
incomingDatagramsChainA, incomingDatagramsChainB,
incomingPacketDatagramsChainA, incomingPacketDatagramsChainB,
relayer1Heights, relayer2Heights,
outgoingDatagrams,
outgoingPacketDatagrams,
closeChannelA, closeChannelB,
historyChainA, historyChainB>>
historyChainA, historyChainB,
packetLog,
appPacketSeqChainA, appPacketSeqChainB>>

chainAvars == <<chainAstore, incomingDatagramsChainA, historyChainA>>
chainBvars == <<chainBstore, incomingDatagramsChainB, historyChainB>>
relayerVars == <<relayer1Heights, relayer2Heights, outgoingDatagrams>>
chainAvars == <<chainAstore, incomingDatagramsChainA, incomingPacketDatagramsChainA, historyChainA, appPacketSeqChainA>>
chainBvars == <<chainBstore, incomingDatagramsChainB, incomingPacketDatagramsChainB, historyChainB, appPacketSeqChainB>>
relayerVars == <<relayer1Heights, relayer2Heights, outgoingDatagrams, outgoingPacketDatagrams>>
Heights == 1..MaxHeight \* set of possible heights of the chains in the system


Expand Down Expand Up @@ -62,14 +72,18 @@ ChainA == INSTANCE Chain
WITH ChainID <- "chainA",
chainStore <- chainAstore,
incomingDatagrams <- incomingDatagramsChainA,
history <- historyChainA
incomingPacketDatagrams <- incomingPacketDatagramsChainA,
history <- historyChainA,
appPacketSeq <- appPacketSeqChainA

\* ChainB -- Instance of Chain.tla
ChainB == INSTANCE Chain
WITH ChainID <- "chainB",
chainStore <- chainBstore,
incomingDatagrams <- incomingDatagramsChainB,
history <- historyChainB
incomingPacketDatagrams <- incomingPacketDatagramsChainB,
history <- historyChainB,
appPacketSeq <- appPacketSeqChainB

(***************************************************************************
Component actions
Expand Down Expand Up @@ -109,9 +123,17 @@ SubmitDatagrams ==
/\ incomingDatagramsChainA' = AsSetDatagrams(incomingDatagramsChainA \union outgoingDatagrams["chainA"])
/\ incomingDatagramsChainB' = AsSetDatagrams(incomingDatagramsChainB \union outgoingDatagrams["chainB"])
/\ outgoingDatagrams' = [chainID \in ChainIDs |-> AsSetDatagrams({})]
/\ incomingPacketDatagramsChainA' = AsSeqPacketDatagrams(incomingPacketDatagramsChainA
\o
outgoingPacketDatagrams["chainA"])
/\ incomingPacketDatagramsChainB' = AsSeqPacketDatagrams(incomingPacketDatagramsChainB
\o
outgoingPacketDatagrams["chainB"])
/\ outgoingPacketDatagrams' = [chainID \in ChainIDs |-> AsSeqPacketDatagrams(<<>>)]
/\ UNCHANGED <<chainAstore, chainBstore, relayer1Heights, relayer2Heights>>
/\ UNCHANGED <<closeChannelA, closeChannelB>>
/\ UNCHANGED <<historyChainA, historyChainB>>
/\ UNCHANGED <<packetLog, appPacketSeqChainA, appPacketSeqChainB>>

\* Non-deterministically set channel closing flags
CloseChannels ==
Expand All @@ -121,12 +143,16 @@ CloseChannels ==
/\ UNCHANGED <<incomingDatagramsChainA, incomingDatagramsChainB, outgoingDatagrams>>
/\ UNCHANGED closeChannelB
/\ UNCHANGED <<historyChainA, historyChainB>>
/\ UNCHANGED <<packetLog, appPacketSeqChainA, appPacketSeqChainB>>
/\ UNCHANGED <<incomingPacketDatagramsChainA, incomingPacketDatagramsChainB, outgoingPacketDatagrams>>
\/ /\ closeChannelB = FALSE
/\ closeChannelB' \in BOOLEAN
/\ UNCHANGED <<chainAstore, chainBstore, relayer1Heights, relayer2Heights>>
/\ UNCHANGED <<incomingDatagramsChainA, incomingDatagramsChainB, outgoingDatagrams>>
/\ UNCHANGED closeChannelA
/\ UNCHANGED <<historyChainA, historyChainB>>
/\ UNCHANGED <<packetLog, appPacketSeqChainA, appPacketSeqChainB>>
/\ UNCHANGED <<incomingPacketDatagramsChainA, incomingPacketDatagramsChainB, outgoingPacketDatagrams>>

\* Faulty relayer action
FaultyRelayer ==
Expand All @@ -150,6 +176,7 @@ Init ==
/\ Relayer2!Init
/\ closeChannelA = FALSE
/\ closeChannelB = FALSE
/\ packetLog = AsPacketLog(<<>>)

\* Next state action
Next ==
Expand Down Expand Up @@ -539,5 +566,5 @@ ICS18Delivery ==

=============================================================================
\* Modification History
\* Last modified Thu Sep 10 15:41:47 CEST 2020 by ilinastoilkovska
\* Last modified Fri Sep 18 18:56:16 CEST 2020 by ilinastoilkovska
\* Created Fri Jun 05 16:48:22 CET 2020 by ilinastoilkovska
Loading