Skip to content

Commit

Permalink
sui-graphql-client: use bcs from Checkpoint instead of manual con…
Browse files Browse the repository at this point in the history
…version (#62)
  • Loading branch information
stefan-mysten authored Dec 12, 2024
1 parent e240ad0 commit b3537da
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 104 deletions.
28 changes: 19 additions & 9 deletions crates/sui-graphql-client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2133,18 +2133,28 @@ mod tests {
chckp.unwrap_err()
);
let chckp_id = chckp.unwrap().unwrap();
let total_transaction_blocks = client.total_transaction_blocks_by_seq_num(chckp_id).await;
assert!(total_transaction_blocks.is_ok());
assert!(total_transaction_blocks.unwrap().is_some_and(|tx| tx > 0));

let chckp = client.checkpoint(None, Some(chckp_id)).await;
assert!(chckp.is_ok());
let digest = chckp.unwrap().unwrap().content_digest;
let total_transaction_blocks = client
.total_transaction_blocks_by_seq_num(chckp_id)
.await
.unwrap()
.unwrap();
assert!(total_transaction_blocks > 0);

let chckp = client
.checkpoint(None, Some(chckp_id))
.await
.unwrap()
.unwrap();

let digest = chckp.digest();
let total_transaction_blocks_by_digest = client
.total_transaction_blocks_by_digest(digest.into())
.await;
assert!(total_transaction_blocks.is_ok());
assert!(total_transaction_blocks.unwrap().is_some_and(|tx| tx > 0));
assert!(total_transaction_blocks_by_digest.is_ok());
assert_eq!(
total_transaction_blocks_by_digest.unwrap().unwrap(),
total_transaction_blocks
);
}

#[tokio::test]
Expand Down
111 changes: 16 additions & 95 deletions crates/sui-graphql-client/src/query_types/checkpoint.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,14 @@
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

use chrono::DateTime as ChronoDT;
use sui_types::types::CheckpointContentsDigest;
use sui_types::types::CheckpointDigest;
use base64ct::Encoding;
use sui_types::types::CheckpointSummary;
use sui_types::types::GasCostSummary as NativeGasCostSummary;

use crate::error;
use crate::error::Error;
use crate::error::Kind;
use crate::query_types::schema;
use crate::query_types::Base64;
use crate::query_types::BigInt;
use crate::query_types::DateTime;
use crate::query_types::Epoch;
use crate::query_types::PageInfo;

// ===========================================================================
Expand Down Expand Up @@ -84,99 +78,26 @@ pub struct CheckpointId {
#[derive(cynic::QueryFragment, Debug)]
#[cynic(schema = "rpc", graphql_type = "Checkpoint")]
pub struct Checkpoint {
pub epoch: Option<Epoch>,
pub digest: String,
pub network_total_transactions: Option<u64>,
pub previous_checkpoint_digest: Option<String>,
pub sequence_number: u64,
pub timestamp: DateTime,
pub validator_signatures: Base64,
pub rolling_gas_summary: Option<GasCostSummary>,
}

#[derive(cynic::QueryFragment, Debug)]
#[cynic(schema = "rpc", graphql_type = "GasCostSummary")]
pub struct GasCostSummary {
pub computation_cost: Option<BigInt>,
pub non_refundable_storage_fee: Option<BigInt>,
pub storage_cost: Option<BigInt>,
pub storage_rebate: Option<BigInt>,
pub bcs: Option<Base64>,
}

// TODO need bcs in GraphQL Checkpoint to avoid this conversion
impl TryInto<CheckpointSummary> for Checkpoint {
type Error = error::Error;

fn try_into(self) -> Result<CheckpointSummary, Self::Error> {
let epoch = self
.epoch
.ok_or_else(|| {
Error::from_error(Kind::Other, "Epoch is checkpoint summary is missing")
})?
.epoch_id;
let network_total_transactions = self.network_total_transactions.ok_or_else(|| {
Error::from_error(
Kind::Other,
"Network total transactions in checkpoint summary is missing",
)
})?;
let sequence_number = self.sequence_number;
let timestamp_ms = ChronoDT::parse_from_rfc3339(&self.timestamp.0)?
.timestamp_millis()
.try_into()?;
let content_digest = CheckpointContentsDigest::from_base58(&self.digest)?;
let previous_digest = self
.previous_checkpoint_digest
.map(|d| CheckpointDigest::from_base58(&d))
fn try_into(self) -> Result<CheckpointSummary, Error> {
let checkpoint = self
.bcs
.map(|x| base64ct::Base64::decode_vec(&x.0))
.transpose()?
.map(|bcs| {
bcs::from_bytes::<CheckpointSummary>(&bcs).map_err(|e| {
Error::from_error(
Kind::Other,
format!("Failed to deserialize checkpoint summary: {}", e),
)
})
})
.transpose()?;
let epoch_rolling_gas_cost_summary = self
.rolling_gas_summary
.ok_or_else(|| {
Error::from_error(
Kind::Other,
"Gas cost summary in checkpoint summary is missing",
)
})?
.try_into()?;
Ok(CheckpointSummary {
epoch,
sequence_number,
network_total_transactions,
timestamp_ms,
content_digest,
previous_digest,
epoch_rolling_gas_cost_summary,
checkpoint_commitments: vec![],
end_of_epoch_data: None,
version_specific_data: vec![],
})
}
}

impl TryInto<NativeGasCostSummary> for GasCostSummary {
type Error = error::Error;
fn try_into(self) -> Result<NativeGasCostSummary, Self::Error> {
let computation_cost = self
.computation_cost
.ok_or_else(|| Error::from_error(Kind::Other, "Computation cost is missing"))?
.try_into()?;
let non_refundable_storage_fee = self
.non_refundable_storage_fee
.ok_or_else(|| Error::from_error(Kind::Other, "Non-refundable storage fee is missing"))?
.try_into()?;
let storage_cost = self
.storage_cost
.ok_or_else(|| Error::from_error(Kind::Other, "Storage cost is missing"))?
.try_into()?;
let storage_rebate = self
.storage_rebate
.ok_or_else(|| Error::from_error(Kind::Other, "Storage rebate is missing"))?
.try_into()?;
Ok(NativeGasCostSummary {
computation_cost,
non_refundable_storage_fee,
storage_cost,
storage_rebate,
})
checkpoint.ok_or_else(|| Error::from_error(Kind::Other, "Checkpoint summary is missing"))
}
}

0 comments on commit b3537da

Please sign in to comment.