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 all 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
65 changes: 59 additions & 6 deletions pool/apollo_xlayer.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ type apolloConfig struct {
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,21 @@ func (c *apolloConfig) enable() bool {
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
}
infoCopy := info
c.FreeGasList[info.Name] = &infoCopy
}
}

func (c *apolloConfig) setFreeGasAddresses(freeGasAddrs []string) {
if c == nil || !c.EnableApollo {
return
Expand Down Expand Up @@ -95,6 +115,8 @@ 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()
}
Expand All @@ -119,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 {
Expand All @@ -139,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 {
Expand Down Expand Up @@ -197,8 +219,39 @@ 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)
}

// 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
}
infoCopy := info
freeGasMap[info.Name] = &infoCopy
}

return contains(localBlockedList, address)
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
29 changes: 27 additions & 2 deletions pool/pool_xlayer.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -40,6 +41,16 @@ func contains(s []string, ele common.Address) bool {
return false
}

// 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
}
}
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 +124,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) {
chengzhinei marked this conversation as resolved.
Show resolved Hide resolved
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
13 changes: 7 additions & 6 deletions sequencer/sequencer.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,18 +231,19 @@ 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)
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(getInitGasPriceMultiple(s.cfg.InitGasPriceMultiple))))
copyBaseGp.Set(defaultGp)
}
txTracker.GasPrice = copyBaseGp.Mul(copyBaseGp, new(big.Int).SetUint64(uint64(gp)))
}

replacedTx, dropReason := s.worker.AddTxTracker(ctx, txTracker)
Expand Down
Loading
Loading