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

Basic packet flow in TLA+ #248

merged 8 commits into from
Sep 30, 2020

Conversation

istoilkovska
Copy link
Contributor

Closes: #124

Description

Added support for handling the basic packet flow in the Relayer TLA+ specification. Currently, the spec handles sending, receiving, and acknowledgements of packets.

The following basic packet flow is assumed:

  1. ChainA sends a packet by writing a sent packet log entry to the packet log and writing a packet commitment
  2. A relayer reads the packet log, picks the sent packet log entry, and creates PacketRecv datagram for ChainB
  3. ChainB processes the PacketRecv datagram, and adds the received packet to its set of packets that should be acknowledged (asynchronous acknowledgements)
  4. ChainB writes the acknowledgement by writing a log entry to the packet log
  5. A relayer reads the packet log, picks the write ack log entry, and creates PacketAck datagram for ChainA
  6. ChainA processes the PacketAck datagram by deleting the packet commitment of the original sent packet

The packets and packet logs are sequences, rather than sets. This is to ensure that there is order in sending, receiving, and acknowledgements of packets.


For contributor use:

  • Unit tests written
  • Added test to CI if applicable
  • Updated CHANGELOG_PENDING.md
  • Linked to Github issue with discussion and accepted design OR link to spec that describes this work.
  • Updated relevant documentation (docs/) and code comments
  • Re-reviewed Files changed in the Github PR explorer

@istoilkovska istoilkovska added I: spec Internal: related to IBC specifications I: logic Internal: related to the relaying logic labels Sep 22, 2020
@istoilkovska istoilkovska added this to the v0.0.4 milestone Sep 22, 2020
@istoilkovska istoilkovska requested a review from romac as a code owner September 22, 2020 12:42
@istoilkovska istoilkovska self-assigned this Sep 22, 2020
@istoilkovska istoilkovska removed this from the v0.0.4 milestone Sep 22, 2020
@istoilkovska istoilkovska removed I: logic Internal: related to the relaying logic I: spec Internal: related to IBC specifications labels Sep 22, 2020
Copy link
Collaborator

@ancazamfir ancazamfir left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice spec! I have a few comments after the first pass. Struggling with TLC, one relayer and minimal config, it still runs after almost 1hr.

docs/spec/relayer/PacketHandlers.tla Outdated Show resolved Hide resolved
docs/spec/relayer/PacketHandlers.tla Outdated Show resolved Hide resolved
docs/spec/relayer/PacketHandlers.tla Outdated Show resolved Hide resolved
\* 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) ==
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should have a sequence of datagrams for everything. We can get handshake datagrams interleaved with packet datagrams and the order matters. And then in the function we should process them in order.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I had the idea to transition to sequences of datagams completely. But doing so increases the state space that TLC enumerates. Will try to think about better handling, while still processing datagrams in order.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree with Anca that orders matter. We can have either sequence or handle only single datagram at the time.

docs/spec/relayer/Relayer.tla Show resolved Hide resolved
docs/spec/relayer/Relayer.tla Show resolved Hide resolved
docs/spec/relayer/Chain.tla Outdated Show resolved Hide resolved
@codecov-commenter
Copy link

Codecov Report

Merging #248 into master will increase coverage by 20.4%.
The diff coverage is 55.2%.

Impacted file tree graph

@@            Coverage Diff            @@
##           master    #248      +/-   ##
=========================================
+ Coverage    13.6%   34.1%   +20.4%     
=========================================
  Files          69     106      +37     
  Lines        3752    7112    +3360     
  Branches     1374    2579    +1205     
=========================================
+ Hits          513    2430    +1917     
- Misses       2618    4318    +1700     
+ Partials      621     364     -257     
Impacted Files Coverage Δ
modules/src/events.rs 0.0% <ø> (ø)
modules/src/ics02_client/events.rs 0.0% <ø> (ø)
modules/src/ics02_client/raw.rs 0.0% <0.0%> (ø)
modules/src/ics03_connection/error.rs 16.6% <0.0%> (-16.7%) ⬇️
...ules/src/ics03_connection/handler/conn_open_ack.rs 87.5% <ø> (ø)
.../src/ics03_connection/handler/conn_open_confirm.rs 87.5% <ø> (ø)
modules/src/ics04_channel/error.rs 75.0% <ø> (+50.0%) ⬆️
modules/src/ics04_channel/packet.rs 0.0% <0.0%> (ø)
modules/src/ics07_tendermint/client_def.rs 0.0% <0.0%> (ø)
modules/src/ics07_tendermint/consensus_state.rs 18.5% <0.0%> (-14.9%) ⬇️
... and 165 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 4877ee9...fc2dd62. Read the comment docs.

@@ -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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the purpose of history variable?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We use the history variable in the invariant we check with Apalache. The history variable is a record that stores flags about the state of the connection and channel ends. The flags are set once, when the state changes. The invariant checks that if a flag is set, the state of the connection or channel end does not go back to a previous state.

Example: a connection is open, and the flag history.connOpen is set to TRUE. The following invariant has to hold:

history.connOpen => /\ chainA.connectionEnd.state /= "UNINIT"
                    /\ chainA.connectionEnd.state /= "INIT"
                    /\ chainA.connectionEnd.state /= "TRYOPEN"

\* (Handler operators defined in PacketHandlers.tla)
PacketUpdate(chainID, store, packetDatagrams, log) ==
\* if the sequence of packet datagrams is not empty
IF packetDatagrams /= AsSeqPacketDatagrams(<<>>)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the structure is not the same as with others, i.e., it contains HandlePacketRecv and HandlePacketAck that internally check for the datagram type?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is because the PacketUpdate operator computes the update to the chain store with a single packet datagram, taken from the sequence of packet datagrams, while the other *Update operators update the chain store with a set of datagrams, which is obtained by taking a subset of the incoming datagrams, containing datagrams of particular type.

Tail(chain.packetsToAcknowledge)]

\* log acknowledgements to packet Log
LogAcknowledgement(chain, log, packet) ==
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure if we need to model event log as it is not necessarily, i.e., current ICS18 is not using it. It might be useful as part of MBT, but in the initial version I would prefer having the minimal set of functionalities needed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can have it merged like this for now, I will experiment to see if by removing it we can obtain some model checking results.

\* add a packet committment in the chain store, and increase nextSendSeq
\/ /\ channelEnd.order = "ORDERED"
/\ packet.sequence = channelEnd.nextSendSeq
/\ packet.sequence <= MaxPacketSeq
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a model constraint, not the handler one; ideally they should not be mixed and model constraint can be a precondition at the higher level.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've refactored this action a bit.

@@ -156,6 +299,8 @@ Init ==
Next ==
\/ AdvanceChain
\/ HandleIncomingDatagrams
\/ SendPacket
\/ AcknowledgePacket
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add timeout handling here? Then it seems complete.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, what about channel closing? Is it also triggered "externally"?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

channel closing is triggered by the application so yes the trigger is "external"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We currently have a flag for each chain that triggers channel closing, which is non-deterministically set by the environment. When we add timeouts we would have channel closing that is triggered by a timeout.

\* Handle "PacketRecv" datagrams
HandlePacketRecv(chainID, chain, packetDatagram, log) ==
\* get chainID's connection end
LET connectionEnd == chain.connectionEnd IN
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am wondering if we are missing important aspect here as we don't use chain and connection id from packetDatagram to fetch local connection and channel end.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can check in lines 32-33

/\ packetDatagram.srcChannelID = channelEnd.channelID
/\ packetDatagram.dstChannelID = channelEnd.counterpartyChannelID

where channelEnd is defined like in line 17. This should filter out packet datagrams that do not have the correct channelIDs.

Copy link
Contributor

@milosevic milosevic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. There are few comments that could be addressed and few more general concerns that we can address later.

Copy link
Collaborator

@ancazamfir ancazamfir left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Thanks Ilina!

@ancazamfir ancazamfir merged commit 10b8a69 into master Sep 30, 2020
@ancazamfir ancazamfir deleted the ilina/packets_tla branch September 30, 2020 12:31
hu55a1n1 pushed a commit to hu55a1n1/hermes that referenced this pull request Sep 13, 2022
* send packet action added, relayer packet creation

* packet receive, ack

* packet ack

* readme updated

* Apply suggestions from code review

Co-authored-by: Anca Zamfir <[email protected]>

* addressed comments

* applied review comments

* moved files around

Co-authored-by: Anca Zamfir <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Specify packet datagram creation and handling
4 participants