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

eth: make duktape dependency optional #20590

Closed
mvdan opened this issue Jan 24, 2020 · 9 comments
Closed

eth: make duktape dependency optional #20590

mvdan opened this issue Jan 24, 2020 · 9 comments
Assignees

Comments

@mvdan
Copy link

mvdan commented Jan 24, 2020

Apologies for skipping the issue template, but this isn't a bug with go-ethereum per se.

Depending on github.com/ethereum/go-ethereum/eth is pretty basic. Unfortunately, it pulls in a pretty heavy cgo dependency:

$ go list -m github.com/ethereum/go-ethereum
github.com/ethereum/go-ethereum v1.9.9
$ go mod why gopkg.in/olebedev/go-duktape.v3
# gopkg.in/olebedev/go-duktape.v3
gitlab.com/vocdoni/go-dvote/chain
github.com/ethereum/go-ethereum/eth
github.com/ethereum/go-ethereum/eth/tracers
gopkg.in/olebedev/go-duktape.v3

For some quick numbers - most Go packages in a regularly sized project build in under two seconds on my laptop, and they mostly build in parallel with other packages. However, go-duktape takes a whopping 25s to build on the same laptop, supposedly because it has a lot of C code to build without any parallelism.

We could make this faster in the Go toolchain, by building cgo files in parallel (golang/go#9887). However, I doubt that would help much. The vast majority of the duktape codebase is in a single C file clocking in at almost four megabytes: https://github.com/olebedev/go-duktape/blob/v3/duktape.c

The bottom line is that duktape is a heavy cgo dependency, and there currently isn't a way around it. Is it truly a core part of go-ethereum? Assuming that it is not, could it be removed from the dependency tree when one simply imports the "core" packages?

If it is absolutely necessary for the core packages, I think you still have other options:

  • Consider alternatives, such as pure-Go javascript engines (was performance a factor here?)
  • Use build tags to enable/disable duktape, similar to math/big's -tags=math_big_pure_go
  • Allow building go-ethereum with CGO_ENABLED=0, which currently fails due to duktape not building
@mvdan
Copy link
Author

mvdan commented Jan 24, 2020

To further drive why the 25s sequential build time is painful: the project in question builds from scratch in a total of 40s or so, including link time. Given that the Go linker is going to get significantly faster soon, I assume the last chunk of linker work will get smaller. This will leave us with duktape being to blame for why over half of the build time is only using one CPU, being a bottleneck for the overall build time.

@karalabe
Copy link
Member

Duktape isn't necessary for your average Ethereum node, however it is used by transaction tracing. The reason we went with it is to allow anyone to upload their own .js tracing script instead of relying on us to build and maintain all the possible tracers in Go ourselves. And yes, you hit the nail on the head, it's used due to performance reasons (an order of magnitude faster than Otto).

I don't think we can nuke it out altogether, but I think adding an optional build tag to disable it could be easy enough if someone knows what they are doing. Will look into how much pain it would be to disable tracing via a tag.

@karalabe karalabe self-assigned this Jan 24, 2020
@mvdan
Copy link
Author

mvdan commented Jan 24, 2020

Sounds good - thanks for considering this :)

@mvdan
Copy link
Author

mvdan commented Jan 25, 2020

Another drive-by thought - would it be possible to keep it entirely out of the dependency tree of the eth package? For example, if a user needs transaction tracing, they can explicitly underscore-import a package that pulls in duktape and enables that feature.

Or, perhaps, have the default be pure Go (Otto?) and use an underscore import to switch to duktape for performance.

@fjl
Copy link
Contributor

fjl commented Feb 2, 2020

The fundamental issue here is that package eth depends on eth/tracers, the only reason being that the eth.Ethereum.APIs callback function returns the tracer API handler. APIs is needed to satisfy the node.Service interface.

To remove the dependency, the path requiring the least amount of changes is refactoring eth/tracers into its own Service. This will require changes in cmd/geth to also register the new service with the node.Node instance.

@mvdan
Copy link
Author

mvdan commented Mar 13, 2020

I personally think that would be great. In my opinion, heavy CGo dependencies such as duktape should be opt-in. That is, one should have to explicitly add it to the import graph.

@mvdan
Copy link
Author

mvdan commented Apr 14, 2020

For what it's worth, we ended up with a temporary workaround which was to do a go mod edit -replace to replace the real duktape with a stub implementation: https://gitlab.com/vocdoni/go-dvote/-/blob/master/duktape-stub/stub.go

Still, that's only a hacky solution that works when we do local builds, so a more general solution for any Go package would be better, such as making the import opt-in.

@ligi
Copy link
Member

ligi commented Nov 19, 2020

In general this would be great to have.
The tracing APIs should move to the tracers package. It is now easier after the node refactoring by @renaynay

@holiman
Copy link
Contributor

holiman commented Nov 3, 2021

I think this is fixed:

$ go mod why gopkg.in/olebedev/go-duktape.v3
# gopkg.in/olebedev/go-duktape.v3
github.com/ethereum/go-ethereum/eth/tracers
gopkg.in/olebedev/go-duktape.v3

@holiman holiman closed this as completed Nov 3, 2021
mvdan added a commit to mvdan/go-dvote that referenced this issue Nov 25, 2022
Since ethereum/go-ethereum#20590 was fixed
last year, the core go-ethereum package no longer pulls in go-duktape.
We can see this because neither our go.mod nor go.sum mention duktape.
jordipainan pushed a commit to vocdoni/vocdoni-node that referenced this issue Nov 28, 2022
Since ethereum/go-ethereum#20590 was fixed
last year, the core go-ethereum package no longer pulls in go-duktape.
We can see this because neither our go.mod nor go.sum mention duktape.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants