Skip to content
This repository has been archived by the owner on Nov 16, 2022. It is now read-only.

Implement consume gas logic test 馃挴 #1818

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions chain/pkg/owasm/execute_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,3 +157,44 @@ func TestNotPanicFromWasm(t *testing.T) {
_, _, err = Execute(env, code, "prepare", []byte{}, 10000)
require.EqualError(t, err, "param count mismatch")
}

func TestExecuteLoop100000(t *testing.T) {
code, err := ioutil.ReadFile("./res/loop_100000.wasm")
require.Nil(t, err)
env := &mockExecEnv{
requestExternalDataResultsCounter: [][]int64{nil, {0}},
maximumResultSize: 1024,
maximumCalldataOfDataSourceSize: 1024,
}

_, gasUsed, err := Execute(env, code, "prepare", []byte{}, 2000000)
require.NoError(t, err)
require.Equal(t, gasUsed, uint64(1200008))
}

func TestExecuteLoop(t *testing.T) {
code, err := ioutil.ReadFile("./res/loop.wasm")
require.Nil(t, err)
env := &mockExecEnv{
requestExternalDataResultsCounter: [][]int64{nil, {0}},
maximumResultSize: 1024,
maximumCalldataOfDataSourceSize: 1024,
}

_, gasUsed, err := Execute(env, code, "prepare", []byte{}, 2000000)
require.NoError(t, err)
require.Equal(t, gasUsed, uint64(72008))
}

func TestExecuteInfiniteLoop(t *testing.T) {
code, err := ioutil.ReadFile("./res/infinite_loop.wasm")
require.Nil(t, err)
env := &mockExecEnv{
requestExternalDataResultsCounter: [][]int64{nil, {0}},
maximumResultSize: 1024,
maximumCalldataOfDataSourceSize: 1024,
}

_, _, err = Execute(env, code, "prepare", []byte{}, 2000000)
require.Error(t, err)
}
Binary file added chain/pkg/owasm/res/infinite_loop.wasm
Binary file not shown.
18 changes: 18 additions & 0 deletions chain/pkg/owasm/res/infinite_loop.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
(module
(import "env" "requestExternalData" (func (param i64 i64 i32 i64) (result i64)))
(import "env" "saveReturnData" (func (param i32 i64) (result i64)))
(func (;infinite loop;)(result i32)
(loop $label$0 (result i32)
(br $label$0)
)
)
(func (;"execute": Resolves with result "beeb";)
i32.const 1048576 (;a raw pointer of string;)
i64.const 4 (;string length;)
call 1 (;call function saveReturnData;)
drop (;clear stack;)
)
(memory 17)
(data (i32.const 1048576) "beeb") (;str = "beeb";)
(export "prepare" (func 2))
(export "execute" (func 3)))
Binary file added chain/pkg/owasm/res/loop.wasm
Binary file not shown.
14 changes: 14 additions & 0 deletions chain/pkg/owasm/res/loop.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
(module
(func (result i32) (;this function uses 72008 gas for execute;)
(local $idx i32)
(set_local $idx (i32.const 0))
(block
(loop
(set_local $idx (get_local $idx) (i32.const 1) (i32.add) )
(br_if 0 (i32.lt_u (get_local $idx) (i32.const 6000)))
)
)
(get_local $idx)
)
(export "prepare" (func 0)))

Binary file added chain/pkg/owasm/res/loop_100000.wasm
Binary file not shown.
14 changes: 14 additions & 0 deletions chain/pkg/owasm/res/loop_100000.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
(module
(func (result i32) (;this function uses 1200008 gas for execute;)
(local $idx i32)
(set_local $idx (i32.const 0))
(block
(loop
(set_local $idx (get_local $idx) (i32.const 1) (i32.add) )
(br_if 0 (i32.lt_u (get_local $idx) (i32.const 100000)))
)
)
(get_local $idx)
)
(export "prepare" (func 0)))

51 changes: 51 additions & 0 deletions chain/x/oracle/keeper/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,57 @@ func getTestOracleScript() (os types.OracleScript, clear func()) {
), func() { deleteFile(filepath.Join(dir, filename)) }
}

func getTestInfiniteLoopOracleScript() (os types.OracleScript, clear func()) {
absPath, _ := filepath.Abs("../../../pkg/owasm/res/infinite_loop.wasm")
code, err := ioutil.ReadFile(absPath)
if err != nil {
panic(err)
}
dir := filepath.Join(viper.GetString(cli.HomeFlag), "files")
f := filecache.New(dir)
filename := f.AddFile(code)
return types.NewOracleScript(
Owner.Address, "imported script", "description",
filename,
"schema",
"sourceCodeURL",
), func() { deleteFile(filepath.Join(dir, filename)) }
}

func getTestLoopOracleScript() (os types.OracleScript, clear func()) {
absPath, _ := filepath.Abs("../../../pkg/owasm/res/loop.wasm")
code, err := ioutil.ReadFile(absPath)
if err != nil {
panic(err)
}
dir := filepath.Join(viper.GetString(cli.HomeFlag), "files")
f := filecache.New(dir)
filename := f.AddFile(code)
return types.NewOracleScript(
Owner.Address, "imported script", "description",
filename,
"schema",
"sourceCodeURL",
), func() { deleteFile(filepath.Join(dir, filename)) }
}

func getTestLoop100000TimesOracleScript() (os types.OracleScript, clear func()) {
absPath, _ := filepath.Abs("../../../pkg/owasm/res/loop_100000.wasm")
code, err := ioutil.ReadFile(absPath)
if err != nil {
panic(err)
}
dir := filepath.Join(viper.GetString(cli.HomeFlag), "files")
f := filecache.New(dir)
filename := f.AddFile(code)
return types.NewOracleScript(
Owner.Address, "imported script", "description",
filename,
"schema",
"sourceCodeURL",
), func() { deleteFile(filepath.Join(dir, filename)) }
}

func getBadOracleScript() (os types.OracleScript, clear func()) {
dir := filepath.Join(viper.GetString(cli.HomeFlag), "files")
f := filecache.New(dir)
Expand Down
104 changes: 103 additions & 1 deletion chain/x/oracle/keeper/owasm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,109 @@ func TestPrepareRequestInvalidAskCountFail(t *testing.T) {
require.Error(t, err)
}

func TestPrepareRequestWithInfiniteLoop(t *testing.T) {
_, ctx, k := createTestInput()
ctx = ctx.WithBlockTime(time.Unix(1581589790, 0))
ctx = ctx.WithGasMeter(sdk.NewGasMeter(1000000)) // Set Gas Meter 1000000

ds1, clear1 := getTestDataSource("code1")
defer clear1()
k.AddDataSource(ctx, ds1)

ds2, clear2 := getTestDataSource("code2")
defer clear2()
k.AddDataSource(ctx, ds2)

ds3, clear3 := getTestDataSource("code3")
defer clear3()
k.AddDataSource(ctx, ds3)

os, clear4 := getTestInfiniteLoopOracleScript()
defer clear4()

oracleScriptID := k.AddOracleScript(ctx, os)
calldata, _ := hex.DecodeString("030000004254436400000000000000")
askCount := uint64(1)
minCount := uint64(2)
clientID := "beeb"

m := types.NewMsgRequestData(oracleScriptID, calldata, askCount, minCount, clientID, Alice.Address)
err := k.PrepareRequest(ctx, &m, nil)
require.Error(t, err)
}

func TestPrepareRequestWithLoopWasm(t *testing.T) {
_, ctx, k := createTestInput()
ctx = ctx.WithBlockTime(time.Unix(1581589790, 0))
ctx = ctx.WithGasMeter(sdk.NewGasMeter(70000))

baseRequestGas := uint64(0)
k.SetParam(ctx, types.KeyBaseRequestGas, baseRequestGas)
perValidatorRequestGas := uint64(0)
k.SetParam(ctx, types.KeyPerValidatorRequestGas, perValidatorRequestGas)

ds1, clear1 := getTestDataSource("code1")
defer clear1()
k.AddDataSource(ctx, ds1)

ds2, clear2 := getTestDataSource("code2")
defer clear2()
k.AddDataSource(ctx, ds2)

ds3, clear3 := getTestDataSource("code3")
defer clear3()
k.AddDataSource(ctx, ds3)

os, clear4 := getTestLoopOracleScript() // this oracle script use 72008gas
defer clear4()

oracleScriptID := k.AddOracleScript(ctx, os)
calldata, _ := hex.DecodeString("030000004254436400000000000000")
askCount := uint64(1)
minCount := uint64(2)
clientID := "beeb"
m := types.NewMsgRequestData(oracleScriptID, calldata, askCount, minCount, clientID, Alice.Address)
err := k.PrepareRequest(ctx, &m, nil)
require.NoError(t, err)
}

func TestPrepareRequestWithLoop100000TimesWasm(t *testing.T) {
_, ctx, k := createTestInput()
ctx = ctx.WithBlockTime(time.Unix(1581589790, 0))
ctx = ctx.WithGasMeter(sdk.NewGasMeter(70000))

baseRequestGas := uint64(0)
k.SetParam(ctx, types.KeyBaseRequestGas, baseRequestGas)
perValidatorRequestGas := uint64(0)
k.SetParam(ctx, types.KeyPerValidatorRequestGas, perValidatorRequestGas)

ds1, clear1 := getTestDataSource("code1")
defer clear1()
k.AddDataSource(ctx, ds1)

ds2, clear2 := getTestDataSource("code2")
defer clear2()
k.AddDataSource(ctx, ds2)

ds3, clear3 := getTestDataSource("code3")
defer clear3()
k.AddDataSource(ctx, ds3)

os, clear4 := getTestLoop100000TimesOracleScript() // this oracle script use 1200008gas.
defer clear4()

oracleScriptID := k.AddOracleScript(ctx, os)
calldata, _ := hex.DecodeString("030000004254436400000000000000")
askCount := uint64(1)
minCount := uint64(2)
Benzbeeb marked this conversation as resolved.
Show resolved Hide resolved
clientID := "beeb"
m := types.NewMsgRequestData(oracleScriptID, calldata, askCount, minCount, clientID, Alice.Address)

// Must error because WasmPrepareGas is 100000 (this oracle script want 1200008gas for execute)
err := k.PrepareRequest(ctx, &m, nil)
require.Error(t, err)
}

func TestPrepareRequestBaseRequestFeePanic(t *testing.T) {
_, ctx, k := createTestInput()
ctx = ctx.WithBlockTime(time.Unix(1581589790, 0))
Expand Down Expand Up @@ -144,7 +247,6 @@ func TestPrepareRequestBaseRequestFeePanic(t *testing.T) {
ctx = ctx.WithGasMeter(sdk.NewGasMeter(200000))
err := k.PrepareRequest(ctx, &m, nil)
require.NoError(t, err)

}

func TestPrepareRequestPerValidatorRequestFeePanic(t *testing.T) {
Expand Down