Skip to content

Commit

Permalink
fix(logic): avoid killing querying goroutine on gas limit exceeded
Browse files Browse the repository at this point in the history
  • Loading branch information
amimart committed Apr 5, 2023
1 parent cfa1221 commit 86a184a
Show file tree
Hide file tree
Showing 3 changed files with 4 additions and 22 deletions.
7 changes: 0 additions & 7 deletions x/logic/keeper/grpc_query_ask.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,6 @@ func (k Keeper) Ask(ctx goctx.Context, req *types.QueryServiceAskRequest) (respo

panic(r)
}
if sdkCtx.GasMeter().IsOutOfGas() {
response, err = nil, sdkerrors.Wrapf(
types.LimitExceeded, "out of gas: %s (%d/%d)",
types.ModuleName, sdkCtx.GasMeter().GasConsumed(), sdkCtx.GasMeter().Limit())

return
}
}()
sdkCtx.GasMeter().ConsumeGas(sdkCtx.GasMeter().GasConsumed(), types.ModuleName)

Expand Down
4 changes: 4 additions & 0 deletions x/logic/keeper/interpreter.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ func (k Keeper) execute(ctx goctx.Context, program, query string) (*types.QueryS
results = append(results, types.Result{Substitutions: m.ToSubstitutions()})
}

if sols.Err() != nil && sdkCtx.GasMeter().IsOutOfGas() {
panic(sdk.ErrorOutOfGas{Descriptor: "Prolog interpreter execution"})
}

return &types.QueryServiceAskResponse{
Height: uint64(sdkCtx.BlockHeight()),
GasUsed: sdkCtx.GasMeter().GasConsumed(),
Expand Down
15 changes: 0 additions & 15 deletions x/logic/meter/safe.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package meter

import (
"runtime"
"sync"

sdk "github.com/cosmos/cosmos-sdk/types"
Expand All @@ -25,20 +24,6 @@ func WithSafeMeter(gasMeter sdk.GasMeter) sdk.GasMeter {
// ConsumeGas consumes the given amount of gas from the decorated gas meter.
func (m *safeMeterDecorater) ConsumeGas(amount uint64, descriptor string) {
m.mutex.Lock()
defer func() {
if r := recover(); r != nil {
if _, ok := r.(sdk.ErrorOutOfGas); ok {
// Since predicate is called into a goroutine, when out of gas is thrown, the main caller
// (grpc: https://github.com/okp4/okp4d/blob/main/x/logic/keeper/grpc_query_ask.go#L25-L36, or querier)
// cannot recover ErrOutOfGas. To avoid the chain panicking, we need to exit without panic.
// Goexit runs all deferred calls before terminating the goroutine. Because Goexit
// is not a panic, any recover calls in those deferred functions will return nil.
// This is a temporary solution before implementing a context cancellation.
runtime.Goexit()
}
panic(r)
}
}()
defer m.mutex.Unlock()

m.gasMeter.ConsumeGas(amount, descriptor)
Expand Down

0 comments on commit 86a184a

Please sign in to comment.