github.com/koko1123/flow-go-1@v0.29.6/fvm/environment/meter.go (about)

     1  package environment
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/onflow/cadence/runtime/common"
     7  
     8  	"github.com/koko1123/flow-go-1/fvm/errors"
     9  	"github.com/koko1123/flow-go-1/fvm/meter"
    10  	"github.com/koko1123/flow-go-1/fvm/state"
    11  )
    12  
    13  const (
    14  	// [2_000, 3_000) reserved for the FVM
    15  	ComputationKindHash                       = 2001
    16  	ComputationKindVerifySignature            = 2002
    17  	ComputationKindAddAccountKey              = 2003
    18  	ComputationKindAddEncodedAccountKey       = 2004
    19  	ComputationKindAllocateStorageIndex       = 2005
    20  	ComputationKindCreateAccount              = 2006
    21  	ComputationKindEmitEvent                  = 2007
    22  	ComputationKindGenerateUUID               = 2008
    23  	ComputationKindGetAccountAvailableBalance = 2009
    24  	ComputationKindGetAccountBalance          = 2010
    25  	ComputationKindGetAccountContractCode     = 2011
    26  	ComputationKindGetAccountContractNames    = 2012
    27  	ComputationKindGetAccountKey              = 2013
    28  	ComputationKindGetBlockAtHeight           = 2014
    29  	ComputationKindGetCode                    = 2015
    30  	ComputationKindGetCurrentBlockHeight      = 2016
    31  	ComputationKindGetProgram                 = 2017
    32  	ComputationKindGetStorageCapacity         = 2018
    33  	ComputationKindGetStorageUsed             = 2019
    34  	ComputationKindGetValue                   = 2020
    35  	ComputationKindRemoveAccountContractCode  = 2021
    36  	ComputationKindResolveLocation            = 2022
    37  	ComputationKindRevokeAccountKey           = 2023
    38  	ComputationKindRevokeEncodedAccountKey    = 2024
    39  	ComputationKindSetProgram                 = 2025
    40  	ComputationKindSetValue                   = 2026
    41  	ComputationKindUpdateAccountContractCode  = 2027
    42  	ComputationKindValidatePublicKey          = 2028
    43  	ComputationKindValueExists                = 2029
    44  	ComputationKindAccountKeysCount           = 2030
    45  	ComputationKindBLSVerifyPOP               = 2031
    46  	ComputationKindBLSAggregateSignatures     = 2032
    47  	ComputationKindBLSAggregatePublicKeys     = 2033
    48  )
    49  
    50  type Meter interface {
    51  	MeterComputation(common.ComputationKind, uint) error
    52  	ComputationUsed() uint64
    53  	ComputationIntensities() meter.MeteredComputationIntensities
    54  
    55  	MeterMemory(usage common.MemoryUsage) error
    56  	MemoryEstimate() uint64
    57  
    58  	MeterEmittedEvent(byteSize uint64) error
    59  	TotalEmittedEventBytes() uint64
    60  }
    61  
    62  type meterImpl struct {
    63  	txnState *state.TransactionState
    64  }
    65  
    66  func NewMeter(txnState *state.TransactionState) Meter {
    67  	return &meterImpl{
    68  		txnState: txnState,
    69  	}
    70  }
    71  
    72  func (meter *meterImpl) MeterComputation(
    73  	kind common.ComputationKind,
    74  	intensity uint,
    75  ) error {
    76  	if meter.txnState.EnforceLimits() {
    77  		return meter.txnState.MeterComputation(kind, intensity)
    78  	}
    79  	return nil
    80  }
    81  
    82  func (meter *meterImpl) ComputationIntensities() meter.MeteredComputationIntensities {
    83  	return meter.txnState.ComputationIntensities()
    84  }
    85  
    86  func (meter *meterImpl) ComputationUsed() uint64 {
    87  	return meter.txnState.TotalComputationUsed()
    88  }
    89  
    90  func (meter *meterImpl) MeterMemory(usage common.MemoryUsage) error {
    91  	if meter.txnState.EnforceLimits() {
    92  		return meter.txnState.MeterMemory(usage.Kind, uint(usage.Amount))
    93  	}
    94  	return nil
    95  }
    96  
    97  func (meter *meterImpl) MemoryEstimate() uint64 {
    98  	return meter.txnState.TotalMemoryEstimate()
    99  }
   100  
   101  func (meter *meterImpl) MeterEmittedEvent(byteSize uint64) error {
   102  	if meter.txnState.EnforceLimits() {
   103  		return meter.txnState.MeterEmittedEvent(byteSize)
   104  	}
   105  	return nil
   106  }
   107  
   108  func (meter *meterImpl) TotalEmittedEventBytes() uint64 {
   109  	return meter.txnState.TotalEmittedEventBytes()
   110  }
   111  
   112  type cancellableMeter struct {
   113  	meterImpl
   114  
   115  	ctx context.Context
   116  }
   117  
   118  func NewCancellableMeter(
   119  	ctx context.Context,
   120  	txnState *state.TransactionState,
   121  ) Meter {
   122  	return &cancellableMeter{
   123  		meterImpl: meterImpl{
   124  			txnState: txnState,
   125  		},
   126  		ctx: ctx,
   127  	}
   128  }
   129  
   130  func (meter *cancellableMeter) MeterComputation(
   131  	kind common.ComputationKind,
   132  	intensity uint,
   133  ) error {
   134  	// this method is called on every unit of operation, so
   135  	// checking the context here is the most likely would capture
   136  	// timeouts or cancellation as soon as they happen, though
   137  	// we might revisit this when optimizing script execution
   138  	// by only checking on specific kind of Meter calls.
   139  	//
   140  	// in the future this context check should be done inside the cadence
   141  	select {
   142  	case <-meter.ctx.Done():
   143  		err := meter.ctx.Err()
   144  		if errors.Is(err, context.DeadlineExceeded) {
   145  			return errors.NewScriptExecutionTimedOutError()
   146  		}
   147  		return errors.NewScriptExecutionCancelledError(err)
   148  	default:
   149  		// do nothing
   150  	}
   151  
   152  	return meter.meterImpl.MeterComputation(kind, intensity)
   153  }