CosmWasm / wasmvm

Go bindings to the running cosmwasm contracts with wasmer
Apache License 2.0
173 stars 99 forks source link

Let StoreCode (formally Create) consume its gas cost internally #395

Closed webmaster128 closed 7 months ago

webmaster128 commented 1 year ago

Right now a call to wasmVM.Create is free of charge. It is up to the caller to charge gas for the call. This is not ideal as Create should not make it easy to forget gas tracking and take responsibility for its own resource usage.

Wasmd charged Create gas here. In other places of wasmd the call is not charged, which is not a problem but you get the point:

$ git grep -C 5 "wasmVM.Create"
x/wasm/keeper/keeper.go-                        return 0, checksum, sdkerrors.Wrap(types.ErrCreateFailed, err.Error())
x/wasm/keeper/keeper.go-                }
x/wasm/keeper/keeper.go-        }
x/wasm/keeper/keeper.go-
x/wasm/keeper/keeper.go-        ctx.GasMeter().ConsumeGas(k.gasRegister.CompileCosts(len(wasmCode)), "Compiling wasm bytecode")
x/wasm/keeper/keeper.go:        checksum, err = k.wasmVM.Create(wasmCode)
x/wasm/keeper/keeper.go-        if err != nil {
x/wasm/keeper/keeper.go-                return 0, checksum, sdkerrors.Wrap(types.ErrCreateFailed, err.Error())
x/wasm/keeper/keeper.go-        }
x/wasm/keeper/keeper.go-        report, err := k.wasmVM.AnalyzeCode(checksum)
x/wasm/keeper/keeper.go-        if err != nil {
--
x/wasm/keeper/keeper.go-                wasmCode, err = ioutils.Uncompress(wasmCode, uint64(types.MaxWasmSize))
x/wasm/keeper/keeper.go-                if err != nil {
x/wasm/keeper/keeper.go-                        return sdkerrors.Wrap(types.ErrCreateFailed, err.Error())
x/wasm/keeper/keeper.go-                }
x/wasm/keeper/keeper.go-        }
x/wasm/keeper/keeper.go:        newCodeHash, err := k.wasmVM.Create(wasmCode)
x/wasm/keeper/keeper.go-        if err != nil {
x/wasm/keeper/keeper.go-                return sdkerrors.Wrap(types.ErrCreateFailed, err.Error())
x/wasm/keeper/keeper.go-        }
x/wasm/keeper/keeper.go-        if !bytes.Equal(codeInfo.CodeHash, newCodeHash) {
x/wasm/keeper/keeper.go-                return sdkerrors.Wrap(types.ErrInvalid, "code hashes not same")
--
x/wasm/keeper/snapshotter.go-   if err != nil {
x/wasm/keeper/snapshotter.go-           return sdkerrors.Wrap(types.ErrCreateFailed, err.Error())
x/wasm/keeper/snapshotter.go-   }
x/wasm/keeper/snapshotter.go-
x/wasm/keeper/snapshotter.go-   // FIXME: check which codeIDs the checksum matches??
x/wasm/keeper/snapshotter.go:   _, err = k.wasmVM.Create(wasmCode)
x/wasm/keeper/snapshotter.go-   if err != nil {
x/wasm/keeper/snapshotter.go-           return sdkerrors.Wrap(types.ErrCreateFailed, err.Error())
x/wasm/keeper/snapshotter.go-   }
x/wasm/keeper/snapshotter.go-   return nil
x/wasm/keeper/snapshotter.go-}

Other functions have gas metering and track their gas usage internally, maybe given cost configuration like deserialization cost, like here:

https://github.com/CosmWasm/wasmvm/blob/825dceaacd28f72bb6cf622a164991c5dade125c/lib.go#L161-L201

This addresses this comment: https://github.com/CosmWasm/wasmvm/blob/825dceaacd28f72bb6cf622a164991c5dade125c/lib.go#L58