Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(Gnovm/std): GasUsed function for std #2149

Closed
19 changes: 19 additions & 0 deletions gnovm/stdlibs/native.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 26 additions & 0 deletions gnovm/stdlibs/std/gas_used.go
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Name this gas.go

Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package std

/*
ref: https://github.com/gnolang/gno/issues/1998
this file contains std functions for query gas cost, gas used etc...
*/
import (
gno "github.com/gnolang/gno/gnovm/pkg/gnolang"
"github.com/gnolang/gno/tm2/pkg/store"
)

var (
gasUsedInvoked = "GasUsedCalled"
/*
Consider where to save this config
defaultGasConfig = store.DefaultGasConfig()
*/
// defaultGasConfig = int64(1000)
defaultInvokeCost = store.DefaultGasConfig().ReadCostFlat
)

// DefaultCost will be consumed whenever GasUsed is called, now set it ReadCostPerByte
func GasUsed(m *gno.Machine) int64 {
m.GasMeter.ConsumeGas(defaultInvokeCost, gasUsedInvoked)
return m.GasMeter.GasConsumedToLimit()
}
Comment on lines +12 to +26
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't consume gas here; we'll need to benchmark all native functions and add a cost on another occasion.

57 changes: 57 additions & 0 deletions gnovm/stdlibs/std/gas_used_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package std

import (
"testing"

gno "github.com/gnolang/gno/gnovm/pkg/gnolang"
"github.com/gnolang/gno/tm2/pkg/store"
"github.com/stretchr/testify/assert"
)

// Focus on test gasToConsume()
func TestGasUsed(t *testing.T) {

Check failure on line 12 in gnovm/stdlibs/std/gas_used_test.go

View workflow job for this annotation

GitHub Actions / Run Main / Go Linter / lint

TestGasUsed's subtests should call t.Parallel (tparallel)
t.Parallel()
m := gno.NewMachine("gasToConsume", nil)
gasCostConfig := store.DefaultGasConfig().ReadCostFlat
testTable := []struct {
tcName string
gasToConsume int64
gasLimit int64
expectPastLimit bool
invokeCost int64
}{
{"Test GasUsed Get", 10, 100000, false, gasCostConfig},
{"Test GasUsed Invoke Cost", 4, 4 + gasCostConfig, false, gasCostConfig},
{"Test GasUsed Past Limit", 4, 4, true, gasCostConfig},
// this case is OutOfGas's behavior
// {"Test GasUsed Get When Out Of Gas", 40, 4, true, cf.ReadCostPerByte},
}
for _, tc := range testTable {
t.Run(tc.tcName, func(t *testing.T) {
m.GasMeter = store.NewGasMeter(tc.gasLimit)
if tc.expectPastLimit {
m.GasMeter.ConsumeGas(tc.gasToConsume, tc.tcName)
// After consume gasToConsume, the remaining gas is lower than invokeCost
// then GasUsed() should panic(OutOfGas)
beforeInvoke := m.GasMeter.Remaining()
assert.Panics(t, func() {
GasUsed(m)
})
afterInvoke := m.GasMeter.Remaining()
// Check if GasMeter() acts as expected
assert.Equal(t, tc.expectPastLimit, m.GasMeter.IsOutOfGas())
// Check if GasUsed() will not consume invokeCost
assert.Equal(t, beforeInvoke, afterInvoke)
} else {
m.GasMeter.ConsumeGas(tc.gasToConsume, tc.tcName)
beforeInvoke := m.GasMeter.Remaining()
result := GasUsed(m)
afterInvoke := m.GasMeter.Remaining()
// Check if GasUsed() invoked the invokeCost
assert.Equal(t, beforeInvoke-afterInvoke, tc.invokeCost)
// Check if the process consumes ecxactly amount of gas
assert.Equal(t, tc.gasToConsume+tc.invokeCost, result)
}
})
}
}
2 changes: 2 additions & 0 deletions gnovm/stdlibs/std/native.gno
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ func IsOriginCall() bool // injected
func GetChainID() string // injected
func GetHeight() int64 // injected

func GasUsed() int64 // injected
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please place this next to the other injected functions (and align // injected), please!


func GetOrigSend() Coins {
den, amt := origSend()
coins := make(Coins, len(den))
Expand Down
Loading