Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support special project in xlayer for free gas #240

Merged
merged 9 commits into from
Aug 9, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/config-file/node-config-doc.html

Large diffs are not rendered by default.

74 changes: 70 additions & 4 deletions docs/config-file/node-config-doc.md
Original file line number Diff line number Diff line change
Expand Up @@ -715,6 +715,8 @@ 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 |

### <a name="Pool_IntervalToRefreshBlockedAddresses"></a>7.1. `Pool.IntervalToRefreshBlockedAddresses`

Expand Down Expand Up @@ -1321,6 +1323,70 @@ FreeGasCountPerAddr=0
FreeGasLimit=0
```

### <a name="Pool_EnableFreeGasList"></a>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
```

### <a name="Pool_FreeGasList"></a>7.25. `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 |

#### <a name="autogenerated_heading_3"></a>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 |
| --------------------------------------------------------------- | ------- | --------------- | ---------- | ---------- | ----------------- |
| - [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 | - | - |

##### <a name="Pool_FreeGasList_items_Name"></a>7.25.1.1. `Pool.FreeGasList.FreeGasList items.Name`

**Type:** : `string`

##### <a name="Pool_FreeGasList_items_FromList"></a>7.25.1.2. `Pool.FreeGasList.FreeGasList items.FromList`

**Type:** : `array of string`

##### <a name="Pool_FreeGasList_items_ToList"></a>7.25.1.3. `Pool.FreeGasList.FreeGasList items.ToList`

**Type:** : `array of string`

##### <a name="Pool_FreeGasList_items_MethodSigs"></a>7.25.1.4. `Pool.FreeGasList.FreeGasList items.MethodSigs`

**Type:** : `array of string`

##### <a name="Pool_FreeGasList_items_GasPriceMultiple"></a>7.25.1.5. `Pool.FreeGasList.FreeGasList items.GasPriceMultiple`

**Type:** : `number`

## <a name="RPC"></a>8. `[RPC]`

**Type:** : `object`
Expand Down Expand Up @@ -2080,7 +2146,7 @@ SpecialApis=[]
| ----------------------------------------------------- | ---------------------------------------------------------- |
| [SpecialApis items](#RPC_RateLimit_SpecialApis_items) | RateLimitItem defines the special rate limit for some apis |

##### <a name="autogenerated_heading_3"></a>8.25.5.1. [RPC.RateLimit.SpecialApis.SpecialApis items]
##### <a name="autogenerated_heading_4"></a>8.25.5.1. [RPC.RateLimit.SpecialApis.SpecialApis items]

**Type:** : `object`
**Description:** RateLimitItem defines the special rate limit for some apis
Expand Down Expand Up @@ -2315,7 +2381,7 @@ ApiKeys=[]
| ----------------------------------------------------- | --------------------------- |
| [ApiKeys items](#RPC_ApiAuthentication_ApiKeys_items) | KeyItem is the api key item |

##### <a name="autogenerated_heading_4"></a>8.29.2.1. [RPC.ApiAuthentication.ApiKeys.ApiKeys items]
##### <a name="autogenerated_heading_5"></a>8.29.2.1. [RPC.ApiAuthentication.ApiKeys.ApiKeys items]

**Type:** : `object`
**Description:** KeyItem is the api key item
Expand Down Expand Up @@ -4633,7 +4699,7 @@ RollupManagerBlockNumber=0
| ----------------------------------------------------- | ------------------------------------------------------------------------- |
| [Actions items](#NetworkConfig_Genesis_Actions_items) | GenesisAction represents one of the values set on the SMT during genesis. |

##### <a name="autogenerated_heading_5"></a>13.3.4.1. [NetworkConfig.Genesis.Actions.Actions items]
##### <a name="autogenerated_heading_6"></a>13.3.4.1. [NetworkConfig.Genesis.Actions.Actions items]

**Type:** : `object`
**Description:** GenesisAction represents one of the values set on the SMT during genesis.
Expand Down Expand Up @@ -5513,7 +5579,7 @@ ChainID=0
| ----------------------------------------------------- | ------------------------------------ |
| [ForkIDIntervals items](#State_ForkIDIntervals_items) | ForkIDInterval is a fork id interval |

#### <a name="autogenerated_heading_6"></a>20.3.1. [State.ForkIDIntervals.ForkIDIntervals items]
#### <a name="autogenerated_heading_7"></a>20.3.1. [State.ForkIDIntervals.ForkIDIntervals items]

**Type:** : `object`
**Description:** ForkIDInterval is a fork id interval
Expand Down
40 changes: 40 additions & 0 deletions docs/config-file/node-config-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,46 @@
"type": "integer",
"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": {
"Name": {
"type": "string"
},
"FromList": {
"items": {
"type": "string"
},
"type": "array"
},
"ToList": {
"items": {
"type": "string"
},
"type": "array"
},
"MethodSigs": {
"items": {
"type": "string"
},
"type": "array"
},
"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,
Expand Down
51 changes: 51 additions & 0 deletions pool/apollo_xlayer.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@
FreeGasCountPerAddr uint64
FreeGasLimit uint64

// for special project
EnableFreeGasList bool
FreeGasFromNameMap map[string]string // map[from]projectName
FreeGasList map[string]*FreeGasInfo // map[projectName]FreeGasInfo

BlockedList []string

sync.RWMutex
Expand All @@ -43,6 +48,20 @@
return c.EnableApollo
}

func (c *apolloConfig) setFreeGasList(freeGasList []FreeGasInfo) {
if c == nil || !c.EnableApollo {
return
}
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

Check failure on line 61 in pool/apollo_xlayer.go

View workflow job for this annotation

GitHub Actions / lint

G601: Implicit memory aliasing in for loop. (gosec)
}
}

func (c *apolloConfig) setFreeGasAddresses(freeGasAddrs []string) {
if c == nil || !c.EnableApollo {
return
Expand Down Expand Up @@ -95,6 +114,8 @@
getApolloConfig().setFreeGasExAddresses(apolloConfig.FreeGasExAddress)
getApolloConfig().FreeGasCountPerAddr = apolloConfig.FreeGasCountPerAddr
getApolloConfig().FreeGasLimit = apolloConfig.FreeGasLimit
getApolloConfig().EnableFreeGasList = apolloConfig.EnableFreeGasList
getApolloConfig().setFreeGasList(apolloConfig.FreeGasList)

getApolloConfig().Unlock()
}
Expand Down Expand Up @@ -202,3 +223,33 @@

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) (map[string]string, map[string]*FreeGasInfo) {
if getApolloConfig().enable() {
getApolloConfig().RLock()
defer getApolloConfig().RUnlock()
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

Check failure on line 251 in pool/apollo_xlayer.go

View workflow job for this annotation

GitHub Actions / lint

G601: Implicit memory aliasing in for loop. (gosec)
}

return freeGasFromNameMap, freeGasMap
}
13 changes: 13 additions & 0 deletions pool/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +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 {
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
Expand Down
25 changes: 24 additions & 1 deletion pool/pool_xlayer.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -113,9 +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
}

// 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 {
Expand Down
6 changes: 3 additions & 3 deletions sequencer/sequencer.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)))
chengzhinei marked this conversation as resolved.
Show resolved Hide resolved
}
}

Expand Down
35 changes: 34 additions & 1 deletion sequencer/sequencer_xlayer.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,36 @@ package sequencer
import (
"context"
"math/big"
"strings"
"time"

"github.com/0xPolygonHermez/zkevm-node/log"
"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

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 {
chengzhinei marked this conversation as resolved.
Show resolved Hide resolved
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))
Expand All @@ -36,15 +56,28 @@ 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)
if addrs[txTracker.FromStr] {
claimTx = true
}

// 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()) &&
chengzhinei marked this conversation as resolved.
Show resolved Hide resolved
containsMethod("0x"+common.Bytes2Hex(tx.Data()), info.MethodSigs) {
gpMul = info.GasPriceMultiple
return
}
}

return
}
2 changes: 1 addition & 1 deletion test/Makefile
Original file line number Diff line number Diff line change
@@ -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
Expand Down
Loading