From 36e05e1593e51ed89648888aed42b8d073f7c4a0 Mon Sep 17 00:00:00 2001 From: bogdan-rosianu Date: Wed, 4 May 2022 12:36:23 +0300 Subject: [PATCH 1/4] extracted max gas limit for vm query to config --- cmd/node/config/config.toml | 3 + config/config.go | 1 + config/tomlConfig_test.go | 9 +++ factory/apiResolverFactory.go | 1 + process/smartContract/scQueryService.go | 7 +- process/smartContract/scQueryService_test.go | 79 ++++++++++++++++++++ 6 files changed, 99 insertions(+), 1 deletion(-) diff --git a/cmd/node/config/config.toml b/cmd/node/config/config.toml index 50a0d7ee1d0..2cbae7cd7c4 100644 --- a/cmd/node/config/config.toml +++ b/cmd/node/config/config.toml @@ -588,6 +588,9 @@ SameSourceRequests = 10000 # SameSourceResetIntervalInSec time frame between counter reset, in seconds SameSourceResetIntervalInSec = 1 + # MaxGasPerVmQuery defines the maximum amount of gas to be allocated for VM Queries comming from API + # If set to 0, then MaxUInt64 will be used + MaxGasPerVmQuery = 1500000000 #1.5b # EndpointsThrottlers represents a map for maximum simultaneous go routines for an endpoint EndpointsThrottlers = [{ Endpoint = "/transaction/:hash", MaxNumGoRoutines = 10 }, { Endpoint = "/transaction/send", MaxNumGoRoutines = 2 }, diff --git a/config/config.go b/config/config.go index 971af171c98..ca4885531f7 100644 --- a/config/config.go +++ b/config/config.go @@ -283,6 +283,7 @@ type EndpointsThrottlersConfig struct { // WebServerAntifloodConfig will hold the anti-flooding parameters for the web server type WebServerAntifloodConfig struct { + MaxGasPerVmQuery uint64 SimultaneousRequests uint32 SameSourceRequests uint32 SameSourceResetIntervalInSec uint32 diff --git a/config/tomlConfig_test.go b/config/tomlConfig_test.go index c99e4b8fc5e..79f694c161e 100644 --- a/config/tomlConfig_test.go +++ b/config/tomlConfig_test.go @@ -126,6 +126,11 @@ func TestTomlParser(t *testing.T) { DoProfileOnShuffleOut: true, }, }, + Antiflood: AntifloodConfig{ + WebServer: WebServerAntifloodConfig{ + MaxGasPerVmQuery: 1_500_000_000, + }, + }, } testString := ` [MiniBlocksStorage] @@ -174,6 +179,10 @@ func TestTomlParser(t *testing.T) { [Consensus] Type = "` + consensusType + `" +[Antiflood] + [Antiflood.WebServer] + MaxGasPerVmQuery = 1500000000 #1.5b + [VirtualMachine] [VirtualMachine.Execution] ArwenVersions = [ diff --git a/factory/apiResolverFactory.go b/factory/apiResolverFactory.go index 7fd72accba9..575ce8bcaf8 100644 --- a/factory/apiResolverFactory.go +++ b/factory/apiResolverFactory.go @@ -346,6 +346,7 @@ func createScQueryElement( ArwenChangeLocker: args.coreComponents.ArwenChangeLocker(), Bootstrapper: args.bootstrapper, AllowExternalQueriesChan: args.allowVMQueriesChan, + MaxGasLimitPerQuery: args.generalConfig.Antiflood.WebServer.MaxGasPerVmQuery, } return smartContract.NewSCQueryService(argsNewSCQueryService) diff --git a/process/smartContract/scQueryService.go b/process/smartContract/scQueryService.go index 2faa7b51dc4..d8831ea41cb 100644 --- a/process/smartContract/scQueryService.go +++ b/process/smartContract/scQueryService.go @@ -42,6 +42,7 @@ type ArgsNewSCQueryService struct { ArwenChangeLocker common.Locker Bootstrapper process.Bootstrapper AllowExternalQueriesChan chan struct{} + MaxGasLimitPerQuery uint64 } // NewSCQueryService returns a new instance of SCQueryService @@ -70,6 +71,10 @@ func NewSCQueryService( return nil, process.ErrNilAllowExternalQueriesChan } + gasForQuery := uint64(math.MaxUint64) + if args.MaxGasLimitPerQuery > 0 { + gasForQuery = args.MaxGasLimitPerQuery + } return &SCQueryService{ vmContainer: args.VmContainer, economicsFee: args.EconomicsFee, @@ -77,7 +82,7 @@ func NewSCQueryService( blockChainHook: args.BlockChainHook, arwenChangeLocker: args.ArwenChangeLocker, bootstrapper: args.Bootstrapper, - gasForQuery: math.MaxUint64, + gasForQuery: gasForQuery, allowExternalQueriesChan: args.AllowExternalQueriesChan, }, nil } diff --git a/process/smartContract/scQueryService_test.go b/process/smartContract/scQueryService_test.go index dd1bb2f8d23..ffab762b31d 100644 --- a/process/smartContract/scQueryService_test.go +++ b/process/smartContract/scQueryService_test.go @@ -308,6 +308,85 @@ func TestExecuteQuery_ReturnsCorrectly(t *testing.T) { assert.Equal(t, d[1], vmOutput.ReturnData[1]) } +func TestExecuteQuery_GasProvidedShouldBeApplied(t *testing.T) { + t.Parallel() + + t.Run("no gas defined, should use max uint64", func(t *testing.T) { + t.Parallel() + + runSCWasCalled := false + mockVM := &mock.VMExecutionHandlerStub{ + RunSmartContractCallCalled: func(input *vmcommon.ContractCallInput) (output *vmcommon.VMOutput, e error) { + require.Equal(t, uint64(math.MaxUint64), input.GasProvided) + runSCWasCalled = true + return &vmcommon.VMOutput{}, nil + }, + } + argsNewSCQuery := createMockArgumentsForSCQuery() + argsNewSCQuery.VmContainer = &mock.VMContainerMock{ + GetCalled: func(key []byte) (handler vmcommon.VMExecutionHandler, e error) { + return mockVM, nil + }, + } + argsNewSCQuery.EconomicsFee = &mock.FeeHandlerStub{ + MaxGasLimitPerBlockCalled: func() uint64 { + return uint64(math.MaxUint64) + }, + } + + target, _ := NewSCQueryService(argsNewSCQuery) + + query := process.SCQuery{ + ScAddress: []byte(DummyScAddress), + FuncName: "function", + Arguments: [][]byte{}, + } + + _, err := target.ExecuteQuery(&query) + require.Nil(t, err) + require.True(t, runSCWasCalled) + }) + + t.Run("custom gas defined, should use max uint64", func(t *testing.T) { + t.Parallel() + + maxGasLimit := uint64(1_500_000_000) + runSCWasCalled := false + mockVM := &mock.VMExecutionHandlerStub{ + RunSmartContractCallCalled: func(input *vmcommon.ContractCallInput) (output *vmcommon.VMOutput, e error) { + require.Equal(t, maxGasLimit, input.GasProvided) + runSCWasCalled = true + return &vmcommon.VMOutput{}, nil + }, + } + argsNewSCQuery := createMockArgumentsForSCQuery() + argsNewSCQuery.VmContainer = &mock.VMContainerMock{ + GetCalled: func(key []byte) (handler vmcommon.VMExecutionHandler, e error) { + return mockVM, nil + }, + } + argsNewSCQuery.EconomicsFee = &mock.FeeHandlerStub{ + MaxGasLimitPerBlockCalled: func() uint64 { + return uint64(math.MaxUint64) + }, + } + + argsNewSCQuery.MaxGasLimitPerQuery = maxGasLimit + + target, _ := NewSCQueryService(argsNewSCQuery) + + query := process.SCQuery{ + ScAddress: []byte(DummyScAddress), + FuncName: "function", + Arguments: [][]byte{}, + } + + _, err := target.ExecuteQuery(&query) + require.Nil(t, err) + require.True(t, runSCWasCalled) + }) +} + func TestExecuteQuery_WhenNotOkCodeShouldNotErr(t *testing.T) { t.Parallel() From c6e7b03bfa84ac4803913c53bba592b7a80d5ee6 Mon Sep 17 00:00:00 2001 From: bogdan-rosianu Date: Wed, 4 May 2022 12:42:53 +0300 Subject: [PATCH 2/4] fixed test description --- process/smartContract/scQueryService_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/process/smartContract/scQueryService_test.go b/process/smartContract/scQueryService_test.go index ffab762b31d..c9180d86d48 100644 --- a/process/smartContract/scQueryService_test.go +++ b/process/smartContract/scQueryService_test.go @@ -347,7 +347,7 @@ func TestExecuteQuery_GasProvidedShouldBeApplied(t *testing.T) { require.True(t, runSCWasCalled) }) - t.Run("custom gas defined, should use max uint64", func(t *testing.T) { + t.Run("custom gas defined, should use it", func(t *testing.T) { t.Parallel() maxGasLimit := uint64(1_500_000_000) From 86f31977d400c637c5caa2dff2be1afaf9106a0b Mon Sep 17 00:00:00 2001 From: bogdan-rosianu Date: Wed, 4 May 2022 17:37:27 +0300 Subject: [PATCH 3/4] moved configuration value --- cmd/node/config/config.toml | 8 +++++--- config/config.go | 7 ++++++- config/tomlConfig_test.go | 15 ++++++--------- factory/apiResolverFactory.go | 2 +- 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/cmd/node/config/config.toml b/cmd/node/config/config.toml index 2cbae7cd7c4..f65c3c86bc3 100644 --- a/cmd/node/config/config.toml +++ b/cmd/node/config/config.toml @@ -588,9 +588,6 @@ SameSourceRequests = 10000 # SameSourceResetIntervalInSec time frame between counter reset, in seconds SameSourceResetIntervalInSec = 1 - # MaxGasPerVmQuery defines the maximum amount of gas to be allocated for VM Queries comming from API - # If set to 0, then MaxUInt64 will be used - MaxGasPerVmQuery = 1500000000 #1.5b # EndpointsThrottlers represents a map for maximum simultaneous go routines for an endpoint EndpointsThrottlers = [{ Endpoint = "/transaction/:hash", MaxNumGoRoutines = 10 }, { Endpoint = "/transaction/send", MaxNumGoRoutines = 2 }, @@ -722,6 +719,11 @@ { StartEpoch = 1, Version = "v1.4" }, ] + [VirtualMachine.GasConfig] + # MaxGasPerVmQuery defines the maximum amount of gas to be allocated for VM Queries comming from API + # If set to 0, then MaxUInt64 will be used + MaxGasPerVmQuery = 1500000000 #1.5b + [Hardfork] EnableTrigger = true EnableTriggerFromP2P = true diff --git a/config/config.go b/config/config.go index ca4885531f7..061b11142e3 100644 --- a/config/config.go +++ b/config/config.go @@ -283,7 +283,6 @@ type EndpointsThrottlersConfig struct { // WebServerAntifloodConfig will hold the anti-flooding parameters for the web server type WebServerAntifloodConfig struct { - MaxGasPerVmQuery uint64 SimultaneousRequests uint32 SameSourceRequests uint32 SameSourceResetIntervalInSec uint32 @@ -356,6 +355,7 @@ type IncreaseFactorConfig struct { type VirtualMachineServicesConfig struct { Execution VirtualMachineConfig Querying QueryVirtualMachineConfig + GasConfig VirtualMachineGasConfig } // VirtualMachineConfig holds configuration for a Virtual Machine service @@ -375,6 +375,11 @@ type QueryVirtualMachineConfig struct { NumConcurrentVMs int } +// VirtualMachineGasConfig holds the configuration for the virtual machine(s) gas operations +type VirtualMachineGasConfig struct { + MaxGasPerVmQuery uint64 +} + // HardforkConfig holds the configuration for the hardfork trigger type HardforkConfig struct { ExportStateStorageConfig StorageConfig diff --git a/config/tomlConfig_test.go b/config/tomlConfig_test.go index 79f694c161e..8de8b3a4e17 100644 --- a/config/tomlConfig_test.go +++ b/config/tomlConfig_test.go @@ -104,6 +104,9 @@ func TestTomlParser(t *testing.T) { NumConcurrentVMs: 16, VirtualMachineConfig: vmConfig, }, + GasConfig: VirtualMachineGasConfig{ + MaxGasPerVmQuery: 1_500_000_000, + }, }, Debug: DebugConfig{ InterceptorResolver: InterceptorResolverDebugConfig{ @@ -126,11 +129,6 @@ func TestTomlParser(t *testing.T) { DoProfileOnShuffleOut: true, }, }, - Antiflood: AntifloodConfig{ - WebServer: WebServerAntifloodConfig{ - MaxGasPerVmQuery: 1_500_000_000, - }, - }, } testString := ` [MiniBlocksStorage] @@ -179,10 +177,6 @@ func TestTomlParser(t *testing.T) { [Consensus] Type = "` + consensusType + `" -[Antiflood] - [Antiflood.WebServer] - MaxGasPerVmQuery = 1500000000 #1.5b - [VirtualMachine] [VirtualMachine.Execution] ArwenVersions = [ @@ -197,6 +191,9 @@ func TestTomlParser(t *testing.T) { { StartEpoch = 88, Version = "v1.2" }, ] + [VirtualMachine.GasConfig] + MaxGasPerVmQuery = 1500000000 + [Debug] [Debug.InterceptorResolver] Enabled = true diff --git a/factory/apiResolverFactory.go b/factory/apiResolverFactory.go index 575ce8bcaf8..4e0fa0418a2 100644 --- a/factory/apiResolverFactory.go +++ b/factory/apiResolverFactory.go @@ -346,7 +346,7 @@ func createScQueryElement( ArwenChangeLocker: args.coreComponents.ArwenChangeLocker(), Bootstrapper: args.bootstrapper, AllowExternalQueriesChan: args.allowVMQueriesChan, - MaxGasLimitPerQuery: args.generalConfig.Antiflood.WebServer.MaxGasPerVmQuery, + MaxGasLimitPerQuery: args.generalConfig.VirtualMachine.GasConfig.MaxGasPerVmQuery, } return smartContract.NewSCQueryService(argsNewSCQueryService) From 5fdf9927ba4224734ebe99eff2912398ad0be4d2 Mon Sep 17 00:00:00 2001 From: bogdan-rosianu Date: Wed, 4 May 2022 17:38:58 +0300 Subject: [PATCH 4/4] fix typo --- cmd/node/config/config.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/node/config/config.toml b/cmd/node/config/config.toml index f65c3c86bc3..16c0582cc4e 100644 --- a/cmd/node/config/config.toml +++ b/cmd/node/config/config.toml @@ -720,7 +720,7 @@ ] [VirtualMachine.GasConfig] - # MaxGasPerVmQuery defines the maximum amount of gas to be allocated for VM Queries comming from API + # MaxGasPerVmQuery defines the maximum amount of gas to be allocated for VM Queries coming from API # If set to 0, then MaxUInt64 will be used MaxGasPerVmQuery = 1500000000 #1.5b