From 2f59a8838b33344e723cc051768393d28fe5f50f Mon Sep 17 00:00:00 2001 From: chatton Date: Thu, 19 Sep 2024 10:42:41 +0100 Subject: [PATCH] wip: got recv flow technically working with some hard coded hacks --- modules/apps/transfer/ibc_module_v2.go | 4 +- modules/apps/transfer/keeper/relay_v2.go | 5 --- modules/apps/transfer/transfer_v2_test.go | 36 +++++++++++++++++- modules/core/04-channel/keeper/keeper.go | 1 + modules/core/keeper/msg_server_v2.go | 9 ++++- modules/core/packet-server/keeper/keeper.go | 8 +++- modules/core/packet-server/keeper/relay_v2.go | 38 ++++++++++--------- 7 files changed, 72 insertions(+), 29 deletions(-) diff --git a/modules/apps/transfer/ibc_module_v2.go b/modules/apps/transfer/ibc_module_v2.go index 5d2da13836c..623beeaa32b 100644 --- a/modules/apps/transfer/ibc_module_v2.go +++ b/modules/apps/transfer/ibc_module_v2.go @@ -56,13 +56,11 @@ func (im *IBCModuleV2) OnSendPacketV2( // fail the unmarshaling above, where if ics20version == types.V1 we first unmarshal // into a V1 packet and then convert. - if data.Sender != string(signer) { + if data.Sender != signer.String() { return errorsmod.Wrapf(ibcerrors.ErrInvalidAddress, "invalid signer address: expected %s, got %s", data.Sender, signer) } return im.keeper.OnSendPacket(ctx, sourceID, data, signer) - - // TODO: port } // OnRecvPacketV2 implements the IBCModuleV2 interface. A successful acknowledgement diff --git a/modules/apps/transfer/keeper/relay_v2.go b/modules/apps/transfer/keeper/relay_v2.go index 3a9528efee9..a02db5b5d84 100644 --- a/modules/apps/transfer/keeper/relay_v2.go +++ b/modules/apps/transfer/keeper/relay_v2.go @@ -176,11 +176,6 @@ func (k Keeper) OnSendPacket( packetData types.FungibleTokenPacketDataV2, sender sdk.AccAddress, ) error { - //_, ok := k.packetServerKeeper.GetCounterparty(ctx, sourceID) - //if !ok { - // return errorsmod.Wrap(packetservertypes.ErrCounterpartyNotFound, sourceID) - //} - var coins sdk.Coins for _, token := range packetData.Tokens { transferAmount, ok := sdkmath.NewIntFromString(token.Amount) diff --git a/modules/apps/transfer/transfer_v2_test.go b/modules/apps/transfer/transfer_v2_test.go index cd70cda9813..7e8f785b3e7 100644 --- a/modules/apps/transfer/transfer_v2_test.go +++ b/modules/apps/transfer/transfer_v2_test.go @@ -7,6 +7,7 @@ import ( clienttypes "github.com/cosmos/ibc-go/v9/modules/core/02-client/types" channeltypes "github.com/cosmos/ibc-go/v9/modules/core/04-channel/types" channeltypesv2 "github.com/cosmos/ibc-go/v9/modules/core/04-channel/v2/types" + host "github.com/cosmos/ibc-go/v9/modules/core/24-host" "testing" testifysuite "github.com/stretchr/testify/suite" @@ -64,6 +65,7 @@ func (suite *TransferV2TestSuite) TestHandleMsgV2Transfer() { msg := types.NewMsgTransfer(pathAToB.EndpointA.ChannelConfig.PortID, pathAToB.EndpointA.ChannelID, originalCoins, suite.chainA.SenderAccount.GetAddress().String(), suite.chainB.SenderAccount.GetAddress().String(), timeoutHeight, 0, "", nil) res, err := suite.chainA.SendMsgs(msg) suite.Require().NoError(err) // message committed + suite.Require().NoError(pathAToB.EndpointB.UpdateClient()) packet, err := ibctesting.ParsePacketFromEvents(res.Events) suite.Require().NoError(err) @@ -92,8 +94,8 @@ func (suite *TransferV2TestSuite) TestHandleMsgV2Transfer() { coinsSentFromAToB = coinsSentFromAToB.Add(coinSentFromAToB) } - suite.Require().NoError(pathAToB.EndpointA.UpdateClient()) suite.Require().NoError(pathAToB.EndpointB.UpdateClient()) + suite.Require().NoError(pathAToB.EndpointA.UpdateClient()) ftpd := types.FungibleTokenPacketDataV2{ Tokens: []types.Token{ @@ -109,7 +111,7 @@ func (suite *TransferV2TestSuite) TestHandleMsgV2Transfer() { Forwarding: types.ForwardingPacketData{}, } - bz, err := ftpd.Marshal() + bz, err := suite.chainB.Codec.Marshal(&ftpd) suite.Require().NoError(err) timeoutTimestamp := suite.chainB.GetTimeoutTimestamp() @@ -133,6 +135,36 @@ func (suite *TransferV2TestSuite) TestHandleMsgV2Transfer() { res, err = suite.chainB.SendMsgs(msgSendPacket) suite.Require().NoError(err) suite.Require().NotNil(res) + suite.Require().NoError(pathAToB.EndpointA.UpdateClient()) + suite.Require().NoError(pathAToB.EndpointB.UpdateClient()) + + packetKey := host.PacketCommitmentKey(host.SentinelV2PortID, pathAToB.EndpointB.ClientID, 1) + proof, proofHeight := pathAToB.EndpointB.QueryProof(packetKey) + suite.Require().NotNil(proof) + suite.Require().False(proofHeight.IsZero()) + + packetV2 := channeltypesv2.NewPacketV2(1, pathAToB.EndpointB.ChannelID, pathAToB.EndpointA.ChannelID, timeoutTimestamp, channeltypes.PacketData{ + SourcePort: "transfer", + DestinationPort: "transfer", + Payload: channeltypes.Payload{ + Version: types.V2, + Encoding: "json", + Value: bz, + }, + }) + + msgRecvPacket := &channeltypesv2.MsgRecvPacket{ + Packet: packetV2, + ProofCommitment: proof, + ProofHeight: proofHeight, + Signer: suite.chainA.SenderAccount.GetAddress().String(), + } + + res, err = suite.chainA.SendMsgs(msgRecvPacket) + suite.Require().NoError(err) + suite.Require().NotNil(res) + suite.Require().NoError(pathAToB.EndpointB.UpdateClient()) + } func TestTransferV2TestSuite(t *testing.T) { diff --git a/modules/core/04-channel/keeper/keeper.go b/modules/core/04-channel/keeper/keeper.go index eb7b9017df7..11c39422e32 100644 --- a/modules/core/04-channel/keeper/keeper.go +++ b/modules/core/04-channel/keeper/keeper.go @@ -873,5 +873,6 @@ func (k *Keeper) GetV2Counterparty(ctx context.Context, portID, channelID string ClientId: connection.ClientId, MerklePathPrefix: merklePathPrefix, } + return counterparty, true } diff --git a/modules/core/keeper/msg_server_v2.go b/modules/core/keeper/msg_server_v2.go index adb710241ab..b57981036fc 100644 --- a/modules/core/keeper/msg_server_v2.go +++ b/modules/core/keeper/msg_server_v2.go @@ -27,7 +27,14 @@ func (k *Keeper) SendPacketV2(ctx context.Context, msg *channeltypesv2.MsgSendPa for _, pd := range msg.PacketData { cbs := k.PortKeeper.AppRouter.Route(pd.SourcePort) - err := cbs.OnSendPacketV2(ctx, msg.SourceId, sequence, msg.TimeoutTimestamp, pd.Payload, sdk.AccAddress(msg.Signer)) + + // TODO: is it safe to assume an sdk.AccAddress? + signer, err := sdk.AccAddressFromBech32(msg.Signer) + if err != nil { + return nil, err + } + + err = cbs.OnSendPacketV2(ctx, msg.SourceId, sequence, msg.TimeoutTimestamp, pd.Payload, signer) if err != nil { return nil, err } diff --git a/modules/core/packet-server/keeper/keeper.go b/modules/core/packet-server/keeper/keeper.go index 927c0fb9600..a80088f192a 100644 --- a/modules/core/packet-server/keeper/keeper.go +++ b/modules/core/packet-server/keeper/keeper.go @@ -72,7 +72,13 @@ func (k *Keeper) GetCounterpartyV2(ctx context.Context, portID, channelID, clien store := k.ChannelStore(ctx, clientID) bz := store.Get([]byte(types.CounterpartyKey)) if len(bz) == 0 { - return k.ChannelKeeper.GetV2Counterparty(ctx, portID, channelID) + cp, ok := k.ChannelKeeper.GetV2Counterparty(ctx, portID, clientID) + if !ok { + return types.Counterparty{}, false + } + k.SetCounterparty(ctx, channelID, cp) + //k.SetCounterparty(ctx, clientID, cp) + return cp, true } var counterparty types.Counterparty diff --git a/modules/core/packet-server/keeper/relay_v2.go b/modules/core/packet-server/keeper/relay_v2.go index 01ba5d9bdb4..2157c46e1a4 100644 --- a/modules/core/packet-server/keeper/relay_v2.go +++ b/modules/core/packet-server/keeper/relay_v2.go @@ -38,7 +38,7 @@ func (k Keeper) SendPacketV2( } // construct packet from given fields and channel state - packet := channeltypesv2.NewPacketV2(sequence, sourceID, counterparty.ClientId, timeoutTimestamp, data...) + packet := channeltypesv2.NewPacketV2(sequence, sourceID, "channel-1", timeoutTimestamp, data...) if err := packet.ValidateBasic(); err != nil { return 0, errorsmod.Wrapf(channeltypes.ErrInvalidPacket, "constructed packet failed basic validation: %v", err) @@ -82,13 +82,13 @@ func (k Keeper) RecvPacketV2( ) error { // Lookup counterparty associated with our channel and ensure // that the packet was indeed sent by our counterparty. - counterparty, ok := k.GetCounterparty(ctx, packet.DestinationId) + counterparty, ok := k.GetCounterpartyV2(ctx, packet.Data[0].DestinationPort, "channel-1", packet.DestinationId) if !ok { return errorsmod.Wrap(types.ErrCounterpartyNotFound, packet.DestinationId) } - if counterparty.ClientId != packet.SourceId { - return channeltypes.ErrInvalidChannelIdentifier - } + //if counterparty.ClientId != packet.SourceId { + // return channeltypes.ErrInvalidChannelIdentifier + //} sdkCtx := sdk.UnwrapSDKContext(ctx) // check if packet timed out by comparing it with the latest height of the chain @@ -101,7 +101,8 @@ func (k Keeper) RecvPacketV2( // REPLAY PROTECTION: Packet receipts will indicate that a packet has already been received // on unordered channels. Packet receipts must not be pruned, unless it has been marked stale // by the increase of the recvStartSequence. - _, found := k.ChannelKeeper.GetPacketReceipt(ctx, host.SentinelV2PortID, packet.DestinationId, packet.Sequence) + //_, found := k.ChannelKeeper.GetPacketReceipt(ctx, host.SentinelV2PortID, packet.DestinationId, packet.Sequence) + _, found := k.ChannelKeeper.GetPacketReceipt(ctx, packet.Data[0].DestinationPort, packet.DestinationId, packet.Sequence) if found { // TODO: figure out events // channelkeeper.EmitRecvPacketEventV2(ctx, packet, sentinelChannel(packet.DestinationChannel)) @@ -111,21 +112,22 @@ func (k Keeper) RecvPacketV2( return channeltypes.ErrNoOpMsg } - path := host.PacketCommitmentKey(host.SentinelV2PortID, packet.SourceId, packet.Sequence) + path := host.PacketCommitmentKey(host.SentinelV2PortID, counterparty.ClientId, packet.Sequence) + //path := host.PacketCommitmentKey(packet.Data[0].SourcePort, packet.SourceId, packet.Sequence) merklePath := types.BuildMerklePath(counterparty.MerklePathPrefix, path) commitment := channeltypes.CommitPacketV2(packet) if err := k.ClientKeeper.VerifyMembership( ctx, - packet.DestinationId, + counterparty.ClientId, proofHeight, 0, 0, proof, merklePath, commitment, ); err != nil { - return errorsmod.Wrapf(err, "failed packet commitment verification for client (%s)", packet.DestinationId) + return errorsmod.Wrapf(err, "failed packet commitment verification for client (%s)", counterparty.ClientId) } // Set Packet Receipt to prevent timeout from occurring on counterparty @@ -150,14 +152,16 @@ func (k Keeper) WriteAcknowledgementV2( // TODO: this should probably error out if any of the acks are async. // Lookup counterparty associated with our channel and ensure // that the packet was indeed sent by our counterparty. - counterparty, ok := k.GetCounterparty(ctx, packet.DestinationId) - if !ok { - return errorsmod.Wrap(types.ErrCounterpartyNotFound, packet.DestinationId) - } - - if counterparty.ClientId != packet.SourceId { - return channeltypes.ErrInvalidChannelIdentifier - } + //counterparty, ok := k.GetCounterparty(ctx, packet.DestinationId) + //if !ok { + // return errorsmod.Wrap(types.ErrCounterpartyNotFound, packet.DestinationId) + //} + + // TODO: how can we make this work if packet.SourceID is a channelID and counterparty has been stored + // under the key of a channelID? + //if counterparty.ClientId != packet.SourceId { + // return channeltypes.ErrInvalidChannelIdentifier + //} // NOTE: IBC app modules might have written the acknowledgement synchronously on // the OnRecvPacket callback so we need to check if the acknowledgement is already