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