github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/fvm/executionParameters_test.go (about) 1 package fvm_test 2 3 import ( 4 "fmt" 5 "testing" 6 7 "github.com/stretchr/testify/mock" 8 "github.com/stretchr/testify/require" 9 10 "github.com/onflow/cadence" 11 "github.com/onflow/cadence/runtime" 12 "github.com/onflow/cadence/runtime/common" 13 14 "github.com/onflow/flow-go/fvm" 15 "github.com/onflow/flow-go/fvm/blueprints" 16 "github.com/onflow/flow-go/fvm/environment" 17 fvmmock "github.com/onflow/flow-go/fvm/environment/mock" 18 "github.com/onflow/flow-go/fvm/errors" 19 "github.com/onflow/flow-go/fvm/meter" 20 reusableRuntime "github.com/onflow/flow-go/fvm/runtime" 21 "github.com/onflow/flow-go/fvm/runtime/testutil" 22 ) 23 24 func TestGetExecutionMemoryWeights(t *testing.T) { 25 address := common.Address{} 26 27 setupEnvMock := func(readStored func( 28 address common.Address, 29 path cadence.Path, 30 context runtime.Context, 31 ) (cadence.Value, error)) environment.Environment { 32 envMock := &fvmmock.Environment{} 33 envMock.On("BorrowCadenceRuntime", mock.Anything).Return( 34 reusableRuntime.NewReusableCadenceRuntime( 35 &testutil.TestInterpreterRuntime{ 36 ReadStoredFunc: readStored, 37 }, 38 runtime.Config{}, 39 ), 40 ) 41 envMock.On("ReturnCadenceRuntime", mock.Anything).Return() 42 return envMock 43 } 44 45 t.Run("return error if nothing is stored", 46 func(t *testing.T) { 47 envMock := setupEnvMock( 48 func(address common.Address, path cadence.Path, context runtime.Context) (cadence.Value, error) { 49 return nil, nil 50 }) 51 _, err := fvm.GetExecutionMemoryWeights(envMock, address) 52 require.Error(t, err) 53 require.EqualError(t, err, errors.NewCouldNotGetExecutionParameterFromStateError( 54 address.Hex(), 55 blueprints.TransactionFeesExecutionMemoryWeightsPath.String()).Error()) 56 }, 57 ) 58 t.Run("return error if can't parse stored", 59 func(t *testing.T) { 60 envMock := setupEnvMock( 61 func(address common.Address, path cadence.Path, context runtime.Context) (cadence.Value, error) { 62 return cadence.NewBool(false), nil 63 }) 64 _, err := fvm.GetExecutionMemoryWeights(envMock, address) 65 require.Error(t, err) 66 require.EqualError(t, err, errors.NewCouldNotGetExecutionParameterFromStateError( 67 address.Hex(), 68 blueprints.TransactionFeesExecutionMemoryWeightsPath.String()).Error()) 69 }, 70 ) 71 t.Run("return error if get stored returns error", 72 func(t *testing.T) { 73 someErr := fmt.Errorf("some error") 74 envMock := setupEnvMock( 75 func(address common.Address, path cadence.Path, context runtime.Context) (cadence.Value, error) { 76 return nil, someErr 77 }) 78 _, err := fvm.GetExecutionMemoryWeights(envMock, address) 79 require.Error(t, err) 80 require.EqualError(t, err, someErr.Error()) 81 }, 82 ) 83 t.Run("return error if get stored returns error", 84 func(t *testing.T) { 85 someErr := fmt.Errorf("some error") 86 envMock := setupEnvMock( 87 func(address common.Address, path cadence.Path, context runtime.Context) (cadence.Value, error) { 88 return nil, someErr 89 }) 90 _, err := fvm.GetExecutionMemoryWeights(envMock, address) 91 require.Error(t, err) 92 require.EqualError(t, err, someErr.Error()) 93 }, 94 ) 95 t.Run("no error if a dictionary is stored", 96 func(t *testing.T) { 97 envMock := setupEnvMock( 98 func(address common.Address, path cadence.Path, context runtime.Context) (cadence.Value, error) { 99 return cadence.NewDictionary([]cadence.KeyValuePair{}), nil 100 }) 101 _, err := fvm.GetExecutionMemoryWeights(envMock, address) 102 require.NoError(t, err) 103 }, 104 ) 105 t.Run("return defaults if empty dict is stored", 106 func(t *testing.T) { 107 envMock := setupEnvMock( 108 func(address common.Address, path cadence.Path, context runtime.Context) (cadence.Value, error) { 109 return cadence.NewDictionary([]cadence.KeyValuePair{}), nil 110 }) 111 weights, err := fvm.GetExecutionMemoryWeights(envMock, address) 112 require.NoError(t, err) 113 require.InDeltaMapValues(t, meter.DefaultMemoryWeights, weights, 0) 114 }, 115 ) 116 t.Run("return merged if some dict is stored", 117 func(t *testing.T) { 118 expectedWeights := meter.ExecutionMemoryWeights{} 119 var existingWeightKey common.MemoryKind 120 var existingWeightValue uint64 121 for k, v := range meter.DefaultMemoryWeights { 122 expectedWeights[k] = v 123 } 124 // change one existing value 125 for kind, u := range meter.DefaultMemoryWeights { 126 existingWeightKey = kind 127 existingWeightValue = u 128 expectedWeights[kind] = u + 1 129 break 130 } 131 expectedWeights[0] = 0 132 133 envMock := setupEnvMock( 134 func(address common.Address, path cadence.Path, context runtime.Context) (cadence.Value, error) { 135 return cadence.NewDictionary([]cadence.KeyValuePair{ 136 { 137 Value: cadence.UInt64(0), 138 Key: cadence.UInt64(0), 139 }, // a new key 140 { 141 Value: cadence.UInt64(existingWeightValue + 1), 142 Key: cadence.UInt64(existingWeightKey), 143 }, // existing key with new value 144 }), nil 145 }) 146 147 weights, err := fvm.GetExecutionMemoryWeights(envMock, address) 148 require.NoError(t, err) 149 require.InDeltaMapValues(t, expectedWeights, weights, 0) 150 }, 151 ) 152 } 153 154 func TestGetExecutionEffortWeights(t *testing.T) { 155 address := common.Address{} 156 157 setupEnvMock := func(readStored func( 158 address common.Address, 159 path cadence.Path, 160 context runtime.Context, 161 ) (cadence.Value, error)) environment.Environment { 162 envMock := &fvmmock.Environment{} 163 envMock.On("BorrowCadenceRuntime", mock.Anything).Return( 164 reusableRuntime.NewReusableCadenceRuntime( 165 &testutil.TestInterpreterRuntime{ 166 ReadStoredFunc: readStored, 167 }, 168 runtime.Config{}, 169 ), 170 ) 171 envMock.On("ReturnCadenceRuntime", mock.Anything).Return() 172 return envMock 173 } 174 175 t.Run("return error if nothing is stored", 176 func(t *testing.T) { 177 envMock := setupEnvMock( 178 func(address common.Address, path cadence.Path, context runtime.Context) (cadence.Value, error) { 179 return nil, nil 180 }) 181 _, err := fvm.GetExecutionEffortWeights(envMock, address) 182 require.Error(t, err) 183 require.EqualError(t, err, errors.NewCouldNotGetExecutionParameterFromStateError( 184 address.Hex(), 185 blueprints.TransactionFeesExecutionEffortWeightsPath.String()).Error()) 186 }, 187 ) 188 t.Run("return error if can't parse stored", 189 func(t *testing.T) { 190 envMock := setupEnvMock( 191 func(address common.Address, path cadence.Path, context runtime.Context) (cadence.Value, error) { 192 return cadence.NewBool(false), nil 193 }) 194 _, err := fvm.GetExecutionEffortWeights(envMock, address) 195 require.Error(t, err) 196 require.EqualError(t, err, errors.NewCouldNotGetExecutionParameterFromStateError( 197 address.Hex(), 198 blueprints.TransactionFeesExecutionEffortWeightsPath.String()).Error()) 199 }, 200 ) 201 t.Run("return error if get stored returns error", 202 func(t *testing.T) { 203 someErr := fmt.Errorf("some error") 204 envMock := setupEnvMock( 205 func(address common.Address, path cadence.Path, context runtime.Context) (cadence.Value, error) { 206 return nil, someErr 207 }) 208 _, err := fvm.GetExecutionEffortWeights(envMock, address) 209 require.Error(t, err) 210 require.EqualError(t, err, someErr.Error()) 211 }, 212 ) 213 t.Run("return error if get stored returns error", 214 func(t *testing.T) { 215 someErr := fmt.Errorf("some error") 216 envMock := setupEnvMock( 217 func(address common.Address, path cadence.Path, context runtime.Context) (cadence.Value, error) { 218 return nil, someErr 219 }) 220 _, err := fvm.GetExecutionEffortWeights(envMock, address) 221 require.Error(t, err) 222 require.EqualError(t, err, someErr.Error()) 223 }, 224 ) 225 t.Run("no error if a dictionary is stored", 226 func(t *testing.T) { 227 envMock := setupEnvMock( 228 func(address common.Address, path cadence.Path, context runtime.Context) (cadence.Value, error) { 229 return cadence.NewDictionary([]cadence.KeyValuePair{}), nil 230 }) 231 _, err := fvm.GetExecutionEffortWeights(envMock, address) 232 require.NoError(t, err) 233 }, 234 ) 235 t.Run("return defaults if empty dict is stored", 236 func(t *testing.T) { 237 envMock := setupEnvMock( 238 func(address common.Address, path cadence.Path, context runtime.Context) (cadence.Value, error) { 239 return cadence.NewDictionary([]cadence.KeyValuePair{}), nil 240 }) 241 weights, err := fvm.GetExecutionEffortWeights(envMock, address) 242 require.NoError(t, err) 243 require.InDeltaMapValues(t, meter.DefaultComputationWeights, weights, 0) 244 }, 245 ) 246 t.Run("return merged if some dict is stored", 247 func(t *testing.T) { 248 expectedWeights := meter.ExecutionEffortWeights{} 249 var existingWeightKey common.ComputationKind 250 var existingWeightValue uint64 251 for k, v := range meter.DefaultComputationWeights { 252 expectedWeights[k] = v 253 } 254 // change one existing value 255 for kind, u := range meter.DefaultComputationWeights { 256 existingWeightKey = kind 257 existingWeightValue = u 258 expectedWeights[kind] = u + 1 259 break 260 } 261 expectedWeights[0] = 0 262 263 envMock := setupEnvMock( 264 func(address common.Address, path cadence.Path, context runtime.Context) (cadence.Value, error) { 265 return cadence.NewDictionary([]cadence.KeyValuePair{ 266 { 267 Value: cadence.UInt64(0), 268 Key: cadence.UInt64(0), 269 }, // a new key 270 { 271 Value: cadence.UInt64(existingWeightValue + 1), 272 Key: cadence.UInt64(existingWeightKey), 273 }, // existing key with new value 274 }), nil 275 }) 276 277 weights, err := fvm.GetExecutionEffortWeights(envMock, address) 278 require.NoError(t, err) 279 require.InDeltaMapValues(t, expectedWeights, weights, 0) 280 }, 281 ) 282 }