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 }