Skip to content

Commit f164b9b

Browse files
crodriguezvegamergify[bot]
authored andcommitted
fix(statemachine)!: use key within IBC store without escaping characters in solomachine (#4429)
(cherry picked from commit 98b0c99) # Conflicts: # modules/light-clients/06-solomachine/client_state.go # modules/light-clients/07-tendermint/upgrade.go
1 parent e3faf70 commit f164b9b

File tree

6 files changed

+138
-30
lines changed

6 files changed

+138
-30
lines changed

modules/core/23-commitment/types/merkle.go

+13-5
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,12 @@ func NewMerklePath(keyPath ...string) MerklePath {
7979
// This represents the path in the same way the tendermint KeyPath will
8080
// represent a key path. The backslashes partition the key path into
8181
// the respective stores they belong to.
82+
//
83+
// Deprecated: This function makes assumptions about the way a merkle path
84+
// in a multistore should be represented as a string that are not standardized.
85+
// The decision on how to represent the merkle path as a string will be deferred
86+
// to upstream users of the type.
87+
// This function will be removed in a next release.
8288
func (mp MerklePath) String() string {
8389
pathStr := ""
8490
for _, k := range mp.KeyPath {
@@ -91,6 +97,12 @@ func (mp MerklePath) String() string {
9197
// This function will unescape any backslash within a particular store key.
9298
// This makes the keypath more human-readable while removing information
9399
// about the exact partitions in the key path.
100+
//
101+
// Deprecated: This function makes assumptions about the way a merkle path
102+
// in a multistore should be represented as a string that are not standardized.
103+
// The decision on how to represent the merkle path as a string will be deferred
104+
// to upstream users of the type.
105+
// This function will be removed in a next release.
94106
func (mp MerklePath) Pretty() string {
95107
path, err := url.PathUnescape(mp.String())
96108
if err != nil {
@@ -105,11 +117,7 @@ func (mp MerklePath) GetKey(i uint64) ([]byte, error) {
105117
if i >= uint64(len(mp.KeyPath)) {
106118
return nil, fmt.Errorf("index out of range. %d (index) >= %d (len)", i, len(mp.KeyPath))
107119
}
108-
key, err := url.PathUnescape(mp.KeyPath[i])
109-
if err != nil {
110-
return nil, err
111-
}
112-
return []byte(key), nil
120+
return []byte(mp.KeyPath[i]), nil
113121
}
114122

115123
// Empty returns true if the path is empty

modules/core/exported/commitment.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ type Prefix interface {
2828
// Path implements spec:CommitmentPath.
2929
// A path is the additional information provided to the verification function.
3030
type Path interface {
31-
String() string
31+
String() string // deprecated
3232
Empty() bool
3333
}
3434

modules/light-clients/06-solomachine/client_state.go

+23-2
Original file line numberDiff line numberDiff line change
@@ -125,15 +125,26 @@ func (cs *ClientState) VerifyMembership(
125125
return sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "expected %T, got %T", commitmenttypes.MerklePath{}, path)
126126
}
127127

128+
<<<<<<< HEAD
128129
if merklePath.Empty() {
129130
return sdkerrors.Wrap(commitmenttypes.ErrInvalidProof, "path is empty")
131+
=======
132+
if len(merklePath.GetKeyPath()) != 2 {
133+
return errorsmod.Wrapf(host.ErrInvalidPath, "path must be of length 2: %s", merklePath.GetKeyPath())
134+
}
135+
136+
// in a multistore context: index 0 is the key for the IBC store in the multistore, index 1 is the key in the IBC store
137+
key, err := merklePath.GetKey(1)
138+
if err != nil {
139+
return errorsmod.Wrapf(host.ErrInvalidPath, "key not found at index 1: %v", err)
140+
>>>>>>> 98b0c992 (fix(statemachine)!: use key within IBC store without escaping characters in solomachine (#4429))
130141
}
131142

132143
signBytes := &SignBytes{
133144
Sequence: sequence,
134145
Timestamp: timestamp,
135146
Diversifier: cs.ConsensusState.Diversifier,
136-
Path: []byte(merklePath.String()),
147+
Path: key,
137148
Data: value,
138149
}
139150

@@ -175,11 +186,21 @@ func (cs *ClientState) VerifyNonMembership(
175186
return sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "expected %T, got %T", commitmenttypes.MerklePath{}, path)
176187
}
177188

189+
if len(merklePath.GetKeyPath()) != 2 {
190+
return errorsmod.Wrapf(host.ErrInvalidPath, "path must be of length 2: %s", merklePath.GetKeyPath())
191+
}
192+
193+
// in a multistore context: index 0 is the key for the IBC store in the multistore, index 1 is the key in the IBC store
194+
key, err := merklePath.GetKey(1)
195+
if err != nil {
196+
return errorsmod.Wrapf(host.ErrInvalidPath, "key not found at index 1: %v", err)
197+
}
198+
178199
signBytes := &SignBytes{
179200
Sequence: sequence,
180201
Timestamp: timestamp,
181202
Diversifier: cs.ConsensusState.Diversifier,
182-
Path: []byte(merklePath.String()),
203+
Path: key,
183204
Data: nil,
184205
}
185206

modules/light-clients/06-solomachine/client_state_test.go

+60-14
Original file line numberDiff line numberDiff line change
@@ -176,11 +176,15 @@ func (suite *SoloMachineTestSuite) TestVerifyMembership() {
176176
suite.Require().NoError(err)
177177

178178
path = suite.solomachine.GetClientStatePath(counterpartyClientIdentifier)
179+
merklePath, ok := path.(commitmenttypes.MerklePath)
180+
suite.Require().True(ok)
181+
key, err := merklePath.GetKey(1) // in a multistore context: index 0 is the key for the IBC store in the multistore, index 1 is the key in the IBC store
182+
suite.Require().NoError(err)
179183
signBytes = solomachine.SignBytes{
180184
Sequence: sm.GetHeight().GetRevisionHeight(),
181185
Timestamp: sm.Time,
182186
Diversifier: sm.Diversifier,
183-
Path: []byte(path.String()),
187+
Path: key,
184188
Data: clientStateBz,
185189
}
186190

@@ -208,11 +212,15 @@ func (suite *SoloMachineTestSuite) TestVerifyMembership() {
208212
suite.Require().NoError(err)
209213

210214
path = sm.GetConsensusStatePath(counterpartyClientIdentifier, clienttypes.NewHeight(0, 1))
215+
merklePath, ok := path.(commitmenttypes.MerklePath)
216+
suite.Require().True(ok)
217+
key, err := merklePath.GetKey(1) // in a multistore context: index 0 is the key for the IBC store in the multistore, index 1 is the key in the IBC store
218+
suite.Require().NoError(err)
211219
signBytes = solomachine.SignBytes{
212220
Sequence: sm.Sequence,
213221
Timestamp: sm.Time,
214222
Diversifier: sm.Diversifier,
215-
Path: []byte(path.String()),
223+
Path: key,
216224
Data: consensusStateBz,
217225
}
218226

@@ -243,11 +251,15 @@ func (suite *SoloMachineTestSuite) TestVerifyMembership() {
243251
suite.Require().NoError(err)
244252

245253
path = sm.GetConnectionStatePath(ibctesting.FirstConnectionID)
254+
merklePath, ok := path.(commitmenttypes.MerklePath)
255+
suite.Require().True(ok)
256+
key, err := merklePath.GetKey(1) // in a multistore context: index 0 is the key for the IBC store in the multistore, index 1 is the key in the IBC store
257+
suite.Require().NoError(err)
246258
signBytes = solomachine.SignBytes{
247259
Sequence: sm.Sequence,
248260
Timestamp: sm.Time,
249261
Diversifier: sm.Diversifier,
250-
Path: []byte(path.String()),
262+
Path: key,
251263
Data: connectionEndBz,
252264
}
253265

@@ -279,11 +291,15 @@ func (suite *SoloMachineTestSuite) TestVerifyMembership() {
279291
suite.Require().NoError(err)
280292

281293
path = sm.GetChannelStatePath(ibctesting.MockPort, ibctesting.FirstChannelID)
294+
merklePath, ok := path.(commitmenttypes.MerklePath)
295+
suite.Require().True(ok)
296+
key, err := merklePath.GetKey(1) // in a multistore context: index 0 is the key for the IBC store in the multistore, index 1 is the key in the IBC store
297+
suite.Require().NoError(err)
282298
signBytes = solomachine.SignBytes{
283299
Sequence: sm.Sequence,
284300
Timestamp: sm.Time,
285301
Diversifier: sm.Diversifier,
286-
Path: []byte(path.String()),
302+
Path: key,
287303
Data: channelEndBz,
288304
}
289305

@@ -312,11 +328,15 @@ func (suite *SoloMachineTestSuite) TestVerifyMembership() {
312328
suite.Require().True(found)
313329

314330
path = sm.GetNextSequenceRecvPath(ibctesting.MockPort, ibctesting.FirstChannelID)
331+
merklePath, ok := path.(commitmenttypes.MerklePath)
332+
suite.Require().True(ok)
333+
key, err := merklePath.GetKey(1) // in a multistore context: index 0 is the key for the IBC store in the multistore, index 1 is the key in the IBC store
334+
suite.Require().NoError(err)
315335
signBytes = solomachine.SignBytes{
316336
Sequence: sm.Sequence,
317337
Timestamp: sm.Time,
318338
Diversifier: sm.Diversifier,
319-
Path: []byte(path.String()),
339+
Path: key,
320340
Data: sdk.Uint64ToBigEndian(nextSeqRecv),
321341
}
322342

@@ -351,11 +371,15 @@ func (suite *SoloMachineTestSuite) TestVerifyMembership() {
351371

352372
commitmentBz := channeltypes.CommitPacket(suite.chainA.Codec, packet)
353373
path = sm.GetPacketCommitmentPath(packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence())
374+
merklePath, ok := path.(commitmenttypes.MerklePath)
375+
suite.Require().True(ok)
376+
key, err := merklePath.GetKey(1) // in a multistore context: index 0 is the key for the IBC store in the multistore, index 1 is the key in the IBC store
377+
suite.Require().NoError(err)
354378
signBytes = solomachine.SignBytes{
355379
Sequence: sm.Sequence,
356380
Timestamp: sm.Time,
357381
Diversifier: sm.Diversifier,
358-
Path: []byte(path.String()),
382+
Path: key,
359383
Data: commitmentBz,
360384
}
361385

@@ -378,11 +402,15 @@ func (suite *SoloMachineTestSuite) TestVerifyMembership() {
378402
"success: packet acknowledgement verification",
379403
func() {
380404
path = sm.GetPacketAcknowledgementPath(ibctesting.MockPort, ibctesting.FirstChannelID, 1)
405+
merklePath, ok := path.(commitmenttypes.MerklePath)
406+
suite.Require().True(ok)
407+
key, err := merklePath.GetKey(1) // index 0 is the key for the IBC store in the multistore, index 1 is the key in the IBC store
408+
suite.Require().NoError(err)
381409
signBytes = solomachine.SignBytes{
382410
Sequence: sm.Sequence,
383411
Timestamp: sm.Time,
384412
Diversifier: sm.Diversifier,
385-
Path: []byte(path.String()),
413+
Path: key,
386414
Data: ibctesting.MockAcknowledgement,
387415
}
388416

@@ -405,11 +433,15 @@ func (suite *SoloMachineTestSuite) TestVerifyMembership() {
405433
"success: packet receipt verification",
406434
func() {
407435
path = sm.GetPacketReceiptPath(ibctesting.MockPort, ibctesting.FirstChannelID, 1)
436+
merklePath, ok := path.(commitmenttypes.MerklePath)
437+
suite.Require().True(ok)
438+
key, err := merklePath.GetKey(1) // in a multistore context: index 0 is the key for the IBC store in the multistore, index 1 is the key in the IBC store
439+
suite.Require().NoError(err)
408440
signBytes = solomachine.SignBytes{
409441
Sequence: sm.Sequence,
410442
Timestamp: sm.Time,
411443
Diversifier: sm.Diversifier,
412-
Path: []byte(path.String()),
444+
Path: key,
413445
Data: []byte{byte(1)}, // packet receipt is stored as a single byte
414446
}
415447

@@ -429,7 +461,7 @@ func (suite *SoloMachineTestSuite) TestVerifyMembership() {
429461
true,
430462
},
431463
{
432-
"invalid path type",
464+
"invalid path type - empty",
433465
func() {
434466
path = ibcmock.KeyPath{}
435467
},
@@ -521,11 +553,15 @@ func (suite *SoloMachineTestSuite) TestVerifyMembership() {
521553
clientState = sm.ClientState()
522554

523555
path = commitmenttypes.NewMerklePath("ibc", "solomachine")
556+
merklePath, ok := path.(commitmenttypes.MerklePath)
557+
suite.Require().True(ok)
558+
key, err := merklePath.GetKey(1) // in a multistore context: index 0 is the key for the IBC store in the multistore, index 1 is the key in the IBC store
559+
suite.Require().NoError(err)
524560
signBytes = solomachine.SignBytes{
525561
Sequence: sm.GetHeight().GetRevisionHeight(),
526562
Timestamp: sm.Time,
527563
Diversifier: sm.Diversifier,
528-
Path: []byte(path.String()),
564+
Path: key,
529565
Data: []byte("solomachine"),
530566
}
531567

@@ -570,19 +606,21 @@ func (suite *SoloMachineTestSuite) TestVerifyMembership() {
570606
func (suite *SoloMachineTestSuite) TestSignBytesMarshalling() {
571607
sm := suite.solomachine
572608
merklePath := commitmenttypes.NewMerklePath("ibc", "solomachine")
609+
key, err := merklePath.GetKey(1) // in a multistore context: index 0 is the key for the IBC store in the multistore, index 1 is the key in the IBC store
610+
suite.Require().NoError(err)
573611
signBytesNilData := solomachine.SignBytes{
574612
Sequence: sm.GetHeight().GetRevisionHeight(),
575613
Timestamp: sm.Time,
576614
Diversifier: sm.Diversifier,
577-
Path: []byte(merklePath.String()),
615+
Path: key,
578616
Data: nil,
579617
}
580618

581619
signBytesEmptyArray := solomachine.SignBytes{
582620
Sequence: sm.GetHeight().GetRevisionHeight(),
583621
Timestamp: sm.Time,
584622
Diversifier: sm.Diversifier,
585-
Path: []byte(merklePath.String()),
623+
Path: key,
586624
Data: []byte{},
587625
}
588626

@@ -621,11 +659,15 @@ func (suite *SoloMachineTestSuite) TestVerifyNonMembership() {
621659
"success: packet receipt absence verification",
622660
func() {
623661
path = suite.solomachine.GetPacketReceiptPath(ibctesting.MockPort, ibctesting.FirstChannelID, 1)
662+
merklePath, ok := path.(commitmenttypes.MerklePath)
663+
suite.Require().True(ok)
664+
key, err := merklePath.GetKey(1) // in a multistore context: index 0 is the key for the IBC store in the multistore, index 1 is the key in the IBC store
665+
suite.Require().NoError(err)
624666
signBytes = solomachine.SignBytes{
625667
Sequence: sm.GetHeight().GetRevisionHeight(),
626668
Timestamp: sm.Time,
627669
Diversifier: sm.Diversifier,
628-
Path: []byte(path.String()),
670+
Path: key,
629671
Data: nil,
630672
}
631673

@@ -740,11 +782,15 @@ func (suite *SoloMachineTestSuite) TestVerifyNonMembership() {
740782
clientState = sm.ClientState()
741783

742784
path = commitmenttypes.NewMerklePath("ibc", "solomachine")
785+
merklePath, ok := path.(commitmenttypes.MerklePath)
786+
suite.Require().True(ok)
787+
key, err := merklePath.GetKey(1) // in a multistore context: index 0 is the key for the IBC store in the multistore, index 1 is the key in the IBC store
788+
suite.Require().NoError(err)
743789
signBytes = solomachine.SignBytes{
744790
Sequence: sm.GetHeight().GetRevisionHeight(),
745791
Timestamp: sm.Time,
746792
Diversifier: sm.Diversifier,
747-
Path: []byte(path.String()),
793+
Path: key,
748794
Data: nil,
749795
}
750796

modules/light-clients/07-tendermint/upgrade.go

+8
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,11 @@ func (cs ClientState) VerifyUpgradeAndUpdateState(
8080
// construct clientState Merkle path
8181
upgradeClientPath := constructUpgradeClientMerklePath(cs.UpgradePath, lastHeight)
8282
if err := merkleProofClient.VerifyMembership(cs.ProofSpecs, consState.GetRoot(), upgradeClientPath, bz); err != nil {
83+
<<<<<<< HEAD
8384
return sdkerrors.Wrapf(err, "client state proof failed. Path: %s", upgradeClientPath.Pretty())
85+
=======
86+
return errorsmod.Wrapf(err, "client state proof failed. Path: %s", upgradeClientPath.GetKeyPath())
87+
>>>>>>> 98b0c992 (fix(statemachine)!: use key within IBC store without escaping characters in solomachine (#4429))
8488
}
8589

8690
// Verify consensus state proof
@@ -91,7 +95,11 @@ func (cs ClientState) VerifyUpgradeAndUpdateState(
9195
// construct consensus state Merkle path
9296
upgradeConsStatePath := constructUpgradeConsStateMerklePath(cs.UpgradePath, lastHeight)
9397
if err := merkleProofConsState.VerifyMembership(cs.ProofSpecs, consState.GetRoot(), upgradeConsStatePath, bz); err != nil {
98+
<<<<<<< HEAD
9499
return sdkerrors.Wrapf(err, "consensus state proof failed. Path: %s", upgradeConsStatePath.Pretty())
100+
=======
101+
return errorsmod.Wrapf(err, "consensus state proof failed. Path: %s", upgradeConsStatePath.GetKeyPath())
102+
>>>>>>> 98b0c992 (fix(statemachine)!: use key within IBC store without escaping characters in solomachine (#4429))
95103
}
96104

97105
// Construct new client state and consensus state

0 commit comments

Comments
 (0)