github.com/onflow/flow-go@v0.33.17/fvm/context.go (about) 1 package fvm 2 3 import ( 4 "math" 5 6 "github.com/rs/zerolog" 7 otelTrace "go.opentelemetry.io/otel/trace" 8 9 "github.com/onflow/flow-go/fvm/environment" 10 reusableRuntime "github.com/onflow/flow-go/fvm/runtime" 11 "github.com/onflow/flow-go/fvm/storage/derived" 12 "github.com/onflow/flow-go/fvm/storage/state" 13 "github.com/onflow/flow-go/fvm/tracing" 14 "github.com/onflow/flow-go/model/flow" 15 "github.com/onflow/flow-go/module" 16 ) 17 18 const ( 19 AccountKeyWeightThreshold = 1000 20 21 DefaultComputationLimit = 100_000 // 100K 22 DefaultMemoryLimit = math.MaxUint64 23 DefaultMaxInteractionSize = 20_000_000 // ~20MB 24 ) 25 26 // A Context defines a set of execution parameters used by the virtual machine. 27 type Context struct { 28 // DisableMemoryAndInteractionLimits will override memory and interaction 29 // limits and set them to MaxUint64, effectively disabling these limits. 30 DisableMemoryAndInteractionLimits bool 31 EVMEnabled bool 32 ComputationLimit uint64 33 MemoryLimit uint64 34 MaxStateKeySize uint64 35 MaxStateValueSize uint64 36 MaxStateInteractionSize uint64 37 38 TransactionExecutorParams 39 40 DerivedBlockData *derived.DerivedBlockData 41 42 tracing.TracerSpan 43 44 environment.EnvironmentParams 45 } 46 47 // NewContext initializes a new execution context with the provided options. 48 func NewContext(opts ...Option) Context { 49 return newContext(defaultContext(), opts...) 50 } 51 52 // NewContextFromParent spawns a child execution context with the provided options. 53 func NewContextFromParent(parent Context, opts ...Option) Context { 54 return newContext(parent, opts...) 55 } 56 57 func newContext(ctx Context, opts ...Option) Context { 58 for _, applyOption := range opts { 59 ctx = applyOption(ctx) 60 } 61 62 return ctx 63 } 64 65 func defaultContext() Context { 66 return Context{ 67 DisableMemoryAndInteractionLimits: false, 68 ComputationLimit: DefaultComputationLimit, 69 MemoryLimit: DefaultMemoryLimit, 70 MaxStateKeySize: state.DefaultMaxKeySize, 71 MaxStateValueSize: state.DefaultMaxValueSize, 72 MaxStateInteractionSize: DefaultMaxInteractionSize, 73 TransactionExecutorParams: DefaultTransactionExecutorParams(), 74 EnvironmentParams: environment.DefaultEnvironmentParams(), 75 } 76 } 77 78 // An Option sets a configuration parameter for a virtual machine context. 79 type Option func(ctx Context) Context 80 81 // WithChain sets the chain parameters for a virtual machine context. 82 func WithChain(chain flow.Chain) Option { 83 return func(ctx Context) Context { 84 ctx.Chain = chain 85 return ctx 86 } 87 } 88 89 // WithGasLimit sets the computation limit for a virtual machine context. 90 // @depricated, please use WithComputationLimit instead. 91 func WithGasLimit(limit uint64) Option { 92 return func(ctx Context) Context { 93 ctx.ComputationLimit = limit 94 return ctx 95 } 96 } 97 98 // WithMemoryAndInteractionLimitsDisabled will override memory and interaction 99 // limits and set them to MaxUint64, effectively disabling these limits. 100 func WithMemoryAndInteractionLimitsDisabled() Option { 101 return func(ctx Context) Context { 102 ctx.DisableMemoryAndInteractionLimits = true 103 return ctx 104 } 105 } 106 107 // WithComputationLimit sets the computation limit for a virtual machine context. 108 func WithComputationLimit(limit uint64) Option { 109 return func(ctx Context) Context { 110 ctx.ComputationLimit = limit 111 return ctx 112 } 113 } 114 115 // WithMemoryLimit sets the memory limit for a virtual machine context. 116 func WithMemoryLimit(limit uint64) Option { 117 return func(ctx Context) Context { 118 ctx.MemoryLimit = limit 119 return ctx 120 } 121 } 122 123 // WithLogger sets the context logger 124 func WithLogger(logger zerolog.Logger) Option { 125 return func(ctx Context) Context { 126 ctx.Logger = logger 127 return ctx 128 } 129 } 130 131 // WithMaxStateKeySize sets the byte size limit for ledger keys 132 func WithMaxStateKeySize(limit uint64) Option { 133 return func(ctx Context) Context { 134 ctx.MaxStateKeySize = limit 135 return ctx 136 } 137 } 138 139 // WithMaxStateValueSize sets the byte size limit for ledger values 140 func WithMaxStateValueSize(limit uint64) Option { 141 return func(ctx Context) Context { 142 ctx.MaxStateValueSize = limit 143 return ctx 144 } 145 } 146 147 // WithMaxStateInteractionSize sets the byte size limit for total interaction with ledger. 148 // this prevents attacks such as reading all large registers 149 func WithMaxStateInteractionSize(limit uint64) Option { 150 return func(ctx Context) Context { 151 ctx.MaxStateInteractionSize = limit 152 return ctx 153 } 154 } 155 156 // WithEventCollectionSizeLimit sets the event collection byte size limit for a virtual machine context. 157 func WithEventCollectionSizeLimit(limit uint64) Option { 158 return func(ctx Context) Context { 159 ctx.EventCollectionByteSizeLimit = limit 160 return ctx 161 } 162 } 163 164 // WithEntropyProvider sets the entropy provider of a virtual machine context. 165 // 166 // The VM uses the input to provide entropy to the Cadence runtime randomness functions. 167 func WithEntropyProvider(source environment.EntropyProvider) Option { 168 return func(ctx Context) Context { 169 ctx.EntropyProvider = source 170 return ctx 171 } 172 } 173 174 // WithBlockHeader sets the block header for a virtual machine context. 175 // 176 // The VM uses the header to provide current block information to the Cadence runtime. 177 func WithBlockHeader(header *flow.Header) Option { 178 return func(ctx Context) Context { 179 ctx.BlockHeader = header 180 return ctx 181 } 182 } 183 184 // WithServiceEventCollectionEnabled enables service event collection 185 func WithServiceEventCollectionEnabled() Option { 186 return func(ctx Context) Context { 187 ctx.ServiceEventCollectionEnabled = true 188 return ctx 189 } 190 } 191 192 // WithBlocks sets the block storage provider for a virtual machine context. 193 // 194 // The VM uses the block storage provider to provide historical block information to 195 // the Cadence runtime. 196 func WithBlocks(blocks environment.Blocks) Option { 197 return func(ctx Context) Context { 198 ctx.Blocks = blocks 199 return ctx 200 } 201 } 202 203 // WithMetricsReporter sets the metrics collector for a virtual machine context. 204 // 205 // A metrics collector is used to gather metrics reported by the Cadence runtime. 206 func WithMetricsReporter(mr environment.MetricsReporter) Option { 207 return func(ctx Context) Context { 208 if mr != nil { 209 ctx.MetricsReporter = mr 210 } 211 return ctx 212 } 213 } 214 215 // WithTracer sets the tracer for a virtual machine context. 216 func WithTracer(tr module.Tracer) Option { 217 return func(ctx Context) Context { 218 ctx.Tracer = tr 219 return ctx 220 } 221 } 222 223 // WithSpan sets the trace span for a virtual machine context. 224 func WithSpan(span otelTrace.Span) Option { 225 return func(ctx Context) Context { 226 ctx.Span = span 227 return ctx 228 } 229 } 230 231 // WithExtensiveTracing sets the extensive tracing 232 func WithExtensiveTracing() Option { 233 return func(ctx Context) Context { 234 ctx.ExtensiveTracing = true 235 return ctx 236 } 237 } 238 239 // WithServiceAccount enables or disables calls to the Flow service account. 240 func WithServiceAccount(enabled bool) Option { 241 return func(ctx Context) Context { 242 ctx.ServiceAccountEnabled = enabled 243 return ctx 244 } 245 } 246 247 // WithRestrictContractRemoval enables or disables restricted contract removal for a 248 // virtual machine context. Warning! this would be overridden with the flag stored on chain. 249 // this is just a fallback value 250 func WithContractRemovalRestricted(enabled bool) Option { 251 return func(ctx Context) Context { 252 ctx.RestrictContractRemoval = enabled 253 return ctx 254 } 255 } 256 257 // WithRestrictedContractDeployment enables or disables restricted contract deployment for a 258 // virtual machine context. Warning! this would be overridden with the flag stored on chain. 259 // this is just a fallback value 260 func WithContractDeploymentRestricted(enabled bool) Option { 261 return func(ctx Context) Context { 262 ctx.RestrictContractDeployment = enabled 263 return ctx 264 } 265 } 266 267 // WithCadenceLogging enables or disables Cadence logging for a 268 // virtual machine context. 269 func WithCadenceLogging(enabled bool) Option { 270 return func(ctx Context) Context { 271 ctx.CadenceLoggingEnabled = enabled 272 return ctx 273 } 274 } 275 276 // WithAccountStorageLimit enables or disables checking if account storage used is 277 // over its storage capacity 278 func WithAccountStorageLimit(enabled bool) Option { 279 return func(ctx Context) Context { 280 ctx.LimitAccountStorage = enabled 281 return ctx 282 } 283 } 284 285 // WithAuthorizationCheckxEnabled enables or disables pre-execution 286 // authorization checks. 287 func WithAuthorizationChecksEnabled(enabled bool) Option { 288 return func(ctx Context) Context { 289 ctx.AuthorizationChecksEnabled = enabled 290 return ctx 291 } 292 } 293 294 // WithSequenceNumberCheckAndIncrementEnabled enables or disables pre-execution 295 // sequence number check / increment. 296 func WithSequenceNumberCheckAndIncrementEnabled(enabled bool) Option { 297 return func(ctx Context) Context { 298 ctx.SequenceNumberCheckAndIncrementEnabled = enabled 299 return ctx 300 } 301 } 302 303 // WithAccountKeyWeightThreshold sets the key weight threshold used for 304 // authorization checks. If the threshold is a negative number, signature 305 // verification is skipped. 306 // 307 // Note: This is set only by tests 308 func WithAccountKeyWeightThreshold(threshold int) Option { 309 return func(ctx Context) Context { 310 ctx.AccountKeyWeightThreshold = threshold 311 return ctx 312 } 313 } 314 315 // WithTransactionBodyExecutionEnabled enables or disables the transaction body 316 // execution. 317 // 318 // Note: This is disabled only by tests 319 func WithTransactionBodyExecutionEnabled(enabled bool) Option { 320 return func(ctx Context) Context { 321 ctx.TransactionBodyExecutionEnabled = enabled 322 return ctx 323 } 324 } 325 326 // WithTransactionFeesEnabled enables or disables deduction of transaction fees 327 func WithTransactionFeesEnabled(enabled bool) Option { 328 return func(ctx Context) Context { 329 ctx.TransactionFeesEnabled = enabled 330 return ctx 331 } 332 } 333 334 // WithRandomSourceHistoryCallAllowed enables or disables calling the `entropy` function 335 // within cadence 336 func WithRandomSourceHistoryCallAllowed(allowed bool) Option { 337 return func(ctx Context) Context { 338 ctx.RandomSourceHistoryCallAllowed = allowed 339 return ctx 340 } 341 } 342 343 // WithReusableCadenceRuntimePool set the (shared) RedusableCadenceRuntimePool 344 // use for creating the cadence runtime. 345 func WithReusableCadenceRuntimePool( 346 pool reusableRuntime.ReusableCadenceRuntimePool, 347 ) Option { 348 return func(ctx Context) Context { 349 ctx.ReusableCadenceRuntimePool = pool 350 return ctx 351 } 352 } 353 354 // WithDerivedBlockData sets the derived data cache storage to be used by the 355 // transaction/script. 356 func WithDerivedBlockData(derivedBlockData *derived.DerivedBlockData) Option { 357 return func(ctx Context) Context { 358 ctx.DerivedBlockData = derivedBlockData 359 return ctx 360 } 361 } 362 363 // WithEventEncoder sets events encoder to be used for encoding events emitted during execution 364 func WithEventEncoder(encoder environment.EventEncoder) Option { 365 return func(ctx Context) Context { 366 ctx.EventEncoder = encoder 367 return ctx 368 } 369 } 370 371 // WithEVMEnabled enables access to the evm environment 372 func WithEVMEnabled(enabled bool) Option { 373 return func(ctx Context) Context { 374 ctx.EVMEnabled = enabled 375 return ctx 376 } 377 }