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

Fix QueryUnreceivedPackets/Acks #7320

Merged
merged 12 commits into from
Sep 18, 2020
Merged

Fix QueryUnreceivedPackets/Acks #7320

merged 12 commits into from
Sep 18, 2020

Conversation

AdityaSripal
Copy link
Member

Description

closes: #7319


Before we can merge this PR, please make sure that all the following items have been
checked off. If any of the checklist items are not applicable, please leave them but
write a little note why.

  • Targeted PR against correct branch (see CONTRIBUTING.md)
  • Linked to Github issue with discussion and accepted design OR link to spec that describes this work.
  • Code follows the module structure standards.
  • Wrote unit and integration tests
  • Updated relevant documentation (docs/) or specification (x/<module>/spec/)
  • Added relevant godoc comments.
  • Added a relevant changelog entry to the Unreleased section in CHANGELOG.md
  • Re-reviewed Files changed in the Github PR explorer
  • Review Codecov Report in the comment section below once CI passes

@AdityaSripal
Copy link
Member Author

AdityaSripal commented Sep 15, 2020

Not exactly sure what all the other proto changes are about. I reran make proto-tools and this was the result.

Also make proto-format errors for me with these errors:

Error reading /Users/adityasripal/go/src/github.com/cosmos/cosmos-sdk/./.clang-format: Invalid argument
YAML:94:22: error: unknown key 'Delimiter'
  - Delimiter:       pb
                     ^~

EDIT: Fixed by reverting to Makefile before proto-tools script. Everything works now except proto-format still gives me the above issue

@colin-axner
Copy link
Contributor

colin-axner commented Sep 16, 2020

Not exactly sure what all the other proto changes are about. I reran make proto-tools and this was the result.

Also make proto-format errors for me with these errors:

Error reading /Users/adityasripal/go/src/github.com/cosmos/cosmos-sdk/./.clang-format: Invalid argument
YAML:94:22: error: unknown key 'Delimiter'
  - Delimiter:       pb
                     ^~

do you have the correct versions installed?


// if packet commitment still exists on the original sending chain, then packet ack has not been received
// since processing the ack will delete the packet commitment
if commitment := q.GetPacketCommitment(ctx, req.PortId, req.ChannelId, seq); len(commitment) != 0 {
Copy link
Contributor

@colin-axner colin-axner Sep 16, 2020

Choose a reason for hiding this comment

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

This differs from the godoc


// Given a list of counterparty packet commitments, the querier checks if the packet
// has already been received by checking if an acknowledgement exists on this
// chain for the packet sequence.

It seems the implemented flow here is trying to take in a list of acknowledgement sequences and check if the packet commitment exists to see the ack needs to be relayed? How does a relayer determine which acknowledgement sequences to send? Unlike packet commitments, acknowledgements live forever so a relayer would have to already know which acknowledgements have not been acknowledged on the original chain, which is the purpose of this function.

The previous flow is to use the receiving chain as the indicator. A packet has 3 life cycles:

  • sent but not received
  • received but not ack'd
  • ack'd and deleted

The sender chain indicates if the packet is in the first two stages (querying packet commitments) and the receiving chain indicates which of the first two stages it is in (ack doesn't exist, stage 1. ack does exist, stage 2).

Copy link
Contributor

@colin-axner colin-axner Sep 16, 2020

Choose a reason for hiding this comment

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

I assume the line of thinking that lead to this function is for it to be used in conjunction with the QueryUnreceivedPackets. This issue here arises with the introduction of async acknowledgements. Even if you relay unreceived packets, the acknowledgement may not be written for some time. You could keep a cache of those sequences, but you'd still need to query the receiving chain to find out if the acknowledgements have been written (verifying that your unreceived packet sequences has now become unreceived acknowledgements). You see what I am saying?

Regardless, the relayer should not rely on these functions beyond the short term. As per recent decisions in the IBC call, acknowledgements do not have to be written for proper functioning channels. This means packet commitments could live forever and relayers could get stuck trying to determine if an ack needs to be relayed. It should primarily rely on events. Maybe we should add this to the godoc?

Copy link
Member Author

@AdityaSripal AdityaSripal Sep 16, 2020

Choose a reason for hiding this comment

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

It seems the implemented flow here is trying to take in a list of acknowledgement sequences and check if the packet commitment exists to see the ack needs to be relayed? How does a relayer determine which acknowledgement sequences to send? Unlike packet commitments, acknowledgements live forever so a relayer would have to already know which acknowledgements have not been acknowledged on the original chain, which is the purpose of this function.

Ahh fair point. My thinking was that the relayer gives the entire list of acknowledgements to this function but that may be too large and inefficient in a long lived channel.

The original intention was to send packet commitments that still exist on the sending chain to the receiving chain and see if the ack exists? I can reimplement that, tho I still think it's better to make it a separate RPC call. Unfortunately this doesn't have a symmetry with the QueryUnreceivedPackets call which makes it non-intuitive.

This issue here arises with the introduction of async acknowledgements. Even if you relay unreceived packets, the acknowledgement may not be written for some time. You could keep a cache of those sequences, but you'd still need to query the receiving chain to find out if the acknowledgements have been written (verifying that your unreceived packet sequences has now become unreceived acknowledgements). You see what I am saying?

Yes its possible even with the original implementation that once async acknowledgements are introduced that packet commitments exist for a long time before the ack gets written. I don't think this is a huge deal and hard to avoid. I think these functions should probably be used on relayer startup and once all pending packets/acks in the queue are cleared, relayer should primarily rely on events

cc: @jackzampolin

@codecov
Copy link

codecov bot commented Sep 16, 2020

Codecov Report

Merging #7320 into master will decrease coverage by 0.09%.
The diff coverage is 15.88%.

@@            Coverage Diff             @@
##           master    #7320      +/-   ##
==========================================
- Coverage   55.41%   55.32%   -0.10%     
==========================================
  Files         583      583              
  Lines       35550    35637      +87     
==========================================
+ Hits        19700    19715      +15     
- Misses      13942    14014      +72     
  Partials     1908     1908              

@AdityaSripal AdityaSripal marked this pull request as ready for review September 16, 2020 21:28
@AdityaSripal
Copy link
Member Author

I kept the implementation of retrieving Acks the same but separated it into two RPC calls for clarity:

UnreceivedPackets: I call this unreceived because it is an RPC call sent to the intended destination chain of the packets, so we're querying the chain to see which packets the chain has not yet received.

UnrelayedAcks: I call this unrelayed because it is an RPC call sent to the chain that is sending the acks, thus it is will return all the acks on this chain that have not yet been relayed.

The name change and separation should make things clearer along with the usage docs, and the unsymmetric names should reflect the unsymmetric nature of the calls and make usage more intuitive.

UnreceivedPackets will need to diverge from UnrelayedPackets implementation anyway with async acknowledgments as mentioned in the TODO docs

@alessio
Copy link
Contributor

alessio commented Sep 16, 2020

Please paste here the output of:

clang-format -version

@AdityaSripal
Copy link
Member Author

@alessio

cosmos-sdk git:(master) ✗ clang-format -version
clang-format version 10.0.1 

Copy link
Contributor

@colin-axner colin-axner left a comment

Choose a reason for hiding this comment

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

LGTM, thanks for updating this!

proto/ibc/channel/query.proto Outdated Show resolved Hide resolved
x/ibc/04-channel/client/cli/query.go Outdated Show resolved Hide resolved
@jackzampolin jackzampolin added the A:automerge Automatically merge PR once all prerequisites pass. label Sep 17, 2020
@mergify mergify bot merged commit 7b1efcb into master Sep 18, 2020
@mergify mergify bot deleted the aditya/query-unreceived branch September 18, 2020 09:56
@colin-axner colin-axner mentioned this pull request Oct 30, 2020
9 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A:automerge Automatically merge PR once all prerequisites pass.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Fix QueryUnrelayedPackets
4 participants