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

refactor: use branch service in recv packet (wip) #7822

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
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
1 change: 1 addition & 0 deletions modules/core/04-channel/types/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,5 @@ var (
ErrPruningSequenceStartNotFound = errorsmod.Register(SubModuleName, 41, "pruning sequence start not found")
ErrRecvStartSequenceNotFound = errorsmod.Register(SubModuleName, 42, "recv start sequence not found")
ErrInvalidCommitment = errorsmod.Register(SubModuleName, 43, "invalid commitment")
ErrFailedAcknowledgement = errorsmod.Register(SubModuleName, 44, "acknowledgement error")
)
64 changes: 36 additions & 28 deletions modules/core/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
channeltypes "github.com/cosmos/ibc-go/v9/modules/core/04-channel/types"
porttypes "github.com/cosmos/ibc-go/v9/modules/core/05-port/types"
ibcerrors "github.com/cosmos/ibc-go/v9/modules/core/errors"
"github.com/cosmos/ibc-go/v9/modules/core/exported"
"github.com/cosmos/ibc-go/v9/modules/core/internal/telemetry"
coretypes "github.com/cosmos/ibc-go/v9/modules/core/types"
)
Expand Down Expand Up @@ -358,9 +359,7 @@
}

// RecvPacket defines a rpc handler method for MsgRecvPacket.
func (k *Keeper) RecvPacket(goCtx context.Context, msg *channeltypes.MsgRecvPacket) (*channeltypes.MsgRecvPacketResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)

func (k *Keeper) RecvPacket(ctx context.Context, msg *channeltypes.MsgRecvPacket) (*channeltypes.MsgRecvPacketResponse, error) {
relayer, err := sdk.AccAddressFromBech32(msg.Signer)
if err != nil {
k.Logger.Error("receive packet failed", "error", errorsmod.Wrap(err, "Invalid address for msg Signer"))
Expand All @@ -374,36 +373,45 @@
return nil, errorsmod.Wrapf(porttypes.ErrInvalidRoute, "route not found to portID: %s", msg.Packet.DestinationPort)
}

// Perform TAO verification
//
// If the packet was already received, perform a no-op
// Use a cached context to prevent accidental state changes
cacheCtx, writeFn := ctx.CacheContext()
channelVersion, err := k.ChannelKeeper.RecvPacket(cacheCtx, msg.Packet, msg.ProofCommitment, msg.ProofHeight)

switch err {
case nil:
writeFn()
case channeltypes.ErrNoOpMsg:
// no-ops do not need event emission as they will be ignored
k.Logger.Debug("no-op on redundant relay", "port-id", msg.Packet.SourcePort, "channel-id", msg.Packet.SourceChannel)
return &channeltypes.MsgRecvPacketResponse{Result: channeltypes.NOOP}, nil
default:
var channelVersion string
if err := k.BranchService.Execute(ctx, func(ctx context.Context) error {
// Perform TAO verification
channelVersion, err = k.ChannelKeeper.RecvPacket(ctx, msg.Packet, msg.ProofCommitment, msg.ProofHeight)
if err != nil {
return err
}

return nil
}); err != nil {
if errors.Is(err, channeltypes.ErrNoOpMsg) {
// no-ops do not need event emission as they will be ignored
k.Logger.Debug("no-op on redundant relay", "port-id", msg.Packet.SourcePort, "channel-id", msg.Packet.SourceChannel)
return &channeltypes.MsgRecvPacketResponse{Result: channeltypes.NOOP}, nil
}

k.Logger.Error("receive packet failed", "port-id", msg.Packet.SourcePort, "channel-id", msg.Packet.SourceChannel, "error", errorsmod.Wrap(err, "receive packet verification failed"))
return nil, errorsmod.Wrap(err, "receive packet verification failed")
}

// Perform application logic callback
//
// Cache context so that we may discard state changes from callback if the acknowledgement is unsuccessful.
cacheCtx, writeFn = ctx.CacheContext()
ack := cbs.OnRecvPacket(cacheCtx, channelVersion, msg.Packet, relayer)
if ack == nil || ack.Success() {
var ack exported.Acknowledgement
if err := k.BranchService.Execute(ctx, func(ctx context.Context) error {
// Perform application logic callback
ack = cbs.OnRecvPacket(ctx, channelVersion, msg.Packet, relayer)
if !ack.Success() {
// we must return an error here so that false positive events are not emitted
return channeltypes.ErrFailedAcknowledgement
}

// write application state changes for asynchronous and successful acknowledgements
writeFn()
} else {
// Modify events in cached context to reflect unsuccessful acknowledgement
ctx.EventManager().EmitEvents(convertToErrorEvents(cacheCtx.EventManager().Events()))
return nil
}); err != nil {
if errors.Is(err, channeltypes.ErrFailedAcknowledgement) {

Check failure on line 408 in modules/core/keeper/msg_server.go

View workflow job for this annotation

GitHub Actions / lint

empty-block: this block is empty, you can remove it (revive)
// k.EventService.EventManager(ctx).EmitKV()
// Modify events in cached context to reflect unsuccessful acknowledgement

// We lost apis to propagate and err prefix events from a branched multistore ctx
// ctx.EventManager().EmitEvents(convertToErrorEvents(cacheCtx.EventManager().Events()))
}
}

// Set packet acknowledgement only if the acknowledgement is not nil.
Expand Down
Loading