-
Notifications
You must be signed in to change notification settings - Fork 329
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
Implement clear packets
command
#1834
Conversation
Mutability does not seem to be required, and this guarantees we can reuse the same Link instance for receiving and acking packets in turn.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks Mikhail! I did some testing and I have 3 suggestions:
-
This was not clear enough in the issue description (User-facing CLI to clear packets #1716), but it would be ideal for
clear packets
to handle clearing in both directions, which means to: a. clear packets from source towards destination chain; b. clear packets from destination towards source chain.- Currently we only handle case a. I believe.
- To reproduce, do the following:
- Setup a single channel with id
channel-0
betweenibc-0
andibc-1
- Submit a packet at chain
ibc-0
-
$ hermes --json tx raw ft-transfer ibc-1 ibc-0 transfer channel-0 0184 -d samoleans -t 1800 -n 1
- Try to clear packets in direction
ibc-1 (source) -> ibc-0 (dest)
, it will not find anything -
$ hermes clear packets ibc-0 ibc-1 transfer channel-0
Success: []
-
Given my suggestion above to handle clearing in both directions, I think a reasonable way to do it as follows:
build_and_send_recv_packet_messages
on direction source -> destbuild_and_send_recv_packet_messages
on direction dest -> sourcebuild_and_send_ack_packet_messages
on direction source -> destbuild_and_send_ack_packet_messages
on direction dest -> source
In the present implementation, I think we do 1 & 3.
This means we'll need to setup the Link
objects for both directions, which means we need to find out the port+channel identifier on the destination chain (we only know the port+channel-id on the source chain). In other words, we'll need to query the channel port+channel end on the source chain and extract the counterparty info from there.
- Testing an debugging this PR is actually difficult because the output is very noisy. It may be a good time to try and tackle issue
hermes tx raw
shows all the data bytes in a column #1559 as part of this PR, namely: to make the output forSendPacket
,WriteAcknowledgement
andAcknowledgePacket
more concise. Just to emphasize: this scope creep is optional, I'm just suggesting what I would do to make debugging more ergonomic here.
Would something like this be a good way to do it? |
Yep, we need to do a |
@adizere I have tested 4bb294c with the repro sequence you have provided, and it looks to be working. |
Adding an e2e test is a challenge, though: I need a clue on what the expected results of the command should be in the Python test classes. These are different for |
relayer-cli/src/commands/clear.rs
Outdated
run_and_collect_events(&mut ev_list, || link.build_and_send_recv_packet_messages()); | ||
run_and_collect_events(&mut ev_list, || link.build_and_send_ack_packet_messages()); | ||
|
||
// Clear packets in the dst -> src direction. | ||
// Some of the checks in the Link constructor may be redundant; | ||
// going slowly, but reliably. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure the order is correct here, in the sense that it will leave pending packets. I believe we need to create the two links (one for A->B and the other for B->A), then build_and_send_recv_packet_messages
on the two links and after build_and_send_ack_packet_messages
on the two links. This is because ``build_and_send_recv_packet_messages` may create pending acks.
Also I believe that these methods end up waiting for commit response from the chain, which is what we want here. But could you please double check?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you @ancazamfir for bringing this up. I'm still learning about these things. I guess the intent is to wait for commit in both directions, which I believe what the low-level tx raw
commands also achieve. I will take care about interleaving the recv and ack phases as suggested.
When processing pending packets for the `clear packets` command, schedule RecvPacket in both directions before proceeding with AckPacket, also in both directions. This ensures we process also the acks created by the packets just received.
relayer-cli/src/commands/clear.rs
Outdated
let opts = LinkParameters { | ||
src_port_id: fwd_link.a_to_b.dst_port_id().clone(), | ||
src_channel_id: fwd_link.a_to_b.dst_channel_id().clone(), | ||
}; | ||
let rev_link = match Link::new_from_opts(chains.dst, chains.src, opts, false) { | ||
Ok(link) => link, | ||
Err(e) => Output::error(format!("{}", e)).exit(), | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This may be the case for a Link::reverse
method, which would do this and maybe skip on some redundant checks and queries.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds like a nice addition, would you mind doing that as part of this PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@romac Can you provide some clue on which of the checks done inside Link::new_from_opts
can be bypassed, and which initializations reused, when creating the reverse Link
?
One more thought for a future PR maybe. Add a |
There is no longer a "source" chain, but we need to clarify that both directions of the channel are cleared even though only one end is used for identification.
Use a span and KV pairs to provide the context in ChainEndpoint::build_packet_proofs, so the log event macro invocations are short and to the point.
As reported by @ancazamfir, this only works correctly on unordered channels. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great stuff!
|
||
// Schedule RecvPacket messages for pending packets in both directions. | ||
// This may produce pending acks which will be processed in the next phase. | ||
run_and_collect_events(&mut ev_list, || { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice!
Actually this works well for ordered channels when tested with gaia v6.0.0 and ibc-go v2.0.0 so I think it's all good (we won't support ordered channels in older versions) |
This is the slowest implementation, not optimizing on any shared state or eliminating redundant checks.
This is an option on Link::new_from_opts, so it seems logical to also make it optional on the same level API.
Tested & looks good, cool work here Mikhail, I will merge it ASAP! |
* Make self immutable on some methods of Link Mutability does not seem to be required, and this guarantees we can reuse the same Link instance for receiving and acking packets in turn. * cli: Add `clear packets` command * Changelog for informalsystems#1834 * Improved help for `clear` and `clear packets` * cli: clear packets in reverse direction as well * fix clippy lints about diverging exit method * Interleave recv and ack in each direction When processing pending packets for the `clear packets` command, schedule RecvPacket in both directions before proceeding with AckPacket, also in both directions. This ensures we process also the acks created by the packets just received. * Rename positional parameters in `clear packets` * No need for counterparty * Clarify help on `clear packets` command There is no longer a "source" chain, but we need to clarify that both directions of the channel are cleared even though only one end is used for identification. * Fix a syntax error * Improve logging in proven_packet Use a span and KV pairs to provide the context in ChainEndpoint::build_packet_proofs, so the log event macro invocations are short and to the point. * Removed the extra debug logs * Implement Link::reverse naively This is the slowest implementation, not optimizing on any shared state or eliminating redundant checks. * Add tx confirmation flag to Link::reverse This is an option on Link::new_from_opts, so it seems logical to also make it optional on the same level API. * Extended error types when port/channel is incorrect Co-authored-by: Anca Zamfir <zamfiranca@gmail.com> Co-authored-by: Adi Seredinschi <adi@informal.systems>
Closes: #1716
Description
Implement
clear packets
command as a combination ofthe effects of
tx raw packet-recv
andtx raw packet-ack
PR author checklist:
unclog
.docs/
).Reviewer checklist:
Files changed
in the GitHub PR explorer.