github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/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/onflow/flow-go/fvm/errors" 9 "github.com/onflow/flow-go/fvm/meter" 10 "github.com/onflow/flow-go/fvm/storage/state" 11 ) 12 13 const ( 14 // [2_000, 3_000) reserved for the FVM 15 ComputationKindHash = 2001 + iota 16 ComputationKindVerifySignature 17 ComputationKindAddAccountKey 18 ComputationKindAddEncodedAccountKey 19 ComputationKindAllocateStorageIndex 20 ComputationKindCreateAccount 21 ComputationKindEmitEvent 22 ComputationKindGenerateUUID 23 ComputationKindGetAccountAvailableBalance 24 ComputationKindGetAccountBalance 25 ComputationKindGetAccountContractCode 26 ComputationKindGetAccountContractNames 27 ComputationKindGetAccountKey 28 ComputationKindGetBlockAtHeight 29 ComputationKindGetCode 30 ComputationKindGetCurrentBlockHeight 31 _ 32 ComputationKindGetStorageCapacity 33 ComputationKindGetStorageUsed 34 ComputationKindGetValue 35 ComputationKindRemoveAccountContractCode 36 ComputationKindResolveLocation 37 ComputationKindRevokeAccountKey 38 _ // removed, DO NOT REUSE 39 _ // removed, DO NOT REUSE 40 ComputationKindSetValue 41 ComputationKindUpdateAccountContractCode 42 ComputationKindValidatePublicKey 43 ComputationKindValueExists 44 ComputationKindAccountKeysCount 45 ComputationKindBLSVerifyPOP 46 ComputationKindBLSAggregateSignatures 47 ComputationKindBLSAggregatePublicKeys 48 ComputationKindGetOrLoadProgram 49 ComputationKindGenerateAccountLocalID 50 ComputationKindGetRandomSourceHistory 51 ComputationKindEVMGasUsage 52 ComputationKindRLPEncoding 53 ComputationKindRLPDecoding 54 ComputationKindEncodeEvent 55 _ 56 ComputationKindEVMEncodeABI 57 ComputationKindEVMDecodeABI 58 ) 59 60 // MainnetExecutionEffortWeights are the execution effort weights as they are 61 // on mainnet from 18.8.2022 62 var MainnetExecutionEffortWeights = meter.ExecutionEffortWeights{ 63 common.ComputationKindStatement: 1569, 64 common.ComputationKindLoop: 1569, 65 common.ComputationKindFunctionInvocation: 1569, 66 ComputationKindGetValue: 808, 67 ComputationKindCreateAccount: 2837670, 68 ComputationKindSetValue: 765, 69 } 70 71 type Meter interface { 72 MeterComputation(common.ComputationKind, uint) error 73 ComputationUsed() (uint64, error) 74 ComputationIntensities() meter.MeteredComputationIntensities 75 ComputationAvailable(common.ComputationKind, uint) bool 76 77 MeterMemory(usage common.MemoryUsage) error 78 MemoryUsed() (uint64, error) 79 80 MeterEmittedEvent(byteSize uint64) error 81 TotalEmittedEventBytes() uint64 82 83 InteractionUsed() (uint64, error) 84 } 85 86 type meterImpl struct { 87 txnState state.NestedTransactionPreparer 88 } 89 90 func NewMeter(txnState state.NestedTransactionPreparer) Meter { 91 return &meterImpl{ 92 txnState: txnState, 93 } 94 } 95 96 func (meter *meterImpl) MeterComputation( 97 kind common.ComputationKind, 98 intensity uint, 99 ) error { 100 return meter.txnState.MeterComputation(kind, intensity) 101 } 102 103 func (meter *meterImpl) ComputationIntensities() meter.MeteredComputationIntensities { 104 return meter.txnState.ComputationIntensities() 105 } 106 107 func (meter *meterImpl) ComputationAvailable( 108 kind common.ComputationKind, 109 intensity uint, 110 ) bool { 111 return meter.txnState.ComputationAvailable(kind, intensity) 112 } 113 114 func (meter *meterImpl) ComputationUsed() (uint64, error) { 115 return meter.txnState.TotalComputationUsed(), nil 116 } 117 118 func (meter *meterImpl) MeterMemory(usage common.MemoryUsage) error { 119 return meter.txnState.MeterMemory(usage.Kind, uint(usage.Amount)) 120 } 121 122 func (meter *meterImpl) MemoryUsed() (uint64, error) { 123 return meter.txnState.TotalMemoryEstimate(), nil 124 } 125 126 func (meter *meterImpl) InteractionUsed() (uint64, error) { 127 return meter.txnState.InteractionUsed(), nil 128 } 129 130 func (meter *meterImpl) MeterEmittedEvent(byteSize uint64) error { 131 return meter.txnState.MeterEmittedEvent(byteSize) 132 } 133 134 func (meter *meterImpl) TotalEmittedEventBytes() uint64 { 135 return meter.txnState.TotalEmittedEventBytes() 136 } 137 138 type cancellableMeter struct { 139 meterImpl 140 141 ctx context.Context 142 } 143 144 func NewCancellableMeter( 145 ctx context.Context, 146 txnState state.NestedTransactionPreparer, 147 ) Meter { 148 return &cancellableMeter{ 149 meterImpl: meterImpl{ 150 txnState: txnState, 151 }, 152 ctx: ctx, 153 } 154 } 155 156 func (meter *cancellableMeter) MeterComputation( 157 kind common.ComputationKind, 158 intensity uint, 159 ) error { 160 // this method is called on every unit of operation, so 161 // checking the context here is the most likely would capture 162 // timeouts or cancellation as soon as they happen, though 163 // we might revisit this when optimizing script execution 164 // by only checking on specific kind of Meter calls. 165 // 166 // in the future this context check should be done inside the cadence 167 select { 168 case <-meter.ctx.Done(): 169 err := meter.ctx.Err() 170 if errors.Is(err, context.DeadlineExceeded) { 171 return errors.NewScriptExecutionTimedOutError() 172 } 173 return errors.NewScriptExecutionCancelledError(err) 174 default: 175 // do nothing 176 } 177 178 return meter.meterImpl.MeterComputation(kind, intensity) 179 }