Skip to content

Commit

Permalink
Add gas limit to StoreCode
Browse files Browse the repository at this point in the history
  • Loading branch information
chipshort committed Jan 25, 2024
1 parent 84376e8 commit 8adad24
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 18 deletions.
3 changes: 2 additions & 1 deletion cmd/demo/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package main

import (
"fmt"
"math"
"os"

wasmvm "github.com/CosmWasm/wasmvm"
Expand Down Expand Up @@ -44,7 +45,7 @@ func main() {
panic(err)
}

checksum, _, err := vm.StoreCode(bz)
checksum, _, err := vm.StoreCode(bz, math.MaxUint64)
if err != nil {
panic(err)
}
Expand Down
6 changes: 3 additions & 3 deletions docs/MIGRATING.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@
two `VM` instances operate on the same directory in parallel. This was
unsupported before already but now leads to an error early on. When doing
parallel testing, use a different directory for each instance.
- `VM.StoreCode` now returns a `uint64` containing the gas cost in CosmWasm gas.
This was previously calculated in wasmd. The change brings consistency with
the other functions that cause gas usage.
- `VM.StoreCode` now returns a `uint64` containing the gas cost in CosmWasm gas
and takes a gas limit as argument. This was previously calculated in wasmd.
The change brings consistency with the other functions that cause gas usage.

## Renamings

Expand Down
6 changes: 3 additions & 3 deletions ibc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func TestIBC(t *testing.T) {
wasm, err := os.ReadFile(IBC_TEST_CONTRACT)
require.NoError(t, err)

checksum, _, err := vm.StoreCode(wasm)
checksum, _, err := vm.StoreCode(wasm, TESTING_GAS_LIMIT)
require.NoError(t, err)

code, err := vm.GetCode(checksum)
Expand Down Expand Up @@ -295,7 +295,7 @@ func TestAnalyzeCode(t *testing.T) {
// Store non-IBC contract
wasm, err := os.ReadFile(HACKATOM_TEST_CONTRACT)
require.NoError(t, err)
checksum, _, err := vm.StoreCode(wasm)
checksum, _, err := vm.StoreCode(wasm, TESTING_GAS_LIMIT)
require.NoError(t, err)
// and analyze
report, err := vm.AnalyzeCode(checksum)
Expand All @@ -307,7 +307,7 @@ func TestAnalyzeCode(t *testing.T) {
// Store IBC contract
wasm2, err := os.ReadFile(IBC_TEST_CONTRACT)
require.NoError(t, err)
checksum2, _, err := vm.StoreCode(wasm2)
checksum2, _, err := vm.StoreCode(wasm2, TESTING_GAS_LIMIT)
require.NoError(t, err)
// and analyze
report2, err := vm.AnalyzeCode(checksum2)
Expand Down
9 changes: 7 additions & 2 deletions lib.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,14 @@ func (vm *VM) Cleanup() {
// be instantiated with custom inputs in the future.
//
// Returns both the checksum, as well as the gas cost of compilation (in CosmWasm Gas) or an error.
func (vm *VM) StoreCode(code WasmCode) (Checksum, uint64, error) {
func (vm *VM) StoreCode(code WasmCode, gasLimit uint64) (Checksum, uint64, error) {
gasCost := compileCosts(code)
if gasLimit < gasCost {
return nil, gasCost, fmt.Errorf("insufficient gas to store contract (%d bytes)", len(code))
}

checksum, err := api.StoreCode(vm.cache, code)
return checksum, compileCosts(code), err
return checksum, gasCost, err
}

// StoreCodeUnchecked is the same as StoreCode but skips static validation checks.
Expand Down
18 changes: 9 additions & 9 deletions lib_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func withVM(t *testing.T) *VM {
func createTestContract(t *testing.T, vm *VM, path string) Checksum {
wasm, err := os.ReadFile(path)
require.NoError(t, err)
checksum, _, err := vm.StoreCode(wasm)
checksum, _, err := vm.StoreCode(wasm, TESTING_GAS_LIMIT)
require.NoError(t, err)
return checksum
}
Expand All @@ -56,15 +56,15 @@ func TestStoreCode(t *testing.T) {
{
wasm, err := os.ReadFile(HACKATOM_TEST_CONTRACT)
require.NoError(t, err)
_, _, err = vm.StoreCode(wasm)
_, _, err = vm.StoreCode(wasm, TESTING_GAS_LIMIT)
require.NoError(t, err)
}

// Valid cyberpunk contract
{
wasm, err := os.ReadFile(CYBERPUNK_TEST_CONTRACT)
require.NoError(t, err)
_, _, err = vm.StoreCode(wasm)
_, _, err = vm.StoreCode(wasm, TESTING_GAS_LIMIT)
require.NoError(t, err)
}

Expand All @@ -74,28 +74,28 @@ func TestStoreCode(t *testing.T) {
// hexdump -C < empty.wasm

wasm := []byte{0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00}
_, _, err := vm.StoreCode(wasm)
_, _, err := vm.StoreCode(wasm, TESTING_GAS_LIMIT)
require.ErrorContains(t, err, "Error during static Wasm validation: Wasm contract must contain exactly one memory")
}

// No Wasm
{
wasm := []byte("foobar")
_, _, err := vm.StoreCode(wasm)
_, _, err := vm.StoreCode(wasm, TESTING_GAS_LIMIT)
require.ErrorContains(t, err, "Wasm bytecode could not be deserialized")
}

// Empty
{
wasm := []byte("")
_, _, err := vm.StoreCode(wasm)
_, _, err := vm.StoreCode(wasm, TESTING_GAS_LIMIT)
require.ErrorContains(t, err, "Wasm bytecode could not be deserialized")
}

// Nil
{
var wasm []byte = nil
_, _, err := vm.StoreCode(wasm)
_, _, err := vm.StoreCode(wasm, TESTING_GAS_LIMIT)
require.ErrorContains(t, err, "Null/Nil argument: wasm")
}
}
Expand All @@ -106,7 +106,7 @@ func TestStoreCodeAndGet(t *testing.T) {
wasm, err := os.ReadFile(HACKATOM_TEST_CONTRACT)
require.NoError(t, err)

checksum, _, err := vm.StoreCode(wasm)
checksum, _, err := vm.StoreCode(wasm, TESTING_GAS_LIMIT)
require.NoError(t, err)

code, err := vm.GetCode(checksum)
Expand All @@ -120,7 +120,7 @@ func TestRemoveCode(t *testing.T) {
wasm, err := os.ReadFile(HACKATOM_TEST_CONTRACT)
require.NoError(t, err)

checksum, _, err := vm.StoreCode(wasm)
checksum, _, err := vm.StoreCode(wasm, TESTING_GAS_LIMIT)
require.NoError(t, err)

err = vm.RemoveCode(checksum)
Expand Down

0 comments on commit 8adad24

Please sign in to comment.