Issues when forking archive node

I forked Moralis achive node of Polygon mainnet using Hardhat and tried sending eth_sendRawTransaction but I received ā€œinvalid JSON-RPC responseā€ error from Hardhat. I know that everything is fine with the transaction itself because it worked when I connected to another archive node provider. Here are steps to reproduce:

  1. Create a new Hardhat project and set up config file as attached below.
  2. Fork archive node by running npx hardhat node --fork https://speedy-nodes-nyc.moralis.io/YOUR_KEY_HERE/polygon/mainnet/archive --fork-block-number 15740991
  3. Try to send eth_sendRawTransaction transaction. I am using Web3 Python library for this. Bytecode of signed transaction is attached below but it doesnā€™t have to be this particular transaction. No transactions worked for me.
// hardhat.config.js

require("@nomiclabs/hardhat-waffle");

// This is a sample Hardhat task. To learn how to create your own go to
// https://hardhat.org/guides/create-task.html
task("accounts", "Prints the list of accounts", async (taskArgs, hre) => {
  const accounts = await hre.ethers.getSigners();

  for (const account of accounts) {
    console.log(account.address);
  }
});

// You need to export an object to set up your config
// Go to https://hardhat.org/config/ to learn more

/**
 * @type import('hardhat/config').HardhatUserConfig
 */
module.exports = {
  solidity: "0.8.4",
  networks: {
    hardhat: {
      chainId: 137,
      timeout: 120000,
      blockGasLimit: 20000000,
      mining: {
        auto: false,
        interval: 0
      }
    },
    localhost: {
      url: "http://localhost:8545",
      chainId: 137
    }
  }
};

Signed transaction

f9016d4b8502cb417800830322ee94a5e0829caced8ffdd4de3c43696c57f7d7a678ff80b90104e8e33700000000000000000000000000d86b5923f3ad7b585ed81b448170ae026c65ae9a0000000000000000000000002791bca1f2de4661ed88a30c99a7a9449aa841740000000000000000000000000000000000000000000001df5d05bd8da4b766320000000000000000000000000000000000000000000000000000000212004ccc0000000000000000000000000000000000000000000001dcf76ff3a5415533c3000000000000000000000000000000000000000000000000000000020f59e60300000000000000000000000017c26aabec62b91cb2a76402ee3a6cae1f79c13c0000000000000000000000000000000000000000000000000000000060c881a7820136a08ec4a9d2a61c6c7f36828a065fa7a2613f6e50399e008a155b18237687da12eba0693f6db047d5bb6e37bd7b6785e2490e788bc16232cf14b9c90f83b7c8c4e8c9
1 Like

Hey @python481516

Iā€™ve checked, it works fine.
In your settings, automining is disabled. After the transaction, do you use evm_mine?

1 Like

Yes, I use evm_mine but this is not relevant because it didnā€™t work with auto mining too. Actually it fails when I send raw transaction before it is even mined. w3.eth.send_raw_transaction() immediately raises ValueError with message 'code': -32603, 'message': 'HardhatError: HH110: Invalid JSON-RPC response received: '. I have create a standalone Python script to reproduce the error. You need to run fork at block 15740991 and update MORALIS_POLYGON_ARCHIVE_ENDPOINT variable to include your key. This is what it does:

  1. Fetches the first transaction at block 15740992 from the remote node.
  2. Tries to execute this transaction on the local fork (fork is set to block 15740991 so the next transaction will be included in block 15740992).

I tried running the same script when forking from Moralis and then from another provider. It fails in case of Moralis but works with another provider. Let me know if you need some additional info.

from web3 import Web3
from web3.middleware import geth_poa_middleware
from eth_account._utils.transactions import (
    encode_transaction,
    serializable_unsigned_transaction_from_dict
)
from web3.types import TxData

MORALIS_POLYGON_ARCHIVE_ENDPOINT = 'https://speedy-nodes-nyc.moralis.io/YOUR_KEY/polygon/mainnet/archive'

def get_raw_signed_tx(tx: TxData) -> bytes:
    unsigned_tx = serializable_unsigned_transaction_from_dict({
                'to': tx['to'],
                'data': tx['input'],
                'gasPrice': tx['gasPrice'],
                'gas': tx['gas'],
                'nonce': tx['nonce'],
                'value': tx['value']
        })
    signed_raw_tx = encode_transaction(unsigned_tx, (tx['v'], int(tx['r'].hex(), 16), int(tx['s'].hex(), 16)))

    return signed_raw_tx

def replay_tx(tx_hash: str, w3_local: Web3, w3_live: Web3):
    tx_data = w3_live.eth.get_transaction(tx_hash)
    tx_signed = get_raw_signed_tx(tx_data)
    w3_local.eth.send_raw_transaction(tx_signed)

if __name__ == '__main__':
    w3_local = Web3(Web3.HTTPProvider('http://localhost:8545'))
    w3_live = Web3(Web3.HTTPProvider(MORALIS_POLYGON_ARCHIVE_ENDPOINT))

    w3_local.middleware_onion.inject(geth_poa_middleware, layer=0)
    w3_live.middleware_onion.inject(geth_poa_middleware, layer=0)

    replay_tx('0x3650ae639ec01bd51a2aeb45e478a8b82065cf280e8f6e6214c3d44345ef8f4e', w3_local, w3_live)