Skip to content

Commit

Permalink
Merge pull request #88 from neutron-org/fix/invalid_url_escape_error
Browse files Browse the repository at this point in the history
Fix: invalid URL escape error during merkle proof verification
  • Loading branch information
Andrew Zavgorodny authored Nov 9, 2022
2 parents d032589 + b50c201 commit a9e8ba5
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 1 deletion.
55 changes: 55 additions & 0 deletions x/interchainqueries/keeper/keeper_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package keeper_test

import (
"encoding/hex"
"fmt"
"testing"

Expand Down Expand Up @@ -903,6 +904,60 @@ func (suite *KeeperTestSuite) TestSubmitInterchainQueryResult() {
},
iqtypes.ErrInvalidHeight,
},
// in this test we check that storageValue.Key with special bytes (characters) can be properly verified
{
"non existence KV proof with special bytes in key",
func(sender string, ctx sdktypes.Context) {
keyWithSpecialBytes, err := hex.DecodeString("0220c746274d3fe20c2c9d06c017e15f8e03f92598fca39d7540aab02244073efe26756a756e6f78")
suite.Require().NoError(err)

registerMsg := iqtypes.MsgRegisterInterchainQuery{
ConnectionId: suite.Path.EndpointA.ConnectionID,
Keys: []*iqtypes.KVKey{
{Path: host.StoreKey, Key: keyWithSpecialBytes},
},
QueryType: string(iqtypes.InterchainQueryTypeKV),
UpdatePeriod: 1,
Sender: sender,
}

msgSrv := keeper.NewMsgServerImpl(suite.GetNeutronZoneApp(suite.ChainA).InterchainQueriesKeeper)

res, err := msgSrv.RegisterInterchainQuery(sdktypes.WrapSDKContext(ctx), &registerMsg)
suite.Require().NoError(err)

// suite.NoError(suite.Path.EndpointB.UpdateClient())
suite.NoError(suite.Path.EndpointA.UpdateClient())

// now we don't care what is really under the value, we just need to be sure that we can verify KV proofs
resp := suite.ChainB.App.Query(abci.RequestQuery{
Path: fmt.Sprintf("store/%s/key", host.StoreKey),
Height: suite.ChainB.LastHeader.Header.Height - 1,
Data: keyWithSpecialBytes,
Prove: true,
})

msg = iqtypes.MsgSubmitQueryResult{
QueryId: res.Id,
Sender: sender, // A bit weird that query owner submits the results, but it doesn't really matter
ClientId: suite.Path.EndpointA.ClientID,
Result: &iqtypes.QueryResult{
KvResults: []*iqtypes.StorageValue{{
Key: resp.Key,
Proof: resp.ProofOps,
Value: resp.Value,
StoragePrefix: host.StoreKey,
}},
// we don't have tests to test transactions proofs verification since it's a tendermint layer,
// and we don't have access to it here
Block: nil,
Height: uint64(resp.Height),
Revision: suite.ChainA.LastHeader.GetHeight().GetRevisionNumber(),
},
}
},
nil,
},
}

for i, tc := range tests {
Expand Down
3 changes: 2 additions & 1 deletion x/interchainqueries/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package keeper
import (
"bytes"
"context"
"net/url"
"strconv"
"time"

Expand Down Expand Up @@ -221,7 +222,7 @@ func (k msgServer) SubmitQueryResult(goCtx context.Context, msg *types.MsgSubmit
return nil, sdkerrors.Wrapf(types.ErrInvalidSubmittedResult, "KV path from result is not equal to registered query storage prefix: %v != %v", result.StoragePrefix, query.Keys[index].Path)
}

path := ibccommitmenttypes.NewMerklePath(result.StoragePrefix, string(result.Key))
path := ibccommitmenttypes.NewMerklePath(result.StoragePrefix, url.PathEscape(string(result.Key)))

// identify what kind proofs (non-existence proof always has *ics23.CommitmentProof_Nonexist as the first item) we got
// and call corresponding method to verify it
Expand Down

0 comments on commit a9e8ba5

Please sign in to comment.