From 18bb7748e5f9fa2fca874d06379650d1e5255486 Mon Sep 17 00:00:00 2001 From: Theo Butler Date: Sat, 14 Oct 2023 11:00:47 -0400 Subject: [PATCH] refactor: use Attestation from toolshed --- Cargo.lock | 130 +++-------------------------- common/Cargo.toml | 7 +- common/src/attestations/signer.rs | 116 +++++-------------------- common/src/attestations/signers.rs | 12 +-- common/src/lib.rs | 4 +- service/src/query_processor.rs | 12 ++- 6 files changed, 47 insertions(+), 234 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 831c45095..3f638aa3f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -218,12 +218,6 @@ dependencies = [ "nodrop", ] -[[package]] -name = "arrayref" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" - [[package]] name = "arrayvec" version = "0.7.2" @@ -982,15 +976,6 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" -[[package]] -name = "clear_on_drop" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38508a63f4979f0048febc9966fadbd48e5dab31fd0ec6a3f151bbf4a74f7423" -dependencies = [ - "cc", -] - [[package]] name = "coins-bip32" version = "0.8.3" @@ -1002,7 +987,7 @@ dependencies = [ "coins-core", "digest 0.10.7", "getrandom 0.2.9", - "hmac 0.12.1", + "hmac", "k256", "lazy_static", "serde", @@ -1019,7 +1004,7 @@ dependencies = [ "bitvec 0.17.4", "coins-bip32", "getrandom 0.2.9", - "hmac 0.12.1", + "hmac", "once_cell", "pbkdf2 0.12.1", "rand 0.8.5", @@ -1267,16 +1252,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "crypto-mac" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" -dependencies = [ - "generic-array", - "subtle", -] - [[package]] name = "ctr" version = "0.9.2" @@ -1533,17 +1508,6 @@ dependencies = [ "spki", ] -[[package]] -name = "eip-712-derive" -version = "0.4.0" -source = "git+https://github.com/graphprotocol/eip-712-derive#0ce4f89c98d0b56d9d67c16b732425e7f2fd14b3" -dependencies = [ - "clear_on_drop", - "keccak-hash", - "lazy_static", - "libsecp256k1", -] - [[package]] name = "either" version = "1.8.1" @@ -1670,7 +1634,7 @@ dependencies = [ "ctr", "digest 0.10.7", "hex", - "hmac 0.12.1", + "hmac", "pbkdf2 0.11.0", "rand 0.8.5", "scrypt", @@ -2521,17 +2485,7 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" dependencies = [ - "hmac 0.12.1", -] - -[[package]] -name = "hmac" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" -dependencies = [ - "crypto-mac", - "digest 0.9.0", + "hmac", ] [[package]] @@ -2543,17 +2497,6 @@ dependencies = [ "digest 0.10.7", ] -[[package]] -name = "hmac-drbg" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1" -dependencies = [ - "digest 0.9.0", - "generic-array", - "hmac 0.8.1", -] - [[package]] name = "home" version = "0.5.5" @@ -2768,10 +2711,9 @@ name = "indexer-common" version = "0.1.0" dependencies = [ "alloy-primitives", + "alloy-sol-types", "anyhow", "arc-swap", - "bs58 0.5.0", - "eip-712-derive", "env_logger", "ethers", "ethers-core", @@ -3004,54 +2946,6 @@ version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" -[[package]] -name = "libsecp256k1" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95b09eff1b35ed3b33b877ced3a691fc7a481919c7e29c53c906226fcf55e2a1" -dependencies = [ - "arrayref", - "base64 0.13.1", - "digest 0.9.0", - "hmac-drbg", - "libsecp256k1-core", - "libsecp256k1-gen-ecmult", - "libsecp256k1-gen-genmult", - "rand 0.8.5", - "serde", - "sha2 0.9.9", - "typenum", -] - -[[package]] -name = "libsecp256k1-core" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be9b9bb642d8522a44d533eab56c16c738301965504753b03ad1de3425d5451" -dependencies = [ - "crunchy", - "digest 0.9.0", - "subtle", -] - -[[package]] -name = "libsecp256k1-gen-ecmult" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3038c808c55c87e8a172643a7d87187fc6c4174468159cb3090659d55bcb4809" -dependencies = [ - "libsecp256k1-core", -] - -[[package]] -name = "libsecp256k1-gen-genmult" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3db8d6ba2cec9eacc40e6e8ccc98931840301f1006e95647ceb2dd5c3aa06f7c" -dependencies = [ - "libsecp256k1-core", -] - [[package]] name = "libsqlite3-sys" version = "0.26.0" @@ -3633,7 +3527,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" dependencies = [ "digest 0.10.7", - "hmac 0.12.1", + "hmac", "password-hash", "sha2 0.10.7", ] @@ -3645,7 +3539,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0ca0b5a68607598bf3bad68f32227a8164f6254833f84eafaac409cd6746c31" dependencies = [ "digest 0.10.7", - "hmac 0.12.1", + "hmac", ] [[package]] @@ -4300,7 +4194,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ - "hmac 0.12.1", + "hmac", "subtle", ] @@ -4638,7 +4532,7 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f9e24d2b632954ded8ab2ef9fea0a0c769ea56ea98bddbafbad22caeeadf45d" dependencies = [ - "hmac 0.12.1", + "hmac", "pbkdf2 0.11.0", "salsa20", "sha2 0.10.7", @@ -5219,7 +5113,7 @@ dependencies = [ "generic-array", "hex", "hkdf", - "hmac 0.12.1", + "hmac", "itoa", "log", "md-5", @@ -5261,7 +5155,7 @@ dependencies = [ "futures-util", "hex", "hkdf", - "hmac 0.12.1", + "hmac", "home", "itoa", "log", @@ -6551,7 +6445,7 @@ dependencies = [ "crc32fast", "crossbeam-utils", "flate2", - "hmac 0.12.1", + "hmac", "pbkdf2 0.11.0", "sha1", "time", diff --git a/common/Cargo.toml b/common/Cargo.toml index aa0459706..e21b433e8 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -5,10 +5,9 @@ edition = "2021" [dependencies] alloy-primitives = { version = "0.3.3", features = ["serde"] } +alloy-sol-types = "0.3" anyhow = "1.0.75" arc-swap = "1.6.0" -bs58 = "0.5.0" -eip-712-derive = { git = "https://github.com/graphprotocol/eip-712-derive" } ethers = "2.0.10" ethers-core = "2.0.10" faux = { version = "0.1.10", optional = true } @@ -21,7 +20,9 @@ secp256k1 = { version = "0.27.0", features = ["recovery"] } serde = { version = "1.0.188", features = ["derive"] } serde_json = "1.0.107" tokio = { version = "1.32.0", features = ["full", "macros", "rt"] } -toolshed = { git = "https://github.com/edgeandnode/toolshed", branch = "main", features = ["graphql"] } +toolshed = { git = "https://github.com/edgeandnode/toolshed", branch = "main", features = [ + "graphql", +] } graphql = { git = "https://github.com/edgeandnode/toolshed", branch = "main" } [dev-dependencies] diff --git a/common/src/attestations/signer.rs b/common/src/attestations/signer.rs index 393da94e8..1b35e87a9 100644 --- a/common/src/attestations/signer.rs +++ b/common/src/attestations/signer.rs @@ -1,122 +1,44 @@ // Copyright 2023-, GraphOps and Semiotic Labs. // SPDX-License-Identifier: Apache-2.0 -use alloy_primitives::Address; -use eip_712_derive::{ - sign_typed, Bytes32, DomainSeparator, Eip712Domain, MemberVisitor, StructType, -}; -use ethers::utils::hex; +use alloy_primitives::{Address, U256}; +use alloy_sol_types::Eip712Domain; use ethers_core::k256::ecdsa::SigningKey; -use ethers_core::types::U256; -use keccak_hash::keccak; -use secp256k1::SecretKey; -use std::convert::TryInto; +use toolshed::thegraph::attestation::{self, Attestation}; 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: DeploymentId, - domain_separator: DomainSeparator, - signer: SecretKey, + domain: Eip712Domain, + signer: SigningKey, } impl AttestationSigner { pub fn new( - chain_id: eip_712_derive::U256, + chain_id: ethers_core::types::U256, dispute_manager: Address, - signer: SecretKey, + signer: SigningKey, deployment_id: DeploymentId, ) -> Self { - let bytes = hex::decode("a070ffb1cd7409649bf77822cce74495468e06dbfaef09556838bf188679b9c2") - .unwrap(); - - let salt: [u8; 32] = bytes.try_into().unwrap(); - - let domain = Eip712Domain { - name: "Graph Protocol".to_owned(), - version: "0".to_owned(), - chain_id, - verifying_contract: eip_712_derive::Address(dispute_manager.into()), - salt, - }; - let domain_separator = DomainSeparator::new(&domain); - + let mut chain_id_buf = [0_u8; 32]; + chain_id.to_big_endian(&mut chain_id_buf); + let chain_id = U256::from_be_bytes(chain_id_buf); Self { - domain_separator, - signer, subgraph_deployment_id: deployment_id, + domain: attestation::eip712_domain(chain_id, dispute_manager), + signer, } } pub fn create_attestation(&self, request: &str, response: &str) -> Attestation { - let request_cid = keccak(request).to_fixed_bytes(); - let response_cid = keccak(response).to_fixed_bytes(); - - let receipt = Receipt { - request_cid, - response_cid, - subgraph_deployment_id: *self.subgraph_deployment_id.0, - }; - - // Unwrap: This can only fail if the SecretKey is invalid. - // Since it is of type SecretKey it has already been validated. - let (rs, v) = sign_typed(&self.domain_separator, &receipt, self.signer.as_ref()).unwrap(); - - let r = rs[0..32].try_into().unwrap(); - let s = rs[32..64].try_into().unwrap(); - - Attestation { - v, - r, - s, - subgraph_deployment_id: *self.subgraph_deployment_id.0, - request_cid, - response_cid, - } + attestation::create( + &self.domain, + &self.signer, + &self.subgraph_deployment_id, + request, + response, + ) } } - -pub struct Receipt { - request_cid: Bytes32, - response_cid: Bytes32, - subgraph_deployment_id: Bytes32, -} - -impl StructType for Receipt { - const TYPE_NAME: &'static str = "Receipt"; - fn visit_members(&self, visitor: &mut T) { - visitor.visit("requestCID", &self.request_cid); - visitor.visit("responseCID", &self.response_cid); - visitor.visit("subgraphDeploymentID", &self.subgraph_deployment_id); - } -} - -#[derive(Debug)] -pub struct Attestation { - pub request_cid: Bytes32, - pub response_cid: Bytes32, - pub subgraph_deployment_id: Bytes32, - pub v: u8, - pub r: Bytes32, - pub s: Bytes32, -} - -/// Helper for creating an AttestationSigner -pub fn create_attestation_signer( - chain_id: U256, - dispute_manager_address: Address, - signer: SigningKey, - deployment_id: DeploymentId, -) -> anyhow::Result { - // Tedious conversions to the "indexer_native" types - let mut chain_id_bytes = [0u8; 32]; - chain_id.to_big_endian(&mut chain_id_bytes); - let signer = AttestationSigner::new( - eip_712_derive::U256(chain_id_bytes), - dispute_manager_address, - secp256k1::SecretKey::from_slice(&signer.to_bytes())?, - deployment_id, - ); - Ok(signer) -} diff --git a/common/src/attestations/signers.rs b/common/src/attestations/signers.rs index 62c1a336d..dbbb346bf 100644 --- a/common/src/attestations/signers.rs +++ b/common/src/attestations/signers.rs @@ -10,7 +10,7 @@ use tokio::sync::RwLock; use crate::prelude::{AllocationMonitor, AttestationSigner}; -use super::{attestation_signer_for_allocation, signer::create_attestation_signer}; +use super::attestation_signer_for_allocation; #[derive(Debug, Clone)] pub struct AttestationSigners { @@ -64,15 +64,16 @@ impl AttestationSigners { if let std::collections::hash_map::Entry::Vacant(e) = attestation_signers_write.entry(allocation.id) { - match attestation_signer_for_allocation(&inner.indexer_mnemonic, allocation) - .and_then(|signer| { - create_attestation_signer( + match attestation_signer_for_allocation(&inner.indexer_mnemonic, allocation).map( + |signer| { + AttestationSigner::new( inner.chain_id, inner.dispute_manager, signer, allocation.subgraph_deployment.id, ) - }) { + }, + ) { Ok(signer) => { e.insert(signer); info!( @@ -119,7 +120,6 @@ impl AttestationSigners { #[cfg(test)] mod tests { use alloy_primitives::Address; - use ethers_core::types::U256; use std::str::FromStr; use std::sync::Arc; diff --git a/common/src/lib.rs b/common/src/lib.rs index b20ddcaad..89048d63d 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -14,9 +14,7 @@ pub mod prelude { pub use super::allocations::monitor::AllocationMonitor; pub use super::allocations::{Allocation, AllocationStatus, SubgraphDeployment}; pub use super::attestations::{ - attestation_signer_for_allocation, - signer::{create_attestation_signer, AttestationSigner}, - signers::AttestationSigners, + attestation_signer_for_allocation, signer::AttestationSigner, signers::AttestationSigners, }; pub use super::network_subgraph::NetworkSubgraph; } diff --git a/service/src/query_processor.rs b/service/src/query_processor.rs index 17a1120f2..f132a438a 100644 --- a/service/src/query_processor.rs +++ b/service/src/query_processor.rs @@ -148,8 +148,8 @@ impl QueryProcessor { ) -> Signature { let attestation = signer.create_attestation(&query, &response.graphql_response); Signature { - r: U256::from_big_endian(&attestation.r), - s: U256::from_big_endian(&attestation.s), + r: U256::from_big_endian(attestation.r.as_slice()), + s: U256::from_big_endian(attestation.s.as_slice()), v: attestation.v as u64, } } @@ -163,8 +163,7 @@ mod tests { use hex_literal::hex; use indexer_common::prelude::{ - attestation_signer_for_allocation, create_attestation_signer, Allocation, AllocationStatus, - SubgraphDeployment, + attestation_signer_for_allocation, Allocation, AllocationStatus, SubgraphDeployment, }; use lazy_static::lazy_static; @@ -209,13 +208,12 @@ mod tests { let allocation_key = attestation_signer_for_allocation(INDEXER_OPERATOR_MNEMONIC, allocation).unwrap(); - let attestation_signer = create_attestation_signer( + let attestation_signer = AttestationSigner::new( U256::from(1), Address::from_str("0xdeadbeefcafebabedeadbeefcafebabedeadbeef").unwrap(), allocation_key, *DEPLOYMENT_ID, - ) - .unwrap(); + ); let attestation = QueryProcessor::create_attestation( &attestation_signer,