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

Issues with upgrading the Ethereum VM with wasm. #508

Closed
wanderer opened this issue Dec 22, 2015 · 8 comments
Closed

Issues with upgrading the Ethereum VM with wasm. #508

wanderer opened this issue Dec 22, 2015 · 8 comments

Comments

@wanderer
Copy link
Contributor

I wrote a proposal today for upgrading the Ethereum VM with wasm. You can see it here ethereum/EIPs#48

One of the harder parts of fitting wasm to Ethereum is the current Ethereum opcodes CALL and CALLCODE. CALL makes a call to another Ethereum contract (module) and the result is placed in memory at a specified location. CALLCODE is kinda like dlopen. It injects code from a given contract into the current running code. Currently I don't know of anyway to support this kind of behavior with wasm semantics. So if we adopt the proposal we will have to modify a wasm VM.

Would there be a better way of doing this that fits close to wasm semantics and does not involve as heavy modification to a wasm implementation? And Ideally what kind of semantics could wasm have to support this?

@lukewagner
Copy link
Member

Although it's not in the MVP, dynamic linking is a high-priority post-v.1 feature that we've thought and discussed a fair amount already in various GH issues (though it seems like DynamicLinking.md still needs updating). The basic idea is there would be, among other things, some dlopen operator which can dynamically inject a new module into an existing instance. Do you think that would address your use case?

@wanderer
Copy link
Contributor Author

@lukewagner thanks for your reply! If there was a dlopen operator and the injected module shared memory with the current module then that would cover CALLCODE.

But I'm not sure for CALL

(import $eth_call "ethereum" "call" (param i64) (param i32) (param i32) (param i32))
;;address are 160 bits i64 + i64 + i32, then memory location for results i32, mem loc for args i32.
(call_import $eth_call (i64.const  <>) (i64.const  <>)  (i32.const  <>) (i32.const <>) (i32.const <>))

The result of $eth_call need to loaded into memory. Also $eth_call needs to read from memory the arguments for the targeted contract.

@lukewagner
Copy link
Member

Ah, so this is a source of confusion that need to be more clearly expressed in docs: wasm imports are quite distinct from dynamic linking (load-time or run-time). The best way to think of wasm imports is as syscalls which implies that you are leaving your address space. With the dynamic linking future-feature, there would be a different way to specific dynamic linking (both load-time and run-time), distinct from import, such that both modules end up in the same instance and thus share linear memory.

@wanderer
Copy link
Contributor Author

I think I see. I think the tricky part is still eth_call because the results are loaded into memory and the arguments are loaded directly from memory. Here called contract cannot have access to the callees memory with the exception of read only access to arguments memory location and write only access to return value memory location. How would fine tuned memory access like fit into dynamic linking?

this is opposed from eth_callcode which is simple a injection.

@ghost
Copy link

ghost commented Dec 23, 2015

@wanderer JS support for accessing the linear memory is expected so if $eth_call is implement in JS then it is expected to be able to read and write operands to the linear memory.

@wanderer
Copy link
Contributor Author

@JSStats that's a very convincing route to go. It would also be nice to have a similar feature in the JITLibrary.

We have C++, Go and JS implementations. C++ and Go would have to use the jit library

@lukewagner
Copy link
Member

To expand on what @JSStats said: you wouldn't use dynamic linking, but rather separate module instances (separate linear memories) which both allowed JS to alias the heap via ArrayBuffer so that JS could do the manual copying in/out of args/results. If we add the post-MVP feature of allowing wasm to import other instances' linear memory, then you could do this copying from within wasm without the thunk through JS.

Alternatively, if you trust the VM implementation on both sides, you could use dynamic linking and a single instance (1 linear memory) and implement the sandboxing yourself within the VM so that no copy was necessary.

@wanderer
Copy link
Contributor Author

Thank you @lukewagner and @JSStats for helping! I'm fairly confident both of the above methods can work for us.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants