Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/gnolang/gno into feat/btr…
Browse files Browse the repository at this point in the history
…ee-dao
  • Loading branch information
matijamarjanovic committed Dec 19, 2024
2 parents c78d6c5 + 87a5035 commit 9e0038e
Show file tree
Hide file tree
Showing 9 changed files with 86 additions and 123 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/gh-pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ jobs:
- run: echo $GOROOT
- run: "cd misc/stdlib_diff && make gen"
- run: "cd misc/gendocs && make install gen"
- run: "mkdir -p pages_ouput/stdlib_diff"
- run: "mkdir -p pages_output/stdlib_diff"
- run: |
mv misc/gendocs/godoc pages_output
mv misc/stdlib_diff/stdlib_diff pages_ouput/stdlib_diff
cp -r misc/gendocs/godoc/* pages_output/
cp -r misc/stdlib_diff/stdlib_diff/* pages_output/stdlib_diff/
- uses: actions/configure-pages@v5
id: pages
- uses: actions/upload-pages-artifact@v3
Expand Down
9 changes: 1 addition & 8 deletions gno.land/cmd/gnoland/testdata/addpkg_outofgas.txtar
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,12 @@ gnoland start
gnokey maketx addpkg -pkgdir $WORK/foo -pkgpath gno.land/r/foo -gas-fee 1000000ugnot -gas-wanted 220000 -broadcast -chainid=tendermint_test test1


# add bar package
# out of gas at store.GetPackage() with gas 60000
# add bar package - out of gas at store.GetPackage() with gas 60000

! gnokey maketx addpkg -pkgdir $WORK/bar -pkgpath gno.land/r/bar -gas-fee 1000000ugnot -gas-wanted 60000 -broadcast -chainid=tendermint_test test1

# Out of gas error

stderr '--= Error =--'
stderr 'Data: out of gas error'
stderr 'Msg Traces:'
stderr 'out of gas.*?in preprocess'
stderr '--= /Error =--'


Expand All @@ -28,8 +23,6 @@ stderr '--= /Error =--'

stderr '--= Error =--'
stderr 'Data: out of gas error'
stderr 'Msg Traces:'
stderr 'out of gas.*?in preprocess'
stderr '--= /Error =--'


Expand Down
4 changes: 2 additions & 2 deletions gno.land/pkg/sdk/vm/gas_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func TestAddPkgDeliverTxInsuffGas(t *testing.T) {
defer func() {
if r := recover(); r != nil {
switch r.(type) {
case store.OutOfGasException:
case store.OutOfGasError:
res.Error = sdk.ABCIError(std.ErrOutOfGas(""))
abort = true
default:
Expand Down Expand Up @@ -117,7 +117,7 @@ func TestAddPkgDeliverTxFailedNoGas(t *testing.T) {
defer func() {
if r := recover(); r != nil {
switch r.(type) {
case store.OutOfGasException:
case store.OutOfGasError:
res.Error = sdk.ABCIError(std.ErrOutOfGas(""))
abort = true
default:
Expand Down
151 changes: 61 additions & 90 deletions gno.land/pkg/sdk/vm/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package vm
import (
"bytes"
"context"
goerrors "errors"
"fmt"
"io"
"log/slog"
Expand Down Expand Up @@ -392,18 +393,7 @@ func (vm *VMKeeper) AddPackage(ctx sdk.Context, msg MsgAddPackage) (err error) {
GasMeter: ctx.GasMeter(),
})
defer m2.Release()
defer func() {
if r := recover(); r != nil {
switch r.(type) {
case store.OutOfGasException: // panic in consumeGas()
panic(r)
default:
err = errors.Wrapf(fmt.Errorf("%v", r), "VM addpkg panic: %v\n%s\n",
r, m2.String())
return
}
}
}()
defer doRecover(m2, &err)
m2.RunMemPackage(memPkg, true)

// Log the telemetry
Expand Down Expand Up @@ -495,21 +485,7 @@ func (vm *VMKeeper) Call(ctx sdk.Context, msg MsgCall) (res string, err error) {
})
defer m.Release()
m.SetActivePackage(mpv)
defer func() {
if r := recover(); r != nil {
switch r := r.(type) {
case store.OutOfGasException: // panic in consumeGas()
panic(r)
case gno.UnhandledPanicError:
err = errors.Wrapf(fmt.Errorf("%v", r.Error()), "VM call panic: %s\nStacktrace: %s\n",
r.Error(), m.ExceptionsStacktrace())
default:
err = errors.Wrapf(fmt.Errorf("%v", r), "VM call panic: %v\nMachine State:%s\nStacktrace: %s\n",
r, m.String(), m.Stacktrace().String())
return
}
}
}()
defer doRecover(m, &err)
rtvs := m.Eval(xn)
for i, rtv := range rtvs {
res = res + rtv.String()
Expand All @@ -534,6 +510,35 @@ func (vm *VMKeeper) Call(ctx sdk.Context, msg MsgCall) (res string, err error) {
// TODO pay for gas? TODO see context?
}

func doRecover(m *gno.Machine, e *error) {
r := recover()
if r == nil {
return
}
if err, ok := r.(error); ok {
var oog types.OutOfGasError
if goerrors.As(err, &oog) {
// Re-panic and don't wrap.
panic(oog)
}
var up gno.UnhandledPanicError
if goerrors.As(err, &up) {
// Common unhandled panic error, skip machine state.
*e = errors.Wrapf(
errors.New(up.Descriptor),
"VM panic: %s\nStacktrace: %s\n",
up.Descriptor, m.ExceptionsStacktrace(),
)
return
}
}
*e = errors.Wrapf(
fmt.Errorf("%v", r),
"VM panic: %v\nMachine State:%s\nStacktrace: %s\n",
r, m.String(), m.Stacktrace().String(),
)
}

// Run executes arbitrary Gno code in the context of the caller's realm.
func (vm *VMKeeper) Run(ctx sdk.Context, msg MsgRun) (res string, err error) {
caller := msg.Caller
Expand Down Expand Up @@ -583,37 +588,36 @@ func (vm *VMKeeper) Run(ctx sdk.Context, msg MsgRun) (res string, err error) {
Params: NewSDKParams(vm, ctx),
EventLogger: ctx.EventLogger(),
}
// Parse and run the files, construct *PV.

buf := new(bytes.Buffer)
output := io.Writer(buf)
if vm.Output != nil {
output = io.MultiWriter(buf, vm.Output)
}
m := gno.NewMachineWithOptions(
gno.MachineOptions{
PkgPath: "",
Output: output,
Store: gnostore,
Alloc: gnostore.GetAllocator(),
Context: msgCtx,
GasMeter: ctx.GasMeter(),
})
// XXX MsgRun does not have pkgPath. How do we find it on chain?
defer m.Release()
defer func() {
if r := recover(); r != nil {
switch r.(type) {
case store.OutOfGasException: // panic in consumeGas()
panic(r)
default:
err = errors.Wrapf(fmt.Errorf("%v", r), "VM run main addpkg panic: %v\n%s\n",
r, m.String())
return
}

// Run as self-executing closure to have own function for doRecover / m.Release defers.
pv := func() *gno.PackageValue {
// Parse and run the files, construct *PV.
if vm.Output != nil {
output = io.MultiWriter(buf, vm.Output)
}
}()
m := gno.NewMachineWithOptions(
gno.MachineOptions{
PkgPath: "",
Output: output,
Store: gnostore,
Alloc: gnostore.GetAllocator(),
Context: msgCtx,
GasMeter: ctx.GasMeter(),
})
// XXX MsgRun does not have pkgPath. How do we find it on chain?
defer m.Release()
defer doRecover(m, &err)

_, pv := m.RunMemPackage(memPkg, false)
_, pv := m.RunMemPackage(memPkg, false)
return pv
}()
if err != nil {
// handle any errors happened within pv generation.
return
}

m2 := gno.NewMachineWithOptions(
gno.MachineOptions{
Expand All @@ -626,18 +630,7 @@ func (vm *VMKeeper) Run(ctx sdk.Context, msg MsgRun) (res string, err error) {
})
defer m2.Release()
m2.SetActivePackage(pv)
defer func() {
if r := recover(); r != nil {
switch r.(type) {
case store.OutOfGasException: // panic in consumeGas()
panic(r)
default:
err = errors.Wrapf(fmt.Errorf("%v", r), "VM run main call panic: %v\n%s\n",
r, m2.String())
return
}
}
}()
defer doRecover(m2, &err)
m2.RunMain()
res = buf.String()

Expand Down Expand Up @@ -758,18 +751,7 @@ func (vm *VMKeeper) QueryEval(ctx sdk.Context, pkgPath string, expr string) (res
GasMeter: ctx.GasMeter(),
})
defer m.Release()
defer func() {
if r := recover(); r != nil {
switch r.(type) {
case store.OutOfGasException: // panic in consumeGas()
panic(r)
default:
err = errors.Wrapf(fmt.Errorf("%v", r), "VM query eval panic: %v\n%s\n",
r, m.String())
return
}
}
}()
defer doRecover(m, &err)
rtvs := m.Eval(xx)
res = ""
for i, rtv := range rtvs {
Expand Down Expand Up @@ -826,18 +808,7 @@ func (vm *VMKeeper) QueryEvalString(ctx sdk.Context, pkgPath string, expr string
GasMeter: ctx.GasMeter(),
})
defer m.Release()
defer func() {
if r := recover(); r != nil {
switch r.(type) {
case store.OutOfGasException: // panic in consumeGas()
panic(r)
default:
err = errors.Wrapf(fmt.Errorf("%v", r), "VM query eval string panic: %v\n%s\n",
r, m.String())
return
}
}
}()
defer doRecover(m, &err)
rtvs := m.Eval(xx)
if len(rtvs) != 1 {
return "", errors.New("expected 1 string result, got %d", len(rtvs))
Expand Down
9 changes: 0 additions & 9 deletions gnovm/pkg/gnolang/preprocess.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"sync/atomic"

"github.com/gnolang/gno/tm2/pkg/errors"
tmstore "github.com/gnolang/gno/tm2/pkg/store"
)

const (
Expand Down Expand Up @@ -366,12 +365,6 @@ func initStaticBlocks(store Store, ctx BlockNode, bn BlockNode) {

func doRecover(stack []BlockNode, n Node) {
if r := recover(); r != nil {
// Catch the out-of-gas exception and throw it
if exp, ok := r.(tmstore.OutOfGasException); ok {
exp.Descriptor = fmt.Sprintf("in preprocess: %v", r)
panic(exp)
}

if _, ok := r.(*PreprocessError); ok {
// re-panic directly if this is a PreprocessError already.
panic(r)
Expand All @@ -388,10 +381,8 @@ func doRecover(stack []BlockNode, n Node) {
var err error
rerr, ok := r.(error)
if ok {
// NOTE: gotuna/gorilla expects error exceptions.
err = errors.Wrap(rerr, loc.String())
} else {
// NOTE: gotuna/gorilla expects error exceptions.
err = fmt.Errorf("%s: %v", loc.String(), r)
}

Expand Down
2 changes: 1 addition & 1 deletion tm2/pkg/sdk/auth/ante.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ func NewAnteHandler(ak AccountKeeper, bank BankKeeperI, sigGasConsumer Signature
defer func() {
if r := recover(); r != nil {
switch ex := r.(type) {
case store.OutOfGasException:
case store.OutOfGasError:
log := fmt.Sprintf(
"out of gas in location: %v; gasWanted: %d, gasUsed: %d",
ex.Descriptor, tx.Fee.GasWanted, newCtx.GasMeter().GasConsumed(),
Expand Down
2 changes: 1 addition & 1 deletion tm2/pkg/sdk/baseapp.go
Original file line number Diff line number Diff line change
Expand Up @@ -759,7 +759,7 @@ func (app *BaseApp) runTx(ctx Context, tx Tx) (result Result) {
defer func() {
if r := recover(); r != nil {
switch ex := r.(type) {
case store.OutOfGasException:
case store.OutOfGasError:
log := fmt.Sprintf(
"out of gas, gasWanted: %d, gasUsed: %d location: %v",
gasWanted,
Expand Down
4 changes: 2 additions & 2 deletions tm2/pkg/store/exports.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ type (
Gas = types.Gas
GasMeter = types.GasMeter
GasConfig = types.GasConfig
OutOfGasException = types.OutOfGasException
GasOverflowException = types.GasOverflowException
OutOfGasError = types.OutOfGasError
GasOverflowError = types.GasOverflowError
)

var (
Expand Down
22 changes: 15 additions & 7 deletions tm2/pkg/store/types/gas.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,25 @@ const (
// Gas measured by the SDK
type Gas = int64

// OutOfGasException defines an error thrown when an action results in out of gas.
type OutOfGasException struct {
// OutOfGasError defines an error thrown when an action results in out of gas.
type OutOfGasError struct {
Descriptor string
}

// GasOverflowException defines an error thrown when an action results gas consumption
func (oog OutOfGasError) Error() string {
return "out of gas in location: " + oog.Descriptor
}

// GasOverflowError defines an error thrown when an action results gas consumption
// unsigned integer overflow.
type GasOverflowException struct {
type GasOverflowError struct {
Descriptor string
}

func (oog GasOverflowError) Error() string {
return "gas overflow in location: " + oog.Descriptor
}

// GasMeter interface to track gas consumption
type GasMeter interface {
GasConsumed() Gas
Expand Down Expand Up @@ -88,13 +96,13 @@ func (g *basicGasMeter) ConsumeGas(amount Gas, descriptor string) {
}
consumed, ok := overflow.Add64(g.consumed, amount)
if !ok {
panic(GasOverflowException{descriptor})
panic(GasOverflowError{descriptor})
}
// consume gas even if out of gas.
// corollary, call (Did)ConsumeGas after consumption.
g.consumed = consumed
if consumed > g.limit {
panic(OutOfGasException{descriptor})
panic(OutOfGasError{descriptor})
}
}

Expand Down Expand Up @@ -139,7 +147,7 @@ func (g *infiniteGasMeter) Remaining() Gas {
func (g *infiniteGasMeter) ConsumeGas(amount Gas, descriptor string) {
consumed, ok := overflow.Add64(g.consumed, amount)
if !ok {
panic(GasOverflowException{descriptor})
panic(GasOverflowError{descriptor})
}
g.consumed = consumed
}
Expand Down

0 comments on commit 9e0038e

Please sign in to comment.