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

Ethanfrey/4938 better gas estimation #6635

Conversation

ethanfrey
Copy link
Contributor

Description

This is a WIP - investigation to share.

Closes #4938

Findings

To reproduce:

cd x/bank
go test -v . -run TestSendGas

I made a test in bank to simulate tx and submit it. The gas numbers from simulation were (very slightly) higher than the real gas numbers from deliver. I tried two tx and there was a clear difference due to the first having the public key and slightly larger txbytes.

However, I tried running:

simGas0 := Simulate(tx)
simGas1 := Simulate(tx2)

Check(tx)
Check(tx2)

resimGas0 := Simulate(tx)
resimGas1 := SImulate(tx2)

simGas0 - simGas1 = 300 (txbytes)

resimGas0 - resimGas1 = 300 (txBytes)

simGas0 - resimGas0 = 4400 (why?)

< --- consumed 135 gas for 'ReadPerByte' ---
< --- consumed 2000 gas for 'WriteFlat' ---
< --- consumed 2550 gas for 'WritePerByte' ---
---
> --- consumed 261 gas for 'ReadPerByte' ---
39c37
< --- consumed 255 gas for 'ReadPerByte' ---
---
> --- consumed 261 gas for 'ReadPerByte' ---
51c49
< --- consumed 255 gas for 'ReadPerByte' ---
---
> --- consumed 261 gas for 'ReadPerByte' ---
54c52
< --- consumed 255 gas for 'ReadPerByte' ---
---
> --- consumed 261 gas for 'ReadPerByte' ---
56c54
< --- consumed 255 gas for 'ReadPerByte' ---
---
> --- consumed 261 gas for 'ReadPerByte' ---
77c75
< Sim 0 used: 55951
---
> Re-Sim 0 (after check) used: 51551

It seems like something being read a lot is slightly smaller (and why do we read it so much)?
It also seems like there is a large write that is not triggered after a CheckTx has run: consumed 2000 gas for 'WriteFlat' --- consumed 2550 gas for 'WritePerByte'.

This is all a bit more confusing than the original issue suggests and I think writing the cache will not do anything (I did add a separate simulateState, that was parallel to checkState, but that didn't help - got some sequence errors when I removed a level of caching even.

Anyway... if someone else wants to wrack their brains....

Before we can merge this PR, please make sure that all the following items have been
checked off. If any of the checklist items are not applicable, please leave them but
write a little note why.

  • Targeted PR against correct branch (see CONTRIBUTING.md)
  • Linked to Github issue with discussion and accepted design OR link to spec that describes this work.
  • Code follows the module structure standards.
  • Wrote unit and integration tests
  • Updated relevant documentation (docs/) or specification (x/<module>/spec/)
  • Added relevant godoc comments.
  • Added a relevant changelog entry to the Unreleased section in CHANGELOG.md
  • Re-reviewed Files changed in the Github PR explorer
  • Review Codecov Report in the comment section below once CI passes

@ethanfrey ethanfrey force-pushed the ethanfrey/4938-better-gas-estimation branch from 4ee54da to 8c53084 Compare July 8, 2020 08:00
@ethanfrey
Copy link
Contributor Author

ethanfrey commented Jul 8, 2020

I got curious as to where all the reads/writes came from for the 50k gas for a simple send (and why the two were different).

Here is some logging of the gas-charged writes

I would love an eye from someone of the core team to explain what all this is - and then I can make better sense of the differences between deliver and simulate.

Note; only the section under ******************* NEW LIMITED ***************** with all the *** is actually related to the transaction delivery. That is still a lot. And everything else going on in this block???

@alexanderbez
Copy link
Contributor

Thanks for looking into this @ethanfrey.

Trying to grok this, and correct me if I'm wrong, simulating (with the current code) tx after CheckTx yields a significantly smaller estimation compared to before CheckTx (diff of 4400)? The 4400 diff here comes from a WriteFlat and a WritePerByte that occurred before CheckTx, correct? In other words, the large discrepancy comes from the fact that we're not writing something after CheckTx has happened?

AFAICT, simulate (via query) and CheckTx run nearly identical execution paths and actually share the same state (checkState). My guess would be that executing simulate (via query) yields some writes to checkState, which are then cached, so that on the subsequent CheckTx, there isn't a need to write something. This is the only thing I can think of...

But my original proposal was to use a separate (third) state object, queryState where I believe you'd end up writing, so the gas estimation should be near the same if not identical?

@alexanderbez
Copy link
Contributor

Also, I don't see any commits of the actual proposal...

@ethanfrey ethanfrey force-pushed the ethanfrey/4938-better-gas-estimation branch from 8c53084 to eab1252 Compare July 8, 2020 21:32
@ethanfrey
Copy link
Contributor Author

ethanfrey commented Jul 8, 2020

Trying to grok this, and correct me if I'm wrong, simulating (with the current code) tx after CheckTx yields a significantly smaller estimation compared to before CheckTx (diff of 4400)? The 4400 diff here comes from a WriteFlat and a WritePerByte that occurred before CheckTx, correct? In other words, the large discrepancy comes from the fact that we're not writing something after CheckTx has happened?

Yes, that is right.

I reverted some changes digging into gas stuff to see if I messed them up. I am pushing it back to a version that:

  1. eab1252 - uses a separate simulate state to avoid CheckTx interference
  2. f74ab1c - implements the proposed fix (msCache.Write() for runTxSimulate as well)

In both cases I still get the issue that:

pregas := app.Simulate(tx)
pregas2 := app.Simulate(tx)
app.Check(tx)
pregas3 := app.Simulate(tx)

pregas == pregas2 (good) but pregas != pregas3 (not so cool)

If I can't even fix this minor issue, I doubt I can get consistent simulation results.

To reproduce, please check out this branch and do the following:

go test ./x/bank -v -count 1 -run TestSendGas

@alessio alessio added this to the 0.39.0 [launchpad] milestone Jul 10, 2020
@clevinson
Copy link
Contributor

@ethanfrey thanks for digging into this. If you're not planning on further work on this can you close the PR, or note in the description that this is not being investigated further?

@ethanfrey
Copy link
Contributor Author

Bez wanted to see what I got to.

I'd be happy for him to close this pr after he takes a look (and maybe figures out some error in my test code that makes everything interact)

@alexanderbez
Copy link
Contributor

Yes pls keep this PR around. I'd like to get to the bottom of this. As much as I hoped this would be an easy win for us, I just don't think we have the bandwidth to get this into launchpad. We obviously have some things we can do here, but just not for launchpad. Please keep the PR open, I'll review and test accordingly.

@ethanfrey
Copy link
Contributor Author

I thought it would be easier too.

I can rebase to master when master is stable, then keep this as an investigation for (post)stargate

@alessio alessio removed this from the 0.39.0 [launchpad] milestone Jul 11, 2020
@alessio alessio closed this Jul 15, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants