github.com/onflow/flow-go@v0.33.17/fvm/meter/memory_meter.go (about)

     1  package meter
     2  
     3  import (
     4  	"math"
     5  
     6  	"github.com/onflow/cadence/runtime/common"
     7  
     8  	"github.com/onflow/flow-go/fvm/errors"
     9  )
    10  
    11  var (
    12  	// DefaultMemoryWeights are currently hard-coded here. In the future we might like to
    13  	// define this in a contract similar to the computation weights
    14  	DefaultMemoryWeights = ExecutionMemoryWeights{
    15  
    16  		// Values
    17  
    18  		common.MemoryKindAddressValue:   32,
    19  		common.MemoryKindStringValue:    138,
    20  		common.MemoryKindCharacterValue: 24,
    21  		common.MemoryKindNumberValue:    8,
    22  		// weights for these values include the cost of the Go struct itself (first number)
    23  		// as well as the overhead for creation of the underlying atree (second number)
    24  		common.MemoryKindArrayValueBase:                   57 + 48,
    25  		common.MemoryKindDictionaryValueBase:              33 + 96,
    26  		common.MemoryKindCompositeValueBase:               233 + 96,
    27  		common.MemoryKindSimpleCompositeValue:             73,
    28  		common.MemoryKindSimpleCompositeValueBase:         89,
    29  		common.MemoryKindOptionalValue:                    41,
    30  		common.MemoryKindTypeValue:                        17,
    31  		common.MemoryKindPathValue:                        24,
    32  		common.MemoryKindPathCapabilityValue:              1,
    33  		common.MemoryKindIDCapabilityValue:                1,
    34  		common.MemoryKindPathLinkValue:                    1,
    35  		common.MemoryKindStorageCapabilityControllerValue: 32,
    36  		common.MemoryKindAccountCapabilityControllerValue: 32,
    37  		common.MemoryKindAccountLinkValue:                 1,
    38  		common.MemoryKindAccountReferenceValue:            1,
    39  		common.MemoryKindPublishedValue:                   1,
    40  		common.MemoryKindStorageReferenceValue:            41,
    41  		common.MemoryKindEphemeralReferenceValue:          41,
    42  		common.MemoryKindInterpretedFunctionValue:         128,
    43  		common.MemoryKindHostFunctionValue:                41,
    44  		common.MemoryKindBoundFunctionValue:               25,
    45  		common.MemoryKindBigInt:                           50,
    46  		common.MemoryKindVoidExpression:                   1,
    47  
    48  		// Atree
    49  
    50  		common.MemoryKindAtreeArrayDataSlab:          80,
    51  		common.MemoryKindAtreeArrayMetaDataSlab:      1024,
    52  		common.MemoryKindAtreeArrayElementOverhead:   16,
    53  		common.MemoryKindAtreeMapDataSlab:            144,
    54  		common.MemoryKindAtreeMapMetaDataSlab:        1024,
    55  		common.MemoryKindAtreeMapElementOverhead:     64,
    56  		common.MemoryKindAtreeMapPreAllocatedElement: 24,
    57  		common.MemoryKindAtreeEncodedSlab:            1536,
    58  
    59  		// Static Types
    60  
    61  		common.MemoryKindPrimitiveStaticType:     8,
    62  		common.MemoryKindCompositeStaticType:     17,
    63  		common.MemoryKindInterfaceStaticType:     17,
    64  		common.MemoryKindVariableSizedStaticType: 17,
    65  		common.MemoryKindConstantSizedStaticType: 25,
    66  		common.MemoryKindDictionaryStaticType:    33,
    67  		common.MemoryKindOptionalStaticType:      17,
    68  		common.MemoryKindRestrictedStaticType:    41,
    69  		common.MemoryKindReferenceStaticType:     41,
    70  		common.MemoryKindCapabilityStaticType:    17,
    71  		common.MemoryKindFunctionStaticType:      9,
    72  
    73  		// Cadence Values
    74  
    75  		common.MemoryKindCadenceVoidValue:           1,
    76  		common.MemoryKindCadenceOptionalValue:       17,
    77  		common.MemoryKindCadenceBoolValue:           8,
    78  		common.MemoryKindCadenceStringValue:         16,
    79  		common.MemoryKindCadenceCharacterValue:      16,
    80  		common.MemoryKindCadenceAddressValue:        8,
    81  		common.MemoryKindCadenceIntValue:            50,
    82  		common.MemoryKindCadenceNumberValue:         1,
    83  		common.MemoryKindCadenceArrayValueBase:      41,
    84  		common.MemoryKindCadenceArrayValueLength:    16,
    85  		common.MemoryKindCadenceDictionaryValue:     41,
    86  		common.MemoryKindCadenceKeyValuePair:        33,
    87  		common.MemoryKindCadenceStructValueBase:     33,
    88  		common.MemoryKindCadenceStructValueSize:     16,
    89  		common.MemoryKindCadenceResourceValueBase:   33,
    90  		common.MemoryKindCadenceResourceValueSize:   16,
    91  		common.MemoryKindCadenceEventValueBase:      33,
    92  		common.MemoryKindCadenceEventValueSize:      16,
    93  		common.MemoryKindCadenceContractValueBase:   33,
    94  		common.MemoryKindCadenceContractValueSize:   16,
    95  		common.MemoryKindCadenceEnumValueBase:       33,
    96  		common.MemoryKindCadenceEnumValueSize:       16,
    97  		common.MemoryKindCadencePathLinkValue:       1,
    98  		common.MemoryKindCadenceAccountLinkValue:    1,
    99  		common.MemoryKindCadencePathValue:           33,
   100  		common.MemoryKindCadenceTypeValue:           17,
   101  		common.MemoryKindCadencePathCapabilityValue: 1,
   102  		common.MemoryKindCadenceIDCapabilityValue:   1,
   103  		common.MemoryKindCadenceFunctionValue:       1,
   104  		common.MemoryKindCadenceAttachmentValueBase: 33,
   105  		common.MemoryKindCadenceAttachmentValueSize: 16,
   106  
   107  		// Cadence Types
   108  
   109  		common.MemoryKindCadenceTypeParameter:          17,
   110  		common.MemoryKindCadenceOptionalType:           17,
   111  		common.MemoryKindCadenceVariableSizedArrayType: 17,
   112  		common.MemoryKindCadenceConstantSizedArrayType: 25,
   113  		common.MemoryKindCadenceDictionaryType:         33,
   114  		common.MemoryKindCadenceField:                  33,
   115  		common.MemoryKindCadenceParameter:              49,
   116  		common.MemoryKindCadenceStructType:             81,
   117  		common.MemoryKindCadenceResourceType:           81,
   118  		common.MemoryKindCadenceEventType:              81,
   119  		common.MemoryKindCadenceContractType:           81,
   120  		common.MemoryKindCadenceStructInterfaceType:    81,
   121  		common.MemoryKindCadenceResourceInterfaceType:  81,
   122  		common.MemoryKindCadenceContractInterfaceType:  81,
   123  		common.MemoryKindCadenceFunctionType:           41,
   124  		common.MemoryKindCadenceReferenceType:          25,
   125  		common.MemoryKindCadenceRestrictedType:         57,
   126  		common.MemoryKindCadenceCapabilityType:         17,
   127  		common.MemoryKindCadenceEnumType:               97,
   128  		common.MemoryKindCadenceAttachmentType:         81,
   129  
   130  		// Misc
   131  
   132  		common.MemoryKindRawString:         9,
   133  		common.MemoryKindAddressLocation:   18,
   134  		common.MemoryKindBytes:             24,
   135  		common.MemoryKindVariable:          18,
   136  		common.MemoryKindCompositeTypeInfo: 41,
   137  		common.MemoryKindCompositeField:    33,
   138  		common.MemoryKindInvocation:        89,
   139  		common.MemoryKindStorageMap:        58,
   140  		common.MemoryKindStorageKey:        41,
   141  
   142  		// Tokens
   143  
   144  		common.MemoryKindErrorToken: 41,
   145  		common.MemoryKindTypeToken:  25,
   146  		common.MemoryKindSpaceToken: 50,
   147  
   148  		// AST nodes
   149  
   150  		common.MemoryKindProgram:           220,
   151  		common.MemoryKindIdentifier:        17,
   152  		common.MemoryKindArgument:          49,
   153  		common.MemoryKindBlock:             25,
   154  		common.MemoryKindFunctionBlock:     25,
   155  		common.MemoryKindParameter:         25,
   156  		common.MemoryKindParameterList:     59,
   157  		common.MemoryKindTypeParameter:     9,
   158  		common.MemoryKindTypeParameterList: 59,
   159  		common.MemoryKindTransfer:          1,
   160  		common.MemoryKindMembers:           276,
   161  		common.MemoryKindTypeAnnotation:    25,
   162  		common.MemoryKindDictionaryEntry:   33,
   163  
   164  		common.MemoryKindFunctionDeclaration:        49,
   165  		common.MemoryKindCompositeDeclaration:       65,
   166  		common.MemoryKindInterfaceDeclaration:       41,
   167  		common.MemoryKindEnumCaseDeclaration:        25,
   168  		common.MemoryKindFieldDeclaration:           41,
   169  		common.MemoryKindTransactionDeclaration:     81,
   170  		common.MemoryKindImportDeclaration:          41,
   171  		common.MemoryKindVariableDeclaration:        97,
   172  		common.MemoryKindSpecialFunctionDeclaration: 17,
   173  		common.MemoryKindPragmaDeclaration:          17,
   174  		common.MemoryKindAttachmentDeclaration:      70,
   175  
   176  		common.MemoryKindAssignmentStatement: 41,
   177  		common.MemoryKindBreakStatement:      1,
   178  		common.MemoryKindContinueStatement:   1,
   179  		common.MemoryKindEmitStatement:       9,
   180  		common.MemoryKindExpressionStatement: 17,
   181  		common.MemoryKindForStatement:        33,
   182  		common.MemoryKindIfStatement:         33,
   183  		common.MemoryKindReturnStatement:     17,
   184  		common.MemoryKindSwapStatement:       33,
   185  		common.MemoryKindSwitchStatement:     41,
   186  		common.MemoryKindWhileStatement:      25,
   187  		common.MemoryKindRemoveStatement:     33,
   188  
   189  		common.MemoryKindBooleanExpression:     9,
   190  		common.MemoryKindNilExpression:         1,
   191  		common.MemoryKindStringExpression:      17,
   192  		common.MemoryKindIntegerExpression:     33,
   193  		common.MemoryKindFixedPointExpression:  49,
   194  		common.MemoryKindArrayExpression:       25,
   195  		common.MemoryKindDictionaryExpression:  25,
   196  		common.MemoryKindIdentifierExpression:  1,
   197  		common.MemoryKindInvocationExpression:  49,
   198  		common.MemoryKindMemberExpression:      25,
   199  		common.MemoryKindIndexExpression:       33,
   200  		common.MemoryKindConditionalExpression: 49,
   201  		common.MemoryKindUnaryExpression:       25,
   202  		common.MemoryKindBinaryExpression:      41,
   203  		common.MemoryKindFunctionExpression:    25,
   204  		common.MemoryKindCastingExpression:     41,
   205  		common.MemoryKindCreateExpression:      9,
   206  		common.MemoryKindDestroyExpression:     17,
   207  		common.MemoryKindReferenceExpression:   33,
   208  		common.MemoryKindForceExpression:       17,
   209  		common.MemoryKindPathExpression:        1,
   210  		common.MemoryKindAttachExpression:      33,
   211  
   212  		common.MemoryKindConstantSizedType: 25,
   213  		common.MemoryKindDictionaryType:    33,
   214  		common.MemoryKindFunctionType:      33,
   215  		common.MemoryKindInstantiationType: 41,
   216  		common.MemoryKindNominalType:       25,
   217  		common.MemoryKindOptionalType:      17,
   218  		common.MemoryKindReferenceType:     25,
   219  		common.MemoryKindRestrictedType:    41,
   220  		common.MemoryKindVariableSizedType: 17,
   221  
   222  		common.MemoryKindPosition:          25,
   223  		common.MemoryKindRange:             1,
   224  		common.MemoryKindActivation:        128,
   225  		common.MemoryKindActivationEntries: 256,
   226  		common.MemoryKindElaboration:       501,
   227  
   228  		// sema types
   229  		common.MemoryKindVariableSizedSemaType: 51,
   230  		common.MemoryKindConstantSizedSemaType: 59,
   231  		common.MemoryKindDictionarySemaType:    67,
   232  		common.MemoryKindOptionalSemaType:      17,
   233  		common.MemoryKindRestrictedSemaType:    75,
   234  		common.MemoryKindReferenceSemaType:     25,
   235  		common.MemoryKindCapabilitySemaType:    51,
   236  
   237  		// ordered-map
   238  		common.MemoryKindOrderedMap:          17,
   239  		common.MemoryKindOrderedMapEntryList: 50,
   240  		common.MemoryKindOrderedMapEntry:     64,
   241  	}
   242  )
   243  
   244  func _() {
   245  	// A compiler error signifies that we have not accounted for all memory kinds
   246  	var x [1]struct{}
   247  	_ = x[int(common.MemoryKindLast)-len(DefaultMemoryWeights)-1]
   248  }
   249  
   250  type ExecutionMemoryWeights map[common.MemoryKind]uint64
   251  type MeteredMemoryIntensities map[common.MemoryKind]uint
   252  
   253  type MemoryMeterParameters struct {
   254  	memoryLimit   uint64
   255  	memoryWeights ExecutionMemoryWeights
   256  }
   257  
   258  func DefaultMemoryParameters() MemoryMeterParameters {
   259  	return MemoryMeterParameters{
   260  		memoryLimit:   math.MaxUint64,
   261  		memoryWeights: DefaultMemoryWeights,
   262  	}
   263  }
   264  
   265  func (params MemoryMeterParameters) MemoryWeights() ExecutionMemoryWeights {
   266  	return params.memoryWeights
   267  }
   268  
   269  // TotalMemoryLimit returns the total memory limit
   270  func (params MemoryMeterParameters) TotalMemoryLimit() uint64 {
   271  	return params.memoryLimit
   272  }
   273  
   274  func (params MeterParameters) WithMemoryLimit(limit uint64) MeterParameters {
   275  	newParams := params
   276  	newParams.memoryLimit = limit
   277  	return newParams
   278  }
   279  
   280  func (params MeterParameters) WithMemoryWeights(
   281  	weights ExecutionMemoryWeights,
   282  ) MeterParameters {
   283  	newParams := params
   284  	newParams.memoryWeights = weights
   285  	return newParams
   286  }
   287  
   288  type MemoryMeter struct {
   289  	params MemoryMeterParameters
   290  
   291  	memoryIntensities MeteredMemoryIntensities
   292  	memoryEstimate    uint64
   293  }
   294  
   295  // MemoryIntensities returns all the measured memory intensities
   296  func (m *MemoryMeter) MemoryIntensities() MeteredMemoryIntensities {
   297  	return m.memoryIntensities
   298  }
   299  
   300  // NewMemoryMeter constructs a new Meter
   301  func NewMemoryMeter(params MemoryMeterParameters) MemoryMeter {
   302  	m := MemoryMeter{
   303  		params:            params,
   304  		memoryIntensities: make(MeteredMemoryIntensities),
   305  	}
   306  
   307  	return m
   308  }
   309  
   310  // MeterMemory captures memory usage and returns an error if it goes beyond the limit
   311  func (m *MemoryMeter) MeterMemory(kind common.MemoryKind, intensity uint) error {
   312  	m.memoryIntensities[kind] += intensity
   313  	w, ok := m.params.memoryWeights[kind]
   314  	if !ok {
   315  		return nil
   316  	}
   317  	m.memoryEstimate += w * uint64(intensity)
   318  	if m.memoryEstimate > m.params.memoryLimit {
   319  		return errors.NewMemoryLimitExceededError(m.params.TotalMemoryLimit())
   320  	}
   321  	return nil
   322  }
   323  
   324  // TotalMemoryEstimate returns the total memory used
   325  func (m *MemoryMeter) TotalMemoryEstimate() uint64 {
   326  	return m.memoryEstimate
   327  }
   328  
   329  // Merge merges the input meter into the current meter and checks for the limits
   330  func (m *MemoryMeter) Merge(child MemoryMeter) {
   331  	m.memoryEstimate = m.memoryEstimate + child.TotalMemoryEstimate()
   332  
   333  	for key, intensity := range child.memoryIntensities {
   334  		m.memoryIntensities[key] += intensity
   335  	}
   336  }