diff --git a/Cargo.lock b/Cargo.lock index 038b33d0d..beada77c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4744,6 +4744,7 @@ dependencies = [ "thiserror", "tokio", "toml 0.7.4", + "toolshed", "tower", "tower-http 0.4.0", "tracing", diff --git a/common/src/allocations/mod.rs b/common/src/allocations/mod.rs index 4e050f2d3..87191e816 100644 --- a/common/src/allocations/mod.rs +++ b/common/src/allocations/mod.rs @@ -9,8 +9,7 @@ use ethers_core::k256::ecdsa::SigningKey; use ethers_core::types::U256; use serde::Deserialize; use serde::Deserializer; - -use crate::types::SubgraphDeploymentID; +use toolshed::thegraph::DeploymentId; pub mod monitor; @@ -42,7 +41,7 @@ pub enum AllocationStatus { #[derive(Debug, Eq, PartialEq, Deserialize)] pub struct SubgraphDeployment { - pub id: SubgraphDeploymentID, + pub id: DeploymentId, #[serde(rename = "deniedAt")] pub denied_at: Option, #[serde(rename = "stakedTokens")] @@ -98,14 +97,13 @@ impl<'d> Deserialize<'d> for Allocation { pub fn derive_key_pair( indexer_mnemonic: &str, epoch: u64, - deployment: &SubgraphDeploymentID, + deployment: &DeploymentId, index: u64, ) -> Result> { let mut derivation_path = format!("m/{}/", epoch); derivation_path.push_str( &deployment - .ipfs_hash() - .as_bytes() + .0 .iter() .map(|char| char.to_string()) .collect::>() @@ -147,44 +145,32 @@ pub fn allocation_signer(indexer_mnemonic: &str, allocation: &Allocation) -> Res #[cfg(test)] mod test { use std::str::FromStr; - - use crate::prelude::SubgraphDeploymentID; + use toolshed::thegraph::DeploymentId; use super::*; const INDEXER_OPERATOR_MNEMONIC: &str = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"; + const DEPLOYMENT_ID: DeploymentId = DeploymentId( + "0xbbde25a2c85f55b53b7698b9476610c3d1202d88870e66502ab0076b7218f98a" + .parse() + .unwrap(), + ); #[test] fn test_derive_key_pair() { assert_eq!( - derive_key_pair( - INDEXER_OPERATOR_MNEMONIC, - 953, - &SubgraphDeploymentID::new( - "0xbbde25a2c85f55b53b7698b9476610c3d1202d88870e66502ab0076b7218f98a" - ) - .unwrap(), - 0 - ) - .unwrap() - .address() - .as_fixed_bytes(), + derive_key_pair(INDEXER_OPERATOR_MNEMONIC, 953, &DEPLOYMENT_ID, 0) + .unwrap() + .address() + .as_fixed_bytes(), Address::from_str("0xfa44c72b753a66591f241c7dc04e8178c30e13af").unwrap() ); assert_eq!( - derive_key_pair( - INDEXER_OPERATOR_MNEMONIC, - 940, - &SubgraphDeploymentID::new( - "0xbbde25a2c85f55b53b7698b9476610c3d1202d88870e66502ab0076b7218f98a" - ) - .unwrap(), - 2 - ) - .unwrap() - .address() - .as_fixed_bytes(), + derive_key_pair(INDEXER_OPERATOR_MNEMONIC, 940, &DEPLOYMENT_ID, 2) + .unwrap() + .address() + .as_fixed_bytes(), Address::from_str("0xa171cd12c3dde7eb8fe7717a0bcd06f3ffa65658").unwrap() ); } @@ -197,10 +183,7 @@ mod test { id: Address::from_str("0xa171cd12c3dde7eb8fe7717a0bcd06f3ffa65658").unwrap(), status: AllocationStatus::Null, subgraph_deployment: SubgraphDeployment { - id: SubgraphDeploymentID::new( - "0xbbde25a2c85f55b53b7698b9476610c3d1202d88870e66502ab0076b7218f98a", - ) - .unwrap(), + id: DEPLOYMENT_ID, denied_at: None, staked_tokens: U256::zero(), signalled_tokens: U256::zero(), @@ -239,10 +222,7 @@ mod test { id: Address::from_str("0xdeadbeefcafebabedeadbeefcafebabedeadbeef").unwrap(), status: AllocationStatus::Null, subgraph_deployment: SubgraphDeployment { - id: SubgraphDeploymentID::new( - "0xbbde25a2c85f55b53b7698b9476610c3d1202d88870e66502ab0076b7218f98a", - ) - .unwrap(), + id: DEPLOYMENT_ID, denied_at: None, staked_tokens: U256::zero(), signalled_tokens: U256::zero(), diff --git a/common/src/allocations/monitor.rs b/common/src/allocations/monitor.rs index 7ddea7963..5c3426b97 100644 --- a/common/src/allocations/monitor.rs +++ b/common/src/allocations/monitor.rs @@ -246,9 +246,7 @@ impl AllocationMonitor { .map(|e| { format!( "{{allocation: {:?}, deployment: {}, closedAtEpoch: {:?})}}", - e.id, - e.subgraph_deployment.id.ipfs_hash(), - e.closed_at_epoch + e.id, e.subgraph_deployment.id, e.closed_at_epoch ) }) .collect::>() diff --git a/common/src/attestations/mod.rs b/common/src/attestations/mod.rs index 21ee4aa50..7196e5a8a 100644 --- a/common/src/attestations/mod.rs +++ b/common/src/attestations/mod.rs @@ -7,8 +7,9 @@ use ethers::signers::MnemonicBuilder; use ethers::signers::Signer; use ethers::signers::Wallet; use ethers_core::k256::ecdsa::SigningKey; +use toolshed::thegraph::DeploymentId; -use crate::prelude::{Allocation, SubgraphDeploymentID}; +use crate::prelude::Allocation; pub mod signer; pub mod signers; @@ -16,14 +17,13 @@ pub mod signers; pub fn derive_key_pair( indexer_mnemonic: &str, epoch: u64, - deployment: &SubgraphDeploymentID, + deployment: &DeploymentId, index: u64, ) -> Result> { let mut derivation_path = format!("m/{}/", epoch); derivation_path.push_str( &deployment - .ipfs_hash() - .as_bytes() + .0 .iter() .map(|char| char.to_string()) .collect::>() diff --git a/common/src/attestations/signer.rs b/common/src/attestations/signer.rs index a01191882..393da94e8 100644 --- a/common/src/attestations/signer.rs +++ b/common/src/attestations/signer.rs @@ -11,11 +11,12 @@ use ethers_core::types::U256; use keccak_hash::keccak; use secp256k1::SecretKey; use std::convert::TryInto; +use toolshed::thegraph::DeploymentId; /// An attestation signer tied to a specific allocation via its signer key #[derive(Debug, Clone)] pub struct AttestationSigner { - subgraph_deployment_id: Bytes32, + subgraph_deployment_id: DeploymentId, domain_separator: DomainSeparator, signer: SecretKey, } @@ -25,7 +26,7 @@ impl AttestationSigner { chain_id: eip_712_derive::U256, dispute_manager: Address, signer: SecretKey, - subgraph_deployment_id: Bytes32, + deployment_id: DeploymentId, ) -> Self { let bytes = hex::decode("a070ffb1cd7409649bf77822cce74495468e06dbfaef09556838bf188679b9c2") .unwrap(); @@ -44,7 +45,7 @@ impl AttestationSigner { Self { domain_separator, signer, - subgraph_deployment_id, + subgraph_deployment_id: deployment_id, } } @@ -55,7 +56,7 @@ impl AttestationSigner { let receipt = Receipt { request_cid, response_cid, - subgraph_deployment_id: self.subgraph_deployment_id, + subgraph_deployment_id: *self.subgraph_deployment_id.0, }; // Unwrap: This can only fail if the SecretKey is invalid. @@ -69,7 +70,7 @@ impl AttestationSigner { v, r, s, - subgraph_deployment_id: self.subgraph_deployment_id, + subgraph_deployment_id: *self.subgraph_deployment_id.0, request_cid, response_cid, } @@ -106,7 +107,7 @@ pub fn create_attestation_signer( chain_id: U256, dispute_manager_address: Address, signer: SigningKey, - deployment_id: [u8; 32], + deployment_id: DeploymentId, ) -> anyhow::Result { // Tedious conversions to the "indexer_native" types let mut chain_id_bytes = [0u8; 32]; diff --git a/common/src/attestations/signers.rs b/common/src/attestations/signers.rs index d362826b6..62c1a336d 100644 --- a/common/src/attestations/signers.rs +++ b/common/src/attestations/signers.rs @@ -70,21 +70,20 @@ impl AttestationSigners { inner.chain_id, inner.dispute_manager, signer, - allocation.subgraph_deployment.id.bytes32(), + allocation.subgraph_deployment.id, ) }) { Ok(signer) => { e.insert(signer); info!( "Found attestation signer for {{allocation: {}, deployment: {}}}", - allocation.id, - allocation.subgraph_deployment.id.ipfs_hash() + allocation.id, allocation.subgraph_deployment.id, ); } Err(e) => { warn!( "Failed to find the attestation signer for {{allocation: {}, deployment: {}, createdAtEpoch: {}, err: {}}}", - allocation.id, allocation.subgraph_deployment.id.ipfs_hash(), allocation.created_at_epoch, e + allocation.id, allocation.subgraph_deployment.id, allocation.created_at_epoch, e ) } } diff --git a/common/src/lib.rs b/common/src/lib.rs index b8e06310c..b20ddcaad 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -6,7 +6,6 @@ pub mod attestations; pub mod graphql; pub mod network_subgraph; pub mod signature_verification; -pub mod types; #[cfg(test)] mod test_vectors; @@ -20,5 +19,4 @@ pub mod prelude { signers::AttestationSigners, }; pub use super::network_subgraph::NetworkSubgraph; - pub use super::types::*; } diff --git a/common/src/types.rs b/common/src/types.rs deleted file mode 100644 index cf30b419c..000000000 --- a/common/src/types.rs +++ /dev/null @@ -1,143 +0,0 @@ -// Copyright 2023-, GraphOps and Semiotic Labs. -// SPDX-License-Identifier: Apache-2.0 - -use ethers::utils::hex; -use serde::Deserialize; - -/// Subgraph identifier type: SubgraphDeploymentID with field 'value' -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct SubgraphDeploymentID { - // bytes32 subgraph deployment Id - value: [u8; 32], -} - -/// Implement deserialization for SubgraphDeploymentID -/// Deserialize from hex string or IPFS multihash string -impl<'de> Deserialize<'de> for SubgraphDeploymentID { - fn deserialize(deserializer: D) -> Result - where - D: serde::Deserializer<'de>, - { - let s = String::deserialize(deserializer)?; - SubgraphDeploymentID::new(&s).map_err(serde::de::Error::custom) - } -} - -/// Implement SubgraphDeploymentID functions -impl SubgraphDeploymentID { - /// Construct SubgraphDeploymentID from a string - /// Validate IPFS hash or hex format before decoding - pub fn new(id: &str) -> anyhow::Result { - SubgraphDeploymentID::from_hex(id) - .or_else(|_| SubgraphDeploymentID::from_ipfs_hash(id)) - .map_err(|_| anyhow::anyhow!("Invalid subgraph deployment ID: {}", id)) - } - - /// Construct SubgraphDeploymentID from a 32 bytes hex string. - /// The '0x' prefix is optional. - /// - /// Returns an error if the input is not a valid hex string or if the input is not 32 bytes long. - pub fn from_hex(id: &str) -> anyhow::Result { - let mut buf = [0u8; 32]; - hex::decode_to_slice(id.trim_start_matches("0x"), &mut buf)?; - Ok(SubgraphDeploymentID { value: buf }) - } - - /// Construct SubgraphDeploymentID from a 34 bytes IPFS multihash string. - /// The 'Qm' prefix is mandatory. - /// - /// Returns an error if the input is not a valid IPFS multihash string or if the input is not 34 bytes long. - pub fn from_ipfs_hash(hash: &str) -> anyhow::Result { - let bytes = bs58::decode(hash).into_vec()?; - let value = bytes[2..].try_into()?; - Ok(SubgraphDeploymentID { value }) - } - - /// Returns the subgraph deployment ID as a 32 bytes array. - pub fn bytes32(&self) -> [u8; 32] { - self.value - } - - /// Returns the subgraph deployment ID as a 34 bytes IPFS multihash string. - pub fn ipfs_hash(&self) -> String { - let value = self.value; - let mut bytes: Vec = vec![0x12, 0x20]; - bytes.extend(value.to_vec()); - bs58::encode(bytes).into_string() - } - - /// Returns the subgraph deployment ID as a 32 bytes hex string. - /// The '0x' prefix is included. - pub fn hex(&self) -> String { - format!("0x{}", hex::encode(self.value)) - } -} - -impl ToString for SubgraphDeploymentID { - fn to_string(&self) -> String { - self.hex() - } -} - -#[cfg(test)] -mod tests { - - use super::*; - - #[test] - fn hex_to_ipfs_multihash() { - let deployment_id = "0xd0b0e5b65df45a3fff1a653b4188881318e8459d3338f936aab16c4003884abf"; - let expected_ipfs_hash = "QmcPHxcC2ZN7m79XfYZ77YmF4t9UCErv87a9NFKrSLWKtJ"; - - assert_eq!( - SubgraphDeploymentID::from_hex(deployment_id) - .unwrap() - .ipfs_hash(), - expected_ipfs_hash - ); - } - - #[test] - fn ipfs_multihash_to_hex() { - let deployment_id = "0xd0b0e5b65df45a3fff1a653b4188881318e8459d3338f936aab16c4003884abf"; - let ipfs_hash = "QmcPHxcC2ZN7m79XfYZ77YmF4t9UCErv87a9NFKrSLWKtJ"; - - assert_eq!( - SubgraphDeploymentID::from_ipfs_hash(ipfs_hash) - .unwrap() - .to_string(), - deployment_id - ); - } - - #[test] - fn subgraph_deployment_id_input_validation_success() { - let deployment_id = "0xd0b0e5b65df45a3fff1a653b4188881318e8459d3338f936aab16c4003884abf"; - let ipfs_hash = "QmcPHxcC2ZN7m79XfYZ77YmF4t9UCErv87a9NFKrSLWKtJ"; - - assert_eq!( - SubgraphDeploymentID::new(ipfs_hash).unwrap().to_string(), - deployment_id - ); - - assert_eq!( - SubgraphDeploymentID::new(deployment_id) - .unwrap() - .ipfs_hash(), - ipfs_hash - ); - } - - #[test] - fn subgraph_deployment_id_input_validation_fail() { - let invalid_deployment_id = - "0xd0b0e5b65df45a3fff1a653b4188881318e8459d3338f936aab16c4003884a"; - let invalid_ipfs_hash = "Qm1234"; - - let res = SubgraphDeploymentID::new(invalid_deployment_id); - assert!(res.is_err()); - - let res = SubgraphDeploymentID::new(invalid_ipfs_hash); - assert!(res.is_err()); - } -} diff --git a/service/Cargo.toml b/service/Cargo.toml index 8b9e2e17c..c0bb3a945 100644 --- a/service/Cargo.toml +++ b/service/Cargo.toml @@ -47,6 +47,7 @@ sqlx = { version = "0.7.1", features = ["postgres", "runtime-tokio", "bigdecimal alloy-primitives = { version = "0.3.3", features = ["serde"] } alloy-sol-types = "0.3.2" lazy_static = "1.4.0" +toolshed = { git = "https://github.com/edgeandnode/toolshed", tag = "v0.2.2", features = ["graphql"] } [dev-dependencies] faux = "0.1.10" diff --git a/service/src/common/indexer_management/mod.rs b/service/src/common/indexer_management/mod.rs index 62c860368..d24a105cb 100644 --- a/service/src/common/indexer_management/mod.rs +++ b/service/src/common/indexer_management/mod.rs @@ -6,8 +6,6 @@ use serde::{Deserialize, Serialize}; use serde_json::Value; use sqlx::{FromRow, PgPool}; -use indexer_common::prelude::SubgraphDeploymentID; - use super::indexer_error::{IndexerError, IndexerErrorCause, IndexerErrorCode}; #[derive(Debug, FromRow, Clone, Serialize, Deserialize, SimpleObject)] @@ -27,16 +25,16 @@ pub async fn cost_models( ) -> Result, IndexerError> { let deployment_ids = deployments .iter() - .map(|d| SubgraphDeploymentID::new(d).unwrap().to_string()) + .map(|s| s.clone()) .collect::>(); let models = if deployment_ids.is_empty() { sqlx::query_as!( CostModel, r#" - SELECT deployment, model, variables - FROM "CostModels" - ORDER BY deployment ASC - "# + SELECT deployment, model, variables + FROM "CostModels" + ORDER BY deployment ASC + "# ) .fetch_all(pool) .await @@ -45,11 +43,11 @@ pub async fn cost_models( sqlx::query_as!( CostModel, r#" - SELECT deployment, model, variables - FROM "CostModels" - WHERE deployment = ANY($1) - ORDER BY deployment ASC - "#, + SELECT deployment, model, variables + FROM "CostModels" + WHERE deployment = ANY($1) + ORDER BY deployment ASC + "#, &deployment_ids ) .fetch_all(pool) @@ -93,14 +91,13 @@ pub async fn cost_model( pool: &PgPool, deployment: &str, ) -> Result, IndexerError> { - let deployment_id = SubgraphDeploymentID::new(deployment).unwrap().to_string(); let model = sqlx::query_as!( CostModel, r#" - SELECT deployment, model, variables - FROM "CostModels" - WHERE deployment = $1 - "#, + SELECT deployment, model, variables + FROM "CostModels" + WHERE deployment = $1 + "#, deployment_id ) .fetch_optional(pool) @@ -113,7 +110,7 @@ pub async fn cost_model( || { Some(merge_global( CostModel { - deployment: deployment.to_string(), + deployment: deployment.into(), model: None, variables: None, }, diff --git a/service/src/escrow_monitor.rs b/service/src/escrow_monitor.rs index 44f032744..4c71965c2 100644 --- a/service/src/escrow_monitor.rs +++ b/service/src/escrow_monitor.rs @@ -10,13 +10,14 @@ use serde_json::json; use std::collections::HashMap; use std::sync::Arc; use tokio::sync::RwLock; +use toolshed::thegraph::DeploymentId; use crate::graph_node::GraphNodeInstance; #[derive(Debug)] struct EscrowMonitorInner { graph_node: GraphNodeInstance, - escrow_subgraph_deployment: String, + escrow_subgraph_deployment: DeploymentId, indexer_address: Address, interval_ms: u64, sender_accounts: Arc>>, @@ -33,7 +34,7 @@ pub struct EscrowMonitor { impl EscrowMonitor { pub async fn new( graph_node: GraphNodeInstance, - escrow_subgraph_deployment: String, + escrow_subgraph_deployment: DeploymentId, indexer_address: Address, interval_ms: u64, ) -> Result { @@ -61,7 +62,7 @@ impl EscrowMonitor { async fn current_accounts( graph_node: &GraphNodeInstance, - escrow_subgraph_deployment: &str, + escrow_subgraph_deployment: &DeploymentId, indexer_address: &Address, ) -> Result> { // These 2 structs are used to deserialize the response from the escrow subgraph. @@ -192,14 +193,15 @@ mod tests { #[tokio::test] async fn test_current_accounts() { let indexer_address = Address::from_str(test_vectors::INDEXER_ADDRESS).unwrap(); - let escrow_subgraph_deployment = "Qmabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGH"; + let escrow_subgraph_deployment = + DeploymentId::from_str("Qmabcdefghijklmnopqrstuvwxyz1234567890ABCDEFGH").unwrap(); let mock_server = MockServer::start().await; let graph_node = graph_node::GraphNodeInstance::new(&mock_server.uri()); let mock = Mock::given(method("POST")) .and(path( - "/subgraphs/id/".to_string() + escrow_subgraph_deployment, + "/subgraphs/id/".to_string() + &escrow_subgraph_deployment.to_string(), )) .respond_with( ResponseTemplate::new(200) @@ -209,7 +211,7 @@ mod tests { let inner = EscrowMonitorInner { graph_node, - escrow_subgraph_deployment: escrow_subgraph_deployment.to_string(), + escrow_subgraph_deployment, indexer_address, interval_ms: 1000, sender_accounts: Arc::new(RwLock::new(HashMap::new())), diff --git a/service/src/graph_node.rs b/service/src/graph_node.rs index fe2b3de4c..72036a6d5 100644 --- a/service/src/graph_node.rs +++ b/service/src/graph_node.rs @@ -1,10 +1,10 @@ // Copyright 2023-, GraphOps and Semiotic Labs. // SPDX-License-Identifier: Apache-2.0 -use std::sync::Arc; - use anyhow::anyhow; use reqwest::{header, Client, Url}; +use std::sync::Arc; +use toolshed::thegraph::DeploymentId; use crate::query_processor::{QueryError, UnattestedQueryResult}; @@ -34,17 +34,21 @@ impl GraphNodeInstance { pub async fn subgraph_query_raw( &self, - subgraph_id: &str, + subgraph_id: &DeploymentId, data: String, ) -> Result { let request = self .client - .post(self.subgraphs_base_url.join(subgraph_id).map_err(|e| { - QueryError::Other(anyhow!( - "Could not build subgraph query URL: {}", - e.to_string() - )) - })?) + .post( + self.subgraphs_base_url + .join(&subgraph_id.to_string()) + .map_err(|e| { + QueryError::Other(anyhow!( + "Could not build subgraph query URL: {}", + e.to_string() + )) + })?, + ) .body(data) .header(header::CONTENT_TYPE, "application/json"); diff --git a/service/src/main.rs b/service/src/main.rs index 5763a35e1..cdbcb980e 100644 --- a/service/src/main.rs +++ b/service/src/main.rs @@ -7,6 +7,7 @@ use axum::Server; use dotenvy::dotenv; use ethereum_types::U256; use std::{net::SocketAddr, str::FromStr}; +use toolshed::thegraph::DeploymentId; use tracing::info; use indexer_common::prelude::{AllocationMonitor, AttestationSigners, NetworkSubgraph}; @@ -99,7 +100,8 @@ async fn main() -> Result<(), std::io::Error> { let escrow_monitor = escrow_monitor::EscrowMonitor::new( graph_node.clone(), - config.escrow_subgraph.escrow_subgraph_deployment, + DeploymentId::from_str(&config.escrow_subgraph.escrow_subgraph_deployment) + .expect("escrow deployment ID is invalid"), config.ethereum.indexer_address, config.escrow_subgraph.escrow_syncing_interval, ) diff --git a/service/src/query_processor.rs b/service/src/query_processor.rs index ae0b683c5..6b555f889 100644 --- a/service/src/query_processor.rs +++ b/service/src/query_processor.rs @@ -5,8 +5,9 @@ use ethers_core::types::{Signature, U256}; use log::error; use serde::{Deserialize, Serialize}; use tap_core::tap_manager::SignedReceipt; +use toolshed::thegraph::DeploymentId; -use indexer_common::prelude::{AttestationSigner, AttestationSigners, SubgraphDeploymentID}; +use indexer_common::prelude::{AttestationSigner, AttestationSigners}; use crate::graph_node::GraphNodeInstance; use crate::tap_manager::TapManager; @@ -36,13 +37,13 @@ pub struct Response { /// Later add along with PaidQuery #[derive(Debug)] pub struct FreeQuery { - pub subgraph_deployment_id: SubgraphDeploymentID, + pub subgraph_deployment_id: DeploymentId, pub query: String, } /// Paid query needs subgraph_deployment_id, query, receipt pub struct PaidQuery { - pub subgraph_deployment_id: SubgraphDeploymentID, + pub subgraph_deployment_id: DeploymentId, pub query: String, pub receipt: String, } @@ -55,15 +56,11 @@ pub enum QueryError { IndexingError, #[error("Bad or invalid entity data found in the subgraph: {}", .0.to_string())] BadData(anyhow::Error), - #[error("Invalid GraphQL query string: {0}")] - InvalidFormat(String), - #[error("Cannot query field: {:#?}", .0)] - UnsupportedFields(Vec), #[error("Unknown error: {0}")] Other(anyhow::Error), } -#[derive(Debug, Clone)] +#[derive(Clone, Debug)] pub struct QueryProcessor { graph_node: GraphNodeInstance, attestation_signers: AttestationSigners, @@ -89,7 +86,7 @@ impl QueryProcessor { ) -> Result, QueryError> { let response = self .graph_node - .subgraph_query_raw(&query.subgraph_deployment_id.ipfs_hash(), query.query) + .subgraph_query_raw(&query.subgraph_deployment_id, query.query) .await?; Ok(Response { @@ -128,7 +125,7 @@ impl QueryProcessor { let response = self .graph_node - .subgraph_query_raw(&subgraph_deployment_id.ipfs_hash(), query.clone()) + .subgraph_query_raw(&subgraph_deployment_id, query.clone()) .await?; let attestation_signature = response @@ -165,82 +162,22 @@ mod tests { use alloy_primitives::Address; use hex_literal::hex; - use indexer_common::prelude::{ - attestation_signer_for_allocation, create_attestation_signer, Allocation, AllocationStatus, - SubgraphDeployment, - }; + use indexer_common::prelude::{Allocation, AllocationStatus, SubgraphDeployment}; use super::*; const INDEXER_OPERATOR_MNEMONIC: &str = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"; const INDEXER_ADDRESS: &str = "0x1234567890123456789012345678901234567890"; - - #[test] - fn hex_to_ipfs_multihash() { - let deployment_id = "0xd0b0e5b65df45a3fff1a653b4188881318e8459d3338f936aab16c4003884abf"; - let expected_ipfs_hash = "QmcPHxcC2ZN7m79XfYZ77YmF4t9UCErv87a9NFKrSLWKtJ"; - - assert_eq!( - SubgraphDeploymentID::from_hex(deployment_id) - .unwrap() - .ipfs_hash(), - expected_ipfs_hash - ); - } - - #[test] - fn ipfs_multihash_to_hex() { - let deployment_id = "0xd0b0e5b65df45a3fff1a653b4188881318e8459d3338f936aab16c4003884abf"; - let ipfs_hash = "QmcPHxcC2ZN7m79XfYZ77YmF4t9UCErv87a9NFKrSLWKtJ"; - - assert_eq!( - SubgraphDeploymentID::from_ipfs_hash(ipfs_hash) - .unwrap() - .to_string(), - deployment_id - ); - } - - #[test] - fn subgraph_deployment_id_input_validation_success() { - let deployment_id = "0xd0b0e5b65df45a3fff1a653b4188881318e8459d3338f936aab16c4003884abf"; - let ipfs_hash = "QmcPHxcC2ZN7m79XfYZ77YmF4t9UCErv87a9NFKrSLWKtJ"; - - assert_eq!( - SubgraphDeploymentID::new(ipfs_hash).unwrap().to_string(), - deployment_id - ); - - assert_eq!( - SubgraphDeploymentID::new(deployment_id) - .unwrap() - .ipfs_hash(), - ipfs_hash - ); - } - - #[test] - fn subgraph_deployment_id_input_validation_fail() { - let invalid_deployment_id = - "0xd0b0e5b65df45a3fff1a653b4188881318e8459d3338f936aab16c4003884a"; - let invalid_ipfs_hash = "Qm1234"; - - let res = SubgraphDeploymentID::new(invalid_deployment_id); - assert!(res.is_err()); - - let res = SubgraphDeploymentID::new(invalid_ipfs_hash); - assert!(res.is_err()); - } + const DEPLOYMENT_ID: DeploymentId = DeploymentId( + "0xc064c354bc21dd958b1d41b67b8ef161b75d2246b425f68ed4c74964ae705cbd" + .parse() + .unwrap(), + ); #[test] fn paid_query_attestation() { - let subgraph_deployment_id = SubgraphDeploymentID::new( - "0xc064c354bc21dd958b1d41b67b8ef161b75d2246b425f68ed4c74964ae705cbd", - ) - .unwrap(); - let subgraph_deployment = SubgraphDeployment { - id: subgraph_deployment_id.clone(), + id: DEPLOYMENT_ID, denied_at: None, staked_tokens: U256::from(0), signalled_tokens: U256::from(0), @@ -263,14 +200,11 @@ mod tests { query_fees_collected: None, }; - let allocation_key = - attestation_signer_for_allocation(INDEXER_OPERATOR_MNEMONIC, allocation).unwrap(); - - let attestation_signer = create_attestation_signer( + let attestation_signer = AttestationSigner::new( + INDEXER_OPERATOR_MNEMONIC, + allocation, U256::from(1), Address::from_str("0xdeadbeefcafebabedeadbeefcafebabedeadbeef").unwrap(), - allocation_key, - subgraph_deployment_id.bytes32(), ) .unwrap(); diff --git a/service/src/server/routes/subgraphs.rs b/service/src/server/routes/subgraphs.rs index b21eeac96..128ff9f9b 100644 --- a/service/src/server/routes/subgraphs.rs +++ b/service/src/server/routes/subgraphs.rs @@ -7,10 +7,10 @@ use axum::{ response::IntoResponse, Json, }; +use std::str::FromStr; +use toolshed::thegraph::DeploymentId; use tracing::trace; -use indexer_common::prelude::SubgraphDeploymentID; - use crate::{ metrics, query_processor::FreeQuery, @@ -31,11 +31,11 @@ pub async fn subgraph_queries( let (parts, body) = req.into_parts(); // Initialize id into a subgraph deployment ID - let subgraph_deployment_id = match SubgraphDeploymentID::new(id.as_str()) { + let subgraph_deployment_id = match DeploymentId::from_str(id.as_str()) { Ok(id) => id, Err(e) => return bad_request_response(&e.to_string()), }; - let deployment_label = subgraph_deployment_id.ipfs_hash(); + let deployment_label = subgraph_deployment_id.to_string(); let query_duration_timer = metrics::QUERY_DURATION .with_label_values(&[&deployment_label])