Charge gas per instance created

This commit is contained in:
Ethan Frey
2020-06-22 21:05:31 +02:00
parent 1fd919287c
commit 751ce5a9bf

View File

@@ -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
@@ -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")
@@ -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)
@@ -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
@@ -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")
@@ -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)