Closed SilentCicero closed 1 year ago
I agree that compile time becomes an issue with multiple contracts/tests. All Gnosis tests run in total for almost 20 minutes. I would suggest adding a cache to the compiler, which could be enabled with a flag. This cache would map a hashed version of the source code to the bytecode:
hash(source code) => compiler version => bytecode
This would allow to compile only when there are changes and would not require any additional setup by the programmer.
Maybe this should be done in a preprocessor.
This feature will also be very valuable for some of the upcoming ethereum package management stuff that's being worked on over at https://github.com/ethpm/epm-spec
@Georgi87 I really like mixing the compiler version as well. very nice!
@pipermerriam yes, this would speed up compile time for epm stuff for sure.
There is currently no way to request only a specific output, the compiler will always generate the bytecode for every single contract it finds in the source. We are changing that when we switch to the new json-based input specification. If that does not help, supplying already compiled bytecode sounds like a useful though potentially dangerous feature.
@chriseth proper hashing/mapping of the bytecode and contracts should help us prevent problems. As Stefan noted, we can tightly hash compiler version, contract data, etc to link and compare bytecode. Infact, we could hash (bytecode, source code, compiler version) etc, to make sure the link is air tight.
We are all having problems with the compile time of Solidity. It's a very cumbersome language to work with on actual platform like apps right now (i.e 15+ contracts dApps).
With packaging right around the corner this feature would be extremely valuable as it fixes one fundamental problem that is going to show up soon. Currently I know of no viable solution for situations where there are conflicting compiler requirements across dependencies.
Ideally with this feature in place package managers can do the following.
One thing that I think would need to be added with this feature is the ability to specify the ABI for the bytecode so that solidity can still do nice "type" checking.
Note that just providing the bytecode for external files will not enable compilation. The compiler needs type information and that goes far beyond the ABI, think of internal library functions and structs being used from other contracts. If you want to separate compilation units across packages, I think the only viable solution now is to specify abstract interfaces - which should be a good software development practice anyway.
@SilentCicero @pipermerriam assuming the new compiler interface will allow to specify what outputs are required from which inputs would that solve this issue? (See #1387.)
E.g. you'd still need to supply all sources required to compile a given output, but the compiler would only generate the bytecode for that single contract if that is what you instruct it to do.
You wouldnt necessarily need all the source. You just need certain symbols and to craft interfaces that can be accessed from a certain address.
Monax currently does this with native contracts that are specified at the address "permissions_contract".
This whole issue assumes that there are inefficiencies at certain parts in the compiler. Let's first implement the selective compilation and then see if they are actually still there.
Hey, just putting my vote on this one.
Sometimes compiling tests in Forge can take forever if the optimizer is turned on, so we'd like the ability to split our compilation pipeline: first, compile non-test contracts with the optimizer on, and then compile the test contracts with the optimizer off, passing in the optimized bytecode for the non-test contracts.
We have a gas report feature that estimates the gas usage of different function calls using tracing, so most users probably want to compile their non-test contracts with the optimizer on, to get more realistic estimates.
The other benefit is that we can improve compilation speed in Forge as well.
Ref https://github.com/foundry-rs/foundry/issues/317
Would this be a hard feature to implement? If not, we'd be happy to try and take a look at some point, if this is something you want to add but do not have the bandwidth to.
Edit: I see there was some talk about the ABI not being enough for type information - this is true, but given the compiler can now be stopped at the parser stage(?) this might not be an issue anymore?
@onbjerg You might be interested in #11787. It's currently being implemented and will allow reimporting the EVM assembly output that the compiler can produce. Just to make sure - @aarlt - it will be possible to import unoptimized asm with --optimize
so that it gets optimized, right?
Also, in case of the viaIR
pipeline it's a bit more complicated because there are two optimization stages - Yul optimizer and then the EVM assembly optimization. You can already use the --ir
compiler output to get the unoptimized Yul and later continue the compilation for each file by passing it to solc --strict-assembly --optimize
.
@cameel thx for linking #11787 here. @onbjerg Yes, it will be possible to import unoptimised asm with --optimize
so that it gets optimized.
And I assume it would also be possible to include optimized bytecode in non-optimized bytecode that is not run through the optimizer?
@onbjerg Yes, that should work. For your use-case the built-in function verbatim
could be a interesting - see https://docs.soliditylang.org/en/v0.8.13/yul.html#verbatim.
This issue has been marked as stale due to inactivity for the last 90 days. It will be automatically closed in 7 days.
Hi everyone! This issue has been automatically closed due to inactivity. If you think this issue is still relevant in the latest Solidity version and you have something to contribute, feel free to reopen. However, unless the issue is a concrete proposal that can be implemented, we recommend starting a language discussion on the forum instead.
Right now the
solc
compiler can only intake the sources of solidity files/source maps. But when I'm compiling more than say, 15 contracts (which I do often, as many of us use the EVM/solc as a testing environment). The compile time takes forever, sometimes up to 10+ minutes depending on the source. Many of the contracts I'm compiling have already been compiled (and have not changed). Often times, I may only be changing one or two at most. So I'd like to request a bytecode input feature (if something like this is possible and doable).Usage:
This way, if the bytecode is presented for a specific contract, then it won't recompile the source, instead it will just use the source provided.
Optimizations like this allow us to have a faster environment to develop large Solidity applications. This way, the build environment can optimize compile time by presenting bytecode that often times does not change.
Thoughts?
One con/Fix:
Note, I also posted this issue in
solc-js
repo, not sure which was more appropriate.