Skip to content

Commit

Permalink
[GraphQL/MovePackage] Paginate by checkpoint
Browse files Browse the repository at this point in the history
## Description

Adds a query, `Query.packages` for fetching all packages that were
introduced within a given checkpoint range. Useful for fetching
package contents in bulk, to do local analyses.

## Test plan

New E2E tests:

```
sui$ cargo nextest run -p sui-graphql-e2e-tests \
  --features pg_integration                     \
  -- packages/versioning
```

Also tested for performance against a large read replica (the query
planner quotes a high estimate for the query but the actual results do
not take very long to run because queries on many sub-partitions are
eliminated).
  • Loading branch information
amnn committed May 14, 2024
1 parent a84ac48 commit e7eb5e6
Show file tree
Hide file tree
Showing 7 changed files with 473 additions and 22 deletions.
203 changes: 191 additions & 12 deletions crates/sui-graphql-e2e-tests/tests/packages/versioning.exp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
processed 14 tasks
processed 15 tasks

init:
A: object(0,0)
Expand All @@ -11,7 +11,7 @@ gas summary: computation_cost: 1000000, storage_cost: 5076800, storage_rebate:
task 2 'create-checkpoint'. lines 11-11:
Checkpoint created: 1

task 3 'run-graphql'. lines 13-21:
task 3 'run-graphql'. lines 13-28:
Response: {
"data": {
"latestPackage": {
Expand All @@ -25,19 +25,43 @@ Response: {
]
}
}
},
"packages": {
"nodes": [
{
"address": "0x0000000000000000000000000000000000000000000000000000000000000001",
"version": 1
},
{
"address": "0x0000000000000000000000000000000000000000000000000000000000000002",
"version": 1
},
{
"address": "0x0000000000000000000000000000000000000000000000000000000000000003",
"version": 1
},
{
"address": "0x000000000000000000000000000000000000000000000000000000000000dee9",
"version": 1
},
{
"address": "0x175ae86f2df1eb652d57fbe9e44c7f2d67870d2b6776a4356f30930221b63b88",
"version": 1
}
]
}
}
}

task 4 'upgrade'. lines 23-27:
task 4 'upgrade'. lines 30-34:
created: object(4,0)
mutated: object(0,0), object(1,1)
gas summary: computation_cost: 1000000, storage_cost: 5251600, storage_rebate: 2595780, non_refundable_storage_fee: 26220

task 5 'create-checkpoint'. lines 29-29:
task 5 'create-checkpoint'. lines 36-36:
Checkpoint created: 2

task 6 'run-graphql'. lines 31-39:
task 6 'run-graphql'. lines 38-53:
Response: {
"data": {
"latestPackage": {
Expand All @@ -54,19 +78,47 @@ Response: {
]
}
}
},
"packages": {
"nodes": [
{
"address": "0x0000000000000000000000000000000000000000000000000000000000000001",
"version": 1
},
{
"address": "0x0000000000000000000000000000000000000000000000000000000000000002",
"version": 1
},
{
"address": "0x0000000000000000000000000000000000000000000000000000000000000003",
"version": 1
},
{
"address": "0x000000000000000000000000000000000000000000000000000000000000dee9",
"version": 1
},
{
"address": "0x175ae86f2df1eb652d57fbe9e44c7f2d67870d2b6776a4356f30930221b63b88",
"version": 1
},
{
"address": "0x351bc614b36f0f522a64334e4c278d4bfe200234958870c084e0a005f041d681",
"version": 2
}
]
}
}
}

task 7 'upgrade'. lines 41-46:
task 7 'upgrade'. lines 55-60:
created: object(7,0)
mutated: object(0,0), object(1,1)
gas summary: computation_cost: 1000000, storage_cost: 5426400, storage_rebate: 2595780, non_refundable_storage_fee: 26220

task 8 'create-checkpoint'. lines 48-48:
task 8 'create-checkpoint'. lines 62-62:
Checkpoint created: 3

task 9 'run-graphql'. lines 50-58:
task 9 'run-graphql'. lines 64-79:
Response: {
"data": {
"latestPackage": {
Expand All @@ -86,11 +138,43 @@ Response: {
]
}
}
},
"packages": {
"nodes": [
{
"address": "0x0000000000000000000000000000000000000000000000000000000000000001",
"version": 1
},
{
"address": "0x0000000000000000000000000000000000000000000000000000000000000002",
"version": 1
},
{
"address": "0x0000000000000000000000000000000000000000000000000000000000000003",
"version": 1
},
{
"address": "0x000000000000000000000000000000000000000000000000000000000000dee9",
"version": 1
},
{
"address": "0x175ae86f2df1eb652d57fbe9e44c7f2d67870d2b6776a4356f30930221b63b88",
"version": 1
},
{
"address": "0x351bc614b36f0f522a64334e4c278d4bfe200234958870c084e0a005f041d681",
"version": 2
},
{
"address": "0x0eae57b7a07b0548b1f6b0c309f0692828ff994e9159b541334b25582980631c",
"version": 3
}
]
}
}
}

task 10 'run-graphql'. lines 60-97:
task 10 'run-graphql'. lines 81-118:
Response: {
"data": {
"v1": {
Expand Down Expand Up @@ -189,7 +273,7 @@ Response: {
}
}

task 11 'run-graphql'. lines 99-136:
task 11 'run-graphql'. lines 120-157:
Response: {
"data": {
"v1_from_p1": {
Expand Down Expand Up @@ -279,7 +363,7 @@ Response: {
}
}

task 12 'run-graphql'. lines 138-193:
task 12 'run-graphql'. lines 159-214:
Response: {
"data": {
"v1": {
Expand Down Expand Up @@ -417,7 +501,7 @@ Response: {
}
}

task 13 'run-graphql'. lines 195-223:
task 13 'run-graphql'. lines 216-244:
Response: {
"data": {
"v0": null,
Expand All @@ -428,3 +512,98 @@ Response: {
"v4": null
}
}

task 14 'run-graphql'. lines 246-277:
Response: {
"data": {
"before": {
"nodes": [
{
"address": "0x0000000000000000000000000000000000000000000000000000000000000001",
"version": 1,
"previousTransactionBlock": {
"effects": {
"checkpoint": {
"sequenceNumber": 0
}
}
}
},
{
"address": "0x0000000000000000000000000000000000000000000000000000000000000002",
"version": 1,
"previousTransactionBlock": {
"effects": {
"checkpoint": {
"sequenceNumber": 0
}
}
}
},
{
"address": "0x0000000000000000000000000000000000000000000000000000000000000003",
"version": 1,
"previousTransactionBlock": {
"effects": {
"checkpoint": {
"sequenceNumber": 0
}
}
}
},
{
"address": "0x000000000000000000000000000000000000000000000000000000000000dee9",
"version": 1,
"previousTransactionBlock": {
"effects": {
"checkpoint": {
"sequenceNumber": 0
}
}
}
}
]
},
"after": {
"nodes": [
{
"address": "0x351bc614b36f0f522a64334e4c278d4bfe200234958870c084e0a005f041d681",
"version": 2,
"previousTransactionBlock": {
"effects": {
"checkpoint": {
"sequenceNumber": 2
}
}
}
},
{
"address": "0x0eae57b7a07b0548b1f6b0c309f0692828ff994e9159b541334b25582980631c",
"version": 3,
"previousTransactionBlock": {
"effects": {
"checkpoint": {
"sequenceNumber": 3
}
}
}
}
]
},
"between": {
"nodes": [
{
"address": "0x351bc614b36f0f522a64334e4c278d4bfe200234958870c084e0a005f041d681",
"version": 2,
"previousTransactionBlock": {
"effects": {
"checkpoint": {
"sequenceNumber": 2
}
}
}
}
]
}
}
}
54 changes: 54 additions & 0 deletions crates/sui-graphql-e2e-tests/tests/packages/versioning.move
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ module P0::m {
functions { nodes { name } }
}
}

packages(first: 10) {
nodes {
address
version
}
}
}

//# upgrade --package P0 --upgrade-capability 1,1 --sender A
Expand All @@ -36,6 +43,13 @@ module P1::m {
functions { nodes { name } }
}
}

packages(first: 10) {
nodes {
address
version
}
}
}

//# upgrade --package P1 --upgrade-capability 1,1 --sender A
Expand All @@ -55,6 +69,13 @@ module P2::m {
functions { nodes { name } }
}
}

packages(first: 10) {
nodes {
address
version
}
}
}

//# run-graphql
Expand Down Expand Up @@ -221,3 +242,36 @@ module P2::m {
}
}
}

//# run-graphql
{ # Querying packages with checkpoint bounds
before: packages(beforeCheckpoint: 1, first: 10) {
nodes {
address
version
previousTransactionBlock {
effects { checkpoint { sequenceNumber } }
}
}
}

after: packages(afterCheckpoint: 1, first: 10) {
nodes {
address
version
previousTransactionBlock {
effects { checkpoint { sequenceNumber } }
}
}
}

between: packages(afterCheckpoint: 1, beforeCheckpoint: 3, first: 10) {
nodes {
address
version
previousTransactionBlock {
effects { checkpoint { sequenceNumber } }
}
}
}
}
8 changes: 8 additions & 0 deletions crates/sui-graphql-rpc/schema/current_progress_schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -2931,6 +2931,14 @@ type Query {
"""
objects(first: Int, after: String, last: Int, before: String, filter: ObjectFilter): ObjectConnection!
"""
The Move packages that exist in the network, optionally filtered to be strictly before
`beforeCheckpoint` and/or strictly after `afterCheckpoint`.
This query will return all versions of a given user package that appear between the
specified checkpoints, but only records the latest versions of system packages.
"""
packages(first: Int, after: String, last: Int, before: String, afterCheckpoint: Int, beforeCheckpoint: Int): MovePackageConnection!
"""
Fetch the protocol config by protocol version (defaults to the latest protocol
version known to the GraphQL service).
"""
Expand Down
12 changes: 6 additions & 6 deletions crates/sui-graphql-rpc/src/types/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,13 +143,13 @@ impl Event {
/// checkpoint sequence numbers as the cursor to determine the correct page of results. The
/// query can optionally be further `filter`-ed by the `EventFilter`.
///
/// The `checkpoint_viewed_at` parameter is represents the checkpoint sequence number at which
/// this page was queried for. Each entity returned in the connection will inherit this
/// checkpoint, so that when viewing that entity's state, it will be from the reference of this
/// checkpoint_viewed_at parameter.
/// The `checkpoint_viewed_at` parameter represents the checkpoint sequence number at which this
/// page was queried. Each entity returned in the connection will inherit this checkpoint, so
/// that when viewing that entity's state, it will be as if it is being viewed at this
/// checkpoint.
///
/// If the `Page<Cursor>` is set, then this function will defer to the `checkpoint_viewed_at` in
/// the cursor if they are consistent.
/// The cursors in `page` may also include checkpoint viewed at fields. If these are set, they
/// take precedence over the checkpoint that pagination is being conducted in.
pub(crate) async fn paginate(
db: &Db,
page: Page<Cursor>,
Expand Down
Loading

0 comments on commit e7eb5e6

Please sign in to comment.