Skip to content

Commit

Permalink
Merge pull request #149 from CosmWasm/gas-for-each-instance
Browse files Browse the repository at this point in the history
Gas for each instance
  • Loading branch information
ethanfrey authored Jun 23, 2020
2 parents 1fd9192 + 420f3e2 commit c1db37b
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 2 deletions.
17 changes: 17 additions & 0 deletions x/wasm/internal/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ const GasMultiplier = 100
// MaxGas for a contract is 900 million (enforced in rust)
const MaxGas = 900_000_000

// InstanceCost is how much SDK gas we charge each time we load a WASM instance.
// Creating a new instance is costly, and this helps put a recursion limit to contracts calling contracts.
const InstanceCost uint64 = 40_000

// CompileCost is how much SDK gas we charge *per byte* for compiling WASM code.
const CompileCost uint64 = 2

// Keeper will have a reference to Wasmer with it's own data directory.
type Keeper struct {
storeKey sdk.StoreKey
Expand Down Expand Up @@ -73,6 +80,8 @@ func (k Keeper) Create(ctx sdk.Context, creator sdk.AccAddress, wasmCode []byte,
if err != nil {
return 0, sdkerrors.Wrap(types.ErrCreateFailed, err.Error())
}
ctx.GasMeter().ConsumeGas(CompileCost*uint64(len(wasmCode)), "Compiling WASM Bytecode")

codeHash, err := k.wasmer.Create(wasmCode)
if err != nil {
// return 0, sdkerrors.Wrap(err, "cosmwasm create")
Expand All @@ -89,6 +98,8 @@ func (k Keeper) Create(ctx sdk.Context, creator sdk.AccAddress, wasmCode []byte,

// Instantiate creates an instance of a WASM contract
func (k Keeper) Instantiate(ctx sdk.Context, codeID uint64, creator, admin sdk.AccAddress, initMsg []byte, label string, deposit sdk.Coins) (sdk.AccAddress, error) {
ctx.GasMeter().ConsumeGas(InstanceCost, "Loading CosmWasm module: init")

// create contract address
contractAddress := k.generateContractAddress(ctx, codeID)
existingAcct := k.accountKeeper.GetAccount(ctx, contractAddress)
Expand Down Expand Up @@ -159,6 +170,8 @@ func (k Keeper) Instantiate(ctx sdk.Context, codeID uint64, creator, admin sdk.A

// Execute executes the contract instance
func (k Keeper) Execute(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.AccAddress, msg []byte, coins sdk.Coins) (*sdk.Result, error) {
ctx.GasMeter().ConsumeGas(InstanceCost, "Loading CosmWasm module: execute")

codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddress)
if err != nil {
return nil, err
Expand Down Expand Up @@ -201,6 +214,8 @@ func (k Keeper) Execute(ctx sdk.Context, contractAddress sdk.AccAddress, caller

// Migrate allows to upgrade a contract to a new code with data migration.
func (k Keeper) Migrate(ctx sdk.Context, contractAddress sdk.AccAddress, caller sdk.AccAddress, newCodeID uint64, msg []byte) (*sdk.Result, error) {
ctx.GasMeter().ConsumeGas(InstanceCost, "Loading CosmWasm module: migrate")

contractInfo := k.GetContractInfo(ctx, contractAddress)
if contractInfo == nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "unknown contract")
Expand Down Expand Up @@ -267,6 +282,8 @@ func (k Keeper) UpdateContractAdmin(ctx sdk.Context, contractAddress sdk.AccAddr

// QuerySmart queries the smart contract itself.
func (k Keeper) QuerySmart(ctx sdk.Context, contractAddr sdk.AccAddress, req []byte) ([]byte, error) {
ctx.GasMeter().ConsumeGas(InstanceCost, "Loading CosmWasm module: query")

ctx = ctx.WithGasMeter(sdk.NewGasMeter(k.queryGasLimit))

codeInfo, prefixStore, err := k.contractInstance(ctx, contractAddr)
Expand Down
4 changes: 2 additions & 2 deletions x/wasm/internal/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ func TestInstantiate(t *testing.T) {
require.Equal(t, "cosmos18vd8fpwxzck93qlwghaj6arh4p7c5n89uzcee5", addr.String())

gasAfter := ctx.GasMeter().GasConsumed()
require.Equal(t, uint64(0x78c3), gasAfter-gasBefore)
require.Equal(t, uint64(0x11503), gasAfter-gasBefore)

// ensure it is stored properly
info := keeper.GetContractInfo(ctx, addr)
Expand Down Expand Up @@ -298,7 +298,7 @@ func TestExecute(t *testing.T) {

// make sure gas is properly deducted from ctx
gasAfter := ctx.GasMeter().GasConsumed()
require.Equal(t, uint64(0x7f9e), gasAfter-gasBefore)
require.Equal(t, uint64(0x11bde), gasAfter-gasBefore)

// ensure bob now exists and got both payments released
bobAcct = accKeeper.GetAccount(ctx, bob)
Expand Down

0 comments on commit c1db37b

Please sign in to comment.