Skip to content

Commit

Permalink
Merge branch 'feat/ibc-eureka' into aditya/write-ack-api
Browse files Browse the repository at this point in the history
  • Loading branch information
AdityaSripal authored Jan 23, 2025
2 parents 5458c21 + 379e3d2 commit 009281b
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 40 deletions.
10 changes: 3 additions & 7 deletions modules/core/04-channel/v2/keeper/packet.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (

clienttypes "github.com/cosmos/ibc-go/v9/modules/core/02-client/types"
"github.com/cosmos/ibc-go/v9/modules/core/04-channel/v2/types"
commitmenttypes "github.com/cosmos/ibc-go/v9/modules/core/23-commitment/types"
hostv2 "github.com/cosmos/ibc-go/v9/modules/core/24-host/v2"
"github.com/cosmos/ibc-go/v9/modules/core/exported"
)
Expand Down Expand Up @@ -121,8 +120,7 @@ func (k *Keeper) recvPacket(
}

path := hostv2.PacketCommitmentKey(packet.SourceClient, packet.Sequence)
merklePrefix := commitmenttypes.NewMerklePath(counterparty.MerklePrefix...)
merklePath := types.BuildMerklePath(merklePrefix, path)
merklePath := types.BuildMerklePath(counterparty.MerklePrefix, path)

commitment := types.CommitPacket(packet)

Expand Down Expand Up @@ -245,8 +243,7 @@ func (k *Keeper) acknowledgePacket(ctx context.Context, packet types.Packet, ack
}

path := hostv2.PacketAcknowledgementKey(packet.DestinationClient, packet.Sequence)
merklePrefix := commitmenttypes.NewMerklePath(counterparty.MerklePrefix...)
merklePath := types.BuildMerklePath(merklePrefix, path)
merklePath := types.BuildMerklePath(counterparty.MerklePrefix, path)

if err := k.ClientKeeper.VerifyMembership(
ctx,
Expand Down Expand Up @@ -324,8 +321,7 @@ func (k *Keeper) timeoutPacket(

// verify packet receipt absence
path := hostv2.PacketReceiptKey(packet.DestinationClient, packet.Sequence)
merklePrefix := commitmenttypes.NewMerklePath(counterparty.MerklePrefix...)
merklePath := types.BuildMerklePath(merklePrefix, path)
merklePath := types.BuildMerklePath(counterparty.MerklePrefix, path)

if err := k.ClientKeeper.VerifyNonMembership(
ctx,
Expand Down
27 changes: 8 additions & 19 deletions modules/core/04-channel/v2/types/merkle.go
Original file line number Diff line number Diff line change
@@ -1,31 +1,20 @@
package types

import (
commitmenttypes "github.com/cosmos/ibc-go/v9/modules/core/23-commitment/types"
commitmenttypesv2 "github.com/cosmos/ibc-go/v9/modules/core/23-commitment/types/v2"
)

// BuildMerklePath takes the merkle path prefix and an ICS24 path
// and builds a new path by appending the ICS24 path to the last element of the merkle path prefix.
func BuildMerklePath(prefix commitmenttypesv2.MerklePath, path []byte) commitmenttypesv2.MerklePath {
if prefix.Empty() {
return commitmenttypes.NewMerklePath(path)
func BuildMerklePath(prefix [][]byte, path []byte) commitmenttypesv2.MerklePath {
prefixLength := len(prefix)
if prefixLength == 0 {
panic("cannot build merkle path with empty prefix")
}

// avoid mutating the provided prefix
prefixKeys := make([][]byte, len(prefix.KeyPath))
copy(prefixKeys, prefix.KeyPath)

lastElement := prefixKeys[len(prefixKeys)-1]
// copy prefix to avoid modifying the original slice
fullPath := append([][]byte(nil), prefix...)
// append path to last element
newLastElement := cloneAppend(lastElement, path)
prefixKeys[len(prefixKeys)-1] = newLastElement
return commitmenttypes.NewMerklePath(prefixKeys...)
}

func cloneAppend(bz []byte, tail []byte) []byte {
res := make([]byte, len(bz)+len(tail))
copy(res, bz)
copy(res[len(bz):], tail)
return res
fullPath[prefixLength-1] = append(fullPath[prefixLength-1], path...)
return commitmenttypesv2.NewMerklePath(fullPath...)
}
35 changes: 21 additions & 14 deletions modules/core/04-channel/v2/types/merkle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package types_test

import (
"github.com/cosmos/ibc-go/v9/modules/core/04-channel/v2/types"
commitmenttypes "github.com/cosmos/ibc-go/v9/modules/core/23-commitment/types"
commitmenttypesv2 "github.com/cosmos/ibc-go/v9/modules/core/23-commitment/types/v2"
host "github.com/cosmos/ibc-go/v9/modules/core/24-host"
ibctesting "github.com/cosmos/ibc-go/v9/testing"
Expand All @@ -12,14 +11,16 @@ func (s *TypesTestSuite) TestBuildMerklePath() {
path := ibctesting.NewPath(s.chainA, s.chainB)
path.SetupV2()

prefixPath := commitmenttypes.NewMerklePath([]byte("ibc"), []byte(""))
prefixPath := [][]byte{[]byte("ibc"), []byte("")}
packetCommitmentKey := host.PacketCommitmentKey(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, 1)
emptyPrefixPanicMsg := "cannot build merkle path with empty prefix"

testCases := []struct {
name string
prefix commitmenttypesv2.MerklePath
path []byte
expPath commitmenttypesv2.MerklePath
name string
prefix [][]byte
path []byte
expPath commitmenttypesv2.MerklePath
expPanics *string
}{
{
name: "standard ibc path",
Expand All @@ -29,21 +30,21 @@ func (s *TypesTestSuite) TestBuildMerklePath() {
},
{
name: "non-empty last element prefix path",
prefix: commitmenttypes.NewMerklePath([]byte("ibc"), []byte("abc")),
prefix: [][]byte{[]byte("ibc"), []byte("abc")},
path: packetCommitmentKey,
expPath: commitmenttypesv2.NewMerklePath([]byte("ibc"), append([]byte("abc"), packetCommitmentKey...)),
},
{
name: "many elements in prefix path",
prefix: commitmenttypes.NewMerklePath([]byte("ibc"), []byte("a"), []byte("b"), []byte("c"), []byte("d")),
prefix: [][]byte{[]byte("ibc"), []byte("a"), []byte("b"), []byte("c"), []byte("d")},
path: packetCommitmentKey,
expPath: commitmenttypesv2.NewMerklePath([]byte("ibc"), []byte("a"), []byte("b"), []byte("c"), append([]byte("d"), packetCommitmentKey...)),
},
{
name: "empty prefix",
prefix: commitmenttypesv2.MerklePath{},
path: packetCommitmentKey,
expPath: commitmenttypesv2.NewMerklePath(packetCommitmentKey),
name: "empty prefix",
prefix: [][]byte{},
path: packetCommitmentKey,
expPanics: &emptyPrefixPanicMsg,
},
{
name: "empty path",
Expand All @@ -57,8 +58,14 @@ func (s *TypesTestSuite) TestBuildMerklePath() {
tc := tc

s.Run(tc.name, func() {
merklePath := types.BuildMerklePath(tc.prefix, tc.path)
s.Require().Equal(tc.expPath, merklePath)
if tc.expPanics == nil {
merklePath := types.BuildMerklePath(tc.prefix, tc.path)
s.Require().Equal(tc.expPath, merklePath)
} else {
s.Require().PanicsWithValue(*tc.expPanics, func() {
_ = types.BuildMerklePath(tc.prefix, tc.path)
})
}
})
}
}

0 comments on commit 009281b

Please sign in to comment.