-
Notifications
You must be signed in to change notification settings - Fork 269
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
v0.7.0 Plan (Experimental) #346
Comments
Hey @cgewecke, I'm very interested in this redesign!
Won't you have to recompile the project anyway? Or am I missing something from how it currently works?
Maybe this can also be workarounded by hooking into the vm
We have an experimental in-process client in Buidler, it's already functional, but it hasn't been released yet. It's also based on |
Also, do you have any idea how this can be tested? |
@alcuadrado Great!
Oh awesome, I'd love to see this.
Yes, that's correct - but only once. At the moment we have to compile twice. Solidity does not allow event statements in view or pure functions since v0.5.0. To get around this we do an initial compilation of the original contracts to get the 'correct' ABI (with view/pure). Then we strip the state-mutability modifiers off and instrument the code to get the bytecode 'with coverage'. At the end we swap the original ABI back into the artifact to trick Truffle into invoking view/pure methods as .call rather than .send. (This strategy was thought up by Zeppelin engineers in #146 if you're interested in its history.)
Unfortunately this error is emitted by solc rather than at runtime which makes it difficult to address. In the strategy proposed above, we will introduce a single additional variable into each function, reducing the available stack depth by 1 (from 16 to 15). I don't know how problematic this will be yet... to some extent it's a question of how common it is for people to be at the limit. In general when this error is hit people are advised to use structs to organize their data and I believe abi-encoder V2 has made this more convenient.
Well . . . I think I can trigger the error, but my only ideas for resolving this are:
(Possibly more info than you wanted :)) |
I'll publish something as soon as I have some time to polish it a little. There's not that much to see though, it's pretty simple 😅It's a minimal provider implemented on top of
It was way more complicated than I suspected. Nice hack though 😁
Oh, yes, I was confused. I think detecting the error and giving a clear explanation would work for the vast majority of the cases. I've only hit this error once while getting lots of data from another contract. I wonder if something else can be implemented with a small modification/hook into the vm. Something not using the stack? Is that even possible? Maybe using an instruction in an unexpected but recognizable way? |
@alcuadrado This is the holy grail as far I'm concerned. If you think of something please lmk - my understanding of how solidity works at the opcode level is very limited & there could well be a cool trick somewhere. |
Did people complain about "stack too deep" errors with the previous approach? How often? I'm almost certain that it should be a cap on how often the new approach will fail. Solidity events use The only thing that makes me doubt it, is that in your example you are doing three assignments. Why three? I know there are some comments there, but I don't see what it can't be done with a single one.
|
Ah interesting.
Occasionally, but now that I look again it's not clear our event injection was the direct cause. . . I think there are several slightly different cases here:
I think the number of assignments as such doesn't matter - there's an open PR here for the core of this idea and it passes unit tests which introduce dozens of new ones.
Yes, the report tracks branch, line, statement and function coverage. The case for each of these is evaluated by stepping through an AST and identifying instrumentation points at the relevant node. You are right that they could be aggregated ... I will look at this. |
This is a good point. I think they shouldn't matter. As the stack before and after an assignment should be the same. If that's the case, there's no need to combine the assignments. |
Copying over the remaining questions raised here....
|
Rewrite this tool as a hybrid of solidity-coverage and 0xProject's opcode tracing sol-cov.
Mechanics
bytes32(0xabc..etc)
is a hash we can pick off the top of the VM step's stack and associate with an entry in the injection map.Interface
Truffle plugin. We'll get fed the config and then we:
.coverageEnv
--> build directoryhide compilation warnings about unused variables.coverageEnv
--> contracts_directoryBuidler plugin - similar, simpler.
Abstract the design enough that any build tool can consume.
Benefits
Problems
Stack too deep? This blog post suggests risks might be comparable to present. Not sure, could be a blocker though.(Solved)Why is this preferable to the opcode-to-sourcemap approach?
In the medium term we can probably resolve any gas distortion issues using etherumjs-vm V4's Interpreter API which lets you process opcodes arbitrarily following a new EEI spec. Have opened an issue there seeking advice about this.
We can probably instrument assembly eventually (#176)
The text was updated successfully, but these errors were encountered: