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

Gas management, estimation, limitation #963

Merged
merged 32 commits into from
May 16, 2018
Merged

Conversation

cwgoes
Copy link
Contributor

@cwgoes cwgoes commented May 7, 2018

Ref #962

See questions on issue.

@codecov
Copy link

codecov bot commented May 8, 2018

Codecov Report

Merging #963 into develop will increase coverage by 0.44%.
The diff coverage is 70%.

@@             Coverage Diff             @@
##           develop     #963      +/-   ##
===========================================
+ Coverage    60.28%   60.73%   +0.44%     
===========================================
  Files           74       75       +1     
  Lines         3591     3716     +125     
===========================================
+ Hits          2165     2257      +92     
- Misses        1256     1288      +32     
- Partials       170      171       +1

@cwgoes
Copy link
Contributor Author

cwgoes commented May 8, 2018

Basic gas accounting implemented. Module structure could be cleaned up a bit.

Currently gas costs are fixed constants in files, probably should be governance parameters modifiable with ParameterChangeProposals.

if err != nil {
result = err.Result()
}
result = app.runTx(true, true, txBytes, tx)
Copy link
Member

Choose a reason for hiding this comment

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

I think we can do this through Query, but we can't just use runTx as is because we want a fresh throw-away state to run the simulation against.

If we do it as is, it will update our checktx state, which sounds appealing, but might not be good because then when we try to add it to the tendermint mempool it will call check tx and possibly fail (since the tx was already executed against the checktx state in the app without tendermint knowing).

So we probably need to refactor runTx to take a ctx so we can pass in the ctx we want and create something fresh every time simulate is called that just gets thrown away after.

Of course this also means that we cant run muiltiple dependent simulate in a row without waiting for block commits.

An alternative option would be to open another connection between Tendermint and App and expose that over the Tendermitn RPC but that would be much more involved ...

@jaekwon

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Presently, runTx with the simulateDeliver flag doesn't write to the multistore -94c00a3.

@cwgoes
Copy link
Contributor Author

cwgoes commented May 10, 2018

Ref #979, now also addressed (not p2p queries though)

@cwgoes
Copy link
Contributor Author

cwgoes commented May 10, 2018

To-do:

  • Fix cross-dependency issue (why gaskvstore is in /types)
  • Add testcases
  • Update docs

@cwgoes cwgoes changed the title WIP: Gas management, estimation, limitation Gas management, estimation, limitation May 11, 2018
@cwgoes cwgoes requested a review from rigelrozanski May 11, 2018 18:28
@cwgoes
Copy link
Contributor Author

cwgoes commented May 11, 2018

Ready for first-pass review @rigelrozanski @ebuchman

@cwgoes
Copy link
Contributor Author

cwgoes commented May 11, 2018

Also @sunnya97 all the gas costs should be governance-controlled parameters once governance is merged (glad to help).

@@ -27,6 +28,7 @@ type BaseApp struct {
// initialized on creation
Logger log.Logger
name string // application name from abci.Info
codec *wire.Codec // Amino codec
Copy link
Contributor

Choose a reason for hiding this comment

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

let's stick to cdc ? that's everywhere really

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated to cdc.

@cwgoes cwgoes changed the title Gas management, estimation, limitation WIP: Gas management, estimation, limitation May 14, 2018
@cwgoes
Copy link
Contributor Author

cwgoes commented May 14, 2018

Would be nice to add crypto wrapper operations with gas costs - however, a bit complex because the go-crypto PubKey interface abstracts over the underlying type. We could modify PubKey to include gas, or just have modules set gas costs themselves - the latter is done now, as only x/auth performs crypto operations.

@cwgoes cwgoes changed the title WIP: Gas management, estimation, limitation Gas management, estimation, limitation May 15, 2018
@cwgoes
Copy link
Contributor Author

cwgoes commented May 15, 2018

Now includes p2p query functions, ref #979

ebuchman
ebuchman previously approved these changes May 15, 2018
Copy link
Member

@ebuchman ebuchman left a comment

Choose a reason for hiding this comment

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

Thanks Chris. This looks great - most comments can be later TODOs, but I think it would be nice if we didn't add gasLimit to NewBaseApp

msg := "application doesn't support queries"
return sdk.ErrUnknownRequest(msg).QueryResult()
path := req.Path
// "/app" prefix for special application queries
Copy link
Member

Choose a reason for hiding this comment

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

What if we ran strings.Split on / and switched on it ? Would be nice not to slice strings with magic numbers everywhere

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed, updated.

}

// txBytes may be nil in some cases, eg. in tests.
// Also, in the future we may support "internal" transactions.
func (app *BaseApp) runTx(isCheckTx bool, txBytes []byte, tx sdk.Tx) (result sdk.Result) {
func (app *BaseApp) runTx(isCheckTx bool, simulateDeliver bool, txBytes []byte, tx sdk.Tx) (result sdk.Result) {
Copy link
Member

Choose a reason for hiding this comment

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

maybe runTx should take a runMode, an enum for checkTx, simulateDeliver, etc. Though probably premature until we know an actual third kind of runTx we need to support - ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We already have three: check, simulate, deliver. Updated to use an enum.

func (gi *gasKVStore) Get(key []byte) (value []byte) {
gi.gasMeter.ConsumeGas(ReadCostFlat, "GetFlat")
value = gi.parent.Get(key)
// TODO overflow-safe math?
Copy link
Member

Choose a reason for hiding this comment

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

lets open an issue for it

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ref #869

x/bank/keeper.go Outdated
@@ -108,6 +108,7 @@ func (keeper ViewKeeper) HasCoins(ctx sdk.Context, addr sdk.Address, amt sdk.Coi
//______________________________________________________________________________________________

func getCoins(ctx sdk.Context, am sdk.AccountMapper, addr sdk.Address) sdk.Coins {
ctx.GasMeter().ConsumeGas(10, "getCoins")
Copy link
Member

Choose a reason for hiding this comment

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

let's get a list of constants for these ... possibly parameters one day ...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Switched to constants at top of file. Also, these gas costs are probably wrong / may be unnecessary with the GasKVStore.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@@ -398,6 +485,14 @@ func (app *BaseApp) runTx(isCheckTx bool, txBytes []byte, tx sdk.Tx) (result sdk
ctx = app.deliverState.ctx.WithTxBytes(txBytes)
}

// Create a new zeroed gas meter
ctx = ctx.WithGasMeter(sdk.NewGasMeter(app.txGasLimit))
Copy link
Member

Choose a reason for hiding this comment

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

doesn't the gas meter need to use the gas provided in the tx, rather than this app level limit ? Perhaps we need to do this set up in the anteHandler

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, this is wrong, thanks. Switched to ante handler.

Do we also need to check that tx.Fee.Gas <= app.txGasLimit, or will Tendermint do that for us?

Copy link
Member

Choose a reason for hiding this comment

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

we'll need to #1007

@@ -57,15 +62,17 @@ var _ abci.Application = (*BaseApp)(nil)

// Create and name new BaseApp
// NOTE: The db is used to store the version number for now.
func NewBaseApp(name string, cdc *wire.Codec, logger log.Logger, db dbm.DB) *BaseApp {
func NewBaseApp(name string, cdc *wire.Codec, logger log.Logger, db dbm.DB, txGasLimit sdk.Gas) *BaseApp {
Copy link
Member

Choose a reason for hiding this comment

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

Seems strange that txGasLimit would become so first class as to be an arg to NewBaseApp - is there a good reason for this ?

Also, BaseApp should probably have a ConsensusParams that mirrors Tendermint's - MaxGasPerTx is part of that , gets initialized by InitChain, and can be updated by EndBlock. Then we shouldnt need to pass txGasLimit in everywhere.

In the meantime anyways I'd rather use setters and defaults than add function args

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed on ConsensusParams, made an issue: #1007

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed txGasLimit, if Tendermint enforces that we may not need it at all actually.

@cwgoes
Copy link
Contributor Author

cwgoes commented May 16, 2018

Ref #1008

if len(path) > 0 && path[0] == "" {
path = path[1:]
}
fmt.Sprintf("Path: %v\n", path)
Copy link
Member

Choose a reason for hiding this comment

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

remove

@@ -210,9 +233,9 @@ func (app *BaseApp) initFromStore(mainKey sdk.StoreKey) error {
// NewContext returns a new Context with the correct store, the given header, and nil txBytes.
func (app *BaseApp) NewContext(isCheckTx bool, header abci.Header) sdk.Context {
if isCheckTx {
return sdk.NewContext(app.checkState.ms, header, true, nil, app.Logger)
return sdk.NewContext(app.checkState.ms, header, true, nil, app.Logger, 0)
Copy link
Member

Choose a reason for hiding this comment

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

can we remove passing the gaslimit here too ? Seems like we're not using it anymore (InfiniteGasMeter ?)

@ebuchman
Copy link
Member

I can finish up and merge this, thanks!

@ebuchman ebuchman merged commit e6d21c6 into develop May 16, 2018
@ebuchman ebuchman deleted the cwgoes/gas-guzzling branch May 16, 2018 02:19
This was referenced May 16, 2018
chillyvee pushed a commit to chillyvee/cosmos-sdk that referenced this pull request Mar 1, 2024
there is no version 4.6.2, 4.2.1 is the latest 4.x release
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.

3 participants