diff --git a/docs/config-file/node-config-doc.html b/docs/config-file/node-config-doc.html index a12f577869..a07f59acaf 100644 --- a/docs/config-file/node-config-doc.html +++ b/docs/config-file/node-config-doc.html @@ -18,7 +18,7 @@
"300ms"
 

Default: "1m0s"Type: string

WriteTimeout is the HTTP server write timeout
check net/http.server.WriteTimeout


Examples:

"1m"
 
"300ms"
-

Default: 500Type: number

MaxRequestsPerIPAndSecond defines how much requests a single IP can
send within a single second


Default: ""Type: string

SequencerNodeURI is used allow Non-Sequencer nodes
to relay transactions to the Sequencer node


Default: 0Type: integer

MaxCumulativeGasUsed is the max gas allowed per batch


WebSockets configuration
Default: trueType: boolean

Enabled defines if the WebSocket requests are enabled or disabled


Default: "0.0.0.0"Type: string

Host defines the network adapter that will be used to serve the WS requests


Default: 8546Type: integer

Port defines the port to serve the endpoints via WS


Default: 104857600Type: integer

ReadLimit defines the maximum size of a message read from the client (in bytes)


Default: trueType: boolean

EnableL2SuggestedGasPricePolling enables polling of the L2 gas price to block tx in the RPC with lower gas price.


Default: falseType: boolean

BatchRequestsEnabled defines if the Batch requests are enabled or disabled


Default: 20Type: integer

BatchRequestsLimit defines the limit of requests that can be incorporated into each batch request


Type: array of integer

L2Coinbase defines which address is going to receive the fees

Must contain a minimum of 20 items

Must contain a maximum of 20 items

Each item of this array must be:

Type: integer

Default: 10000Type: integer

MaxLogsCount is a configuration to set the max number of logs that can be returned
in a single call to the state, if zero it means no limit


Default: 10000Type: integer

MaxLogsBlockRange is a configuration to set the max range for block number when querying TXs
logs in a single call to the state, if zero it means no limit


Default: 60000Type: integer

MaxNativeBlockHashBlockRange is a configuration to set the max range for block number when querying
native block hashes in a single call to the state, if zero it means no limit


Default: trueType: boolean

EnableHttpLog allows the user to enable or disable the logs related to the HTTP
requests to be captured by the server.


ZKCountersLimits defines the ZK Counter limits
Default: 0Type: integer

Default: 0Type: integer

Default: 0Type: integer

Default: 0Type: integer

Default: 0Type: integer

Default: 0Type: integer

Default: 0Type: integer

Default: 0Type: integer

Default: falseType: boolean

XLayer config
EnablePendingTransactionFilter enables pending transaction filter that can support query L2 pending transaction


Nacos configuration
Default: ""Type: string

URLs nacos server urls for discovery service of rest api, url is separated by ","


Default: ""Type: string

NamespaceId nacos namepace id for discovery service of rest api


Default: ""Type: string

ApplicationName rest application name in nacos


Default: ""Type: string

ExternalListenAddr Set the rest-server external ip and port, when it is launched by Docker


NacosWs configuration
Default: ""Type: string

URLs nacos server urls for discovery service of rest api, url is separated by ","


Default: ""Type: string

NamespaceId nacos namepace id for discovery service of rest api


Default: ""Type: string

ApplicationName rest application name in nacos


Default: ""Type: string

ExternalListenAddr Set the rest-server external ip and port, when it is launched by Docker


Default: 1Type: number

GasLimitFactor is used to multiply the suggested gas provided by the network
in order to allow a enough gas to be set for all the transactions default value is 1.

ex:
suggested gas limit: 100
GasLimitFactor: 1
gas limit = 100

suggested gas limit: 100
GasLimitFactor: 1.1
gas limit = 110


Default: []Type: array of string

DisableAPIs disable some API

Each item of this array must be:

Type: string

RateLimit enable rate limit
Default: falseType: boolean

Enabled defines if the rate limit is enabled or disabled


Default: []Type: array of string

RateLimitApis defines the apis that need to be rate limited

Each item of this array must be:


Default: 100Type: integer

RateLimitBurst defines the maximum burst size of requests


Default: 1Type: integer

RateLimitDuration defines the time window for the rate limit


Default: []Type: array of object

SpecialApis defines the apis that need to be rate limited with special rate limit

Each item of this array must be:

Type: string

Api defines the api that need to be rate limited


Type: integer

Count defines the maximum burst size of requests


Type: integer

Duration defines the time window for the rate limit



DynamicGP defines the config of dynamic gas price
Default: falseType: boolean

Enabled defines if the dynamic gas price is enabled or disabled


Default: 100Type: integer

CongestionTxThreshold defines the tx threshold to measure whether there is congestion


Default: 5Type: integer

CheckBatches defines the number of recent Batches used to sample gas price


Default: 3Type: integer

SampleTxNumer defines the number of sampled gas prices in each batch


Default: 70Type: integer

Percentile defines the sampling weight of all sampled gas prices


Default: 20000000000Type: integer

MaxPrice defines the dynamic gas price upper limit


Default: 2000000000Type: integer

MinPrice defines the dynamic gas price lower limit


Default: "10s"Type: string

UpdatePeriod defines the time interval for updating dynamic gas price


Examples:

"1m"
+

Default: 500Type: number

MaxRequestsPerIPAndSecond defines how much requests a single IP can
send within a single second


Default: ""Type: string

SequencerNodeURI is used allow Non-Sequencer nodes
to relay transactions to the Sequencer node


Default: 0Type: integer

MaxCumulativeGasUsed is the max gas allowed per batch


WebSockets configuration
Default: trueType: boolean

Enabled defines if the WebSocket requests are enabled or disabled


Default: "0.0.0.0"Type: string

Host defines the network adapter that will be used to serve the WS requests


Default: 8546Type: integer

Port defines the port to serve the endpoints via WS


Default: 104857600Type: integer

ReadLimit defines the maximum size of a message read from the client (in bytes)


Default: trueType: boolean

EnableL2SuggestedGasPricePolling enables polling of the L2 gas price to block tx in the RPC with lower gas price.


Default: falseType: boolean

BatchRequestsEnabled defines if the Batch requests are enabled or disabled


Default: 20Type: integer

BatchRequestsLimit defines the limit of requests that can be incorporated into each batch request


Type: array of integer

L2Coinbase defines which address is going to receive the fees

Must contain a minimum of 20 items

Must contain a maximum of 20 items

Each item of this array must be:


Default: 10000Type: integer

MaxLogsCount is a configuration to set the max number of logs that can be returned
in a single call to the state, if zero it means no limit


Default: 10000Type: integer

MaxLogsBlockRange is a configuration to set the max range for block number when querying TXs
logs in a single call to the state, if zero it means no limit


Default: 60000Type: integer

MaxNativeBlockHashBlockRange is a configuration to set the max range for block number when querying
native block hashes in a single call to the state, if zero it means no limit


Default: trueType: boolean

EnableHttpLog allows the user to enable or disable the logs related to the HTTP
requests to be captured by the server.


ZKCountersLimits defines the ZK Counter limits
Default: 0Type: integer

Default: 0Type: integer

Default: 0Type: integer

Default: 0Type: integer

Default: 0Type: integer

Default: 0Type: integer

Default: 0Type: integer

Default: 0Type: integer

Default: falseType: boolean

XLayer config
EnablePendingTransactionFilter enables pending transaction filter that can support query L2 pending transaction


Nacos configuration
Default: ""Type: string

URLs nacos server urls for discovery service of rest api, url is separated by ","


Default: ""Type: string

NamespaceId nacos namepace id for discovery service of rest api


Default: ""Type: string

ApplicationName rest application name in nacos


Default: ""Type: string

ExternalListenAddr Set the rest-server external ip and port, when it is launched by Docker


NacosWs configuration
Default: ""Type: string

URLs nacos server urls for discovery service of rest api, url is separated by ","


Default: ""Type: string

NamespaceId nacos namepace id for discovery service of rest api


Default: ""Type: string

ApplicationName rest application name in nacos


Default: ""Type: string

ExternalListenAddr Set the rest-server external ip and port, when it is launched by Docker


Default: 1Type: number

GasLimitFactor is used to multiply the suggested gas provided by the network
in order to allow a enough gas to be set for all the transactions default value is 1.

ex:
suggested gas limit: 100
GasLimitFactor: 1
gas limit = 100

suggested gas limit: 100
GasLimitFactor: 1.1
gas limit = 110


Default: falseType: boolean

Default: []Type: array of string

DisableAPIs disable some API

Each item of this array must be:


RateLimit enable rate limit
Default: falseType: boolean

Enabled defines if the rate limit is enabled or disabled


Default: []Type: array of string

RateLimitApis defines the apis that need to be rate limited

Each item of this array must be:


Default: 100Type: integer

RateLimitBurst defines the maximum burst size of requests


Default: 1Type: integer

RateLimitDuration defines the time window for the rate limit


Default: []Type: array of object

SpecialApis defines the apis that need to be rate limited with special rate limit

Each item of this array must be:

Type: string

Api defines the api that need to be rate limited


Type: integer

Count defines the maximum burst size of requests


Type: integer

Duration defines the time window for the rate limit



DynamicGP defines the config of dynamic gas price
Default: falseType: boolean

Enabled defines if the dynamic gas price is enabled or disabled


Default: 100Type: integer

CongestionTxThreshold defines the tx threshold to measure whether there is congestion


Default: 5Type: integer

CheckBatches defines the number of recent Batches used to sample gas price


Default: 3Type: integer

SampleTxNumer defines the number of sampled gas prices in each batch


Default: 70Type: integer

Percentile defines the sampling weight of all sampled gas prices


Default: 20000000000Type: integer

MaxPrice defines the dynamic gas price upper limit


Default: 2000000000Type: integer

MinPrice defines the dynamic gas price lower limit


Default: "10s"Type: string

UpdatePeriod defines the time interval for updating dynamic gas price


Examples:

"1m"
 
"300ms"
 

Default: falseType: boolean

EnableInnerTxCacheDB enables the inner tx cache db


Type: array of integer

BridgeAddress is the address of the bridge contract

Must contain a minimum of 20 items

Must contain a maximum of 20 items

Each item of this array must be:


ApiAuthentication defines the authentication configuration for the API
Default: falseType: boolean

Enabled defines if the api authentication is enabled


Default: []Type: array of object

ApiKeys defines the api keys

Each item of this array must be:

Type: string

Name defines the name of the key


Type: string

Key defines the key


Type: string

Timeout defines the timeout



ApiRelay defines the relay configuration for the API
Default: falseType: boolean

Default: ""Type: string

Default: []Type: array of string

Each item of this array must be:


Configuration of service `Syncrhonizer`. For this service is also really important the value of `IsTrustedSequencer` because depending of this values is going to ask to a trusted node for trusted transactions or not
Default: "1s"Type: string

SyncInterval is the delay interval between reading new rollup information


Examples:

"1m"
 
"300ms"
diff --git a/docs/config-file/node-config-doc.md b/docs/config-file/node-config-doc.md
index dc55845efc..986e0cefc0 100644
--- a/docs/config-file/node-config-doc.md
+++ b/docs/config-file/node-config-doc.md
@@ -1333,6 +1333,7 @@ FreeGasLimit=0
 | - [Nacos](#RPC_Nacos )                                                       | No      | object           | No         | -          | Nacos configuration                                                                                                                                                                                                                                                                                                                                |
 | - [NacosWs](#RPC_NacosWs )                                                   | No      | object           | No         | -          | NacosWs configuration                                                                                                                                                                                                                                                                                                                              |
 | - [GasLimitFactor](#RPC_GasLimitFactor )                                     | No      | number           | No         | -          | GasLimitFactor is used to multiply the suggested gas provided by the network
in order to allow a enough gas to be set for all the transactions default value is 1.

ex:
suggested gas limit: 100
GasLimitFactor: 1
gas limit = 100

suggested gas limit: 100
GasLimitFactor: 1.1
gas limit = 110 | +| - [EnableEstimateGasOpt](#RPC_EnableEstimateGasOpt ) | No | boolean | No | - | - | | - [DisableAPIs](#RPC_DisableAPIs ) | No | array of string | No | - | DisableAPIs disable some API | | - [RateLimit](#RPC_RateLimit ) | No | object | No | - | RateLimit enable rate limit | | - [DynamicGP](#RPC_DynamicGP ) | No | object | No | - | DynamicGP defines the config of dynamic gas price | @@ -1929,7 +1930,19 @@ gas limit = 110 GasLimitFactor=1 ``` -### 8.22. `RPC.DisableAPIs` +### 8.22. `RPC.EnableEstimateGasOpt` + +**Type:** : `boolean` + +**Default:** `false` + +**Example setting the default value** (false): +``` +[RPC] +EnableEstimateGasOpt=false +``` + +### 8.23. `RPC.DisableAPIs` **Type:** : `array of string` @@ -1943,7 +1956,7 @@ GasLimitFactor=1 DisableAPIs=[] ``` -### 8.23. `[RPC.RateLimit]` +### 8.24. `[RPC.RateLimit]` **Type:** : `object` **Description:** RateLimit enable rate limit @@ -1956,7 +1969,7 @@ DisableAPIs=[] | - [RateLimitDuration](#RPC_RateLimit_RateLimitDuration ) | No | integer | No | - | RateLimitDuration defines the time window for the rate limit | | - [SpecialApis](#RPC_RateLimit_SpecialApis ) | No | array of object | No | - | SpecialApis defines the apis that need to be rate limited with special rate limit | -#### 8.23.1. `RPC.RateLimit.Enabled` +#### 8.24.1. `RPC.RateLimit.Enabled` **Type:** : `boolean` @@ -1970,7 +1983,7 @@ DisableAPIs=[] Enabled=false ``` -#### 8.23.2. `RPC.RateLimit.RateLimitApis` +#### 8.24.2. `RPC.RateLimit.RateLimitApis` **Type:** : `array of string` @@ -1984,7 +1997,7 @@ Enabled=false RateLimitApis=[] ``` -#### 8.23.3. `RPC.RateLimit.RateLimitCount` +#### 8.24.3. `RPC.RateLimit.RateLimitCount` **Type:** : `integer` @@ -1998,7 +2011,7 @@ RateLimitApis=[] RateLimitCount=100 ``` -#### 8.23.4. `RPC.RateLimit.RateLimitDuration` +#### 8.24.4. `RPC.RateLimit.RateLimitDuration` **Type:** : `integer` @@ -2012,7 +2025,7 @@ RateLimitCount=100 RateLimitDuration=1 ``` -#### 8.23.5. `RPC.RateLimit.SpecialApis` +#### 8.24.5. `RPC.RateLimit.SpecialApis` **Type:** : `array of object` @@ -2038,7 +2051,7 @@ SpecialApis=[] | ----------------------------------------------------- | ---------------------------------------------------------- | | [SpecialApis items](#RPC_RateLimit_SpecialApis_items) | RateLimitItem defines the special rate limit for some apis | -##### 8.23.5.1. [RPC.RateLimit.SpecialApis.SpecialApis items] +##### 8.24.5.1. [RPC.RateLimit.SpecialApis.SpecialApis items] **Type:** : `object` **Description:** RateLimitItem defines the special rate limit for some apis @@ -2049,22 +2062,22 @@ SpecialApis=[] | - [Count](#RPC_RateLimit_SpecialApis_items_Count ) | No | integer | No | - | Count defines the maximum burst size of requests | | - [Duration](#RPC_RateLimit_SpecialApis_items_Duration ) | No | integer | No | - | Duration defines the time window for the rate limit | -##### 8.23.5.1.1. `RPC.RateLimit.SpecialApis.SpecialApis items.Api` +##### 8.24.5.1.1. `RPC.RateLimit.SpecialApis.SpecialApis items.Api` **Type:** : `string` **Description:** Api defines the api that need to be rate limited -##### 8.23.5.1.2. `RPC.RateLimit.SpecialApis.SpecialApis items.Count` +##### 8.24.5.1.2. `RPC.RateLimit.SpecialApis.SpecialApis items.Count` **Type:** : `integer` **Description:** Count defines the maximum burst size of requests -##### 8.23.5.1.3. `RPC.RateLimit.SpecialApis.SpecialApis items.Duration` +##### 8.24.5.1.3. `RPC.RateLimit.SpecialApis.SpecialApis items.Duration` **Type:** : `integer` **Description:** Duration defines the time window for the rate limit -### 8.24. `[RPC.DynamicGP]` +### 8.25. `[RPC.DynamicGP]` **Type:** : `object` **Description:** DynamicGP defines the config of dynamic gas price @@ -2080,7 +2093,7 @@ SpecialApis=[] | - [MinPrice](#RPC_DynamicGP_MinPrice ) | No | integer | No | - | MinPrice defines the dynamic gas price lower limit | | - [UpdatePeriod](#RPC_DynamicGP_UpdatePeriod ) | No | string | No | - | Duration | -#### 8.24.1. `RPC.DynamicGP.Enabled` +#### 8.25.1. `RPC.DynamicGP.Enabled` **Type:** : `boolean` @@ -2094,7 +2107,7 @@ SpecialApis=[] Enabled=false ``` -#### 8.24.2. `RPC.DynamicGP.CongestionTxThreshold` +#### 8.25.2. `RPC.DynamicGP.CongestionTxThreshold` **Type:** : `integer` @@ -2108,7 +2121,7 @@ Enabled=false CongestionTxThreshold=100 ``` -#### 8.24.3. `RPC.DynamicGP.CheckBatches` +#### 8.25.3. `RPC.DynamicGP.CheckBatches` **Type:** : `integer` @@ -2122,7 +2135,7 @@ CongestionTxThreshold=100 CheckBatches=5 ``` -#### 8.24.4. `RPC.DynamicGP.SampleNumber` +#### 8.25.4. `RPC.DynamicGP.SampleNumber` **Type:** : `integer` @@ -2136,7 +2149,7 @@ CheckBatches=5 SampleNumber=3 ``` -#### 8.24.5. `RPC.DynamicGP.Percentile` +#### 8.25.5. `RPC.DynamicGP.Percentile` **Type:** : `integer` @@ -2150,7 +2163,7 @@ SampleNumber=3 Percentile=70 ``` -#### 8.24.6. `RPC.DynamicGP.MaxPrice` +#### 8.25.6. `RPC.DynamicGP.MaxPrice` **Type:** : `integer` @@ -2164,7 +2177,7 @@ Percentile=70 MaxPrice=20000000000 ``` -#### 8.24.7. `RPC.DynamicGP.MinPrice` +#### 8.25.7. `RPC.DynamicGP.MinPrice` **Type:** : `integer` @@ -2178,7 +2191,7 @@ MaxPrice=20000000000 MinPrice=2000000000 ``` -#### 8.24.8. `RPC.DynamicGP.UpdatePeriod` +#### 8.25.8. `RPC.DynamicGP.UpdatePeriod` **Title:** Duration @@ -2204,7 +2217,7 @@ MinPrice=2000000000 UpdatePeriod="10s" ``` -### 8.25. `RPC.EnableInnerTxCacheDB` +### 8.26. `RPC.EnableInnerTxCacheDB` **Type:** : `boolean` @@ -2218,12 +2231,12 @@ UpdatePeriod="10s" EnableInnerTxCacheDB=false ``` -### 8.26. `RPC.BridgeAddress` +### 8.27. `RPC.BridgeAddress` **Type:** : `array of integer` **Description:** BridgeAddress is the address of the bridge contract -### 8.27. `[RPC.ApiAuthentication]` +### 8.28. `[RPC.ApiAuthentication]` **Type:** : `object` **Description:** ApiAuthentication defines the authentication configuration for the API @@ -2233,7 +2246,7 @@ EnableInnerTxCacheDB=false | - [Enabled](#RPC_ApiAuthentication_Enabled ) | No | boolean | No | - | Enabled defines if the api authentication is enabled | | - [ApiKeys](#RPC_ApiAuthentication_ApiKeys ) | No | array of object | No | - | ApiKeys defines the api keys | -#### 8.27.1. `RPC.ApiAuthentication.Enabled` +#### 8.28.1. `RPC.ApiAuthentication.Enabled` **Type:** : `boolean` @@ -2247,7 +2260,7 @@ EnableInnerTxCacheDB=false Enabled=false ``` -#### 8.27.2. `RPC.ApiAuthentication.ApiKeys` +#### 8.28.2. `RPC.ApiAuthentication.ApiKeys` **Type:** : `array of object` @@ -2273,7 +2286,7 @@ ApiKeys=[] | ----------------------------------------------------- | --------------------------- | | [ApiKeys items](#RPC_ApiAuthentication_ApiKeys_items) | KeyItem is the api key item | -##### 8.27.2.1. [RPC.ApiAuthentication.ApiKeys.ApiKeys items] +##### 8.28.2.1. [RPC.ApiAuthentication.ApiKeys.ApiKeys items] **Type:** : `object` **Description:** KeyItem is the api key item @@ -2284,22 +2297,22 @@ ApiKeys=[] | - [Key](#RPC_ApiAuthentication_ApiKeys_items_Key ) | No | string | No | - | Key defines the key | | - [Timeout](#RPC_ApiAuthentication_ApiKeys_items_Timeout ) | No | string | No | - | Timeout defines the timeout | -##### 8.27.2.1.1. `RPC.ApiAuthentication.ApiKeys.ApiKeys items.Project` +##### 8.28.2.1.1. `RPC.ApiAuthentication.ApiKeys.ApiKeys items.Project` **Type:** : `string` **Description:** Name defines the name of the key -##### 8.27.2.1.2. `RPC.ApiAuthentication.ApiKeys.ApiKeys items.Key` +##### 8.28.2.1.2. `RPC.ApiAuthentication.ApiKeys.ApiKeys items.Key` **Type:** : `string` **Description:** Key defines the key -##### 8.27.2.1.3. `RPC.ApiAuthentication.ApiKeys.ApiKeys items.Timeout` +##### 8.28.2.1.3. `RPC.ApiAuthentication.ApiKeys.ApiKeys items.Timeout` **Type:** : `string` **Description:** Timeout defines the timeout -### 8.28. `[RPC.ApiRelay]` +### 8.29. `[RPC.ApiRelay]` **Type:** : `object` **Description:** ApiRelay defines the relay configuration for the API @@ -2310,7 +2323,7 @@ ApiKeys=[] | - [DestURI](#RPC_ApiRelay_DestURI ) | No | string | No | - | - | | - [RPCs](#RPC_ApiRelay_RPCs ) | No | array of string | No | - | - | -#### 8.28.1. `RPC.ApiRelay.Enabled` +#### 8.29.1. `RPC.ApiRelay.Enabled` **Type:** : `boolean` @@ -2322,7 +2335,7 @@ ApiKeys=[] Enabled=false ``` -#### 8.28.2. `RPC.ApiRelay.DestURI` +#### 8.29.2. `RPC.ApiRelay.DestURI` **Type:** : `string` @@ -2334,7 +2347,7 @@ Enabled=false DestURI="" ``` -#### 8.28.3. `RPC.ApiRelay.RPCs` +#### 8.29.3. `RPC.ApiRelay.RPCs` **Type:** : `array of string` diff --git a/docs/config-file/node-config-schema.json b/docs/config-file/node-config-schema.json index 7f220848ec..df973e70e8 100644 --- a/docs/config-file/node-config-schema.json +++ b/docs/config-file/node-config-schema.json @@ -727,6 +727,10 @@ "description": "GasLimitFactor is used to multiply the suggested gas provided by the network\nin order to allow a enough gas to be set for all the transactions default value is 1.\n\nex:\nsuggested gas limit: 100\nGasLimitFactor: 1\ngas limit = 100\n\nsuggested gas limit: 100\nGasLimitFactor: 1.1\ngas limit = 110", "default": 1 }, + "EnableEstimateGasOpt": { + "type": "boolean", + "default": false + }, "DisableAPIs": { "items": { "type": "string" diff --git a/jsonrpc/apollo_xlayer.go b/jsonrpc/apollo_xlayer.go index ecb6dee4f6..156625f98e 100644 --- a/jsonrpc/apollo_xlayer.go +++ b/jsonrpc/apollo_xlayer.go @@ -12,6 +12,7 @@ type ApolloConfig struct { BatchRequestsEnabled bool BatchRequestsLimit uint GasLimitFactor float64 + EnableEstimateGasOpt bool DisableAPIs []string RateLimit RateLimitConfig DynamicGP DynamicGPConfig @@ -63,6 +64,7 @@ func UpdateConfig(apolloConfig Config) { getApolloConfig().BatchRequestsEnabled = apolloConfig.BatchRequestsEnabled getApolloConfig().BatchRequestsLimit = apolloConfig.BatchRequestsLimit getApolloConfig().GasLimitFactor = apolloConfig.GasLimitFactor + getApolloConfig().EnableEstimateGasOpt = apolloConfig.EnableEstimateGasOpt getApolloConfig().setDisableAPIs(apolloConfig.DisableAPIs) setRateLimit(apolloConfig.RateLimit) setApiAuth(apolloConfig.ApiAuthentication) diff --git a/jsonrpc/config.go b/jsonrpc/config.go index fe9f2b202f..53ec1e6053 100644 --- a/jsonrpc/config.go +++ b/jsonrpc/config.go @@ -87,7 +87,8 @@ type Config struct { // suggested gas limit: 100 // GasLimitFactor: 1.1 // gas limit = 110 - GasLimitFactor float64 `mapstructure:"GasLimitFactor"` + GasLimitFactor float64 `mapstructure:"GasLimitFactor"` + EnableEstimateGasOpt bool `mapstructure:"EnableEstimateGasOpt"` // DisableAPIs disable some API DisableAPIs []string `mapstructure:"DisableAPIs"` diff --git a/jsonrpc/endpoints_eth.go b/jsonrpc/endpoints_eth.go index 9b67934cdf..fa3f359ef5 100644 --- a/jsonrpc/endpoints_eth.go +++ b/jsonrpc/endpoints_eth.go @@ -207,7 +207,13 @@ func (e *EthEndpoints) EstimateGas(arg *types.TxArgs, blockArg *types.BlockNumbe t2 := time.Now() toTxTime := t2.Sub(t1) - gasEstimation, returnValue, err := e.state.EstimateGas(tx, sender, isGasFreeSender, blockToProcess, dbTx) + var gasEstimation uint64 + var returnValue []byte + if e.enableEstimateGasOpt() { + gasEstimation, returnValue, err = e.state.EstimateGasOpt(tx, sender, isGasFreeSender, blockToProcess, dbTx) + } else { + gasEstimation, returnValue, err = e.state.EstimateGas(tx, sender, isGasFreeSender, blockToProcess, dbTx) + } if errors.Is(err, runtime.ErrExecutionReverted) { data := make([]byte, len(returnValue)) copy(data, returnValue) diff --git a/jsonrpc/endpoints_eth_xlayer.go b/jsonrpc/endpoints_eth_xlayer.go index 2ab478108d..36ca8be500 100644 --- a/jsonrpc/endpoints_eth_xlayer.go +++ b/jsonrpc/endpoints_eth_xlayer.go @@ -278,9 +278,25 @@ func (e *EthEndpoints) getGasEstimationWithFactorXLayer(gasEstimation uint64) ui if gasLimitFactor > 0 { gasEstimationWithFactor = uint64(float64(gasEstimation) * gasLimitFactor) } + if gasEstimationWithFactor > state.MaxTxGasLimit { + gasEstimationWithFactor = state.MaxTxGasLimit + } return gasEstimationWithFactor } +func (e *EthEndpoints) enableEstimateGasOpt() bool { + res := false + if getApolloConfig().Enable() { + getApolloConfig().RLock() + res = getApolloConfig().EnableEstimateGasOpt + getApolloConfig().RUnlock() + } else { + res = e.cfg.EnableEstimateGasOpt + } + + return res +} + // internal func (e *EthEndpoints) newPendingTransactionFilterXLayer(wsConn *concurrentWsConn) (interface{}, types.Error) { //XLayer handle diff --git a/jsonrpc/mocks/mock_state.go b/jsonrpc/mocks/mock_state.go index bc9070e6a6..5c93ab7272 100644 --- a/jsonrpc/mocks/mock_state.go +++ b/jsonrpc/mocks/mock_state.go @@ -151,6 +151,11 @@ func (_m *StateMock) EstimateGas(transaction *coretypes.Transaction, senderAddre return r0, r1, r2 } +// EstimateGasOpt provides a mock function with given fields: transaction, senderAddress, l2BlockNumber, dbTx +func (_m *StateMock) EstimateGasOpt(transaction *coretypes.Transaction, senderAddress common.Address, isGasFreeSender bool, l2BlockNumber *uint64, dbTx pgx.Tx) (uint64, []byte, error) { + return _m.EstimateGas(transaction, senderAddress, isGasFreeSender, l2BlockNumber, dbTx) +} + // GetBalance provides a mock function with given fields: ctx, address, root func (_m *StateMock) GetBalance(ctx context.Context, address common.Address, root common.Hash) (*big.Int, error) { ret := _m.Called(ctx, address, root) diff --git a/jsonrpc/types/interfaces.go b/jsonrpc/types/interfaces.go index c09dcdc0ce..f733df5eb2 100644 --- a/jsonrpc/types/interfaces.go +++ b/jsonrpc/types/interfaces.go @@ -39,6 +39,7 @@ type StateInterface interface { BeginStateTransaction(ctx context.Context) (pgx.Tx, error) DebugTransaction(ctx context.Context, transactionHash common.Hash, traceConfig state.TraceConfig, dbTx pgx.Tx) (*runtime.ExecutionResult, error) EstimateGas(transaction *types.Transaction, senderAddress common.Address, isGasFreeSender bool, l2BlockNumber *uint64, dbTx pgx.Tx) (uint64, []byte, error) + EstimateGasOpt(transaction *types.Transaction, senderAddress common.Address, isGasFreeSender bool, l2BlockNumber *uint64, dbTx pgx.Tx) (uint64, []byte, error) GetBalance(ctx context.Context, address common.Address, root common.Hash) (*big.Int, error) GetCode(ctx context.Context, address common.Address, root common.Hash) ([]byte, error) GetL2BlockByHash(ctx context.Context, hash common.Hash, dbTx pgx.Tx) (*state.L2Block, error) diff --git a/state/transaction.go b/state/transaction.go index ef62cc14fe..2fd7562377 100644 --- a/state/transaction.go +++ b/state/transaction.go @@ -863,6 +863,8 @@ func (s *State) EstimateGas(transaction *types.Transaction, senderAddress common if lowEnd < estimationResult.gasUsed { lowEnd = estimationResult.gasUsed } + firstLowEnd := lowEnd + firstGasued := estimationResult.gasUsed optimisticGasLimit := (estimationResult.gasUsed + estimationResult.gasRefund + params.CallStipend) * 64 / 63 // nolint:gomnd if optimisticGasLimit < highEnd { @@ -927,6 +929,7 @@ func (s *State) EstimateGas(transaction *types.Transaction, senderAddress common } log.Infof("state-EstimateGas time. getBlock:%vms, getBatch:%vms, getForkID:%vms, getNonce:%vms, getEnd:%vms, internalGas:%vms, exec:%vms", getBlockTime.Milliseconds(), getBatchTime.Milliseconds(), getForkIDTime.Milliseconds(), getNonceTime.Milliseconds(), getEndTime.Milliseconds(), internalGasTime.Milliseconds(), time.Since(t6).Milliseconds()) + log.Infof("state-EstimateGas value.firstLowEnd:%d, first gasUsed:%d, final gas:%d, factor:%f", firstLowEnd, firstGasued, highEnd, float64(highEnd)/float64(firstGasued)) return highEnd, nil, nil } diff --git a/state/transaction_xlayer.go b/state/transaction_xlayer.go new file mode 100644 index 0000000000..7cc3186eef --- /dev/null +++ b/state/transaction_xlayer.go @@ -0,0 +1,166 @@ +package state + +import ( + "context" + "errors" + "fmt" + "math/big" + "time" + + "github.com/0xPolygonHermez/zkevm-node/log" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" + "github.com/jackc/pgx/v4" +) + +// EstimateGasOpt for a transaction +func (s *State) EstimateGasOpt(transaction *types.Transaction, senderAddress common.Address, isGasFreeSender bool, l2BlockNumber *uint64, dbTx pgx.Tx) (uint64, []byte, error) { + const ethTransferGas = 21000 + + ctx := context.Background() + + t0 := time.Now() + + var l2Block *L2Block + var err error + if l2BlockNumber == nil { + l2Block, err = s.GetLastL2Block(ctx, dbTx) + } else { + l2Block, err = s.GetL2BlockByNumber(ctx, *l2BlockNumber, dbTx) + } + if err != nil { + return 0, nil, err + } + + t1 := time.Now() + getBlockTime := t1.Sub(t0) + + batch, err := s.GetBatchByL2BlockNumber(ctx, l2Block.NumberU64(), dbTx) + if err != nil { + return 0, nil, err + } + + t2 := time.Now() + getBatchTime := t2.Sub(t1) + + forkID := s.GetForkIDByBatchNumber(batch.BatchNumber) + latestL2BlockNumber, err := s.GetLastL2BlockNumber(ctx, dbTx) + if err != nil { + return 0, nil, err + } + + t3 := time.Now() + getForkIDTime := t3.Sub(t2) + + loadedNonce, err := s.tree.GetNonce(ctx, senderAddress, l2Block.Root().Bytes()) + if err != nil { + return 0, nil, err + } + nonce := loadedNonce.Uint64() + + t4 := time.Now() + getNonceTime := t4.Sub(t3) + + highEnd := MaxTxGasLimit + + // if gas price is set, set the highEnd to the max amount + // of the account afford + isGasPriceSet := !isGasFreeSender && transaction.GasPrice().BitLen() != 0 + if isGasPriceSet { + senderBalance, err := s.tree.GetBalance(ctx, senderAddress, l2Block.Root().Bytes()) + if errors.Is(err, ErrNotFound) { + senderBalance = big.NewInt(0) + } else if err != nil { + return 0, nil, err + } + + availableBalance := new(big.Int).Set(senderBalance) + // check if the account has funds to pay the transfer value + if transaction.Value() != nil { + if transaction.Value().Cmp(availableBalance) > 0 { + return 0, nil, ErrInsufficientFundsForTransfer + } + + // deduct the value from the available balance + availableBalance.Sub(availableBalance, transaction.Value()) + } + + // Check the gas allowance for this account, make sure high end is capped to it + gasAllowance := new(big.Int).Div(availableBalance, transaction.GasPrice()) + if gasAllowance.IsUint64() && highEnd > gasAllowance.Uint64() { + log.Debugf("Gas estimation high-end capped by allowance [%d]", gasAllowance.Uint64()) + highEnd = gasAllowance.Uint64() + } + } + + // if the tx gas is set and it is smaller than the highEnd, + // limit the highEnd to the maximum allowed by the tx gas + if transaction.Gas() != 0 && transaction.Gas() < highEnd { + highEnd = transaction.Gas() + } + + // set start values for lowEnd and highEnd: + lowEnd, err := core.IntrinsicGas(transaction.Data(), transaction.AccessList(), s.isContractCreation(transaction), true, false, false) + if err != nil { + return 0, nil, err + } + + // if the intrinsic gas is the same as the constant value for eth transfer + // and the transaction has a receiver address + if lowEnd == ethTransferGas && transaction.To() != nil { + receiver := *transaction.To() + // check if the receiver address is not a smart contract + code, err := s.tree.GetCode(ctx, receiver, l2Block.Root().Bytes()) + if err != nil { + log.Warnf("error while getting code for address %v: %v", receiver.String(), err) + } else if len(code) == 0 { + // in case it is just an account, we can avoid the execution and return + // the transfer constant amount + return lowEnd, nil, nil + } + } + + t5 := time.Now() + getEndTime := t5.Sub(t4) + + // testTransaction runs the transaction with the specified gas value. + // it returns a status indicating if the transaction has failed, if it + // was reverted and the accompanying error + + // Check if the highEnd is a good value to make the transaction pass, if it fails we + // can return immediately. + log.Debugf("Estimate gas. Trying to execute TX with %v gas", highEnd) + var estimationResult *testGasEstimationResult + if forkID < FORKID_ETROG { + estimationResult, err = s.internalTestGasEstimationTransactionV1(ctx, batch, l2Block, latestL2BlockNumber, transaction, forkID, senderAddress, isGasFreeSender, highEnd, nonce, false) + } else { + estimationResult, err = s.internalTestGasEstimationTransactionV2(ctx, batch, l2Block, latestL2BlockNumber, transaction, forkID, senderAddress, isGasFreeSender, highEnd, nonce, false) + } + if err != nil { + return 0, nil, err + } + if estimationResult.failed { + if estimationResult.reverted { + return 0, estimationResult.returnValue, estimationResult.executionError + } + + if estimationResult.ooc { + return 0, nil, estimationResult.executionError + } + + // The transaction shouldn't fail, for whatever reason, at highEnd + return 0, nil, fmt.Errorf( + "gas required exceeds allowance (%d)", + highEnd, + ) + } + + t6 := time.Now() + internalGasTime := t6.Sub(t5) + + log.Infof("state-EstimateGas time. getBlock:%vms, getBatch:%vms, getForkID:%vms, getNonce:%vms, getEnd:%vms, internalGas:%vms", + getBlockTime.Milliseconds(), getBatchTime.Milliseconds(), getForkIDTime.Milliseconds(), getNonceTime.Milliseconds(), getEndTime.Milliseconds(), internalGasTime.Milliseconds()) + + return estimationResult.gasUsed, nil, nil +}