Skip to content

Commit

Permalink
feat(logic): add go-routine safe version of GasMeter
Browse files Browse the repository at this point in the history
  • Loading branch information
ccamel committed Jan 22, 2023
1 parent 47ce4e3 commit 5c1b4b9
Showing 1 changed file with 87 additions and 0 deletions.
87 changes: 87 additions & 0 deletions x/logic/types/gas.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package types

import (
"sync"

sdk "github.com/cosmos/cosmos-sdk/types"
)

var _ sdk.GasMeter = (*safeGasMeter)(nil)

// safeGasMeter is a wrapper around sdk.GasMeter that provides go-routine-safe access to the underlying gas meter.
// This is needed because the interpreter is uses multiple go-routines, and the gas meter is shared between multiple
// goroutines.
type safeGasMeter struct {
gasMeter sdk.GasMeter
mutex sync.RWMutex
}

func (m *safeGasMeter) ConsumeGas(amount uint64, descriptor string) {
m.mutex.Lock()
defer m.mutex.Unlock()

m.gasMeter.ConsumeGas(amount, descriptor)
}

func (m *safeGasMeter) GasConsumed() uint64 {
m.mutex.RLocker().Lock()
defer m.mutex.RLocker().Unlock()

return m.gasMeter.GasConsumed()
}

func (m *safeGasMeter) GasConsumedToLimit() uint64 {
m.mutex.RLocker().Lock()
defer m.mutex.RLocker().Unlock()

return m.gasMeter.GasConsumedToLimit()
}

func (m *safeGasMeter) IsPastLimit() bool {
m.mutex.RLocker().Lock()
defer m.mutex.RLocker().Unlock()

return m.gasMeter.IsPastLimit()
}

func (m *safeGasMeter) Limit() uint64 {
m.mutex.RLocker().Lock()
defer m.mutex.RLocker().Unlock()

return m.gasMeter.Limit()
}

func (m *safeGasMeter) RefundGas(amount uint64, descriptor string) {
m.mutex.Lock()
defer m.mutex.Unlock()

m.gasMeter.RefundGas(amount, descriptor)
}

func (m *safeGasMeter) GasRemaining() uint64 {
m.mutex.RLocker().Lock()
defer m.mutex.RLocker().Unlock()

return m.gasMeter.GasRemaining()
}

func (m *safeGasMeter) String() string {
m.mutex.RLocker().Lock()
defer m.mutex.RLocker().Unlock()

return m.gasMeter.String()
}

func (m *safeGasMeter) IsOutOfGas() bool {
m.mutex.RLocker().Lock()
defer m.mutex.RLocker().Unlock()

return m.gasMeter.IsOutOfGas()
}

// NewSafeGasMeter returns a new instance of sdk.GasMeter that is go-routine-safe.
func NewSafeGasMeter(gasMeter sdk.GasMeter) sdk.GasMeter {
return &safeGasMeter{
gasMeter: gasMeter,
}
}

0 comments on commit 5c1b4b9

Please sign in to comment.