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