From d36fde197e7e5dd9c55d3707c00f897ffc3bc180 Mon Sep 17 00:00:00 2001 From: Zoran Cvetkov Date: Mon, 7 Apr 2025 18:38:45 +0300 Subject: [PATCH 1/5] test: check grafting from pre 0.0.6 to 0.0.6 and later --- tests/docker-compose.yml | 2 +- .../grafted/abis/Contract.abi | 33 +++++ tests/integration-tests/grafted/package.json | 25 ++++ .../integration-tests/grafted/schema.graphql | 5 + .../integration-tests/grafted/src/mapping.ts | 9 ++ tests/integration-tests/grafted/subgraph.yaml | 25 ++++ .../grafting/abis/Contract.abi | 33 +++++ tests/integration-tests/grafting/package.json | 25 ++++ .../integration-tests/grafting/schema.graphql | 5 + .../integration-tests/grafting/src/mapping.ts | 9 ++ .../integration-tests/grafting/subgraph.yaml | 30 ++++ tests/src/contract.rs | 11 +- tests/src/subgraph.rs | 2 +- tests/tests/integration_tests.rs | 138 ++++++++++++++++-- 14 files changed, 334 insertions(+), 18 deletions(-) create mode 100644 tests/integration-tests/grafted/abis/Contract.abi create mode 100644 tests/integration-tests/grafted/package.json create mode 100644 tests/integration-tests/grafted/schema.graphql create mode 100644 tests/integration-tests/grafted/src/mapping.ts create mode 100644 tests/integration-tests/grafted/subgraph.yaml create mode 100644 tests/integration-tests/grafting/abis/Contract.abi create mode 100644 tests/integration-tests/grafting/package.json create mode 100644 tests/integration-tests/grafting/schema.graphql create mode 100644 tests/integration-tests/grafting/src/mapping.ts create mode 100644 tests/integration-tests/grafting/subgraph.yaml diff --git a/tests/docker-compose.yml b/tests/docker-compose.yml index f45360fd367..252a76e373c 100644 --- a/tests/docker-compose.yml +++ b/tests/docker-compose.yml @@ -23,7 +23,7 @@ services: image: ghcr.io/foundry-rs/foundry:stable ports: - '3021:8545' - command: "'anvil --host 0.0.0.0 --gas-limit 100000000000 --base-fee 1 --block-time 5 --mnemonic \"test test test test test test test test test test test junk\"'" + command: "'anvil --host 0.0.0.0 --gas-limit 100000000000 --base-fee 1 --block-time 5 --timestamp 1743944919 --mnemonic \"test test test test test test test test test test test junk\"'" # graph-node ports: # json-rpc: 8020 diff --git a/tests/integration-tests/grafted/abis/Contract.abi b/tests/integration-tests/grafted/abis/Contract.abi new file mode 100644 index 00000000000..02da1a9e7f3 --- /dev/null +++ b/tests/integration-tests/grafted/abis/Contract.abi @@ -0,0 +1,33 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "x", + "type": "uint16" + } + ], + "name": "Trigger", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "x", + "type": "uint16" + } + ], + "name": "emitTrigger", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/tests/integration-tests/grafted/package.json b/tests/integration-tests/grafted/package.json new file mode 100644 index 00000000000..d45b6fc6727 --- /dev/null +++ b/tests/integration-tests/grafted/package.json @@ -0,0 +1,25 @@ +{ + "name": "grafted-subgraph", + "version": "0.1.0", + "scripts": { + "build-contracts": "../../common/build-contracts.sh", + "codegen": "graph codegen --skip-migrations", + "test": "yarn build-contracts && truffle test --compile-none --network test", + "create:test": "graph create test/grafted-subgraph --node $GRAPH_NODE_ADMIN_URI", + "deploy:test": "graph deploy test/grafted-subgraph --version-label v0.0.1 --ipfs $IPFS_URI --node $GRAPH_NODE_ADMIN_URI" + }, + "devDependencies": { + "@graphprotocol/graph-cli": "0.69.0", + "@graphprotocol/graph-ts": "0.34.0", + "solc": "^0.8.2" + }, + "dependencies": { + "@truffle/contract": "^4.3", + "@truffle/hdwallet-provider": "^1.2", + "apollo-fetch": "^0.7.0", + "babel-polyfill": "^6.26.0", + "babel-register": "^6.26.0", + "gluegun": "^4.6.1", + "truffle": "^5.2" + } +} \ No newline at end of file diff --git a/tests/integration-tests/grafted/schema.graphql b/tests/integration-tests/grafted/schema.graphql new file mode 100644 index 00000000000..b83083fd466 --- /dev/null +++ b/tests/integration-tests/grafted/schema.graphql @@ -0,0 +1,5 @@ +type GraftedData @entity(immutable: true) { + id: ID! + data: String! + blockNumber: BigInt! +} \ No newline at end of file diff --git a/tests/integration-tests/grafted/src/mapping.ts b/tests/integration-tests/grafted/src/mapping.ts new file mode 100644 index 00000000000..8b140ac9864 --- /dev/null +++ b/tests/integration-tests/grafted/src/mapping.ts @@ -0,0 +1,9 @@ +import { ethereum } from '@graphprotocol/graph-ts' +import { GraftedData } from '../generated/schema' + +export function handleBlock(block: ethereum.Block): void { + let entity = new GraftedData(block.number.toString()) + entity.data = 'from grafted' + entity.blockNumber = block.number + entity.save() +} \ No newline at end of file diff --git a/tests/integration-tests/grafted/subgraph.yaml b/tests/integration-tests/grafted/subgraph.yaml new file mode 100644 index 00000000000..180a8cea181 --- /dev/null +++ b/tests/integration-tests/grafted/subgraph.yaml @@ -0,0 +1,25 @@ +specVersion: 0.0.5 +description: Grafted Subgraph +repository: https://github.com/graphprotocol/graph-node +schema: + file: ./schema.graphql +dataSources: + - kind: ethereum/contract + name: SimpleContract + network: test + source: + address: "0x5FbDB2315678afecb367f032d93F642f64180aa3" + abi: SimpleContract + startBlock: 0 + mapping: + kind: ethereum/events + apiVersion: 0.0.6 + language: wasm/assemblyscript + entities: + - GraftedData + abis: + - name: SimpleContract + file: ./abis/Contract.abi + blockHandlers: + - handler: handleBlock + file: ./src/mapping.ts \ No newline at end of file diff --git a/tests/integration-tests/grafting/abis/Contract.abi b/tests/integration-tests/grafting/abis/Contract.abi new file mode 100644 index 00000000000..02da1a9e7f3 --- /dev/null +++ b/tests/integration-tests/grafting/abis/Contract.abi @@ -0,0 +1,33 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint16", + "name": "x", + "type": "uint16" + } + ], + "name": "Trigger", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "x", + "type": "uint16" + } + ], + "name": "emitTrigger", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/tests/integration-tests/grafting/package.json b/tests/integration-tests/grafting/package.json new file mode 100644 index 00000000000..4aca162ca96 --- /dev/null +++ b/tests/integration-tests/grafting/package.json @@ -0,0 +1,25 @@ +{ + "name": "grafting-subgraph", + "version": "0.1.0", + "scripts": { + "build-contracts": "../../common/build-contracts.sh", + "codegen": "graph codegen --skip-migrations", + "test": "yarn build-contracts && truffle test --compile-none --network test", + "create:test": "graph create test/grafting-subgraph --node $GRAPH_NODE_ADMIN_URI", + "deploy:test": "graph deploy test/grafting-subgraph --version-label v0.0.1 --ipfs $IPFS_URI --node $GRAPH_NODE_ADMIN_URI" + }, + "devDependencies": { + "@graphprotocol/graph-cli": "0.69.0", + "@graphprotocol/graph-ts": "0.34.0", + "solc": "^0.8.2" + }, + "dependencies": { + "@truffle/contract": "^4.3", + "@truffle/hdwallet-provider": "^1.2", + "apollo-fetch": "^0.7.0", + "babel-polyfill": "^6.26.0", + "babel-register": "^6.26.0", + "gluegun": "^4.6.1", + "truffle": "^5.2" + } +} \ No newline at end of file diff --git a/tests/integration-tests/grafting/schema.graphql b/tests/integration-tests/grafting/schema.graphql new file mode 100644 index 00000000000..58111f9548a --- /dev/null +++ b/tests/integration-tests/grafting/schema.graphql @@ -0,0 +1,5 @@ +type GraftingData @entity(immutable: true) { + id: ID! + data: String! + blockNumber: BigInt! +} \ No newline at end of file diff --git a/tests/integration-tests/grafting/src/mapping.ts b/tests/integration-tests/grafting/src/mapping.ts new file mode 100644 index 00000000000..db224e64533 --- /dev/null +++ b/tests/integration-tests/grafting/src/mapping.ts @@ -0,0 +1,9 @@ +import { ethereum } from '@graphprotocol/graph-ts' +import { GraftingData } from '../generated/schema' + +export function handleBlock(block: ethereum.Block): void { + let entity = new GraftingData(block.number.toString()) + entity.data = 'to grafting' + entity.blockNumber = block.number + entity.save() +} \ No newline at end of file diff --git a/tests/integration-tests/grafting/subgraph.yaml b/tests/integration-tests/grafting/subgraph.yaml new file mode 100644 index 00000000000..7c1227608db --- /dev/null +++ b/tests/integration-tests/grafting/subgraph.yaml @@ -0,0 +1,30 @@ +specVersion: 0.0.6 +description: Grafting Subgraph +repository: https://github.com/graphprotocol/graph-node +schema: + file: ./schema.graphql +dataSources: + - kind: ethereum/contract + name: SimpleContract + network: test + source: + address: "0x5FbDB2315678afecb367f032d93F642f64180aa3" + abi: SimpleContract + startBlock: 0 + mapping: + kind: ethereum/events + apiVersion: 0.0.6 + language: wasm/assemblyscript + entities: + - GraftedData + abis: + - name: SimpleContract + file: ./abis/Contract.abi + blockHandlers: + - handler: handleBlock + file: ./src/mapping.ts +features: + - grafting +graft: + base: QmTiueTVFgeUedMsx8trJDYYwCfFxrHmzkgRnKbvBkujq9 + block: 2 \ No newline at end of file diff --git a/tests/src/contract.rs b/tests/src/contract.rs index 4fdf767b041..05fda947839 100644 --- a/tests/src/contract.rs +++ b/tests/src/contract.rs @@ -7,7 +7,7 @@ use graph::prelude::{ api::{Eth, Namespace}, contract::{tokens::Tokenize, Contract as Web3Contract, Options}, transports::Http, - types::{Address, Bytes, TransactionReceipt}, + types::{Address, Block, BlockId, BlockNumber, Bytes, TransactionReceipt, H256}, }, }; // web3 version 0.18 does not expose this; once the graph crate updates to @@ -165,4 +165,13 @@ impl Contract { } Ok(contracts) } + + pub async fn latest_block() -> Option> { + let eth = Self::eth(); + let block = eth + .block(BlockId::Number(BlockNumber::Latest)) + .await + .unwrap_or_default(); + block + } } diff --git a/tests/src/subgraph.rs b/tests/src/subgraph.rs index 810b87cbb78..92e42836b68 100644 --- a/tests/src/subgraph.rs +++ b/tests/src/subgraph.rs @@ -164,7 +164,7 @@ impl Subgraph { } /// Make a GraphQL query to the index node API - pub async fn index_with_vars(&self, text: &str, vars: Value) -> anyhow::Result { + pub async fn query_with_vars(text: &str, vars: Value) -> anyhow::Result { let endpoint = CONFIG.graph_node.index_node_uri(); graphql_query_with_vars(&endpoint, text, vars).await } diff --git a/tests/tests/integration_tests.rs b/tests/tests/integration_tests.rs index 5c6ab96968d..83fdeeef62b 100644 --- a/tests/tests/integration_tests.rs +++ b/tests/tests/integration_tests.rs @@ -11,7 +11,8 @@ use std::future::Future; use std::pin::Pin; -use std::time::{Duration, Instant}; +use std::thread; +use std::time::{self, Duration, Instant}; use anyhow::{anyhow, bail, Context, Result}; use graph::futures03::StreamExt; @@ -25,6 +26,8 @@ use tokio::process::{Child, Command}; use tokio::task::JoinError; use tokio::time::sleep; +const SUBGRAPH_LAST_GRAFTING_BLOCK: i32 = 3; + type TestFn = Box< dyn FnOnce(TestContext) -> Pin> + Send>> + Sync @@ -110,6 +113,15 @@ impl TestCase { } } + fn new_with_grafting(name: &str, test: fn(TestContext) -> T, grafted_subgraph: &str) -> Self + where + T: Future> + Send + 'static, + { + let mut test_case = Self::new(name, test); + test_case.source_subgraph = Some(grafted_subgraph.to_string()); + test_case + } + fn new_with_source_subgraph( name: &str, test: fn(TestContext) -> T, @@ -246,7 +258,7 @@ impl TestCase { let subgraph = self.deploy_and_wait(source, contracts).await?; status!( source, - "source subgraph deployed with hash {}", + "Source subgraph deployed with hash {}", subgraph.deployment ); } @@ -456,9 +468,8 @@ async fn test_block_handlers(ctx: TestContext) -> anyhow::Result<()> { .await?; // test subgraphFeatures endpoint returns handlers correctly - let subgraph_features = subgraph - .index_with_vars( - "query GetSubgraphFeatures($deployment: String!) { + let subgraph_features = Subgraph::query_with_vars( + "query GetSubgraphFeatures($deployment: String!) { subgraphFeatures(subgraphId: $deployment) { specVersion apiVersion @@ -468,9 +479,9 @@ async fn test_block_handlers(ctx: TestContext) -> anyhow::Result<()> { handlers } }", - json!({ "deployment": subgraph.deployment }), - ) - .await?; + json!({ "deployment": subgraph.deployment }), + ) + .await?; let handlers = &subgraph_features["data"]["subgraphFeatures"]["handlers"]; assert!( handlers.is_array(), @@ -697,9 +708,8 @@ async fn test_non_fatal_errors(ctx: TestContext) -> anyhow::Result<()> { } }"; - let resp = subgraph - .index_with_vars(query, json!({ "deployment" : subgraph.deployment })) - .await?; + let resp = + Subgraph::query_with_vars(query, json!({ "deployment" : subgraph.deployment })).await?; let subgraph_features = &resp["data"]["subgraphFeatures"]; let exp = json!({ "specVersion": "0.0.4", @@ -796,6 +806,79 @@ async fn test_remove_then_update(ctx: TestContext) -> anyhow::Result<()> { Ok(()) } +async fn test_subgraph_grafting(ctx: TestContext) -> anyhow::Result<()> { + async fn get_bloock_hash(block_number: i32) -> Option { + const FETCH_BLOCK_HASH: &str = r#" + query blockHashFromNumber($network: String!, $blockNumber: Int!) { + hash: blockHashFromNumber( + network: $network, + blockNumber: $blockNumber, + ) } "#; + let vars = json!({ + "network": "test", + "blockNumber": block_number + }); + + let resp = Subgraph::query_with_vars(FETCH_BLOCK_HASH, vars) + .await + .unwrap(); + assert_eq!(None, resp.get("errors")); + resp["data"]["hash"].as_str().map(|s| s.to_owned()) + } + + let subgraph = ctx.subgraph; + + assert!(subgraph.healthy); + + let block_hashes: Vec<&str> = vec![ + "fc66417a289a112cf2078d6506bce89046a21f121b367906caec3500f4f43285", + "b6a1582c94b5cfab23d203dfbae7eda7f5dc53fb5cdf40b377c0816f10ff8860", + "655f22340c650eb2089ee09773789f3f00bf7e359516d09736b58bb951e4f92c", + ]; + + let pois: Vec<&str> = vec![ + "0x34b294b9663a79c454f7acf1f806972278893ffe0deea5c16da35ae1c6e13de9", + "0x77659812fc4f75102a9d712cf2f36050cd9263c83a753daf7ab5ddcbe6a26272", + "0x67a66fdb886ad476703b37fec1d0bffaf9bd6d20f41287aee18afa5910f9b400", + ]; + + for i in 1..4 { + let block_hash = get_bloock_hash(i).await.unwrap(); + // We need to make sure that the preconditions for POI are fulfiled + // namely that the anvil produces the proper block hashes for the + // blocks of which we will check the POI + assert_eq!(block_hash, block_hashes[(i - 1) as usize]); + + const FETCH_POI: &str = r#" + query proofOfIndexing($subgraph: String!, $blockNumber: Int!, $blockHash: String!) { + proofOfIndexing( + subgraph: $subgraph, + blockNumber: $blockNumber, + blockHash: $blockHash + ) } "#; + + let vars = json!({ + "subgraph": subgraph.deployment, + "blockNumber": i, + "blockHash": block_hash, + }); + let resp = Subgraph::query_with_vars(FETCH_POI, vars).await?; + assert_eq!(None, resp.get("errors")); + assert!(resp["data"]["proofOfIndexing"].is_string()); + let poi = resp["data"]["proofOfIndexing"].as_str().unwrap(); + // Check the expected value of the POI. The transition from the old legacy + // hashing to the new one is done in the block #2 anything before that + // should not change as the legacy code will not be updated. Any change + // after that might indicate a change in the way new POI is now calculated. + // Change on the block #2 would mean a change in the transitioning + // from the old to the new algorithm hence would be reflected only + // subgraphs that are grafting from pre 0.0.5 to 0.0.6 or newer. + assert_eq!(poi, pois[(i - 1) as usize]); + } + + Ok(()) +} + async fn test_poi_for_failed_subgraph(ctx: TestContext) -> anyhow::Result<()> { let subgraph = ctx.subgraph; const INDEXING_STATUS: &str = r#" @@ -829,9 +912,9 @@ async fn test_poi_for_failed_subgraph(ctx: TestContext) -> anyhow::Result<()> { } async fn fetch_status(subgraph: &Subgraph) -> anyhow::Result { - let resp = subgraph - .index_with_vars(INDEXING_STATUS, json!({ "subgraphName": subgraph.name })) - .await?; + let resp = + Subgraph::query_with_vars(INDEXING_STATUS, json!({ "subgraphName": subgraph.name })) + .await?; assert_eq!(None, resp.get("errors")); let statuses = &resp["data"]["statuses"]; assert_eq!(1, statuses.as_array().unwrap().len()); @@ -877,7 +960,7 @@ async fn test_poi_for_failed_subgraph(ctx: TestContext) -> anyhow::Result<()> { "blockNumber": block_number, "blockHash": status.latest_block["hash"], }); - let resp = subgraph.index_with_vars(FETCH_POI, vars).await?; + let resp = Subgraph::query_with_vars(FETCH_POI, vars).await?; assert_eq!(None, resp.get("errors")); assert!(resp["data"]["proofOfIndexing"].is_string()); Ok(()) @@ -915,6 +998,25 @@ async fn test_multiple_subgraph_datasources(ctx: TestContext) -> anyhow::Result< Ok(()) } +async fn wait_for_blockchain_block(block_number: i32) -> bool { + // Wait up to 5 minutes for the expected block to appear + const STATUS_WAIT: Duration = Duration::from_secs(300); + let start = Instant::now(); + while start.elapsed() < STATUS_WAIT { + let latest_block = Contract::latest_block().await; + if let Some(latest_block) = latest_block { + if let Some(number) = latest_block.number { + if number >= block_number.into() { + return true; + } + } + } + let one_sec = time::Duration::from_secs(1); + thread::sleep(one_sec); + } + false +} + /// The main test entrypoint. #[tokio::test] async fn integration_tests() -> anyhow::Result<()> { @@ -936,6 +1038,7 @@ async fn integration_tests() -> anyhow::Result<()> { TestCase::new("timestamp", test_timestamp), TestCase::new("ethereum-api-tests", test_eth_api), TestCase::new("topic-filter", test_topic_filters), + TestCase::new_with_grafting("grafting", test_subgraph_grafting, "grafted"), TestCase::new_with_source_subgraph( "subgraph-data-sources", subgraph_data_sources, @@ -958,6 +1061,11 @@ async fn integration_tests() -> anyhow::Result<()> { cases }; + // Here we wait got a block in anvil environment in order not to mess up + // block hashes for all the blocks until the end of the grafting tests. + // Currently the block 3. + assert!(wait_for_blockchain_block(SUBGRAPH_LAST_GRAFTING_BLOCK).await); + let contracts = Contract::deploy_all().await?; status!("setup", "Resetting database"); From 85d6b7b0825a651f12c16a57403db292911e6e61 Mon Sep 17 00:00:00 2001 From: Zoran Cvetkov Date: Mon, 7 Apr 2025 18:52:21 +0300 Subject: [PATCH 2/5] fix CI --- .github/workflows/ci.yml | 2 +- tests/docker-compose.yml | 2 +- tests/tests/integration_tests.rs | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0fa6d58bbb7..24993639945 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -153,7 +153,7 @@ jobs: - name: Install Foundry uses: foundry-rs/foundry-toolchain@v1 - name: Start anvil - run: anvil --gas-limit 100000000000 --base-fee 1 --block-time 2 --port 3021 & + run: anvil --gas-limit 100000000000 --base-fee 1 --block-time 2 --timestamp 1743944919 --port 3021 & - name: Install graph CLI run: curl -sSL http://cli.thegraph.com/install.sh | sudo bash diff --git a/tests/docker-compose.yml b/tests/docker-compose.yml index 252a76e373c..7385b4b08a2 100644 --- a/tests/docker-compose.yml +++ b/tests/docker-compose.yml @@ -23,7 +23,7 @@ services: image: ghcr.io/foundry-rs/foundry:stable ports: - '3021:8545' - command: "'anvil --host 0.0.0.0 --gas-limit 100000000000 --base-fee 1 --block-time 5 --timestamp 1743944919 --mnemonic \"test test test test test test test test test test test junk\"'" + command: "'anvil --host 0.0.0.0 --gas-limit 100000000000 --base-fee 1 --block-time 2 --timestamp 1743944919 --mnemonic \"test test test test test test test test test test test junk\"'" # graph-node ports: # json-rpc: 8020 diff --git a/tests/tests/integration_tests.rs b/tests/tests/integration_tests.rs index 83fdeeef62b..95ef045aeda 100644 --- a/tests/tests/integration_tests.rs +++ b/tests/tests/integration_tests.rs @@ -831,15 +831,15 @@ async fn test_subgraph_grafting(ctx: TestContext) -> anyhow::Result<()> { assert!(subgraph.healthy); let block_hashes: Vec<&str> = vec![ - "fc66417a289a112cf2078d6506bce89046a21f121b367906caec3500f4f43285", - "b6a1582c94b5cfab23d203dfbae7eda7f5dc53fb5cdf40b377c0816f10ff8860", - "655f22340c650eb2089ee09773789f3f00bf7e359516d09736b58bb951e4f92c", + "384c705d4d1933ae8ba89026f016f09854057a267e1143e47bb7511d772a35d4", + "b90423eead33404dae0684169d35edd494b36802b721fb8de0bb8bc036c10480", + "2a6c4b65d659e0485371a93bc1ac0f0d7bc0f25a454b5f23a842335fea0638d5", ]; let pois: Vec<&str> = vec![ - "0x34b294b9663a79c454f7acf1f806972278893ffe0deea5c16da35ae1c6e13de9", - "0x77659812fc4f75102a9d712cf2f36050cd9263c83a753daf7ab5ddcbe6a26272", - "0x67a66fdb886ad476703b37fec1d0bffaf9bd6d20f41287aee18afa5910f9b400", + "0x4f3e32c290fd6aa3613a0bbd0cc4367ae082036086cf75f292f8eaf798648a27", + "0x6053124bc1042dfc9c153b49c626f11860a1bc34d0fde384526a2dbed909d242", + "0xca535e3a5be9b93012f6173b33cf9c053cac8028dda9c398b619b67f53a9e1a4", ]; for i in 1..4 { From 0c5b0e873ae3fe517b3a8bed7bc24f788f40fb9e Mon Sep 17 00:00:00 2001 From: Zoran Cvetkov Date: Thu, 10 Apr 2025 01:10:22 +0300 Subject: [PATCH 3/5] fix local runs --- tests/tests/integration_tests.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/tests/integration_tests.rs b/tests/tests/integration_tests.rs index 95ef045aeda..aaf587d6d64 100644 --- a/tests/tests/integration_tests.rs +++ b/tests/tests/integration_tests.rs @@ -850,17 +850,20 @@ async fn test_subgraph_grafting(ctx: TestContext) -> anyhow::Result<()> { assert_eq!(block_hash, block_hashes[(i - 1) as usize]); const FETCH_POI: &str = r#" - query proofOfIndexing($subgraph: String!, $blockNumber: Int!, $blockHash: String!) { + query proofOfIndexing($subgraph: String!, $blockNumber: Int!, $blockHash: String!, $indexer: String!) { proofOfIndexing( subgraph: $subgraph, blockNumber: $blockNumber, - blockHash: $blockHash + blockHash: $blockHash, + indexer: $indexer ) } "#; + let zero_addr = "0000000000000000000000000000000000000000"; let vars = json!({ "subgraph": subgraph.deployment, "blockNumber": i, "blockHash": block_hash, + "indexer": zero_addr, }); let resp = Subgraph::query_with_vars(FETCH_POI, vars).await?; assert_eq!(None, resp.get("errors")); From 6d80ecb1a2051ac653446c885fece4ba44785529 Mon Sep 17 00:00:00 2001 From: Zoran Cvetkov Date: Mon, 14 Apr 2025 13:18:39 +0300 Subject: [PATCH 4/5] address review comments --- tests/tests/integration_tests.rs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/tests/tests/integration_tests.rs b/tests/tests/integration_tests.rs index aaf587d6d64..108708f8254 100644 --- a/tests/tests/integration_tests.rs +++ b/tests/tests/integration_tests.rs @@ -11,7 +11,6 @@ use std::future::Future; use std::pin::Pin; -use std::thread; use std::time::{self, Duration, Instant}; use anyhow::{anyhow, bail, Context, Result}; @@ -807,7 +806,7 @@ async fn test_remove_then_update(ctx: TestContext) -> anyhow::Result<()> { } async fn test_subgraph_grafting(ctx: TestContext) -> anyhow::Result<()> { - async fn get_bloock_hash(block_number: i32) -> Option { + async fn get_block_hash(block_number: i32) -> Option { const FETCH_BLOCK_HASH: &str = r#" query blockHashFromNumber($network: String!, $blockNumber: Int!) { hash: blockHashFromNumber( @@ -843,10 +842,10 @@ async fn test_subgraph_grafting(ctx: TestContext) -> anyhow::Result<()> { ]; for i in 1..4 { - let block_hash = get_bloock_hash(i).await.unwrap(); + let block_hash = get_block_hash(i).await.unwrap(); // We need to make sure that the preconditions for POI are fulfiled - // namely that the anvil produces the proper block hashes for the - // blocks of which we will check the POI + // namely that the blockchain produced the proper block hashes for the + // blocks of which we will check the POI. assert_eq!(block_hash, block_hashes[(i - 1) as usize]); const FETCH_POI: &str = r#" @@ -1004,6 +1003,7 @@ async fn test_multiple_subgraph_datasources(ctx: TestContext) -> anyhow::Result< async fn wait_for_blockchain_block(block_number: i32) -> bool { // Wait up to 5 minutes for the expected block to appear const STATUS_WAIT: Duration = Duration::from_secs(300); + const REQUEST_REPEATING: Duration = time::Duration::from_secs(1); let start = Instant::now(); while start.elapsed() < STATUS_WAIT { let latest_block = Contract::latest_block().await; @@ -1014,8 +1014,7 @@ async fn wait_for_blockchain_block(block_number: i32) -> bool { } } } - let one_sec = time::Duration::from_secs(1); - thread::sleep(one_sec); + tokio::time::sleep(REQUEST_REPEATING).await; } false } From 6f7edc0223c5cd2112802a964ffb9e0ebe1e286d Mon Sep 17 00:00:00 2001 From: Zoran Cvetkov Date: Mon, 14 Apr 2025 15:35:59 +0300 Subject: [PATCH 5/5] renames --- .../{grafting => base}/abis/Contract.abi | 0 .../{grafting => base}/package.json | 6 +++--- .../{grafting => base}/schema.graphql | 2 +- .../{grafting => base}/src/mapping.ts | 6 +++--- .../{grafting => base}/subgraph.yaml | 13 ++++--------- tests/integration-tests/grafted/src/mapping.ts | 2 +- tests/integration-tests/grafted/subgraph.yaml | 9 +++++++-- tests/tests/integration_tests.rs | 16 ++++++++-------- 8 files changed, 27 insertions(+), 27 deletions(-) rename tests/integration-tests/{grafting => base}/abis/Contract.abi (100%) rename tests/integration-tests/{grafting => base}/package.json (71%) rename tests/integration-tests/{grafting => base}/schema.graphql (53%) rename tests/integration-tests/{grafting => base}/src/mapping.ts (54%) rename tests/integration-tests/{grafting => base}/subgraph.yaml (73%) diff --git a/tests/integration-tests/grafting/abis/Contract.abi b/tests/integration-tests/base/abis/Contract.abi similarity index 100% rename from tests/integration-tests/grafting/abis/Contract.abi rename to tests/integration-tests/base/abis/Contract.abi diff --git a/tests/integration-tests/grafting/package.json b/tests/integration-tests/base/package.json similarity index 71% rename from tests/integration-tests/grafting/package.json rename to tests/integration-tests/base/package.json index 4aca162ca96..2cfb6b94def 100644 --- a/tests/integration-tests/grafting/package.json +++ b/tests/integration-tests/base/package.json @@ -1,12 +1,12 @@ { - "name": "grafting-subgraph", + "name": "base-subgraph", "version": "0.1.0", "scripts": { "build-contracts": "../../common/build-contracts.sh", "codegen": "graph codegen --skip-migrations", "test": "yarn build-contracts && truffle test --compile-none --network test", - "create:test": "graph create test/grafting-subgraph --node $GRAPH_NODE_ADMIN_URI", - "deploy:test": "graph deploy test/grafting-subgraph --version-label v0.0.1 --ipfs $IPFS_URI --node $GRAPH_NODE_ADMIN_URI" + "create:test": "graph create test/base-subgraph --node $GRAPH_NODE_ADMIN_URI", + "deploy:test": "graph deploy test/base-subgraph --version-label v0.0.1 --ipfs $IPFS_URI --node $GRAPH_NODE_ADMIN_URI" }, "devDependencies": { "@graphprotocol/graph-cli": "0.69.0", diff --git a/tests/integration-tests/grafting/schema.graphql b/tests/integration-tests/base/schema.graphql similarity index 53% rename from tests/integration-tests/grafting/schema.graphql rename to tests/integration-tests/base/schema.graphql index 58111f9548a..f7034353d73 100644 --- a/tests/integration-tests/grafting/schema.graphql +++ b/tests/integration-tests/base/schema.graphql @@ -1,4 +1,4 @@ -type GraftingData @entity(immutable: true) { +type BaseData @entity(immutable: true) { id: ID! data: String! blockNumber: BigInt! diff --git a/tests/integration-tests/grafting/src/mapping.ts b/tests/integration-tests/base/src/mapping.ts similarity index 54% rename from tests/integration-tests/grafting/src/mapping.ts rename to tests/integration-tests/base/src/mapping.ts index db224e64533..11767070a5b 100644 --- a/tests/integration-tests/grafting/src/mapping.ts +++ b/tests/integration-tests/base/src/mapping.ts @@ -1,9 +1,9 @@ import { ethereum } from '@graphprotocol/graph-ts' -import { GraftingData } from '../generated/schema' +import { BaseData } from '../generated/schema' export function handleBlock(block: ethereum.Block): void { - let entity = new GraftingData(block.number.toString()) - entity.data = 'to grafting' + let entity = new BaseData(block.number.toString()) + entity.data = 'from base' entity.blockNumber = block.number entity.save() } \ No newline at end of file diff --git a/tests/integration-tests/grafting/subgraph.yaml b/tests/integration-tests/base/subgraph.yaml similarity index 73% rename from tests/integration-tests/grafting/subgraph.yaml rename to tests/integration-tests/base/subgraph.yaml index 7c1227608db..808b446c622 100644 --- a/tests/integration-tests/grafting/subgraph.yaml +++ b/tests/integration-tests/base/subgraph.yaml @@ -1,5 +1,5 @@ -specVersion: 0.0.6 -description: Grafting Subgraph +specVersion: 0.0.5 +description: Base Subgraph repository: https://github.com/graphprotocol/graph-node schema: file: ./schema.graphql @@ -16,15 +16,10 @@ dataSources: apiVersion: 0.0.6 language: wasm/assemblyscript entities: - - GraftedData + - BaseData abis: - name: SimpleContract file: ./abis/Contract.abi blockHandlers: - handler: handleBlock - file: ./src/mapping.ts -features: - - grafting -graft: - base: QmTiueTVFgeUedMsx8trJDYYwCfFxrHmzkgRnKbvBkujq9 - block: 2 \ No newline at end of file + file: ./src/mapping.ts \ No newline at end of file diff --git a/tests/integration-tests/grafted/src/mapping.ts b/tests/integration-tests/grafted/src/mapping.ts index 8b140ac9864..742d5d67c54 100644 --- a/tests/integration-tests/grafted/src/mapping.ts +++ b/tests/integration-tests/grafted/src/mapping.ts @@ -3,7 +3,7 @@ import { GraftedData } from '../generated/schema' export function handleBlock(block: ethereum.Block): void { let entity = new GraftedData(block.number.toString()) - entity.data = 'from grafted' + entity.data = 'to grafted' entity.blockNumber = block.number entity.save() } \ No newline at end of file diff --git a/tests/integration-tests/grafted/subgraph.yaml b/tests/integration-tests/grafted/subgraph.yaml index 180a8cea181..f946f201941 100644 --- a/tests/integration-tests/grafted/subgraph.yaml +++ b/tests/integration-tests/grafted/subgraph.yaml @@ -1,4 +1,4 @@ -specVersion: 0.0.5 +specVersion: 0.0.6 description: Grafted Subgraph repository: https://github.com/graphprotocol/graph-node schema: @@ -22,4 +22,9 @@ dataSources: file: ./abis/Contract.abi blockHandlers: - handler: handleBlock - file: ./src/mapping.ts \ No newline at end of file + file: ./src/mapping.ts +features: + - grafting +graft: + base: QmQpiC9bJGFssQfeZippfQ7rcTv7QA67X7jUejc8nV125F + block: 2 \ No newline at end of file diff --git a/tests/tests/integration_tests.rs b/tests/tests/integration_tests.rs index 108708f8254..9df36f7145a 100644 --- a/tests/tests/integration_tests.rs +++ b/tests/tests/integration_tests.rs @@ -112,12 +112,12 @@ impl TestCase { } } - fn new_with_grafting(name: &str, test: fn(TestContext) -> T, grafted_subgraph: &str) -> Self + fn new_with_grafting(name: &str, test: fn(TestContext) -> T, base_subgraph: &str) -> Self where T: Future> + Send + 'static, { let mut test_case = Self::new(name, test); - test_case.source_subgraph = Some(grafted_subgraph.to_string()); + test_case.source_subgraph = Some(base_subgraph.to_string()); test_case } @@ -836,9 +836,9 @@ async fn test_subgraph_grafting(ctx: TestContext) -> anyhow::Result<()> { ]; let pois: Vec<&str> = vec![ - "0x4f3e32c290fd6aa3613a0bbd0cc4367ae082036086cf75f292f8eaf798648a27", - "0x6053124bc1042dfc9c153b49c626f11860a1bc34d0fde384526a2dbed909d242", - "0xca535e3a5be9b93012f6173b33cf9c053cac8028dda9c398b619b67f53a9e1a4", + "0xde9e5650e22e61def6990d3fc4bd5915a4e8e0dd54af0b6830bf064aab16cc03", + "0x5d790dca3e37bd9976345d32d437b84ba5ea720a0b6ea26231a866e9f078bd52", + "0x719c04b78e01804c86f2bd809d20f481e146327af07227960e2242da365754ef", ]; for i in 1..4 { @@ -1040,7 +1040,7 @@ async fn integration_tests() -> anyhow::Result<()> { TestCase::new("timestamp", test_timestamp), TestCase::new("ethereum-api-tests", test_eth_api), TestCase::new("topic-filter", test_topic_filters), - TestCase::new_with_grafting("grafting", test_subgraph_grafting, "grafted"), + TestCase::new_with_grafting("grafted", test_subgraph_grafting, "base"), TestCase::new_with_source_subgraph( "subgraph-data-sources", subgraph_data_sources, @@ -1063,9 +1063,9 @@ async fn integration_tests() -> anyhow::Result<()> { cases }; - // Here we wait got a block in anvil environment in order not to mess up + // Here we wait for a block in the blockchain in order not to influence // block hashes for all the blocks until the end of the grafting tests. - // Currently the block 3. + // Currently the last used block for grafting test is the block 3. assert!(wait_for_blockchain_block(SUBGRAPH_LAST_GRAFTING_BLOCK).await); let contracts = Contract::deploy_all().await?;