Skip to content

Commit

Permalink
[GraphQL/Package] Query using Db, not IndexerReader (#17179)
Browse files Browse the repository at this point in the history
## Description

Change GraphQL's package store implementation to depend on GraphQL's
`Db` type, instead of `IndexerReader`. This means package loads are
subject to our limits and metrics, and makes it easier to switch them to
using data loaders in future.

## Test plan

Existing tests

## Stack

- #17177 
- #17178 

---

## Release notes

Check each box that your changes affect. If none of the boxes relate to
your changes, release notes aren't required.

For each box you select, include information after the relevant heading
that describes the impact of your changes that a user might notice and
any actions they must take to implement updates.

- [ ] Protocol: 
- [ ] Nodes (Validators and Full nodes): 
- [ ] Indexer: 
- [ ] JSON-RPC: 
- [ ] GraphQL: 
- [ ] CLI: 
- [ ] Rust SDK:
  • Loading branch information
amnn authored Apr 16, 2024
1 parent e00a289 commit aecdf86
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 42 deletions.
88 changes: 47 additions & 41 deletions crates/sui-graphql-rpc/src/data/package_resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,19 @@
use std::sync::Arc;

use async_trait::async_trait;
use diesel::{ExpressionMethods, OptionalExtension, QueryDsl, RunQueryDsl};
use diesel::{ExpressionMethods, OptionalExtension, QueryDsl};
use move_core_types::account_address::AccountAddress;
use sui_indexer::errors::IndexerError;
use sui_indexer::{indexer_reader::IndexerReader, schema::objects};
use sui_indexer::schema::objects;
use sui_package_resolver::Resolver;
use sui_package_resolver::{
error::Error as PackageResolverError, Package, PackageStore, PackageStoreWithLruCache, Result,
};
use sui_types::base_types::SequenceNumber;
use sui_types::object::Object;
use thiserror::Error;

use crate::error::Error;

use super::{Db, DbConnection, QueryExecutor};

const STORE: &str = "PostgresDB";

Expand All @@ -23,59 +25,63 @@ pub(crate) type PackageResolver = Resolver<PackageCache>;

/// Store which fetches package for the given address from the backend db on every call
/// to `fetch`
pub struct DbPackageStore(pub IndexerReader);
pub struct DbPackageStore(Db);

#[derive(Error, Debug)]
pub enum Error {
#[error("{0}")]
Indexer(#[from] IndexerError),
impl DbPackageStore {
pub fn new(db: Db) -> Self {
Self(db)
}
}

#[async_trait]
impl PackageStore for DbPackageStore {
async fn version(&self, id: AccountAddress) -> Result<SequenceNumber> {
let query = objects::dsl::objects
.select(objects::dsl::object_version)
.filter(objects::dsl::object_id.eq(id.to_vec()));

let Some(version) = self
.0
.run_query_async(move |conn| query.get_result::<i64>(conn).optional())
.await
.map_err(Error::Indexer)?
else {
return Err(PackageResolverError::PackageNotFound(id));
};
let Self(db) = self;
let version: Option<i64> = db
.execute(move |conn| {
conn.result(move || {
objects::dsl::objects
.select(objects::dsl::object_version)
.filter(objects::dsl::object_id.eq(id.to_vec()))
})
.optional()
})
.await?;

Ok(SequenceNumber::from_u64(version as u64))
if let Some(version) = version {
Ok(SequenceNumber::from_u64(version as u64))
} else {
Err(PackageResolverError::PackageNotFound(id))
}
}

async fn fetch(&self, id: AccountAddress) -> Result<Arc<Package>> {
let query = objects::dsl::objects
.select(objects::dsl::serialized_object)
.filter(objects::dsl::object_id.eq(id.to_vec()));

let Some(bcs) = self
.0
.run_query_async(move |conn| query.get_result::<Vec<u8>>(conn).optional())
.await
.map_err(Error::Indexer)?
else {
return Err(PackageResolverError::PackageNotFound(id));
};
let Self(db) = self;
let bcs: Option<Vec<u8>> = db
.execute(move |conn| {
conn.result(move || {
objects::dsl::objects
.select(objects::dsl::serialized_object)
.filter(objects::dsl::object_id.eq(id.to_vec()))
})
.optional()
})
.await?;

let object = bcs::from_bytes::<Object>(&bcs)?;
Ok(Arc::new(Package::read(&object)?))
if let Some(bcs) = bcs {
let object = bcs::from_bytes::<Object>(&bcs)?;
Ok(Arc::new(Package::read(&object)?))
} else {
Err(PackageResolverError::PackageNotFound(id))
}
}
}

impl From<Error> for PackageResolverError {
fn from(source: Error) -> Self {
match source {
Error::Indexer(indexer_error) => Self::Store {
store: STORE,
source: Box::new(indexer_error),
},
Self::Store {
store: STORE,
source: Box::new(source),
}
}
}
2 changes: 1 addition & 1 deletion crates/sui-graphql-rpc/src/server/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ impl ServerBuilder {
// DB
let db = Db::new(reader.clone(), config.service.limits, metrics.clone());
let pg_conn_pool = PgManager::new(reader.clone());
let package_store = DbPackageStore(reader.clone());
let package_store = DbPackageStore::new(db.clone());
let package_cache = PackageStoreWithLruCache::new(package_store);
builder.db_reader = Some(db.clone());

Expand Down

0 comments on commit aecdf86

Please sign in to comment.