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

fix(gno.land): pre-load all standard libraries in vm.Initialize #2504

Merged
merged 17 commits into from
Jul 6, 2024

Conversation

thehowl
Copy link
Member

@thehowl thehowl commented Jul 4, 2024

Fixes #2283 (with a different approach from #2319)

This PR loads all the standard libraries into the database when vm.Initialize is called. It doesn't fully fix the problems that #2319 is trying to address, but it does fix the most immediate bug of not being able to publish certain packages on portal loop.

With these changes, we don't need a PackageGetter on-chain anymore. All packages are already loaded into the store, thus solving the problem @jaekwon was talking about here at its root.

This PR has a problem, which is that adding loading the entire stdlibs in the VM initialization step brings a huge overhead computationally; this is not a problem on the node, but it is when testing as it needs to happen very often. This translates to 2x slower txtar tests, compared to master. On my PC, it adds a 2-3 second overhead whenever running Initialize.

I tried working out on a system which could save the data to quickly recover it, at least for some cases where we need to Initialize often; see this diff. But I didn't get it to work so far; after copying the DB, attempting initialization crashes because ParseMemPackage is being handed a nil package, for some reason. @gfanton, any tips?? :)) I'd want to avoid lazy loading in the node, as that's what got us here in the first place.

Contributors' checklist...
  • Added new tests, or not needed, or not feasible
  • Provided an example (e.g. screenshot) to aid review or the PR is self-explanatory
  • Updated the official documentation or not needed
  • No breaking changes were made, or a BREAKING CHANGE: xxx message was included in the description
  • Added references to related issues and PRs
  • Provided any useful hints for running manual tests
  • Added new benchmarks to generated graphs, if any. More info here.

@thehowl thehowl self-assigned this Jul 4, 2024
@github-actions github-actions bot added 📦 🤖 gnovm Issues or PRs gnovm related 📦 ⛰️ gno.land Issues or PRs gno.land package related labels Jul 4, 2024
Copy link

codecov bot commented Jul 4, 2024

Codecov Report

Attention: Patch coverage is 74.35897% with 40 lines in your changes missing coverage. Please review.

Project coverage is 54.75%. Comparing base (1c162de) to head (2bfba4b).

Files Patch % Lines
misc/genstd/walk.go 50.00% 7 Missing and 6 partials ⚠️
gno.land/pkg/sdk/vm/keeper.go 83.87% 7 Missing and 3 partials ⚠️
gnovm/pkg/gnolang/store.go 0.00% 6 Missing ⚠️
misc/genstd/util.go 62.50% 2 Missing and 1 partial ⚠️
gno.land/pkg/gnoland/app.go 0.00% 2 Missing ⚠️
gnovm/stdlibs/generated.go 0.00% 2 Missing ⚠️
gnovm/tests/stdlibs/generated.go 0.00% 2 Missing ⚠️
gno.land/pkg/gnoland/node_inmemory.go 0.00% 1 Missing ⚠️
misc/genstd/genstd.go 92.85% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #2504      +/-   ##
==========================================
+ Coverage   54.70%   54.75%   +0.04%     
==========================================
  Files         590      592       +2     
  Lines       79036    79150     +114     
==========================================
+ Hits        43236    43337     +101     
+ Misses      32550    32545       -5     
- Partials     3250     3268      +18     
Flag Coverage Δ
contribs/gnodev 23.42% <ø> (-0.39%) ⬇️
contribs/gnofaucet 14.46% <ø> (ø)
contribs/gnokeykc 0.00% <ø> (ø)
contribs/gnomd 0.00% <ø> (ø)
gnovm 59.79% <0.00%> (-0.03%) ⬇️
misc/autocounterd 0.00% <ø> (ø)
misc/genproto 0.00% <ø> (ø)
misc/genstd 80.54% <78.48%> (+6.64%) ⬆️
misc/goscan 0.00% <ø> (ø)
misc/logos 17.38% <ø> (ø)
misc/loop 0.00% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@thehowl thehowl marked this pull request as ready for review July 4, 2024 15:31
misc/devdeps/go.mod Outdated Show resolved Hide resolved
gno.land/pkg/sdk/vm/keeper.go Outdated Show resolved Hide resolved
gno.land/pkg/sdk/vm/keeper.go Outdated Show resolved Hide resolved
Copy link
Member

@moul moul left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you don't completely remove the support of packagegetter, and your fix mostly occurs in gno.land's vmkeepr, I favor merging this. Then, we can focus on speeding up local tests and take more time to fix the underlying caching issues that could still occur.

Pinging @jaekwon for a complementary review.

@jaekwon
Copy link
Contributor

jaekwon commented Jul 4, 2024

general approach seems good.

@thehowl
Copy link
Member Author

thehowl commented Jul 5, 2024

I did it 😃

I implemented a cache mechanism, which keeps the writes to the iavlStore and the baseStore in a separated database, as well as an instance of the gno store, and then simply copies them after the first time. On my machine, this leads to a "cold" load of ~2.6 seconds, followed by hot loads of ~45 ms!

As a consequence, the CI is now in line with the results on master :) if not some ~20 seconds faster (hard to tell, could be statistical error). In theory, it should be faster, as now any tests that import standard libraries won't have to spend time loading them on-the-fly; and can instead just use the cached data.

ping for a last review @jaekwon @moul

gno.land/pkg/sdk/vm/keeper.go Outdated Show resolved Hide resolved
gno.land/pkg/sdk/vm/keeper.go Outdated Show resolved Hide resolved
gno.land/pkg/sdk/vm/keeper.go Show resolved Hide resolved
misc/genstd/package_sort_test.go Show resolved Hide resolved
@moul moul enabled auto-merge (squash) July 5, 2024 20:53
@moul moul merged commit f28444a into master Jul 6, 2024
110 of 111 checks passed
@moul moul deleted the dev/morgan/preload-stdlibs branch July 6, 2024 07:37
gfanton pushed a commit to gfanton/gno that referenced this pull request Jul 23, 2024
…ang#2504)

Fixes gnolang#2283 (with a different approach from gnolang#2319)

This PR loads all the standard libraries into the database when
vm.Initialize is called. It doesn't fully fix the problems that gnolang#2319 is
trying to address, but it does fix the most immediate bug of not being
able to publish certain packages on portal loop.

With these changes, we don't need a PackageGetter on-chain anymore. All
packages are already loaded into the store, thus solving the problem
@jaekwon was talking about
[here](gnolang#2319 (comment))
at its root.

This PR has a problem, which is that adding loading the entire stdlibs
in the VM initialization step brings a huge overhead computationally;
this is not a problem on the node, but it is when testing as it needs to
happen very often. This translates to 2x slower txtar tests, compared to
master. On my PC, it adds a 2-3 second overhead whenever running
Initialize.

I tried working out on a system which could save the data to quickly
recover it, at least for some cases where we need to Initialize often;
[see this
diff](https://gist.github.com/thehowl/cb1ee79e63cf77d3f323730580eb2d18).
But I didn't get it to work so far; after copying the DB, attempting
initialization crashes because [ParseMemPackage is being handed a nil
package, for some
reason](https://gist.github.com/thehowl/d1efa51858d865fb5beb9c3a9cb0eeef).
@gfanton, any tips?? :)) I'd want to avoid lazy loading in the node, as
that's what got us here in the first place.

<details><summary>Contributors' checklist...</summary>

- [ ] Added new tests, or not needed, or not feasible
- [x] Provided an example (e.g. screenshot) to aid review or the PR is
self-explanatory
- [x] Updated the official documentation or not needed
- [x] No breaking changes were made, or a `BREAKING CHANGE: xxx` message
was included in the description
- [x] Added references to related issues and PRs
- [x] Provided any useful hints for running manual tests
- [x] Added new benchmarks to [generated
graphs](https://gnoland.github.io/benchmarks), if any. More info
[here](https://github.com/gnolang/gno/blob/master/.benchmarks/README.md).
</details>

---------

Co-authored-by: Manfred Touron <94029+moul@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
📦 ⛰️ gno.land Issues or PRs gno.land package related 📦 🤖 gnovm Issues or PRs gnovm related
Projects
Status: Done
Status: ✅ Done
4 participants