-
Notifications
You must be signed in to change notification settings - Fork 281
Closed
Description
Rewrite this tool as a hybrid of solidity-coverage and 0xProject's opcode tracing sol-cov.
Mechanics
- instead of a file of event hashes written by testrpc-sc, maintain an in memory map of them.
- example instrumentation where
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.
contract Test {
function coverage_0xab123(bytes32 c__0xab123) public pure {}
function a(uint x) public {
coverage_0xab123(0xdc08f...08ed1); /* function */
coverage_0xab123(0xa9065...549e2); /* line */
coverage_0xab123(0x6ac83...f2037); /* statement */
if (x == 1) {
coverage_0xab123(0x85e7e...afacf); /* branch */
coverage_0xab123(0xfa262...4fb28); /* line */
coverage_0xab123(0xa3e17...38d49); /* statement */
x = 3;
} else {
coverage_0xab123(0xb54c1...3ef6b); /* branch */
}
}- listen to the vm step of a ganache-core in-process provider
const Ganache = require("ganache-core");
// ... some setup w/ web3
const vm = web3.currentProvider.engine.manager.state.blockchain.vm;
const self = this;
this.vm.on("step", function(info){
if (info.opcode.name.includes("PUSH1") && info.stack.length > 0){
const idx = info.stack.length - 1;
const hash = web3Utils.toHex(info.stack[idx]).toString(); // Could be ours!
if(self.instrumentationData[hash]){
self.instrumentationData[hash].hits++;
}
}
})Interface
-
Truffle plugin. We'll get fed the config and then we:
- Instantiate a ganache provider (hooking into the step)
- instrument
- run truffle-workflow-compile
.coverageEnv--> build directory- optimization off
hide compilation warnings about unused variables
- run truffle-core.test
.coverageEnv--> contracts_directory- listen to step
- generate coverage
-
Buidler plugin - similar, simpler.
-
Abstract the design enough that any build tool can consume.
Benefits
- No more copying folders etc.
- No more abi modification, double compilation, weird problems w/ libraries
- No more testrpc-sc to update (eventually)
- Get rid of most options, user config
- Much faster & simpler.
Problems
- Gas cost distortion (+13 gas per instrumentation statement).
- Ternary expressions still un-coverable.
Stack too deep? This blog post suggests risks might be comparable to present. Not sure, could be a blocker though.(Solved)- Requires in-process client
- Are there cases where gas sensitive solidity checks require compilation w/ solc optimization enabled? (This would impact any opcode tracer though) Does solc optimize assembly?
Why is this preferable to the opcode-to-sourcemap approach?
- small modification of what we already have.
- truffle-debugger and the 0x tools are complex
- Not currently supported on 0x. Why?
- require as branch ( code)
- contract created within contract
- proxied contracts?
- enum?
- source to opcode mapping / trace has gaps & oddities
- embark, after spending months building an opcode tracing solution, abandoned that work to pursue event instrumentation (?!). Why?
- we know we instrument ok (mostly).
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)
BrendanChou
Metadata
Metadata
Assignees
Labels
No labels