Skip to content

Commit

Permalink
Interchainquery Proto Cleanup (#373)
Browse files Browse the repository at this point in the history
  • Loading branch information
sampocs authored Nov 25, 2022
1 parent 46a54f6 commit 9d5e1f6
Show file tree
Hide file tree
Showing 9 changed files with 112 additions and 259 deletions.
12 changes: 1 addition & 11 deletions proto/stride/interchainquery/v1/genesis.proto
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,9 @@ message Query {
string chain_id = 3;
string query_type = 4;
bytes request = 5;
string period = 6 [
(cosmos_proto.scalar) = "cosmos.Int",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
string last_height = 7 [
(cosmos_proto.scalar) = "cosmos.Int",
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int",
(gogoproto.nullable) = false
];
string callback_id = 8;
uint64 ttl = 9;
int64 height = 10;
bool request_sent = 11;
}

message DataPoint {
Expand Down
24 changes: 11 additions & 13 deletions x/interchainquery/keeper/abci.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,30 +17,28 @@ func (k Keeper) EndBlocker(ctx sdk.Context) {
_ = k.Logger(ctx)
events := sdk.Events{}
// emit events for periodic queries
k.IterateQueries(ctx, func(_ int64, queryInfo types.Query) (stop bool) {
if queryInfo.LastHeight.Equal(sdk.ZeroInt()) || queryInfo.LastHeight.Add(queryInfo.Period).Equal(sdk.NewInt(ctx.BlockHeight())) {
k.Logger(ctx).Info(fmt.Sprintf("Interchainquery event emitted %s", queryInfo.Id))
k.IterateQueries(ctx, func(_ int64, query types.Query) (stop bool) {
if !query.RequestSent {
k.Logger(ctx).Info(fmt.Sprintf("Interchainquery event emitted %s", query.Id))
// QUESTION: Do we need to emit this event twice?
event := sdk.NewEvent(
sdk.EventTypeMessage,
sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory),
sdk.NewAttribute(sdk.AttributeKeyAction, types.AttributeValueQuery),
sdk.NewAttribute(types.AttributeKeyQueryId, queryInfo.Id),
sdk.NewAttribute(types.AttributeKeyChainId, queryInfo.ChainId),
sdk.NewAttribute(types.AttributeKeyConnectionId, queryInfo.ConnectionId),
sdk.NewAttribute(types.AttributeKeyType, queryInfo.QueryType),
// TODO: add height to request type
sdk.NewAttribute(types.AttributeKeyQueryId, query.Id),
sdk.NewAttribute(types.AttributeKeyChainId, query.ChainId),
sdk.NewAttribute(types.AttributeKeyConnectionId, query.ConnectionId),
sdk.NewAttribute(types.AttributeKeyType, query.QueryType),
sdk.NewAttribute(types.AttributeKeyHeight, "0"),
sdk.NewAttribute(types.AttributeKeyRequest, hex.EncodeToString(queryInfo.Request)),
sdk.NewAttribute(types.AttributeKeyRequest, hex.EncodeToString(query.Request)),
)

events = append(events, event)

event.Type = "query_request"
events = append(events, event)

queryInfo.LastHeight = sdk.NewInt(ctx.BlockHeight())
k.SetQuery(ctx, queryInfo)

query.RequestSent = true
k.SetQuery(ctx, query)
}
return false
})
Expand Down
35 changes: 8 additions & 27 deletions x/interchainquery/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,27 +45,18 @@ func (k Keeper) Logger(ctx sdk.Context) log.Logger {
return ctx.Logger().With("module", fmt.Sprintf("x/%s", types.ModuleName))
}

func (k *Keeper) MakeRequest(ctx sdk.Context, connectionId string, chainId string, queryType string, request []byte, period sdk.Int, module string, callbackId string, ttl uint64, height int64) error {
func (k *Keeper) MakeRequest(ctx sdk.Context, module string, callbackId string, chainId string, connectionId string, queryType string, request []byte, ttl uint64) error {
k.Logger(ctx).Info(
"MakeRequest",
"connectionId", connectionId,
"module", module,
"callbackId", callbackId,
"chainId", chainId,
"connectionId", connectionId,
"queryType", queryType,
"request", request,
"period", period,
"module", module,
"callback", callbackId,
"ttl", ttl,
"height", height,
)

// Only 0 height queries are currently supported
if height != 0 {
errMsg := "[ICQ Validation Check] Failed! height for interchainquery must be 0 (we exclusively query at the latest height on the host zone)"
k.Logger(ctx).Error(errMsg)
return sdkerrors.Wrapf(sdkerrors.ErrInvalidRequest, errMsg)
}

// Confirm the connectionId and chainId are valid
if connectionId == "" {
errMsg := "[ICQ Validation Check] Failed! connection id cannot be empty"
Expand Down Expand Up @@ -97,21 +88,11 @@ func (k *Keeper) MakeRequest(ctx sdk.Context, connectionId string, chainId strin
}
}

// Check to see if the query already exists
key := GenerateQueryHash(connectionId, chainId, queryType, request, module, height)
query, found := k.GetQuery(ctx, key)

// If this is a new query, build the query object
if !found {
query = *k.NewQuery(ctx, module, connectionId, chainId, queryType, request, period, callbackId, ttl, height)
} else {
// Otherwise, if the same query is re-requested - reset the TTL
k.Logger(ctx).Info("Query already exists - resetting TTL")
query.Ttl = ttl
query.LastHeight = sdk.ZeroInt() // allows query to be emitted again
}

// Save the query to the store
// If the same query is re-requested, it will get replace in the store with an updated TTL
// and the RequestSent bool reset to false
query := k.NewQuery(ctx, module, callbackId, chainId, connectionId, queryType, request, ttl)
k.SetQuery(ctx, query)

return nil
}
7 changes: 2 additions & 5 deletions x/interchainquery/keeper/msg_submit_query_response_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,12 @@ func (s *KeeperTestSuite) SetupMsgSubmitQueryResponse() MsgSubmitQueryResponseTe
// save the query to Stride state, so it can be retrieved in the response
query := types.Query{
Id: expectedId,
ConnectionId: s.TransferPath.EndpointA.ConnectionID,
CallbackId: "withdrawalbalance",
ChainId: HostChainId,
ConnectionId: s.TransferPath.EndpointA.ConnectionID,
QueryType: types.BANK_STORE_QUERY_WITH_PROOF,
Request: append(data, []byte(HostChainId)...),
Period: sdk.NewInt(0),
LastHeight: sdk.NewInt(height),
CallbackId: "withdrawalbalance",
Ttl: uint64(12545592938) * uint64(1000000000), // set ttl to August 2050, mult by nano conversion factor
Height: height,
}

return MsgSubmitQueryResponseTestCase{
Expand Down
44 changes: 15 additions & 29 deletions x/interchainquery/keeper/new_query_test.go
Original file line number Diff line number Diff line change
@@ -1,57 +1,48 @@
package keeper_test

import (
sdk "github.com/cosmos/cosmos-sdk/types"
_ "github.com/stretchr/testify/suite"

icqtypes "github.com/Stride-Labs/stride/v3/x/interchainquery/types"
)

type NewQueryTestCase struct {
module string
connectionId string
callbackId string
chainId string
connectionId string
queryType string
request []byte
period sdk.Int
callbackId string
ttl uint64
height int64
}

func (suite *KeeperTestSuite) SetupNewQuery() NewQueryTestCase {
// module is the name of the module invoking the query, used to find the callback upon response
module := "stakeibc"
// connectionId of the target chain you're querying
connectionId := "connection-0"
// callbackId is a string that is used to identify the callback you'd like to execute upon receiving the result of the query
callbackId := "validator"
// chain Id of the target chain you're querying
chainId := "GAIA"
// connectionId of the target chain you're querying
connectionId := "connection-0"
// QueryType is a string that is used to identify the store you'd like to query, as well as whether you'd like a proof returned alongside the result
// use "staking" store to access validator which lives in the staking module
// use "key" suffix to retrieve a proof alongside the query result
queryType := icqtypes.STAKING_STORE_QUERY_WITH_PROOF
// request is a byte array that points to the entry in the target store you'd like to query on the host zone
// e.g. for querying a validator, `data := stakingtypes.GetValidatorKey(valAddr)`
request := []byte{0x01, 0x02, 0x03}
// period is the frequency at which you'd like the query to be executed, if you're executing a period query (note -1 specifies a one-time query)
period := sdk.NewInt(-1)
// callbackId is a string that is used to identify the callback you'd like to execute upon receiving the result of the query
callbackId := "validator"
// ttl is the expiry time of the query, in absolute units of time, unix nanos
ttl := uint64(0) // ttl
// height is the height at which you'd like the query to be executed on the host zone. height=0 means execute at the latest height
height := int64(0) // height always 0 (which means current height)

return NewQueryTestCase{
module: module,
connectionId: connectionId,
callbackId: callbackId,
chainId: chainId,
connectionId: connectionId,
queryType: queryType,
request: request,
period: period,
callbackId: callbackId,
ttl: ttl,
height: height,
}
}

Expand All @@ -61,34 +52,29 @@ func (s *KeeperTestSuite) TestNewQuerySuccessful() {
actualQuery := s.App.InterchainqueryKeeper.NewQuery(
s.Ctx(),
tc.module,
tc.connectionId,
tc.callbackId,
tc.chainId,
tc.connectionId,
tc.queryType,
tc.request,
tc.period,
tc.callbackId,
tc.ttl,
tc.height,
)

// this hash is testing `GenerateQueryHash`.
// note: the module gets hashed in the `GenerateQueryHash` function, so hashes will be unique to each module
// note: the queryID does NOT distinguish between two queries issued with the same (connection_id, chain_id, query_type, request, module, height, request)
// practically the differentiator will be `request`, but it DOES mean that if we submit more than 1 automated query to the same value on the same host account simultaneously, we would get callback conflicts!
expectedId := "9792c1d779a3846a8de7ae82f31a74d308b279a521fa9e0d5c4f08917117bf3e"
// note: the queryID is a has of (module, callbackId, chainId, connectionId, queryType, and request)
// . meaning for a given query type, the ID will be identical across each epoch
expectedId := "e97f7bdad3c4c521165321f78a8329c54f35db23ee9cec7bddf5c60703ac9ba7"
s.Require().Equal(expectedId, actualQuery.Id)

// lastHeight should be 0
expectedLastHeight := sdk.NewInt(0)
s.Require().Equal(expectedLastHeight, actualQuery.LastHeight)
// RequestSent should be false
s.Require().False(actualQuery.RequestSent)

// all other arguments should be the same as the input
s.Require().Equal(tc.connectionId, actualQuery.ConnectionId)
s.Require().Equal(tc.chainId, actualQuery.ChainId)
s.Require().Equal(tc.queryType, actualQuery.QueryType)
s.Require().Equal(tc.request, actualQuery.Request)
s.Require().Equal(tc.period, actualQuery.Period)
s.Require().Equal(tc.callbackId, actualQuery.CallbackId)
s.Require().Equal(tc.ttl, actualQuery.Ttl)
s.Require().Equal(tc.height, actualQuery.Height)
}
15 changes: 6 additions & 9 deletions x/interchainquery/keeper/queries.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package keeper

import (
"fmt"
"strconv"

"github.com/cosmos/cosmos-sdk/store/prefix"
sdk "github.com/cosmos/cosmos-sdk/types"
Expand All @@ -11,22 +10,20 @@ import (
"github.com/Stride-Labs/stride/v3/x/interchainquery/types"
)

func GenerateQueryHash(connectionId string, chainId string, queryType string, request []byte, module string, height int64) string {
return fmt.Sprintf("%x", crypto.Sha256(append([]byte(module+connectionId+chainId+queryType+strconv.FormatInt(height, 10)), request...)))
func GenerateQueryHash(connectionId string, chainId string, queryType string, request []byte, module string, callbackId string) string {
return fmt.Sprintf("%x", crypto.Sha256(append([]byte(module+connectionId+chainId+queryType+callbackId), request...)))
}

func (k Keeper) NewQuery(ctx sdk.Context, module string, connectionId string, chainId string, queryType string, request []byte, period sdk.Int, callbackId string, ttl uint64, height int64) *types.Query {
return &types.Query{
Id: GenerateQueryHash(connectionId, chainId, queryType, request, module, height),
func (k Keeper) NewQuery(ctx sdk.Context, module string, callbackId string, chainId string, connectionId string, queryType string, request []byte, ttl uint64) types.Query {
return types.Query{
Id: GenerateQueryHash(connectionId, chainId, queryType, request, module, callbackId),
ConnectionId: connectionId,
ChainId: chainId,
QueryType: queryType,
Request: request,
Period: period,
LastHeight: sdk.ZeroInt(),
CallbackId: callbackId,
Ttl: ttl,
Height: height,
RequestSent: false,
}
}

Expand Down
Loading

0 comments on commit 9d5e1f6

Please sign in to comment.