1

Is there a way to run a Hardhat fork off mainnet such that it remains in sync with the mainnet while also letting us deploy contracts on the local copy of the blockchain?

Is that even possible?

https://hardhat.org/hardhat-network/guides/mainnet-forking.html#resetting-the-fork seems to be something similar.

2
  • The moment you deploy a contract on your "fork" you are no longer in sync with mainnet, if you resync : your deployment never took place.. I don't think it is possible to be honest. Why do you want to do that in the first place ?
    – hroussille
    Nov 23, 2021 at 14:11
  • 2
    Basically, I want to interact with the mainnet without having to deploy a contract. Specifically, I want to: a) work with updated DeFi balances, and b) simulate transactions on updated states and not just the same forked state and balances. A learning exercise.
    – td-bn
    Nov 23, 2021 at 15:18

2 Answers 2

1

For me, HH always runs a few blocks behind on fork for some reason. But you could remain relatively synced (about always 5 blocks behind) by continuously resetting your fork per "Resetting the fork" here: https://hardhat.org/hardhat-network/guides/mainnet-forking

For example if you've an ethers-js provider:

const resp = await ethProvider.send('hardhat_reset', params);

where

const params = [
        {
            forking: {
                jsonRpcUrl: "https://your.infura.or.alchemy.url",
            },
        },
    ];

And you just send hardhat_reset whenever you need it to get an approximate latest in your code

0

I managed to keep a local fork synced with the live mainnet on the most up-to-date block.

First, you need a provider pointing to the live mainnet.

const liveProvider = new ethers.providers.JsonRpcProvider(url);
let blockNumberLive = await liveProvider.getBlockNumber();

Then you can fetch blocks from live mainnet at arbitrary intervals, so you will get the most up-to-date block number as soon as it is available:

async function checkLiveBlockNumber() {
    return new Promise((resolve, reject) => {
        const interval = setInterval(async () => {
            let blockNumber = await liveProvider.getBlockNumber();
            if (blockNumberLive !== blockNumber) {
                clearInterval(interval);
                resolve(blockNumber);
            }
        }, 1000);
    });
}

Then whenever you want, you can sync (reset) your localhost provider for the most recent block number:

async function updateBlockNumber() {
    const params = {
        forking: {
            jsonRpcUrl: url,
            blockNumber: blockNumberLive,
        }
    }
    await ethers.provider.send('hardhat_reset', [ params ]);
}

Just remember, that whatever transactions you submit to your localhost network will be erased on each sync operation.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.