Skip to content

Commit

Permalink
Add package versions for replay
Browse files Browse the repository at this point in the history
  • Loading branch information
stefan-mysten committed Dec 11, 2024
1 parent b6f1a87 commit 29a09a7
Show file tree
Hide file tree
Showing 5 changed files with 183 additions and 1 deletion.
2 changes: 1 addition & 1 deletion crates/sui-graphql-client-build/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ version = "0.1.0"
edition = "2021"

[dependencies]
cynic-codegen = "3.8.0"
cynic-codegen = "3.7.3"

121 changes: 121 additions & 0 deletions crates/sui-graphql-client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ use query_types::LatestPackageQuery;
use query_types::MoveFunction;
use query_types::MoveModule;
use query_types::MovePackageVersionFilter;
use query_types::MovePackageVersionFilterReplay;
use query_types::NormalizedMoveFunctionQuery;
use query_types::NormalizedMoveFunctionQueryArgs;
use query_types::NormalizedMoveModuleQuery;
Expand All @@ -57,7 +58,9 @@ use query_types::PackageByNameQuery;
use query_types::PackageCheckpointFilter;
use query_types::PackageQuery;
use query_types::PackageVersionsArgs;
use query_types::PackageVersionsArgsReplay;
use query_types::PackageVersionsQuery;
use query_types::PackageVersionsWithEpochDataQuery;
use query_types::PackagesQuery;
use query_types::PackagesQueryArgs;
use query_types::PageInfo;
Expand All @@ -84,6 +87,7 @@ use sui_types::types::Address;
use sui_types::types::CheckpointSequenceNumber;
use sui_types::types::CheckpointSummary;
use sui_types::types::Digest;
use sui_types::types::EpochId;
use sui_types::types::Event;
use sui_types::types::MovePackage;
use sui_types::types::Object;
Expand All @@ -106,6 +110,7 @@ use reqwest::Url;
use serde::de::DeserializeOwned;
use serde::Serialize;
use std::str::FromStr;
use sui_types::types::Version;

use crate::error::Kind;
use crate::error::Result;
Expand Down Expand Up @@ -1255,6 +1260,122 @@ impl Client {
}
}

/// Return a (Option<MovePackage>, version, Option<EpochId>) tuple for each version of the
/// package at address. The Option<EpochId> is the epoch in which this package was published.
pub async fn package_versions_for_replay(
&self,
address: Address,
pagination_filter: PaginationFilter,
after_version: Option<u64>,
before_version: Option<u64>,
) -> Result<Page<(Option<MovePackage>, Version, Option<EpochId>)>, Error> {
let (after, before, first, last) = self.pagination_filter(pagination_filter).await;
let operation = PackageVersionsWithEpochDataQuery::build(PackageVersionsArgsReplay {
address,
after: after.as_deref(),
before: before.as_deref(),
first,
last,
filter: Some(MovePackageVersionFilterReplay {
after_version,
before_version,
}),
});

let response = self.run_query(&operation).await?;

if let Some(errors) = response.errors {
return Err(Error::msg(format!("{:?}", errors)));
}

if let Some(packages) = response.data {
let pc = packages.package_versions;
let page_info = pc.page_info;
let data = pc
.nodes
.into_iter()
.map(|p| (p.package_bcs, p.version, p.previous_transaction_block))
.collect::<Vec<_>>();

let mut output = vec![];

for (bcs, version, previous_transaction_block) in data {
let bcs = bcs
.as_ref()
.map(|b| base64ct::Base64::decode_vec(b.0.as_str()))
.transpose()
.map_err(|e| {
Error::msg(format!("Cannot decode Base64 package bcs bytes: {e}"))
})?;
let package = bcs
.map(|b| bcs::from_bytes::<MovePackage>(&b))
.transpose()
.map_err(|e| {
Error::msg(format!("Cannot decode bcs bytes into MovePackage: {e}"))
})?;

let effects = previous_transaction_block.and_then(|x| x.effects);
let effects = effects.and_then(|x| x.bcs);
let bcs = effects
.map(|x| base64ct::Base64::decode_vec(x.0.as_str()))
.transpose()
.map_err(|e| {
Error::msg(format!("Cannot decode Base64 effects bcs bytes: {e}"))
})?;
let effects = bcs
.map(|b| bcs::from_bytes::<TransactionEffects>(&b))
.transpose()
.map_err(|e| {
Error::msg(format!(
"Cannot decode bcs bytes into TransactionEffects: {e}"
))
})?;
let epoch = effects.map(|e| match e {
TransactionEffects::V1(e) => e.epoch,
TransactionEffects::V2(e) => e.epoch,
});

output.push((package, version, epoch));
}

Ok(Page::new(page_info, output))
} else {
Ok(Page::new_empty())
}
}

/// A stream of package versions for replay.
///
/// Examples
/// ```rust,ignore
/// let client = sui_graphql_client::Client::new_mainnet();
/// let address = Address::from_str("0x2").unwrap();
/// let mut stream = client.package_versions_for_replay_stream(address, Direction::Forward);
/// while let Some(result) = stream.next().await {
/// match result {
/// Ok((Some(pkg), version, Some(epoch))) => {
/// println!("Package: {:#?}", pkg);
/// println!("Version: {:#?}", version);
/// println!("Epoch: {:#?}", epoch);
/// }
/// Ok(_) => {}
/// Err(e) => {
/// println!("Error: {:#?}", e);
/// }
/// }
/// }
pub async fn package_versions_for_replay_stream(
&self,
address: Address,
streaming_direction: Direction,
) -> impl Stream<Item = Result<(Option<MovePackage>, Version, Option<EpochId>), Error>> + '_
{
stream_paginated_query(
move |filter| self.package_versions_for_replay(address, filter, None, None),
streaming_direction,
)
}

/// Fetch the latest version of the package at address.
/// This corresponds to the package with the highest version that shares its original ID with
/// the package at address.
Expand Down
4 changes: 4 additions & 0 deletions crates/sui-graphql-client/src/query_types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ mod events;
mod execute_tx;
mod normalized_move;
mod object;
mod package_replay;
mod packages;
mod protocol_config;
mod service_config;
Expand Down Expand Up @@ -76,6 +77,9 @@ pub use object::ObjectQuery;
pub use object::ObjectQueryArgs;
pub use object::ObjectsQuery;
pub use object::ObjectsQueryArgs;
pub use package_replay::MovePackageVersionFilter as MovePackageVersionFilterReplay;
pub use package_replay::PackageVersionsArgs as PackageVersionsArgsReplay;
pub use package_replay::PackageVersionsWithEpochDataQuery;
pub use packages::LatestPackageQuery;
pub use packages::MovePackage;
pub use packages::MovePackageVersionFilter;
Expand Down
56 changes: 56 additions & 0 deletions crates/sui-graphql-client/src/query_types/package_replay.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

use sui_types::types::Address;

use crate::query_types::schema;
use crate::query_types::Base64;
use crate::query_types::PageInfo;
use crate::query_types::TransactionBlock;

// ===========================================================================
// PackagesVersions
// ===========================================================================

#[derive(cynic::QueryFragment, Debug)]
#[cynic(
schema = "rpc",
graphql_type = "Query",
variables = "PackageVersionsArgs"
)]
pub struct PackageVersionsWithEpochDataQuery {
#[arguments(address: $address, after: $after, first: $first, last: $last, before: $before, filter:$filter)]
pub package_versions: MovePackageConnection,
}

#[derive(cynic::QueryVariables, Debug)]
pub struct PackageVersionsArgs<'a> {
pub address: Address,
pub after: Option<&'a str>,
pub first: Option<i32>,
pub last: Option<i32>,
pub before: Option<&'a str>,
pub filter: Option<MovePackageVersionFilter>,
}

#[derive(cynic::InputObject, Debug)]
#[cynic(schema = "rpc", graphql_type = "MovePackageVersionFilter")]
pub struct MovePackageVersionFilter {
pub after_version: Option<u64>,
pub before_version: Option<u64>,
}

#[derive(cynic::QueryFragment, Debug)]
#[cynic(schema = "rpc", graphql_type = "MovePackage")]
pub struct MovePackage {
pub version: u64,
pub package_bcs: Option<Base64>,
pub previous_transaction_block: Option<TransactionBlock>,
}

#[derive(cynic::QueryFragment, Debug)]
#[cynic(schema = "rpc", graphql_type = "MovePackageConnection")]
pub struct MovePackageConnection {
pub nodes: Vec<MovePackage>,
pub page_info: PageInfo,
}
1 change: 1 addition & 0 deletions crates/sui-graphql-client/src/query_types/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ pub struct TransactionBlocksQueryArgs<'a> {
#[cynic(schema = "rpc", graphql_type = "TransactionBlock")]
pub struct TransactionBlock {
pub bcs: Option<Base64>,
pub effects: Option<TransactionBlockEffects>,
pub signatures: Option<Vec<Base64>>,
}

Expand Down

0 comments on commit 29a09a7

Please sign in to comment.