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

Comments after alpha audit of path forwarding #6696

Closed
10 tasks done
crodriguezvega opened this issue Jun 25, 2024 · 1 comment · Fixed by #6731
Closed
10 tasks done

Comments after alpha audit of path forwarding #6696

crodriguezvega opened this issue Jun 25, 2024 · 1 comment · Fixed by #6731
Assignees
Labels
20-transfer audit Feedback from implementation audit

Comments

@crodriguezvega
Copy link
Contributor

crodriguezvega commented Jun 25, 2024

From internal alpha audit of ICS20 v2 path forwarding:

Thank you @chatton for leading the walkthrough and the rest of the team for the feedback.

@damiannolan
Copy link
Contributor

damiannolan commented Jun 26, 2024

Add hops to the ack error while propogating back to source so we know which chain the packet failed or timed out on [could also do counter]. Include also the deterministic error string from the error acknowledgement written by the chain where the forwarding failed

Spent some time looking at this with @chatton today! This is not so straight forward to do, we must also consider that the final destination hop may or may not be on ics20-1. In any case, it seems better to add the path forwarding info here, accepting the ack as an additional argument from the caller, here.

Using something like the following (where packet is the forwardPacket, and not the reverse (prevPacket):

// NewForwardErrorAcknowledgement returns a new error acknowledgement with path forwarding information.
func NewForwardErrorAcknowledgement(packet channeltypes.Packet, ack channeltypes.Acknowledgement) channeltypes.Acknowledgement {
	ackErr := fmt.Sprintf("%s/%s/%s", packet.GetSourcePort(), packet.GetSourceChannel(), ack.GetError())
	return channeltypes.Acknowledgement{
		Response: &channeltypes.Acknowledgement_Error{
			Error: ackErr,
		},
	}
}

Consider a path of len(4), where the final destination is ics20-1. We fail with error acknolwedgement for {code}.
Acks would be propagated like so:

  • RecvPacket failure (hop3): ABCI code: {code}: error handling packet: see events for details
  • Handle ack(hop2), append path info and writeAck: transfer/channel-2/ABCI code: {code} ...
  • Handle ack(hop1), append path info and writeAck: transfer/channel-1/transfer/channel-2/ABCI code: {code}...
  • Handle ack(hop0) - original sender. Note, we cannot modify the acknowledgement on the chain that it was not written on and therefore the first outbound port/channel ID from A->B would not be included in the emitted event.

Ultimately, we cannot control if the final hop has upgrade yet or not. However, we can add packet.DestPort()/packet.DestChannel() to ALL error acknowledgements using ibc-go/v9.
For example:

-func NewErrorAcknowledgement(err error) Acknowledgement {
+func NewErrorAcknowledgement(portID, channelID string, err error) Acknowledgement {
        // the ABCI code is included in the abcitypes.ResponseDeliverTx hash
        // constructed in Tendermint and is therefore deterministic
        _, code, _ := errorsmod.ABCIInfo(err, false) // discard non-deterministic codespace and log values

        return Acknowledgement{
                Response: &Acknowledgement_Error{
-                       Error: fmt.Sprintf("ABCI code: %d: %s", code, ackErrorString),
+                       Error: fmt.Sprintf("%s/%s ABCI code: %d: %s", portID, channelID, code, ackErrorString),
                },
        }
 }

I think this would give us a bit more info, but no guarantees that the final destination has been upgraded.

Personally, I think other solutions sound pretty hacky. You could add some index to the error string in the acknowledgement, and parse that string on every async ack write, and increment. And then use the index to determine the failed hop when you have been propagated back to the original src and have all forwarding path info available. I would vote against this!

cc. @AdityaSripal

edit: We've decided to go with source port and channel only, as this will match the user provided info in Forwarding.Hop. See #6731

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
20-transfer audit Feedback from implementation audit
Projects
No open projects
Archived in project
Development

Successfully merging a pull request may close this issue.

5 participants