github.com/koko1123/flow-go-1@v0.29.6/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/koko1123/flow-go-1/fvm"
    15  	"github.com/koko1123/flow-go-1/fvm/blueprints"
    16  	"github.com/koko1123/flow-go-1/fvm/environment"
    17  	fvmmock "github.com/koko1123/flow-go-1/fvm/environment/mock"
    18  	"github.com/koko1123/flow-go-1/fvm/errors"
    19  	"github.com/koko1123/flow-go-1/fvm/meter"
    20  	reusableRuntime "github.com/koko1123/flow-go-1/fvm/runtime"
    21  	"github.com/koko1123/flow-go-1/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  }