Skip to content

Commit

Permalink
[graphql][feature][breaking] compound type filter on ObjectFilter (#1…
Browse files Browse the repository at this point in the history
…5200)

## Description 

Today we have a cascading filter of package, module, and ty on the
ObjectFilter. This PR combines the three fields into 1, and adds logic
to handle looking up generic types.
Now, callers can provide
1. primitive like u64
2. just the package, 0x2
3. package and module: 0x2::coin
4. package, module, type: 0x2::coin::Coin
5. fully instantiated type: 0x2::coin::Coin<0x2::sui::SUI>

## Test Plan 

New filter_by_type.move

---
If your changes are not user-facing and not a breaking change, you can
skip the following section. Otherwise, please indicate what changed, and
then add to the Release Notes section as highlighted during the release
process.

### Type of Change (Check all that apply)

- [ ] protocol change
- [ ] user-visible impact
- [ ] breaking change for a client SDKs
- [ ] breaking change for FNs (FN binary must upgrade)
- [ ] breaking change for validators or node operators (must upgrade
binaries)
- [ ] breaking change for on-chain data layout
- [ ] necessitate either a data wipe or data migration

### Release notes
  • Loading branch information
wlmyng authored Dec 6, 2023
1 parent 0949e61 commit 54c9ecd
Show file tree
Hide file tree
Showing 10 changed files with 797 additions and 22 deletions.
450 changes: 450 additions & 0 deletions crates/sui-graphql-e2e-tests/tests/objects/filter_by_type.exp

Large diffs are not rendered by default.

196 changes: 196 additions & 0 deletions crates/sui-graphql-e2e-tests/tests/objects/filter_by_type.move
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

//# init --simulator --accounts C

// TODO: Short term hack to get around indexer epoch issue
//# create-checkpoint

//# advance-epoch

//# programmable --sender C --inputs 10000000000 @C
//> SplitCoins(Gas, [Input(0)]);
//> TransferObjects([Result(0)], Input(1))

//# run 0x3::sui_system::request_add_stake --args object(0x5) object(3,0) @validator_0 --sender C

// TODO: Short term hack to get around indexer epoch issue
//# create-checkpoint

//# advance-epoch

//# run-graphql
{
objectConnection(filter: {type: "0x3::staking_pool::StakedSui"}) {
edges {
node {
asMoveObject {
contents {
type {
repr
}
}
}
}
}
}
}

//# run-graphql
{
objectConnection(filter: {type: "0x2"}) {
edges {
node {
asMoveObject {
contents {
type {
repr
}
}
}
}
}
}
}

//# run-graphql
{
objectConnection(filter: {type: "0x2::coin"}) {
edges {
node {
asMoveObject {
contents {
type {
repr
}
}
}
}
}
}
}

//# run-graphql
{
objectConnection(filter: {type: "0x2::coin::Coin"}) {
edges {
node {
asMoveObject {
contents {
type {
repr
}
}
}
}
}
}
}

//# run-graphql
# Fetch coins of 0x2::sui::SUI inner type
{
objectConnection(filter: {type: "0x2::coin::Coin<0x2::sui::SUI>"}) {
edges {
node {
asMoveObject {
contents {
type {
repr
}
}
}
}
}
}
}

//# run-graphql
# Inner type should be fully qualified
{
objectConnection(filter: {type: "0x2::coin::Coin<ye>"}) {
edges {
node {
asMoveObject {
contents {
type {
repr
}
}
}
}
}
}
}

//# run-graphql
# If caller provides angle brackets, they must be balanced and wrap a valid type
{
objectConnection(filter: {type: "0x2::coin::Coin<"}) {
edges {
node {
asMoveObject {
contents {
type {
repr
}
}
}
}
}
}
}

//# run-graphql
# Package, module, and name must be valid addresses and identifiers
{
objectConnection(filter: {type: "0x2::a%::B&"}) {
edges {
node {
asMoveObject {
contents {
type {
repr
}
}
}
}
}
}
}

//# run-graphql
# Empty strings are invalid inputs
{
objectConnection(filter: {type: "::::"}) {
edges {
node {
asMoveObject {
contents {
type {
repr
}
}
}
}
}
}
}

//# run-graphql
# Should run successfully but return an empty result
{
objectConnection(filter: {type: "u64"}) {
edges {
node {
asMoveObject {
contents {
type {
repr
}
}
}
}
}
}
}
46 changes: 43 additions & 3 deletions crates/sui-graphql-rpc/docs/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@
#### &emsp;&emsp;[Object](#655350)
### [Object Connection](#11)
#### &emsp;&emsp;[Filter Object Ids](#720885)
#### &emsp;&emsp;[Filter Owner](#720886)
#### &emsp;&emsp;[Object Connection](#720887)
#### &emsp;&emsp;[Filter On Generic Type](#720886)
#### &emsp;&emsp;[Filter On Type](#720887)
#### &emsp;&emsp;[Filter Owner](#720888)
#### &emsp;&emsp;[Object Connection](#720889)
### [Owner](#12)
#### &emsp;&emsp;[Dynamic Field](#786420)
#### &emsp;&emsp;[Dynamic Field Connection](#786421)
Expand Down Expand Up @@ -816,6 +818,44 @@
>}</pre>
### <a id=720886></a>
### Filter On Generic Type

><pre>{
> objectConnection(filter: {type: "0x2::coin::Coin"}) {
> edges {
> node {
> asMoveObject {
> contents {
> type {
> repr
> }
> }
> }
> }
> }
> }
>}</pre>
### <a id=720887></a>
### Filter On Type

><pre>{
> objectConnection(filter: {type: "0x3::staking_pool::StakedSui"}) {
> edges {
> node {
> asMoveObject {
> contents {
> type {
> repr
> }
> }
> }
> }
> }
> }
>}</pre>
### <a id=720888></a>
### Filter Owner
#### Filter on owner

Expand All @@ -834,7 +874,7 @@
> }
>}</pre>
### <a id=720887></a>
### <a id=720889></a>
### Object Connection

><pre>{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
objectConnection(filter: {type: "0x2::coin::Coin"}) {
edges {
node {
asMoveObject {
contents {
type {
repr
}
}
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
objectConnection(filter: {type: "0x3::staking_pool::StakedSui"}) {
edges {
node {
asMoveObject {
contents {
type {
repr
}
}
}
}
}
}
}
10 changes: 7 additions & 3 deletions crates/sui-graphql-rpc/schema/current_progress_schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -1349,9 +1349,13 @@ type ObjectEdge {
}

input ObjectFilter {
package: SuiAddress
module: String
ty: String
"""
This field is used to specify the type of objects that should be included
in the query results. Generic types can be queried by either the generic
type name, e.g. `0x2::coin::Coin`, or by the full type name, such as
`0x2::coin::Coin<0x2::sui::SUI>`.
"""
type: String
owner: SuiAddress
objectIds: [SuiAddress!]
objectKeys: [ObjectKey!]
Expand Down
9 changes: 3 additions & 6 deletions crates/sui-graphql-rpc/src/context_data/db_data_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,8 @@ pub enum DbValidationError {
QueryCostExceeded(u64, u64),
#[error("Page size exceeded - requested: {0}, limit: {1}")]
PageSizeExceeded(u64, u64),
#[error("Invalid type provided as filter: {0}")]
InvalidType(String),
}

pub(crate) struct PgManager {
Expand Down Expand Up @@ -549,9 +551,6 @@ impl PgManager {
}

pub(crate) fn validate_obj_filter(&self, filter: &ObjectFilter) -> Result<(), Error> {
if filter.package.is_some() || filter.module.is_some() || filter.ty.is_some() {
return Err(DbValidationError::UnsupportedPMT.into());
}
if filter.object_keys.is_some() {
return Err(DbValidationError::UnsupportedObjectKeys.into());
}
Expand Down Expand Up @@ -1139,9 +1138,7 @@ impl PgManager {
before: Option<String>,
) -> Result<Option<Connection<String, StakedSui>>, Error> {
let obj_filter = ObjectFilter {
package: None,
module: None,
ty: Some(MoveObjectType::staked_sui().to_canonical_string(/* with_prefix */ true)),
type_: Some(MoveObjectType::staked_sui().to_canonical_string(/* with_prefix */ true)),
owner: Some(address),
object_ids: None,
object_keys: None,
Expand Down
Loading

3 comments on commit 54c9ecd

@vercel
Copy link

@vercel vercel bot commented on 54c9ecd Dec 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vercel
Copy link

@vercel vercel bot commented on 54c9ecd Dec 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vercel
Copy link

@vercel vercel bot commented on 54c9ecd Dec 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

mysten-ui – ./apps/ui

mysten-ui-mysten-labs.vercel.app
mysten-ui-git-main-mysten-labs.vercel.app
mysten-ui.vercel.app

Please sign in to comment.