Friday, May 05, 2023

Fixing "Failed to get Recent Blockhash" Error in Solana Development with Anchor Framework

I took a break from exploring development in Solana, and the first thing I hit when I recently resumed again was failing tests when using the Anchor framework.

Running anchor run test leads to this error:

  1) calculator
  Is initialized!:
  Error: failed to get recent blockhash: FetchError:
  request to http://localhost:8899/ failed, reason:
  connect ECONNREFUSED ::1:8899
  at Connection.getLatestBlockhash
  (node_modules/@solana/web3.js/src/connection.ts:4555:13)
  at processTicksAndRejections
  (node:internal/process/task_queues:95:5)
  at AnchorProvider.sendAndConfirm
  (node_modules/@coral-xyz/anchor/src/provider.ts:147:9)
  at MethodsBuilder.rpc [as _rpcFn]
  (node_modules/@coral-xyz/anchor/src/program/namespace/rpc.ts:29:16)

The important part of the error message is:

Error: failed to get recent blockhash: FetchError:
request to http://localhost:8899/ failed, reason:
connect ECONNREFUSED ::1:8899
      at Connection.getLatestBlockhash

Googling the error, I found this suggestion here which says to "Try using node 16 instead of 17 if you're on 17".

I tried this and sure this works. But it does not feel right. node's current version is 20.x, dropping down to version 16 does not feel like the most appropriate way to solve this problem.

So why is the issue happening in the first place? Maybe if we understand that, we can come up with a better solution.

Well, the reason why dropping down to version 16 works, is because, starting from version 17, node now by default resolves "localhost" to IPv6's ::1, not IPv4's 127.0.0.1. Version 16 was the last version were node resolves localhost to 127.0.0.1.

And you guessed it, when you run the local Solana test validator, via solana-test-validator it is automatically listening on 127.0.0.1. So Anchor test is trying to connect to the validator using "localhost", but this resolves to an IPv6 address, but our Solana validator is listening for connections on an IPv4 address, which is 127.0.0.1 

Now that we know the problem, a better solution then is to configure the Solana test validator to listen on the IPv6 address, or better still configure it to listen on 0.0.0.0 which means it will be able to serve request that comes in both as IPv4 or IPv6.

To do this, stop your Solana test validator if it was running and then run the following command:

solana config set --url http://0.0.0.0:8899
// or to set to IPv6
solana config set --url http://\[::1\]:8899

Start your test validator and run the tests, everything should work fine.


No comments: