graphprotocol / graph-tooling

Monorepo for various tools used by subgraph developers.
https://thegraph.com/docs
Apache License 2.0
392 stars 209 forks source link

`graph add` errors with `getaddrinfo ENOTFOUND api-localhost.etherscan.io` on localhost #1748

Closed schmidsi closed 3 weeks ago

schmidsi commented 1 month ago

Steps to reproduce:

  1. Have a subgraph with network: localhost in subgraph.yaml
  2. Run graph add 0x5FbDB2315678afecb367f032d93F642f64180aa3 (or any other address)

Result:

✖ Failed to fetch ABI from Etherscan: getaddrinfo ENOTFOUND api-localhost.etherscan.io
    Error: getaddrinfo ENOTFOUND api-localhost.etherscan.io
    Code: ENOTFOUND

Expected result:

schmidsi commented 1 month ago

This works:

graph add 0x5FbDB2315678afecb367f032d93F642f64180aa3 --abi /Users/schmidsi/Development/@schmidsi/savp-prototype/packages/hardhat/deployments/localhost/LittleBigPicture.json
✖ Failed to fetch Start Block: Failed to fetch contract creation transaction hash
✔ Start Block · 0
✖ Failed to fetch Contract Name: getaddrinfo ENOTFOUND api-localhost.etherscan.io
✔ Contract Name · SAVP
✔ Running codegen

But the command never exits.

0237h commented 3 weeks ago

Hi @schmidsi,

The error comes from the default case of the getEtherscanLikeAPIUrl method which tries to create a Etherscan URL given the network name (here localhost):

const getEtherscanLikeAPIUrl = (network: string) => {
  switch (network) {
    case 'mainnet':
      return `https://mainnet.abi.pinax.network/api`;
    [...]
    default:
      return `https://api-${network}.etherscan.io/api`; // `localhost` falls into the default case
  }
};

Obviously, this isn't right. ABI should be provided (or asked if missing) in the case of localhost as you mentioned.

After that, the graph add command flow also makes calls to loadStartBlockForContract and loadContractNameForAddress which both resolves to making call to the Etherscan API, which is why you're getting an error as well even after providing the ABI.


To solve this, would you mind clarifying what you're trying to achieve ?

If I understand correctly, your goal is to keep the network set to localhost for local development while also being able to fetch and add external contract datasources ? In that case, you might have to specify the network you're trying to load the ABI from (e.g. mainnet) before running graph add. That way the CLI knows where to fetch the ABI, startBlock and contract name.

schmidsi commented 3 weeks ago

loadStartBlockForContract should work on localhost actually. The JSON RPC server usually runs at http://127.0.0.1:8545/.

To answer your questions:

If I understand correctly, your goal is to keep the network set to localhost for local development while also being able to fetch and add external contract datasources ? Not sure. Yes, I want to keep the network set to localhost, but I want to add another contract deployed on my local dev chain.

In that case, you might have to specify the network you're trying to load the ABI from (e.g. mainnet) before running graph add. That way the CLI knows where to fetch the ABI, startBlock and contract name. In my scenario, I don't want to interact with mainnet at all. I'm developing some smart contracts locally and want to develop the subgraph in parallel. This is actually the preferred way of subgraph development for new projects in my opinion.

What you are referring to would be if I run a local mainnet fork. In that case, I would set the network to mainnet but point my local Graph Node to my local fork endpoint. That should work out of the box.

0237h commented 3 weeks ago

Thanks for the feedback @schmidsi.

loadStartBlockForContract should work on localhost actually. The JSON RPC server usually runs at http://127.0.0.1:8545/.

This method needs the transaction hash where the contract is created (which is what the Etherscan lookup returns) and then makes an RPC call for fetching the start block.

So it could work fully locally if the user provides the correct tx_hash, which is not currently implemented in the flow. But since the user would need to input the tx_hash I think we should rather ask for the block number directly, like it is done now.

Regarding your answers, the implementation that will be available in the next release should be able to cover your use case. Feel free to open new issues if that's not the case.