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  }