generated from okp4/template-oss
-
Notifications
You must be signed in to change notification settings - Fork 126
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(logic): add go-routine safe version of GasMeter
- Loading branch information
Showing
1 changed file
with
87 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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, | ||
} | ||
} |