Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support of network forking with Hardhat #718

Open
maksimKrukovich opened this issue Apr 8, 2024 · 6 comments
Open

Add support of network forking with Hardhat #718

maksimKrukovich opened this issue Apr 8, 2024 · 6 comments
Assignees
Labels
enhancement New feature or request Tooling tooling

Comments

@maksimKrukovich
Copy link

maksimKrukovich commented Apr 8, 2024

Problem

It would be really helpful to have the option to fork all Hedera networks with hardhat for testing contracts and scripts.
Explanation why forking is the really important thing:
https://hardhat.org/hardhat-network/docs/guides/forking-other-networks

Now if you try to fork for example testnet network it's the next error:

ProviderError: Invalid parent hash: 0x5c4eb51347f68986db69a79aea1f64f0a5baa22aae494b64b1204745a7fd3f6f. Expected: 0xb2adf94780dc4a445a2bd41a75e1aff8f91ce016ec283c0012338d75897a1726.

Solution

Add support of network forking with Hardhat

Alternatives

No response

@maksimKrukovich maksimKrukovich added the enhancement New feature or request label Apr 8, 2024
@quiet-node quiet-node self-assigned this Apr 15, 2024
@Nana-EC
Copy link
Collaborator

Nana-EC commented Apr 17, 2024

Thanks @maksimKrukovich for the ticket and context.
We're in full agreement with you on the value and relevance of forking.
It's just a bit tricky.

For context most EVM tools that provide forking support actually run their own EVM client as part of the node, sometimes with custom logic to support that tools features.
The challenge here is it's not a clear copy of the network being tested.
With networks that don't have any extra EVM logic this is not a problem and is transparent to the users as the client operations are the same.

For Hedera because we have additional functionality such as system contracts that expose native services in smart contracts the tool encounters issues as it doesn't have the logic for these services.
It's a challenge for us to easily adopt it as it requires the external tool modifying their logic for our particular chain.

Nonetheless we're actively looking into this and exploring how we can support this in a seamless way for developers like yourself.

That being said if you're not forking contracts with system contract functions you should be fine and forking should work.
If you're seeing otherwise please kindly provide some more details to help our investigation.

If your flow relies on system contract functionality then the above issue applies and we're currently blocked in supporting this flow.

We'll continue to explore this challenge though to best enable devs

@Nana-EC Nana-EC added the Tooling tooling label Apr 17, 2024
@Nana-EC
Copy link
Collaborator

Nana-EC commented Jul 17, 2024

Revisiting.
Forking for contracts using non system contract logic should work fine.
if there's an issue there let's explore what hardhat is doing.
If it's system contract logic related then we can put this back in the backlog as we need to design that more before being able to address this

@georgi-l95 georgi-l95 self-assigned this Jul 18, 2024
@georgi-l95
Copy link
Collaborator

@maksimKrukovich Can you give me a snippet of how you try to fork the network ?
Does using npx hardhat node --fork https://testnet.hashio.io/api not work ?

@acuarica acuarica self-assigned this Jul 29, 2024
@maksimKrukovich
Copy link
Author

maksimKrukovich commented Aug 6, 2024

@maksimKrukovich Can you give me a snippet of how you try to fork the network ? Does using npx hardhat node --fork https://testnet.hashio.io/api not work ?

Hey @georgi-l95,

Often I do this like that:

  1. Configure the forking in the hardhat.config.ts:
    forking: { url: process.env.RPC_URL || "", },
  2. yarn hardhat test
  3. And on this step I received the error:
    ProviderError: Invalid parent hash: 0x41043892a6b4d00731a84a5e825c93774498189dafebe7ee4861205464a2177b. Expected: 0x064cc975bfc2a39bd32ba080fc0c2ef483a1a0313fe03e61648fe13756bb7364.

And it fails on this line:
const { ... } = await deployFixture();

I've heard Hedera doesn't support fixtures, so I use deployFixture() instead of loadFixture(deployFixture)

Of course I run a test which involves HTS.

@acuarica
Copy link
Contributor

acuarica commented Aug 7, 2024

Hi @maksimKrukovich, thanks for sending this. We are aware of this situation. See #863 (comment) for a related issue on forking with HTS.

Would you be able to provide a minimal example on how to reproduce the error you mentioned above? This will help us to provide a more comprehensible solution for forking.

@maksimKrukovich
Copy link
Author

Hi @acuarica,

The example contract:

contract Example {
    IERC20 public stakingToken;
   
    constructor(address _stakingToken) payable {
        stakingToken = IERC20(_stakingToken);

        SafeHTS.safeAssociateToken(address(_stakingToken), address(this));
    }

    function stake(uint256 amount) external {
        SafeHTS.safeTransferToken(address(stakingToken), msg.sender, address(this), int64(uint64(amount)));
    }

The example test:

describe("Example", function () {
    async function deployFixture() {
        const [
            owner,
        ] = await ethers.getSigners();

        let client = Client.forTestnet();

        const operatorPrKey = PrivateKey.fromStringECDSA(process.env.PRIVATE_KEY || '');
        const operatorAccountId = AccountId.fromString(process.env.ACCOUNT_ID || '');

        client.setOperator(
            operatorAccountId,
            operatorPrKey
        );

        const stakingToken = await ethers.getContractAt(
            "ExampleToken",
            stakingTokenAddress
        );

        const Example = await ethers.getContractFactory("Example");
        const example = await Example.deploy(
             stakingTokenAddress,
             { from: owner.address, gasLimit: 3000000, value: ethers.parseUnits("12", 18) }
        );
        await example.waitForDeployment();

        return {
            example,
            stakingToken,
            client,
            owner,
        };
    }

    describe("stake", function () {
        it("Should stake the staking token", async function () {
            const { example, stakingToken } = await deployFixture();
            const amountToStake = ethers.parseUnits("10", 8);

            await stakingToken.approve(example.target, amountToStake);

            const tx = await example.stake(amountToStake);
        });
    });
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request Tooling tooling
Projects
Status: Sprint Backlog
Development

No branches or pull requests

5 participants