ethereumjs-monorepo icon indicating copy to clipboard operation
ethereumjs-monorepo copied to clipboard

Implement an ethers provider that wraps `ethersStateManager`

Open acolytec3 opened this issue 3 years ago • 7 comments

When we introduced the new ethersStateManager, it allows for essentially forking mainnet (or any chain) and running transactions locally against the state of that chain. One can chain transactions together and see the effect of multiple transactions on the state of the chain without actually submitting a real transaction.

It would be nice to implement a new ethers provider interface that extends the JsonRPCProvider by wrapping it with the ethersStateManager and proxying getBalance/getCode/getStorageAt state related calls to the ethersStateManager so that developers can make simulated testing against forked chain state much easier since they will be able to just use ethers without directly having to interact with the stateManager or other lower level primitives in the @ethereumjs stack.

An approximate implementation will be:

  1. Add a new ethersForkedStateProvider file under the stateManager package
  2. Create a new class that will extend the jsonRpcProvider interface from ethers
  3. Accepts a remote RPC provider URL as a parameter
  4. Has the ethersStateManager as a private element of the class
  5. Override the getAccount/getCode/getStorageAt functions with new innards that call the equivalent methods on the ethersStateManager object (which will in turn call out to the remote RPC provider if the state isn't found locally).

acolytec3 avatar Nov 30 '22 19:11 acolytec3

Took a stab at this following the model of the Ultralight provider.

Biggest question has to do with getAccount - and what the equivalent ethers call is.

ScottyPoi avatar Dec 03 '22 01:12 ScottyPoi

Took a stab at this following the model of the Ultralight provider.

Biggest question has to do with getAccount - and what the equivalent ethers call is.

There isn't a 1-1 equivalent there. You would use it inside of ethers.provider.getBalance if the main one I can think of.

acolytec3 avatar Dec 03 '22 02:12 acolytec3

I just realized my original issue description wasn't exactly correct be there is no getAccount in the rpc. It's really just getBalance. You might also have to implement a wrapper around getTransactionCount and then use stateManager.getAccount to retrieve the nonce and return that.

acolytec3 avatar Dec 03 '22 02:12 acolytec3

There isn't a 1-1 equivalent there. You would use it inside of ethers.provider.getBalance if the main one I can think of.

So i should include a wrapper for getBalance and others that look up accounts?

ScottyPoi avatar Dec 03 '22 02:12 ScottyPoi

There isn't a 1-1 equivalent there. You would use it inside of ethers.provider.getBalance if the main one I can think of.

So i should include a wrapper for getBalance and others that look up accounts?

I think getBalance and getTransactionCount are the two. Would need to look through the rest of the rpc endpoint list to see if there are any others.

acolytec3 avatar Dec 03 '22 02:12 acolytec3

@acolytec3 can you take a peek at #2442 and tell me if I'm doing what you had in mind?

In working on it I found a couple inconsistencies in EthersStateManager. Between what the comments said should happen, and what was happening in the methods.

ScottyPoi avatar Dec 07 '22 04:12 ScottyPoi

Will do today

acolytec3 avatar Dec 07 '22 10:12 acolytec3