-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
feat(evm-adapters): transport agnostic forking #1003
feat(evm-adapters): transport agnostic forking #1003
Conversation
thanks, good point! |
5caa009
to
c40bb87
Compare
@@ -378,14 +379,16 @@ impl SharedBackend { | |||
cache: SharedCache<MemCache>, | |||
vicinity: MemoryVicinity, | |||
pin_block: Option<BlockId>, | |||
runtime: Option<Runtime>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Had to pass runtime along because WebSocket connection would be closed when the runtime that it was created on drops.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
btw, i don't think RuntimeOrHandle
was good idea here (i'm to blame) - it would be better to have clean async constructor with native spawn & wrap it in sync version.
Not sure, do we plan to keep and support the sputnik evm alongside revm? I was thinking that's the plan since we have |
Supportive of the PR in principle, we're getting rid of other evm types so could you give a stab maybe at integrating this against https://github.com/gakonst/foundry/tree/revm? |
No sir, we will not keep Sputnik. The multi-EVM thing was an early design thought but we're moving away from that. The relevant files in the |
c40bb87
to
cecd9dd
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm cc @mattsse to double check
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks a lot,
couple of nits
@@ -11,7 +11,7 @@ foundry-utils = { path = "./../utils" } | |||
serde_json = "1.0.67" | |||
serde = "1.0.130" | |||
hex = "0.4.3" | |||
ethers = { git = "https://github.com/gakonst/ethers-rs", default-features = false, features = ["solc-full"] } | |||
ethers = { git = "https://github.com/gakonst/ethers-rs", default-features = false, features = ["solc-full", "ws", "rustls", "ipc"] } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ipc is only available on unix.
and enabling this will definitely not compile on windows
so we need to feature gate this here as well
perhaps fine as ipc
module should be ignored even if enabled on non linux
it should be ignored:
let provider = Arc::new( | ||
rt.block_on(Provider::connect_ipc(url)).expect("Failed to establish provider"), | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
needs a cfg for unix, otherwise should panic
provider: M, | ||
db: BlockchainDb, | ||
pin_block: Option<BlockId>, | ||
runtime: Option<Runtime>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm not a big fan of supplying the runtime here.
I'd consider creating a new runtime negligible additional effort
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, however, I am establishing the IPC and WebSocket connections. You cannot use those in different runtimes or after the runtime that it was created on ceases to exist.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
imho this function should be async
match rt { | ||
RuntimeOrHandle::Runtime(runtime) => runtime.block_on(fut), | ||
RuntimeOrHandle::Handle(handle) => handle.block_on(fut), | ||
} | ||
.expect("could not instantiate forked environment") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this getting a bit messy.
we have already a block_on
in cli/utils
I believe.
let's either replicate that for this crate or better make this function async so we only have to do it once for the whole evm_env
function.
let fut = async { | ||
let provider = Provider::connect_ipc(fork_url.as_str()) | ||
.await | ||
.expect("could not instantiated provider"); | ||
environment(&provider, self.env.chain_id, self.fork_block_number, self.sender) | ||
.await | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also needs cfg
Feels like ethers provider is getting to the point where we should do an enum over the transports and abstract it HTTP/WS/IPC away from the user.. I just tested this and weirdly enough when I run it with WSS twice caching works, but when I switch URL to be back to the https it reruns w/o caching. Didn't expect that, sounds like a bug? Separately, here's a WS vs HTTPS comparison on performance on same Alchemy API key without cache: WSS Time:
HTTPS Time:
Seems like WS is slower? |
same host? |
Aha! It's |
yeah the host differs, there's a let's ignore the endpoint in comparison but we can keep them as |
Sorry to pile on here, but one last stretch goal (feel free to skip it!) would be to change the ETH_URL we use in our test workflow to use the websocket endpoint instead of HTTP 😄 |
I will try to look into why ws is so much slower. I suspect there might be something off in how we are handling the requests in |
@meetmangukiya just trying to keep things clean, any plans to resume this PR? else can I close as stale, and we re-visit later? |
Can close for now. Might pick again when frustrated with lack of ws support. I actually couldn't think any rational reason why websocket is 2x slower. Thought might have to do something with the websocket server implementation in ethers or with the backend implementation in foundry. However, don't see anything obvious there that could lead to such unexpected results. Are we open to merge ws and ipc provider support even though they may be slower or have no perfomance gains? If yes, i will address the review comments and can get this merged. |
I would say let's only merge if we figure out the performance overheads. It's possible it's in the ethers websocket impl, I have never tried benchmarking it. |
I had tested ethersjs and ethers-rs websocket. There weren't significant differences in response times. But it was just simple looping of |
ethersjs just recently (as in after your comment) properly implemented WS FYI |
@sambacha got a link to the PR? |
Here is the relevant issue which has a long thread about websockets and the various PRs ethers-io/ethers.js#1053 |
Motivation
Run tests on forked mainnet will probably gain some speed when using WebSocket / IPC which will prevent opening and closing connections for each RPC requests(account data, storage slots).
P.S.: Have not tested IPC
Solution