From 2a563164e40359317717a06608d8ad87973c9b9f Mon Sep 17 00:00:00 2001 From: chengzhinei Date: Wed, 7 Aug 2024 12:26:38 +0800 Subject: [PATCH 1/9] support special project in xlayer for free gas --- pool/apollo_xlayer.go | 20 ++++++++++++++++++++ pool/config.go | 10 ++++++++++ pool/pool_xlayer.go | 8 ++++++++ sequencer/sequencer.go | 6 +++--- sequencer/sequencer_xlayer.go | 16 +++++++++++++++- 5 files changed, 56 insertions(+), 4 deletions(-) diff --git a/pool/apollo_xlayer.go b/pool/apollo_xlayer.go index bad98fad87..4d18dc1481 100644 --- a/pool/apollo_xlayer.go +++ b/pool/apollo_xlayer.go @@ -20,6 +20,7 @@ type apolloConfig struct { FreeGasExAddress []string FreeGasCountPerAddr uint64 FreeGasLimit uint64 + FreeGasList []FreeGasInfo BlockedList []string @@ -43,6 +44,14 @@ func (c *apolloConfig) enable() bool { return c.EnableApollo } +func (c *apolloConfig) setFreeGasList(freeGasList []FreeGasInfo) { + if c == nil || !c.EnableApollo { + return + } + c.FreeGasList = make([]FreeGasInfo, len(freeGasList)) + copy(c.FreeGasList, freeGasList) +} + func (c *apolloConfig) setFreeGasAddresses(freeGasAddrs []string) { if c == nil || !c.EnableApollo { return @@ -95,6 +104,7 @@ func UpdateConfig(apolloConfig Config) { getApolloConfig().setFreeGasExAddresses(apolloConfig.FreeGasExAddress) getApolloConfig().FreeGasCountPerAddr = apolloConfig.FreeGasCountPerAddr getApolloConfig().FreeGasLimit = apolloConfig.FreeGasLimit + getApolloConfig().setFreeGasList(apolloConfig.FreeGasList) getApolloConfig().Unlock() } @@ -202,3 +212,13 @@ func isBlockedAddress(localBlockedList []string, address common.Address) bool { return contains(localBlockedList, address) } + +func GetSpecialFreeGasList(freeGasList []FreeGasInfo) []FreeGasInfo { + if getApolloConfig().enable() { + getApolloConfig().RLock() + defer getApolloConfig().RUnlock() + return getApolloConfig().FreeGasList + } + + return freeGasList +} diff --git a/pool/config.go b/pool/config.go index 283788a706..6972d79481 100644 --- a/pool/config.go +++ b/pool/config.go @@ -71,6 +71,16 @@ type Config struct { FreeGasCountPerAddr uint64 `mapstructure:"FreeGasCountPerAddr"` // FreeGasLimit is the max gas allowed use to do a free gas tx FreeGasLimit uint64 `mapstructure:"FreeGasLimit"` + // FreeGasList is the special project of XLayer + FreeGasList []FreeGasInfo `mapstructure:"FreeGasList"` +} + +// FreeGasInfo contains the detail for what tx should be free +type FreeGasInfo struct { + From string `mapstructure:"From"` + To string `mapstructure:"To"` + MethodSig string `mapstructure:"MethodSig"` + GasPriceMultiple float64 `mapstructure:"GasPriceMultiple"` } // EffectiveGasPriceCfg contains the configuration properties for the effective gas price diff --git a/pool/pool_xlayer.go b/pool/pool_xlayer.go index ce7b4f1f3a..de1cd3ce7f 100644 --- a/pool/pool_xlayer.go +++ b/pool/pool_xlayer.go @@ -116,6 +116,14 @@ func (p *Pool) checkFreeGp(ctx context.Context, poolTx Transaction, from common. if isFreeGasAddress(p.cfg.FreeGasAddress, from) && poolTx.IsClaims { // claim tx return true, nil } + freeGpList := GetSpecialFreeGasList(p.cfg.FreeGasList) + for _, info := range freeGpList { + if from.String() == info.From { + if poolTx.To().String() == info.To && strings.HasPrefix("0x"+common.Bytes2Hex(poolTx.Data()), info.MethodSig) { + return true, nil + } + } + } if getEnableFreeGasByNonce(p.cfg.EnableFreeGasByNonce) && poolTx.GasPrice().Cmp(big.NewInt(0)) == 0 { // free-gas tx by count isFreeAddr, err := p.storage.IsFreeGasAddr(ctx, from) if err != nil { diff --git a/sequencer/sequencer.go b/sequencer/sequencer.go index 2ba8dfb96d..6870bbb605 100644 --- a/sequencer/sequencer.go +++ b/sequencer/sequencer.go @@ -231,8 +231,8 @@ func (s *Sequencer) addTxToWorker(ctx context.Context, tx pool.Transaction) erro return err } - // XLayer claim tx - freeGp, isClaimTx := s.checkFreeGas(tx, txTracker) + // XLayer free gas tx + freeGp, isClaimTx, gp := s.checkFreeGas(tx, txTracker) if freeGp { defaultGp := s.pool.GetDynamicGasPrice() baseGp := s.worker.getBaseClaimGp(defaultGp) @@ -241,7 +241,7 @@ func (s *Sequencer) addTxToWorker(ctx context.Context, tx pool.Transaction) erro txTracker.IsClaimTx = true txTracker.GasPrice = copyBaseGp.Mul(copyBaseGp, new(big.Int).SetUint64(uint64(getGasPriceMultiple(s.cfg.GasPriceMultiple)))) } else { - txTracker.GasPrice = defaultGp.Mul(defaultGp, new(big.Int).SetUint64(uint64(getInitGasPriceMultiple(s.cfg.InitGasPriceMultiple)))) + txTracker.GasPrice = defaultGp.Mul(defaultGp, new(big.Int).SetUint64(uint64(gp))) } } diff --git a/sequencer/sequencer_xlayer.go b/sequencer/sequencer_xlayer.go index 838c9a8e4e..ad4e16ec5a 100644 --- a/sequencer/sequencer_xlayer.go +++ b/sequencer/sequencer_xlayer.go @@ -2,7 +2,9 @@ package sequencer import ( "context" + "github.com/ethereum/go-ethereum/common" "math/big" + "strings" "time" "github.com/0xPolygonHermez/zkevm-node/log" @@ -36,9 +38,10 @@ func (s *Sequencer) countReadyTx() { state.InfiniteSafeRun(s.updateReadyTxCount, "error counting ready tx", time.Second) } -func (s *Sequencer) checkFreeGas(tx pool.Transaction, txTracker *TxTracker) (freeGp, claimTx bool) { +func (s *Sequencer) checkFreeGas(tx pool.Transaction, txTracker *TxTracker) (freeGp, claimTx bool, gpMul float64) { // check if tx is init-free-gas and if it can be prior pack freeGp = tx.GasPrice().Cmp(big.NewInt(0)) == 0 + gpMul = getInitGasPriceMultiple(s.cfg.InitGasPriceMultiple) // check if tx is bridge-claim addrs := getPackBatchSpacialList(s.cfg.PackBatchSpacialList) @@ -46,5 +49,16 @@ func (s *Sequencer) checkFreeGas(tx pool.Transaction, txTracker *TxTracker) (fre claimTx = true } + // special project of XLayer + freeGpList := pool.GetSpecialFreeGasList(s.poolCfg.FreeGasList) + for _, info := range freeGpList { + if txTracker.From.String() == info.From { + if tx.To().String() == info.To && strings.HasPrefix("0x"+common.Bytes2Hex(tx.Data()), info.MethodSig) { + gpMul = info.GasPriceMultiple + return + } + } + } + return } From b2c421d3ac593f196fbf3179b9e5ac1065ca2554 Mon Sep 17 00:00:00 2001 From: chengzhinei Date: Wed, 7 Aug 2024 12:30:13 +0800 Subject: [PATCH 2/9] fmt code --- sequencer/sequencer_xlayer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sequencer/sequencer_xlayer.go b/sequencer/sequencer_xlayer.go index ad4e16ec5a..18d451e286 100644 --- a/sequencer/sequencer_xlayer.go +++ b/sequencer/sequencer_xlayer.go @@ -2,7 +2,6 @@ package sequencer import ( "context" - "github.com/ethereum/go-ethereum/common" "math/big" "strings" "time" @@ -11,6 +10,7 @@ import ( "github.com/0xPolygonHermez/zkevm-node/pool" pmetric "github.com/0xPolygonHermez/zkevm-node/sequencer/metrics" "github.com/0xPolygonHermez/zkevm-node/state" + "github.com/ethereum/go-ethereum/common" ) var countinterval = 10 From ce3015b992576fdb77e1ddf519caa1153bebc2d9 Mon Sep 17 00:00:00 2001 From: chengzhinei Date: Wed, 7 Aug 2024 12:42:20 +0800 Subject: [PATCH 3/9] fmt code --- docs/config-file/node-config-doc.html | 2 +- docs/config-file/node-config-doc.md | 54 ++++++++++++++++++++++-- docs/config-file/node-config-schema.json | 23 ++++++++++ pool/apollo_xlayer.go | 1 + pool/config.go | 2 +- 5 files changed, 76 insertions(+), 6 deletions(-) diff --git a/docs/config-file/node-config-doc.html b/docs/config-file/node-config-doc.html index 67e8abca6b..cf646339b2 100644 --- a/docs/config-file/node-config-doc.html +++ b/docs/config-file/node-config-doc.html @@ -14,7 +14,7 @@
"300ms"
 

Default: "15s"Type: string

PollMinAllowedGasPriceInterval is the interval to poll the suggested min gas price for a tx


Examples:

"1m"
 
"300ms"
-

Default: 64Type: integer

AccountQueue represents the maximum number of non-executable transaction slots permitted per account


Default: 1024Type: integer

GlobalQueue represents the maximum number of non-executable transaction slots for all accounts


EffectiveGasPrice is the config for the effective gas price calculation
Default: falseType: boolean

Enabled is a flag to enable/disable the effective gas price


Default: 0.25Type: number

L1GasPriceFactor is the percentage of the L1 gas price that will be used as the L2 min gas price


Default: 16Type: integer

ByteGasCost is the gas cost per byte that is not 0


Default: 4Type: integer

ZeroByteGasCost is the gas cost per byte that is 0


Default: 1Type: number

NetProfit is the profit margin to apply to the calculated breakEvenGasPrice


Default: 1.1Type: number

BreakEvenFactor is the factor to apply to the calculated breakevenGasPrice when comparing it with the gasPriceSigned of a tx


Default: 10Type: integer

FinalDeviationPct is the max allowed deviation percentage BreakEvenGasPrice on re-calculation


Default: 0Type: integer

EthTransferGasPrice is the fixed gas price returned as effective gas price for txs tha are ETH transfers (0 means disabled)
Only one of EthTransferGasPrice or EthTransferL1GasPriceFactor params can be different than 0. If both params are set to 0, the sequencer will halt and log an error


Default: 0Type: number

EthTransferL1GasPriceFactor is the percentage of L1 gas price returned as effective gas price for txs tha are ETH transfers (0 means disabled)
Only one of EthTransferGasPrice or EthTransferL1GasPriceFactor params can be different than 0. If both params are set to 0, the sequencer will halt and log an error


Default: 0.5Type: number

L2GasPriceSuggesterFactor is the factor to apply to L1 gas price to get the suggested L2 gas price used in the
calculations when the effective gas price is disabled (testing/metrics purposes)


Default: 0Type: integer

ForkID is the current fork ID of the chain


Default: 1Type: number

TxFeeCap is the global transaction fee(price * gaslimit) cap for
send-transaction variants. The unit is ether. 0 means no cap.


Type: array of string

XLayer config
BlockedList is the blocked address list

Each item of this array must be:


Default: ["0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"]Type: array of string

FreeGasAddress is the default free gas address

Each item of this array must be:


Default: 150000Type: integer

FreeClaimGasLimit is the max gas allowed use to do a free claim


Type: array of string

BridgeClaimMethodSignature for tracking BridgeClaimMethodSignature method

Each item of this array must be:


Default: falseType: boolean

EnableFreeGasByNonce enable free gas


Type: array of string

FreeGasExAddress is the ex address which can be free gas for the transfer receiver

Each item of this array must be:


Default: 0Type: integer

FreeGasCountPerAddr is the count limit of free gas tx per address


Default: 0Type: integer

FreeGasLimit is the max gas allowed use to do a free gas tx


Configuration for RPC service. THis one offers a extended Ethereum JSON-RPC API interface to interact with the node
Default: "0.0.0.0"Type: string

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


Default: 8545Type: integer

Port defines the port to serve the endpoints via HTTP


Default: "1m0s"Type: string

ReadTimeout is the HTTP server read timeout
check net/http.server.ReadTimeout and net/http.server.ReadHeaderTimeout


Examples:

"1m"
+

Default: 64Type: integer

AccountQueue represents the maximum number of non-executable transaction slots permitted per account


Default: 1024Type: integer

GlobalQueue represents the maximum number of non-executable transaction slots for all accounts


EffectiveGasPrice is the config for the effective gas price calculation
Default: falseType: boolean

Enabled is a flag to enable/disable the effective gas price


Default: 0.25Type: number

L1GasPriceFactor is the percentage of the L1 gas price that will be used as the L2 min gas price


Default: 16Type: integer

ByteGasCost is the gas cost per byte that is not 0


Default: 4Type: integer

ZeroByteGasCost is the gas cost per byte that is 0


Default: 1Type: number

NetProfit is the profit margin to apply to the calculated breakEvenGasPrice


Default: 1.1Type: number

BreakEvenFactor is the factor to apply to the calculated breakevenGasPrice when comparing it with the gasPriceSigned of a tx


Default: 10Type: integer

FinalDeviationPct is the max allowed deviation percentage BreakEvenGasPrice on re-calculation


Default: 0Type: integer

EthTransferGasPrice is the fixed gas price returned as effective gas price for txs tha are ETH transfers (0 means disabled)
Only one of EthTransferGasPrice or EthTransferL1GasPriceFactor params can be different than 0. If both params are set to 0, the sequencer will halt and log an error


Default: 0Type: number

EthTransferL1GasPriceFactor is the percentage of L1 gas price returned as effective gas price for txs tha are ETH transfers (0 means disabled)
Only one of EthTransferGasPrice or EthTransferL1GasPriceFactor params can be different than 0. If both params are set to 0, the sequencer will halt and log an error


Default: 0.5Type: number

L2GasPriceSuggesterFactor is the factor to apply to L1 gas price to get the suggested L2 gas price used in the
calculations when the effective gas price is disabled (testing/metrics purposes)


Default: 0Type: integer

ForkID is the current fork ID of the chain


Default: 1Type: number

TxFeeCap is the global transaction fee(price * gaslimit) cap for
send-transaction variants. The unit is ether. 0 means no cap.


Type: array of string

XLayer config
BlockedList is the blocked address list

Each item of this array must be:


Default: ["0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"]Type: array of string

FreeGasAddress is the default free gas address

Each item of this array must be:


Default: 150000Type: integer

FreeClaimGasLimit is the max gas allowed use to do a free claim


Type: array of string

BridgeClaimMethodSignature for tracking BridgeClaimMethodSignature method

Each item of this array must be:


Default: falseType: boolean

EnableFreeGasByNonce enable free gas


Type: array of string

FreeGasExAddress is the ex address which can be free gas for the transfer receiver

Each item of this array must be:


Default: 0Type: integer

FreeGasCountPerAddr is the count limit of free gas tx per address


Default: 0Type: integer

FreeGasLimit is the max gas allowed use to do a free gas tx


Type: array of object

FreeGasList is the special project of XLayer

Each item of this array must be:


Configuration for RPC service. THis one offers a extended Ethereum JSON-RPC API interface to interact with the node
Default: "0.0.0.0"Type: string

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


Default: 8545Type: integer

Port defines the port to serve the endpoints via HTTP


Default: "1m0s"Type: string

ReadTimeout is the HTTP server read timeout
check net/http.server.ReadTimeout and net/http.server.ReadHeaderTimeout


Examples:

"1m"
 
"300ms"
 

Default: "1m0s"Type: string

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


Examples:

"1m"
 
"300ms"
diff --git a/docs/config-file/node-config-doc.md b/docs/config-file/node-config-doc.md
index 607bda00b9..6890225d89 100644
--- a/docs/config-file/node-config-doc.md
+++ b/docs/config-file/node-config-doc.md
@@ -715,6 +715,7 @@ SecretKey=""
 | - [FreeGasExAddress](#Pool_FreeGasExAddress )                                   | No      | array of string | No         | -          | FreeGasExAddress is the ex address which can be free gas for the transfer receiver                                                  |
 | - [FreeGasCountPerAddr](#Pool_FreeGasCountPerAddr )                             | No      | integer         | No         | -          | FreeGasCountPerAddr is the count limit of free gas tx per address                                                                   |
 | - [FreeGasLimit](#Pool_FreeGasLimit )                                           | No      | integer         | No         | -          | FreeGasLimit is the max gas allowed use to do a free gas tx                                                                         |
+| - [FreeGasList](#Pool_FreeGasList )                                             | No      | array of object | No         | -          | FreeGasList is the special project of XLayer                                                                                        |
 
 ### 7.1. `Pool.IntervalToRefreshBlockedAddresses`
 
@@ -1321,6 +1322,51 @@ FreeGasCountPerAddr=0
 FreeGasLimit=0
 ```
 
+### 7.24. `Pool.FreeGasList`
+
+**Type:** : `array of object`
+**Description:** FreeGasList is the special project of XLayer
+
+|                      | Array restrictions |
+| -------------------- | ------------------ |
+| **Min items**        | N/A                |
+| **Max items**        | N/A                |
+| **Items unicity**    | False              |
+| **Additional items** | False              |
+| **Tuple validation** | See below          |
+
+| Each item of this array must be              | Description                                                 |
+| -------------------------------------------- | ----------------------------------------------------------- |
+| [FreeGasList items](#Pool_FreeGasList_items) | FreeGasInfo contains the details for what tx should be free |
+
+#### 7.24.1. [Pool.FreeGasList.FreeGasList items]
+
+**Type:** : `object`
+**Description:** FreeGasInfo contains the details for what tx should be free
+
+| Property                                                        | Pattern | Type   | Deprecated | Definition | Title/Description |
+| --------------------------------------------------------------- | ------- | ------ | ---------- | ---------- | ----------------- |
+| - [From](#Pool_FreeGasList_items_From )                         | No      | string | No         | -          | -                 |
+| - [To](#Pool_FreeGasList_items_To )                             | No      | string | No         | -          | -                 |
+| - [MethodSig](#Pool_FreeGasList_items_MethodSig )               | No      | string | No         | -          | -                 |
+| - [GasPriceMultiple](#Pool_FreeGasList_items_GasPriceMultiple ) | No      | number | No         | -          | -                 |
+
+##### 7.24.1.1. `Pool.FreeGasList.FreeGasList items.From`
+
+**Type:** : `string`
+
+##### 7.24.1.2. `Pool.FreeGasList.FreeGasList items.To`
+
+**Type:** : `string`
+
+##### 7.24.1.3. `Pool.FreeGasList.FreeGasList items.MethodSig`
+
+**Type:** : `string`
+
+##### 7.24.1.4. `Pool.FreeGasList.FreeGasList items.GasPriceMultiple`
+
+**Type:** : `number`
+
 ## 8. `[RPC]`
 
 **Type:** : `object`
@@ -2080,7 +2126,7 @@ SpecialApis=[]
 | ----------------------------------------------------- | ---------------------------------------------------------- |
 | [SpecialApis items](#RPC_RateLimit_SpecialApis_items) | RateLimitItem defines the special rate limit for some apis |
 
-##### 8.25.5.1. [RPC.RateLimit.SpecialApis.SpecialApis items]
+##### 8.25.5.1. [RPC.RateLimit.SpecialApis.SpecialApis items]
 
 **Type:** : `object`
 **Description:** RateLimitItem defines the special rate limit for some apis
@@ -2315,7 +2361,7 @@ ApiKeys=[]
 | ----------------------------------------------------- | --------------------------- |
 | [ApiKeys items](#RPC_ApiAuthentication_ApiKeys_items) | KeyItem is the api key item |
 
-##### 8.29.2.1. [RPC.ApiAuthentication.ApiKeys.ApiKeys items]
+##### 8.29.2.1. [RPC.ApiAuthentication.ApiKeys.ApiKeys items]
 
 **Type:** : `object`
 **Description:** KeyItem is the api key item
@@ -4633,7 +4679,7 @@ RollupManagerBlockNumber=0
 | ----------------------------------------------------- | ------------------------------------------------------------------------- |
 | [Actions items](#NetworkConfig_Genesis_Actions_items) | GenesisAction represents one of the values set on the SMT during genesis. |
 
-##### 13.3.4.1. [NetworkConfig.Genesis.Actions.Actions items]
+##### 13.3.4.1. [NetworkConfig.Genesis.Actions.Actions items]
 
 **Type:** : `object`
 **Description:** GenesisAction represents one of the values set on the SMT during genesis.
@@ -5513,7 +5559,7 @@ ChainID=0
 | ----------------------------------------------------- | ------------------------------------ |
 | [ForkIDIntervals items](#State_ForkIDIntervals_items) | ForkIDInterval is a fork id interval |
 
-#### 20.3.1. [State.ForkIDIntervals.ForkIDIntervals items]
+#### 20.3.1. [State.ForkIDIntervals.ForkIDIntervals items]
 
 **Type:** : `object`
 **Description:** ForkIDInterval is a fork id interval
diff --git a/docs/config-file/node-config-schema.json b/docs/config-file/node-config-schema.json
index 847d43b296..d5c3bbeb82 100644
--- a/docs/config-file/node-config-schema.json
+++ b/docs/config-file/node-config-schema.json
@@ -505,6 +505,29 @@
 					"type": "integer",
 					"description": "FreeGasLimit is the max gas allowed use to do a free gas tx",
 					"default": 0
+				},
+				"FreeGasList": {
+					"items": {
+						"properties": {
+							"From": {
+								"type": "string"
+							},
+							"To": {
+								"type": "string"
+							},
+							"MethodSig": {
+								"type": "string"
+							},
+							"GasPriceMultiple": {
+								"type": "number"
+							}
+						},
+						"additionalProperties": false,
+						"type": "object",
+						"description": "FreeGasInfo contains the details for what tx should be free"
+					},
+					"type": "array",
+					"description": "FreeGasList is the special project of XLayer"
 				}
 			},
 			"additionalProperties": false,
diff --git a/pool/apollo_xlayer.go b/pool/apollo_xlayer.go
index 4d18dc1481..54a8a3fac9 100644
--- a/pool/apollo_xlayer.go
+++ b/pool/apollo_xlayer.go
@@ -213,6 +213,7 @@ func isBlockedAddress(localBlockedList []string, address common.Address) bool {
 	return contains(localBlockedList, address)
 }
 
+// GetSpecialFreeGasList returns the special project in XLayer for free gas
 func GetSpecialFreeGasList(freeGasList []FreeGasInfo) []FreeGasInfo {
 	if getApolloConfig().enable() {
 		getApolloConfig().RLock()
diff --git a/pool/config.go b/pool/config.go
index 6972d79481..0eca248db0 100644
--- a/pool/config.go
+++ b/pool/config.go
@@ -75,7 +75,7 @@ type Config struct {
 	FreeGasList []FreeGasInfo `mapstructure:"FreeGasList"`
 }
 
-// FreeGasInfo contains the detail for what tx should be free
+// FreeGasInfo contains the details for what tx should be free
 type FreeGasInfo struct {
 	From             string  `mapstructure:"From"`
 	To               string  `mapstructure:"To"`

From e92769209b12eae08e0bccce90936947dcb7e117 Mon Sep 17 00:00:00 2001
From: chengzhinei 
Date: Thu, 8 Aug 2024 16:55:30 +0800
Subject: [PATCH 4/9] fix ci

---
 test/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test/Makefile b/test/Makefile
index d1df75cd76..01b7da898c 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -1,4 +1,4 @@
-DOCKERCOMPOSE := docker-compose -f docker-compose.yml
+DOCKERCOMPOSE := docker compose -f docker-compose.yml
 DOCKERCOMPOSEAPPSEQ := xlayer-sequencer
 DOCKERCOMPOSEAPPSEQSENDER := xlayer-sequence-sender
 DOCKERCOMPOSEAPPSIGNER := xlayer-signer

From 182842217f69dfcd837d4e9a6ef52bd2392717e8 Mon Sep 17 00:00:00 2001
From: chengzhinei 
Date: Thu, 8 Aug 2024 17:59:45 +0800
Subject: [PATCH 5/9] add enable flag; config use list

---
 pool/apollo_xlayer.go         | 42 ++++++++++++++++++++++++++++++-----
 pool/config.go                | 11 +++++----
 pool/pool_xlayer.go           | 29 ++++++++++++++++++------
 sequencer/sequencer_xlayer.go | 35 ++++++++++++++++++++++-------
 4 files changed, 92 insertions(+), 25 deletions(-)

diff --git a/pool/apollo_xlayer.go b/pool/apollo_xlayer.go
index 54a8a3fac9..82af2e909b 100644
--- a/pool/apollo_xlayer.go
+++ b/pool/apollo_xlayer.go
@@ -20,7 +20,11 @@ type apolloConfig struct {
 	FreeGasExAddress     []string
 	FreeGasCountPerAddr  uint64
 	FreeGasLimit         uint64
-	FreeGasList          []FreeGasInfo
+
+	// for special project
+	EnableFreeGasList  bool
+	FreeGasFromNameMap map[string]string       // map[from]projectName
+	FreeGasList        map[string]*FreeGasInfo // map[projectName]FreeGasInfo
 
 	BlockedList []string
 
@@ -48,8 +52,14 @@ func (c *apolloConfig) setFreeGasList(freeGasList []FreeGasInfo) {
 	if c == nil || !c.EnableApollo {
 		return
 	}
-	c.FreeGasList = make([]FreeGasInfo, len(freeGasList))
-	copy(c.FreeGasList, freeGasList)
+	c.FreeGasFromNameMap = make(map[string]string)
+	c.FreeGasList = make(map[string]*FreeGasInfo, len(freeGasList))
+	for _, info := range freeGasList {
+		for _, from := range info.FromList {
+			c.FreeGasFromNameMap[from] = info.Name
+		}
+		c.FreeGasList[info.Name] = &info
+	}
 }
 
 func (c *apolloConfig) setFreeGasAddresses(freeGasAddrs []string) {
@@ -104,6 +114,7 @@ func UpdateConfig(apolloConfig Config) {
 	getApolloConfig().setFreeGasExAddresses(apolloConfig.FreeGasExAddress)
 	getApolloConfig().FreeGasCountPerAddr = apolloConfig.FreeGasCountPerAddr
 	getApolloConfig().FreeGasLimit = apolloConfig.FreeGasLimit
+	getApolloConfig().EnableFreeGasList = apolloConfig.EnableFreeGasList
 	getApolloConfig().setFreeGasList(apolloConfig.FreeGasList)
 
 	getApolloConfig().Unlock()
@@ -213,13 +224,32 @@ func isBlockedAddress(localBlockedList []string, address common.Address) bool {
 	return contains(localBlockedList, address)
 }
 
+// GetEnableSpecialFreeGasList returns enable flag of FreeGasList
+func GetEnableSpecialFreeGasList(enableFreeGasList bool) bool {
+	if getApolloConfig().enable() {
+		getApolloConfig().RLock()
+		defer getApolloConfig().RUnlock()
+		return getApolloConfig().EnableFreeGasList
+	}
+	return enableFreeGasList
+}
+
 // GetSpecialFreeGasList returns the special project in XLayer for free gas
-func GetSpecialFreeGasList(freeGasList []FreeGasInfo) []FreeGasInfo {
+func GetSpecialFreeGasList(freeGasList []FreeGasInfo) (map[string]string, map[string]*FreeGasInfo) {
 	if getApolloConfig().enable() {
 		getApolloConfig().RLock()
 		defer getApolloConfig().RUnlock()
-		return getApolloConfig().FreeGasList
+		return getApolloConfig().FreeGasFromNameMap, getApolloConfig().FreeGasList
+	}
+
+	freeGasFromNameMap := make(map[string]string)
+	freeGasMap := make(map[string]*FreeGasInfo, len(freeGasList))
+	for _, info := range freeGasList {
+		for _, from := range info.FromList {
+			freeGasFromNameMap[from] = info.Name
+		}
+		freeGasMap[info.Name] = &info
 	}
 
-	return freeGasList
+	return freeGasFromNameMap, freeGasMap
 }
diff --git a/pool/config.go b/pool/config.go
index 0eca248db0..a7cd61baa1 100644
--- a/pool/config.go
+++ b/pool/config.go
@@ -71,16 +71,19 @@ type Config struct {
 	FreeGasCountPerAddr uint64 `mapstructure:"FreeGasCountPerAddr"`
 	// FreeGasLimit is the max gas allowed use to do a free gas tx
 	FreeGasLimit uint64 `mapstructure:"FreeGasLimit"`
+	// EnableFreeGasList enable the special project of XLayer for free gas
+	EnableFreeGasList bool `mapstructure:"EnableFreeGasList"`
 	// FreeGasList is the special project of XLayer
 	FreeGasList []FreeGasInfo `mapstructure:"FreeGasList"`
 }
 
 // FreeGasInfo contains the details for what tx should be free
 type FreeGasInfo struct {
-	From             string  `mapstructure:"From"`
-	To               string  `mapstructure:"To"`
-	MethodSig        string  `mapstructure:"MethodSig"`
-	GasPriceMultiple float64 `mapstructure:"GasPriceMultiple"`
+	Name             string   `mapstructure:"Name"`
+	FromList         []string `mapstructure:"FromList"`
+	ToList           []string `mapstructure:"ToList"`
+	MethodSigs       []string `mapstructure:"MethodSigs"`
+	GasPriceMultiple float64  `mapstructure:"GasPriceMultiple"`
 }
 
 // EffectiveGasPriceCfg contains the configuration properties for the effective gas price
diff --git a/pool/pool_xlayer.go b/pool/pool_xlayer.go
index de1cd3ce7f..3baabba02f 100644
--- a/pool/pool_xlayer.go
+++ b/pool/pool_xlayer.go
@@ -40,6 +40,15 @@ func contains(s []string, ele common.Address) bool {
 	return false
 }
 
+func containsMethod(data string, methods []string) bool {
+	for _, m := range methods {
+		if strings.HasPrefix(data, m) {
+			return true
+		}
+	}
+	return false
+}
+
 // StartRefreshingWhiteAddressesPeriodically will make this instance of the pool
 // to check periodically(accordingly to the configuration) for updates regarding
 // the white address and update the in memory blocked addresses
@@ -113,17 +122,23 @@ func (p *Pool) GetDynamicGasPrice() *big.Int {
 }
 
 func (p *Pool) checkFreeGp(ctx context.Context, poolTx Transaction, from common.Address) (bool, error) {
-	if isFreeGasAddress(p.cfg.FreeGasAddress, from) && poolTx.IsClaims { // claim tx
+	// claim tx
+	if isFreeGasAddress(p.cfg.FreeGasAddress, from) && poolTx.IsClaims {
 		return true, nil
 	}
-	freeGpList := GetSpecialFreeGasList(p.cfg.FreeGasList)
-	for _, info := range freeGpList {
-		if from.String() == info.From {
-			if poolTx.To().String() == info.To && strings.HasPrefix("0x"+common.Bytes2Hex(poolTx.Data()), info.MethodSig) {
-				return true, nil
-			}
+
+	// special project
+	if GetEnableSpecialFreeGasList(p.cfg.EnableFreeGasList) {
+		fromToName, freeGpList := GetSpecialFreeGasList(p.cfg.FreeGasList)
+		info := freeGpList[fromToName[from.String()]]
+		if info != nil &&
+			contains(info.ToList, *poolTx.To()) &&
+			containsMethod("0x"+common.Bytes2Hex(poolTx.Data()), info.MethodSigs) {
+			return true, nil
 		}
 	}
+
+	// new bridge address
 	if getEnableFreeGasByNonce(p.cfg.EnableFreeGasByNonce) && poolTx.GasPrice().Cmp(big.NewInt(0)) == 0 { // free-gas tx by count
 		isFreeAddr, err := p.storage.IsFreeGasAddr(ctx, from)
 		if err != nil {
diff --git a/sequencer/sequencer_xlayer.go b/sequencer/sequencer_xlayer.go
index 18d451e286..5f525611f8 100644
--- a/sequencer/sequencer_xlayer.go
+++ b/sequencer/sequencer_xlayer.go
@@ -15,6 +15,24 @@ import (
 
 var countinterval = 10
 
+func contains(s []string, ele common.Address) bool {
+	for _, e := range s {
+		if common.HexToAddress(e) == ele {
+			return true
+		}
+	}
+	return false
+}
+
+func containsMethod(data string, methods []string) bool {
+	for _, m := range methods {
+		if strings.HasPrefix(data, m) {
+			return true
+		}
+	}
+	return false
+}
+
 func (s *Sequencer) countPendingTx() {
 	for {
 		<-time.After(time.Second * time.Duration(countinterval))
@@ -49,14 +67,15 @@ func (s *Sequencer) checkFreeGas(tx pool.Transaction, txTracker *TxTracker) (fre
 		claimTx = true
 	}
 
-	// special project of XLayer
-	freeGpList := pool.GetSpecialFreeGasList(s.poolCfg.FreeGasList)
-	for _, info := range freeGpList {
-		if txTracker.From.String() == info.From {
-			if tx.To().String() == info.To && strings.HasPrefix("0x"+common.Bytes2Hex(tx.Data()), info.MethodSig) {
-				gpMul = info.GasPriceMultiple
-				return
-			}
+	// check if tx is from special project
+	if pool.GetEnableSpecialFreeGasList(s.poolCfg.EnableFreeGasList) {
+		fromToName, freeGpList := pool.GetSpecialFreeGasList(s.poolCfg.FreeGasList)
+		info := freeGpList[fromToName[txTracker.FromStr]]
+		if info != nil &&
+			contains(info.ToList, *tx.To()) &&
+			containsMethod("0x"+common.Bytes2Hex(tx.Data()), info.MethodSigs) {
+			gpMul = info.GasPriceMultiple
+			return
 		}
 	}
 

From c2e1864a1d8cf528b3ccf1a376952b7c7cc31c07 Mon Sep 17 00:00:00 2001
From: chengzhinei 
Date: Thu, 8 Aug 2024 18:01:05 +0800
Subject: [PATCH 6/9] fix json

---
 docs/config-file/node-config-doc.html    |  2 +-
 docs/config-file/node-config-doc.md      | 48 +++++++++++++++++-------
 docs/config-file/node-config-schema.json | 27 ++++++++++---
 3 files changed, 57 insertions(+), 20 deletions(-)

diff --git a/docs/config-file/node-config-doc.html b/docs/config-file/node-config-doc.html
index cf646339b2..7a8fab3a3d 100644
--- a/docs/config-file/node-config-doc.html
+++ b/docs/config-file/node-config-doc.html
@@ -14,7 +14,7 @@
 
"300ms"
 

Default: "15s"Type: string

PollMinAllowedGasPriceInterval is the interval to poll the suggested min gas price for a tx


Examples:

"1m"
 
"300ms"
-

Default: 64Type: integer

AccountQueue represents the maximum number of non-executable transaction slots permitted per account


Default: 1024Type: integer

GlobalQueue represents the maximum number of non-executable transaction slots for all accounts


EffectiveGasPrice is the config for the effective gas price calculation
Default: falseType: boolean

Enabled is a flag to enable/disable the effective gas price


Default: 0.25Type: number

L1GasPriceFactor is the percentage of the L1 gas price that will be used as the L2 min gas price


Default: 16Type: integer

ByteGasCost is the gas cost per byte that is not 0


Default: 4Type: integer

ZeroByteGasCost is the gas cost per byte that is 0


Default: 1Type: number

NetProfit is the profit margin to apply to the calculated breakEvenGasPrice


Default: 1.1Type: number

BreakEvenFactor is the factor to apply to the calculated breakevenGasPrice when comparing it with the gasPriceSigned of a tx


Default: 10Type: integer

FinalDeviationPct is the max allowed deviation percentage BreakEvenGasPrice on re-calculation


Default: 0Type: integer

EthTransferGasPrice is the fixed gas price returned as effective gas price for txs tha are ETH transfers (0 means disabled)
Only one of EthTransferGasPrice or EthTransferL1GasPriceFactor params can be different than 0. If both params are set to 0, the sequencer will halt and log an error


Default: 0Type: number

EthTransferL1GasPriceFactor is the percentage of L1 gas price returned as effective gas price for txs tha are ETH transfers (0 means disabled)
Only one of EthTransferGasPrice or EthTransferL1GasPriceFactor params can be different than 0. If both params are set to 0, the sequencer will halt and log an error


Default: 0.5Type: number

L2GasPriceSuggesterFactor is the factor to apply to L1 gas price to get the suggested L2 gas price used in the
calculations when the effective gas price is disabled (testing/metrics purposes)


Default: 0Type: integer

ForkID is the current fork ID of the chain


Default: 1Type: number

TxFeeCap is the global transaction fee(price * gaslimit) cap for
send-transaction variants. The unit is ether. 0 means no cap.


Type: array of string

XLayer config
BlockedList is the blocked address list

Each item of this array must be:


Default: ["0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"]Type: array of string

FreeGasAddress is the default free gas address

Each item of this array must be:


Default: 150000Type: integer

FreeClaimGasLimit is the max gas allowed use to do a free claim


Type: array of string

BridgeClaimMethodSignature for tracking BridgeClaimMethodSignature method

Each item of this array must be:


Default: falseType: boolean

EnableFreeGasByNonce enable free gas


Type: array of string

FreeGasExAddress is the ex address which can be free gas for the transfer receiver

Each item of this array must be:


Default: 0Type: integer

FreeGasCountPerAddr is the count limit of free gas tx per address


Default: 0Type: integer

FreeGasLimit is the max gas allowed use to do a free gas tx


Type: array of object

FreeGasList is the special project of XLayer

Each item of this array must be:


Configuration for RPC service. THis one offers a extended Ethereum JSON-RPC API interface to interact with the node
Default: "0.0.0.0"Type: string

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


Default: 8545Type: integer

Port defines the port to serve the endpoints via HTTP


Default: "1m0s"Type: string

ReadTimeout is the HTTP server read timeout
check net/http.server.ReadTimeout and net/http.server.ReadHeaderTimeout


Examples:

"1m"
+

Default: 64Type: integer

AccountQueue represents the maximum number of non-executable transaction slots permitted per account


Default: 1024Type: integer

GlobalQueue represents the maximum number of non-executable transaction slots for all accounts


EffectiveGasPrice is the config for the effective gas price calculation
Default: falseType: boolean

Enabled is a flag to enable/disable the effective gas price


Default: 0.25Type: number

L1GasPriceFactor is the percentage of the L1 gas price that will be used as the L2 min gas price


Default: 16Type: integer

ByteGasCost is the gas cost per byte that is not 0


Default: 4Type: integer

ZeroByteGasCost is the gas cost per byte that is 0


Default: 1Type: number

NetProfit is the profit margin to apply to the calculated breakEvenGasPrice


Default: 1.1Type: number

BreakEvenFactor is the factor to apply to the calculated breakevenGasPrice when comparing it with the gasPriceSigned of a tx


Default: 10Type: integer

FinalDeviationPct is the max allowed deviation percentage BreakEvenGasPrice on re-calculation


Default: 0Type: integer

EthTransferGasPrice is the fixed gas price returned as effective gas price for txs tha are ETH transfers (0 means disabled)
Only one of EthTransferGasPrice or EthTransferL1GasPriceFactor params can be different than 0. If both params are set to 0, the sequencer will halt and log an error


Default: 0Type: number

EthTransferL1GasPriceFactor is the percentage of L1 gas price returned as effective gas price for txs tha are ETH transfers (0 means disabled)
Only one of EthTransferGasPrice or EthTransferL1GasPriceFactor params can be different than 0. If both params are set to 0, the sequencer will halt and log an error


Default: 0.5Type: number

L2GasPriceSuggesterFactor is the factor to apply to L1 gas price to get the suggested L2 gas price used in the
calculations when the effective gas price is disabled (testing/metrics purposes)


Default: 0Type: integer

ForkID is the current fork ID of the chain


Default: 1Type: number

TxFeeCap is the global transaction fee(price * gaslimit) cap for
send-transaction variants. The unit is ether. 0 means no cap.


Type: array of string

XLayer config
BlockedList is the blocked address list

Each item of this array must be:


Default: ["0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"]Type: array of string

FreeGasAddress is the default free gas address

Each item of this array must be:


Default: 150000Type: integer

FreeClaimGasLimit is the max gas allowed use to do a free claim


Type: array of string

BridgeClaimMethodSignature for tracking BridgeClaimMethodSignature method

Each item of this array must be:


Default: falseType: boolean

EnableFreeGasByNonce enable free gas


Type: array of string

FreeGasExAddress is the ex address which can be free gas for the transfer receiver

Each item of this array must be:


Default: 0Type: integer

FreeGasCountPerAddr is the count limit of free gas tx per address


Default: 0Type: integer

FreeGasLimit is the max gas allowed use to do a free gas tx


Default: falseType: boolean

EnableFreeGasList enable the special project of XLayer for free gas


Type: array of object

FreeGasList is the special project of XLayer

Each item of this array must be:


Configuration for RPC service. THis one offers a extended Ethereum JSON-RPC API interface to interact with the node
Default: "0.0.0.0"Type: string

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


Default: 8545Type: integer

Port defines the port to serve the endpoints via HTTP


Default: "1m0s"Type: string

ReadTimeout is the HTTP server read timeout
check net/http.server.ReadTimeout and net/http.server.ReadHeaderTimeout


Examples:

"1m"
 
"300ms"
 

Default: "1m0s"Type: string

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


Examples:

"1m"
 
"300ms"
diff --git a/docs/config-file/node-config-doc.md b/docs/config-file/node-config-doc.md
index 6890225d89..8c8281c85c 100644
--- a/docs/config-file/node-config-doc.md
+++ b/docs/config-file/node-config-doc.md
@@ -715,6 +715,7 @@ SecretKey=""
 | - [FreeGasExAddress](#Pool_FreeGasExAddress )                                   | No      | array of string | No         | -          | FreeGasExAddress is the ex address which can be free gas for the transfer receiver                                                  |
 | - [FreeGasCountPerAddr](#Pool_FreeGasCountPerAddr )                             | No      | integer         | No         | -          | FreeGasCountPerAddr is the count limit of free gas tx per address                                                                   |
 | - [FreeGasLimit](#Pool_FreeGasLimit )                                           | No      | integer         | No         | -          | FreeGasLimit is the max gas allowed use to do a free gas tx                                                                         |
+| - [EnableFreeGasList](#Pool_EnableFreeGasList )                                 | No      | boolean         | No         | -          | EnableFreeGasList enable the special project of XLayer for free gas                                                                 |
 | - [FreeGasList](#Pool_FreeGasList )                                             | No      | array of object | No         | -          | FreeGasList is the special project of XLayer                                                                                        |
 
 ### 7.1. `Pool.IntervalToRefreshBlockedAddresses`
@@ -1322,7 +1323,21 @@ FreeGasCountPerAddr=0
 FreeGasLimit=0
 ```
 
-### 7.24. `Pool.FreeGasList`
+### 7.24. `Pool.EnableFreeGasList`
+
+**Type:** : `boolean`
+
+**Default:** `false`
+
+**Description:** EnableFreeGasList enable the special project of XLayer for free gas
+
+**Example setting the default value** (false):
+```
+[Pool]
+EnableFreeGasList=false
+```
+
+### 7.25. `Pool.FreeGasList`
 
 **Type:** : `array of object`
 **Description:** FreeGasList is the special project of XLayer
@@ -1339,31 +1354,36 @@ FreeGasLimit=0
 | -------------------------------------------- | ----------------------------------------------------------- |
 | [FreeGasList items](#Pool_FreeGasList_items) | FreeGasInfo contains the details for what tx should be free |
 
-#### 7.24.1. [Pool.FreeGasList.FreeGasList items]
+#### 7.25.1. [Pool.FreeGasList.FreeGasList items]
 
 **Type:** : `object`
 **Description:** FreeGasInfo contains the details for what tx should be free
 
-| Property                                                        | Pattern | Type   | Deprecated | Definition | Title/Description |
-| --------------------------------------------------------------- | ------- | ------ | ---------- | ---------- | ----------------- |
-| - [From](#Pool_FreeGasList_items_From )                         | No      | string | No         | -          | -                 |
-| - [To](#Pool_FreeGasList_items_To )                             | No      | string | No         | -          | -                 |
-| - [MethodSig](#Pool_FreeGasList_items_MethodSig )               | No      | string | No         | -          | -                 |
-| - [GasPriceMultiple](#Pool_FreeGasList_items_GasPriceMultiple ) | No      | number | No         | -          | -                 |
+| Property                                                        | Pattern | Type            | Deprecated | Definition | Title/Description |
+| --------------------------------------------------------------- | ------- | --------------- | ---------- | ---------- | ----------------- |
+| - [Name](#Pool_FreeGasList_items_Name )                         | No      | string          | No         | -          | -                 |
+| - [FromList](#Pool_FreeGasList_items_FromList )                 | No      | array of string | No         | -          | -                 |
+| - [ToList](#Pool_FreeGasList_items_ToList )                     | No      | array of string | No         | -          | -                 |
+| - [MethodSigs](#Pool_FreeGasList_items_MethodSigs )             | No      | array of string | No         | -          | -                 |
+| - [GasPriceMultiple](#Pool_FreeGasList_items_GasPriceMultiple ) | No      | number          | No         | -          | -                 |
 
-##### 7.24.1.1. `Pool.FreeGasList.FreeGasList items.From`
+##### 7.25.1.1. `Pool.FreeGasList.FreeGasList items.Name`
 
 **Type:** : `string`
 
-##### 7.24.1.2. `Pool.FreeGasList.FreeGasList items.To`
+##### 7.25.1.2. `Pool.FreeGasList.FreeGasList items.FromList`
 
-**Type:** : `string`
+**Type:** : `array of string`
 
-##### 7.24.1.3. `Pool.FreeGasList.FreeGasList items.MethodSig`
+##### 7.25.1.3. `Pool.FreeGasList.FreeGasList items.ToList`
 
-**Type:** : `string`
+**Type:** : `array of string`
+
+##### 7.25.1.4. `Pool.FreeGasList.FreeGasList items.MethodSigs`
+
+**Type:** : `array of string`
 
-##### 7.24.1.4. `Pool.FreeGasList.FreeGasList items.GasPriceMultiple`
+##### 7.25.1.5. `Pool.FreeGasList.FreeGasList items.GasPriceMultiple`
 
 **Type:** : `number`
 
diff --git a/docs/config-file/node-config-schema.json b/docs/config-file/node-config-schema.json
index d5c3bbeb82..9414fe86d0 100644
--- a/docs/config-file/node-config-schema.json
+++ b/docs/config-file/node-config-schema.json
@@ -506,17 +506,34 @@
 					"description": "FreeGasLimit is the max gas allowed use to do a free gas tx",
 					"default": 0
 				},
+				"EnableFreeGasList": {
+					"type": "boolean",
+					"description": "EnableFreeGasList enable the special project of XLayer for free gas",
+					"default": false
+				},
 				"FreeGasList": {
 					"items": {
 						"properties": {
-							"From": {
+							"Name": {
 								"type": "string"
 							},
-							"To": {
-								"type": "string"
+							"FromList": {
+								"items": {
+									"type": "string"
+								},
+								"type": "array"
 							},
-							"MethodSig": {
-								"type": "string"
+							"ToList": {
+								"items": {
+									"type": "string"
+								},
+								"type": "array"
+							},
+							"MethodSigs": {
+								"items": {
+									"type": "string"
+								},
+								"type": "array"
 							},
 							"GasPriceMultiple": {
 								"type": "number"

From e7ab9d98e0aa106ce748f24e1fcbac262f4133de Mon Sep 17 00:00:00 2001
From: chengzhinei 
Date: Fri, 9 Aug 2024 10:55:22 +0800
Subject: [PATCH 7/9] fix comment

---
 pool/apollo_xlayer.go         | 18 ++++++++++--------
 pool/pool_xlayer.go           | 10 ++++++----
 sequencer/sequencer.go        |  9 +++++----
 sequencer/sequencer_xlayer.go | 24 +++---------------------
 4 files changed, 24 insertions(+), 37 deletions(-)

diff --git a/pool/apollo_xlayer.go b/pool/apollo_xlayer.go
index 82af2e909b..411f9262ea 100644
--- a/pool/apollo_xlayer.go
+++ b/pool/apollo_xlayer.go
@@ -58,7 +58,8 @@ func (c *apolloConfig) setFreeGasList(freeGasList []FreeGasInfo) {
 		for _, from := range info.FromList {
 			c.FreeGasFromNameMap[from] = info.Name
 		}
-		c.FreeGasList[info.Name] = &info
+		name := info.Name
+		c.FreeGasList[name] = &info
 	}
 }
 
@@ -140,10 +141,10 @@ func isFreeGasAddress(localFreeGasAddrs []string, address common.Address) bool {
 	if getApolloConfig().enable() {
 		getApolloConfig().RLock()
 		defer getApolloConfig().RUnlock()
-		return contains(getApolloConfig().FreeGasAddresses, address)
+		return Contains(getApolloConfig().FreeGasAddresses, address)
 	}
 
-	return contains(localFreeGasAddrs, address)
+	return Contains(localFreeGasAddrs, address)
 }
 
 func getEnableFreeGasByNonce(enableFreeGasByNonce bool) bool {
@@ -160,10 +161,10 @@ func isFreeGasExAddress(localFreeGasExAddrs []string, address common.Address) bo
 	if getApolloConfig().enable() {
 		getApolloConfig().RLock()
 		defer getApolloConfig().RUnlock()
-		return contains(getApolloConfig().FreeGasExAddress, address)
+		return Contains(getApolloConfig().FreeGasExAddress, address)
 	}
 
-	return contains(localFreeGasExAddrs, address)
+	return Contains(localFreeGasExAddrs, address)
 }
 
 func getFreeGasCountPerAddr(localFreeGasCountPerAddr uint64) uint64 {
@@ -218,10 +219,10 @@ func isBlockedAddress(localBlockedList []string, address common.Address) bool {
 	if getApolloConfig().enable() {
 		getApolloConfig().RLock()
 		defer getApolloConfig().RUnlock()
-		return contains(getApolloConfig().BlockedList, address)
+		return Contains(getApolloConfig().BlockedList, address)
 	}
 
-	return contains(localBlockedList, address)
+	return Contains(localBlockedList, address)
 }
 
 // GetEnableSpecialFreeGasList returns enable flag of FreeGasList
@@ -248,7 +249,8 @@ func GetSpecialFreeGasList(freeGasList []FreeGasInfo) (map[string]string, map[st
 		for _, from := range info.FromList {
 			freeGasFromNameMap[from] = info.Name
 		}
-		freeGasMap[info.Name] = &info
+		name := info.Name
+		freeGasMap[name] = &info
 	}
 
 	return freeGasFromNameMap, freeGasMap
diff --git a/pool/pool_xlayer.go b/pool/pool_xlayer.go
index 3baabba02f..e6d2e16713 100644
--- a/pool/pool_xlayer.go
+++ b/pool/pool_xlayer.go
@@ -31,7 +31,8 @@ const (
 	MainnetBridgeURL = "https://www.okx.com/xlayer/bridge"
 )
 
-func contains(s []string, ele common.Address) bool {
+// Contains returns if string[] contains ele string
+func Contains(s []string, ele common.Address) bool {
 	for _, e := range s {
 		if common.HexToAddress(e) == ele {
 			return true
@@ -40,7 +41,8 @@ func contains(s []string, ele common.Address) bool {
 	return false
 }
 
-func containsMethod(data string, methods []string) bool {
+// ContainsMethod returns if data has prefix of method sig
+func ContainsMethod(data string, methods []string) bool {
 	for _, m := range methods {
 		if strings.HasPrefix(data, m) {
 			return true
@@ -132,8 +134,8 @@ func (p *Pool) checkFreeGp(ctx context.Context, poolTx Transaction, from common.
 		fromToName, freeGpList := GetSpecialFreeGasList(p.cfg.FreeGasList)
 		info := freeGpList[fromToName[from.String()]]
 		if info != nil &&
-			contains(info.ToList, *poolTx.To()) &&
-			containsMethod("0x"+common.Bytes2Hex(poolTx.Data()), info.MethodSigs) {
+			Contains(info.ToList, *poolTx.To()) &&
+			ContainsMethod("0x"+common.Bytes2Hex(poolTx.Data()), info.MethodSigs) {
 			return true, nil
 		}
 	}
diff --git a/sequencer/sequencer.go b/sequencer/sequencer.go
index 6870bbb605..c99ef4f661 100644
--- a/sequencer/sequencer.go
+++ b/sequencer/sequencer.go
@@ -235,14 +235,15 @@ func (s *Sequencer) addTxToWorker(ctx context.Context, tx pool.Transaction) erro
 	freeGp, isClaimTx, gp := s.checkFreeGas(tx, txTracker)
 	if freeGp {
 		defaultGp := s.pool.GetDynamicGasPrice()
-		baseGp := s.worker.getBaseClaimGp(defaultGp)
-		copyBaseGp := new(big.Int).Set(baseGp)
+		copyBaseGp := new(big.Int)
 		if isClaimTx {
 			txTracker.IsClaimTx = true
-			txTracker.GasPrice = copyBaseGp.Mul(copyBaseGp, new(big.Int).SetUint64(uint64(getGasPriceMultiple(s.cfg.GasPriceMultiple))))
+			baseGp := s.worker.getBaseClaimGp(defaultGp)
+			copyBaseGp.Set(baseGp)
 		} else {
-			txTracker.GasPrice = defaultGp.Mul(defaultGp, new(big.Int).SetUint64(uint64(gp)))
+			copyBaseGp.Set(defaultGp)
 		}
+		txTracker.GasPrice = copyBaseGp.Mul(copyBaseGp, new(big.Int).SetUint64(uint64(gp)))
 	}
 
 	replacedTx, dropReason := s.worker.AddTxTracker(ctx, txTracker)
diff --git a/sequencer/sequencer_xlayer.go b/sequencer/sequencer_xlayer.go
index 5f525611f8..aa1e9a6a5c 100644
--- a/sequencer/sequencer_xlayer.go
+++ b/sequencer/sequencer_xlayer.go
@@ -3,7 +3,6 @@ package sequencer
 import (
 	"context"
 	"math/big"
-	"strings"
 	"time"
 
 	"github.com/0xPolygonHermez/zkevm-node/log"
@@ -15,24 +14,6 @@ import (
 
 var countinterval = 10
 
-func contains(s []string, ele common.Address) bool {
-	for _, e := range s {
-		if common.HexToAddress(e) == ele {
-			return true
-		}
-	}
-	return false
-}
-
-func containsMethod(data string, methods []string) bool {
-	for _, m := range methods {
-		if strings.HasPrefix(data, m) {
-			return true
-		}
-	}
-	return false
-}
-
 func (s *Sequencer) countPendingTx() {
 	for {
 		<-time.After(time.Second * time.Duration(countinterval))
@@ -65,6 +46,7 @@ func (s *Sequencer) checkFreeGas(tx pool.Transaction, txTracker *TxTracker) (fre
 	addrs := getPackBatchSpacialList(s.cfg.PackBatchSpacialList)
 	if addrs[txTracker.FromStr] {
 		claimTx = true
+		gpMul = getGasPriceMultiple(s.cfg.GasPriceMultiple)
 	}
 
 	// check if tx is from special project
@@ -72,8 +54,8 @@ func (s *Sequencer) checkFreeGas(tx pool.Transaction, txTracker *TxTracker) (fre
 		fromToName, freeGpList := pool.GetSpecialFreeGasList(s.poolCfg.FreeGasList)
 		info := freeGpList[fromToName[txTracker.FromStr]]
 		if info != nil &&
-			contains(info.ToList, *tx.To()) &&
-			containsMethod("0x"+common.Bytes2Hex(tx.Data()), info.MethodSigs) {
+			pool.Contains(info.ToList, *tx.To()) &&
+			pool.ContainsMethod("0x"+common.Bytes2Hex(tx.Data()), info.MethodSigs) {
 			gpMul = info.GasPriceMultiple
 			return
 		}

From 9b5754a2d6eac41849673a2131d646ceb99c1e6e Mon Sep 17 00:00:00 2001
From: chengzhinei 
Date: Fri, 9 Aug 2024 11:00:40 +0800
Subject: [PATCH 8/9] fix lint

---
 pool/apollo_xlayer.go | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/pool/apollo_xlayer.go b/pool/apollo_xlayer.go
index 411f9262ea..16ea4953cd 100644
--- a/pool/apollo_xlayer.go
+++ b/pool/apollo_xlayer.go
@@ -58,8 +58,8 @@ func (c *apolloConfig) setFreeGasList(freeGasList []FreeGasInfo) {
 		for _, from := range info.FromList {
 			c.FreeGasFromNameMap[from] = info.Name
 		}
-		name := info.Name
-		c.FreeGasList[name] = &info
+		infoCopy := info
+		c.FreeGasList[info.Name] = &infoCopy
 	}
 }
 
@@ -249,8 +249,8 @@ func GetSpecialFreeGasList(freeGasList []FreeGasInfo) (map[string]string, map[st
 		for _, from := range info.FromList {
 			freeGasFromNameMap[from] = info.Name
 		}
-		name := info.Name
-		freeGasMap[name] = &info
+		infoCopy := info
+		freeGasMap[info.Name] = &infoCopy
 	}
 
 	return freeGasFromNameMap, freeGasMap

From 713e3feeed22b15307fc36d1deac6ee1684a7026 Mon Sep 17 00:00:00 2001
From: chengzhinei 
Date: Fri, 9 Aug 2024 15:56:17 +0800
Subject: [PATCH 9/9] fix comment

---
 sequencer/sequencer_xlayer.go | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sequencer/sequencer_xlayer.go b/sequencer/sequencer_xlayer.go
index aa1e9a6a5c..3a27452f22 100644
--- a/sequencer/sequencer_xlayer.go
+++ b/sequencer/sequencer_xlayer.go
@@ -47,6 +47,7 @@ func (s *Sequencer) checkFreeGas(tx pool.Transaction, txTracker *TxTracker) (fre
 	if addrs[txTracker.FromStr] {
 		claimTx = true
 		gpMul = getGasPriceMultiple(s.cfg.GasPriceMultiple)
+		return
 	}
 
 	// check if tx is from special project