Skip to content

Commit

Permalink
support init freegas (#207)
Browse files Browse the repository at this point in the history
* support init free gas

* support prior pack tx

* init initFreeAddress

* txTracker gp use default gp

* start bridge service on testing

* Update Makefile

* Update docker-compose.yml

* update config

* and bridge ui

* start bridge ui

* Update docker-compose.yml

* Update docker-compose.yml

* Update docker-compose.yml

* Update Makefile

* opt code

* Update docker-compose.yml

* Update docker-compose.yml

* Update test.bridge.config.toml

* add cfg of nonce

* Update Makefile

* Update test.node.config.toml

* Update docker-compose.yml

* create table pool.free_gas

* rename FreeGasNonce to FreeGasCountPerAddr

* Update test.node.config.toml

* get addr from input

* fix addr

* del log

* add cfg of free gaslimit

* fix lint and json

* fix UT

* Update test.node.config.toml

* Update test.node.config.toml

* Update pool.go

* and free gas config

* fix

* add dgp

* add AddDynamicGp

* fix lint

* add GetDynamicGasPrice

* fix rpc

* test

* fix ut

* test

* log error

* fix ut

* fix ut

* fix ut

* fix ut

* fix ut

* test

* test

* fix ut

* use dgp

* fix ut

* update error msg

* opt code

* opt code

* opt code

* opt code

* opt code

* Update pool_xlayer.go

* Update pool_xlayer.go

* Update pool_xlayer.go

* opt code

* fix lint

---------

Co-authored-by: ylsGit <[email protected]>
  • Loading branch information
chengzhinei and ylsGit authored May 31, 2024
1 parent 8100533 commit d405aa5
Show file tree
Hide file tree
Showing 26 changed files with 750 additions and 37 deletions.
7 changes: 7 additions & 0 deletions db/migrations/pool/1004.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
-- +migrate Up
CREATE TABLE IF NOT EXISTS pool.free_gas (
addr varchar NOT NULL PRIMARY KEY
);

-- +migrate Down
DROP TABLE IF EXISTS pool.free_gas;
4 changes: 2 additions & 2 deletions docs/config-file/node-config-doc.html

Large diffs are not rendered by default.

68 changes: 67 additions & 1 deletion docs/config-file/node-config-doc.md
Original file line number Diff line number Diff line change
Expand Up @@ -709,6 +709,10 @@ SecretKey=""
| - [FreeGasAddress](#Pool_FreeGasAddress ) | No | array of string | No | - | XLayer config<br />FreeGasAddress is the default free gas address |
| - [FreeClaimGasLimit](#Pool_FreeClaimGasLimit ) | No | integer | No | - | FreeClaimGasLimit is the max gas allowed use to do a free claim |
| - [BridgeClaimMethodSigs](#Pool_BridgeClaimMethodSigs ) | No | array of string | No | - | BridgeClaimMethodSignature for tracking BridgeClaimMethodSignature method |
| - [EnableFreeGasByNonce](#Pool_EnableFreeGasByNonce ) | No | boolean | No | - | EnableFreeGasByNonce enable free gas |
| - [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 |

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

Expand Down Expand Up @@ -1248,6 +1252,53 @@ FreeClaimGasLimit=150000
**Type:** : `array of string`
**Description:** BridgeClaimMethodSignature for tracking BridgeClaimMethodSignature method

### <a name="Pool_EnableFreeGasByNonce"></a>7.18. `Pool.EnableFreeGasByNonce`

**Type:** : `boolean`

**Default:** `false`

**Description:** EnableFreeGasByNonce enable free gas

**Example setting the default value** (false):
```
[Pool]
EnableFreeGasByNonce=false
```

### <a name="Pool_FreeGasExAddress"></a>7.19. `Pool.FreeGasExAddress`

**Type:** : `array of string`
**Description:** FreeGasExAddress is the ex address which can be free gas for the transfer receiver

### <a name="Pool_FreeGasCountPerAddr"></a>7.20. `Pool.FreeGasCountPerAddr`

**Type:** : `integer`

**Default:** `0`

**Description:** FreeGasCountPerAddr is the count limit of free gas tx per address

**Example setting the default value** (0):
```
[Pool]
FreeGasCountPerAddr=0
```

### <a name="Pool_FreeGasLimit"></a>7.21. `Pool.FreeGasLimit`

**Type:** : `integer`

**Default:** `0`

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

**Example setting the default value** (0):
```
[Pool]
FreeGasLimit=0
```

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

**Type:** : `object`
Expand Down Expand Up @@ -2885,6 +2936,7 @@ CheckLastL2BlockHashOnCloseBatch=true
| - [StreamServer](#Sequencer_StreamServer ) | No | object | No | - | StreamServerCfg is the config for the stream server |
| - [PackBatchSpacialList](#Sequencer_PackBatchSpacialList ) | No | array of string | No | - | XLayer config<br />PackBatchSpacialList is the list of addresses that will have a special gas price |
| - [GasPriceMultiple](#Sequencer_GasPriceMultiple ) | No | number | No | - | GasPriceMultiple is the multiple of the gas price |
| - [InitGasPriceMultiple](#Sequencer_InitGasPriceMultiple ) | No | number | No | - | InitGasPriceMultiple is the multiple of the gas price for init free gas tx |
| - [QueryPendingTxsLimit](#Sequencer_QueryPendingTxsLimit ) | No | integer | No | - | QueryPendingTxsLimit is used to limit amount txs from the db |

### <a name="Sequencer_DeletePoolTxsL1BlockConfirmations"></a>10.1. `Sequencer.DeletePoolTxsL1BlockConfirmations`
Expand Down Expand Up @@ -3572,7 +3624,21 @@ PackBatchSpacialList is the list of addresses that will have a special gas price
GasPriceMultiple=0
```

### <a name="Sequencer_QueryPendingTxsLimit"></a>10.11. `Sequencer.QueryPendingTxsLimit`
### <a name="Sequencer_InitGasPriceMultiple"></a>10.11. `Sequencer.InitGasPriceMultiple`

**Type:** : `number`

**Default:** `0`

**Description:** InitGasPriceMultiple is the multiple of the gas price for init free gas tx

**Example setting the default value** (0):
```
[Sequencer]
InitGasPriceMultiple=0
```

### <a name="Sequencer_QueryPendingTxsLimit"></a>10.12. `Sequencer.QueryPendingTxsLimit`

**Type:** : `integer`

Expand Down
27 changes: 27 additions & 0 deletions docs/config-file/node-config-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,28 @@
},
"type": "array",
"description": "BridgeClaimMethodSignature for tracking BridgeClaimMethodSignature method"
},
"EnableFreeGasByNonce": {
"type": "boolean",
"description": "EnableFreeGasByNonce enable free gas",
"default": false
},
"FreeGasExAddress": {
"items": {
"type": "string"
},
"type": "array",
"description": "FreeGasExAddress is the ex address which can be free gas for the transfer receiver"
},
"FreeGasCountPerAddr": {
"type": "integer",
"description": "FreeGasCountPerAddr is the count limit of free gas tx per address",
"default": 0
},
"FreeGasLimit": {
"type": "integer",
"description": "FreeGasLimit is the max gas allowed use to do a free gas tx",
"default": 0
}
},
"additionalProperties": false,
Expand Down Expand Up @@ -1391,6 +1413,11 @@
"description": "GasPriceMultiple is the multiple of the gas price",
"default": 0
},
"InitGasPriceMultiple": {
"type": "number",
"description": "InitGasPriceMultiple is the multiple of the gas price for init free gas tx",
"default": 0
},
"QueryPendingTxsLimit": {
"type": "integer",
"description": "QueryPendingTxsLimit is used to limit amount txs from the db",
Expand Down
3 changes: 3 additions & 0 deletions jsonrpc/endpoints_eth.go
Original file line number Diff line number Diff line change
Expand Up @@ -1043,6 +1043,9 @@ func (e *EthEndpoints) tryToAddTxToPool(input, ip string) (interface{}, types.Er
return RPCErrorResponse(types.InvalidParamsErrorCode, "invalid tx input", err, false)
}
log.Infof("adding TX to the pool: %v", tx.Hash().Hex())

dgp := getDynamicGp(e.cfg.DynamicGP.Enabled, e.dgpMan.lastPrice)
e.pool.AddDynamicGp(dgp)
if err := e.pool.AddTx(context.Background(), *tx, ip); err != nil {
// it's not needed to log the error here, because we check and log if needed
// for each specific case during the "pool.AddTx" internal steps
Expand Down
7 changes: 7 additions & 0 deletions jsonrpc/endpoints_eth_xlayer.go
Original file line number Diff line number Diff line change
Expand Up @@ -420,3 +420,10 @@ func (e *EthEndpoints) GetPendingStat() (interface{}, types.Error) {
ReadyTxCount: readyTxCount,
}, nil
}

func getDynamicGp(enableDgp bool, dgp *big.Int) *big.Int {
if !enableDgp || dgp == nil {
return big.NewInt(0)
}
return dgp
}
2 changes: 2 additions & 0 deletions jsonrpc/mocks/mock_pool.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions jsonrpc/types/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
// PoolInterface contains the methods required to interact with the tx pool.
type PoolInterface interface {
AddTx(ctx context.Context, tx types.Transaction, ip string) error
AddDynamicGp(dgp *big.Int)
GetGasPrices(ctx context.Context) (pool.GasPrices, error)
GetNonce(ctx context.Context, address common.Address) (uint64, error)
GetPendingTxHashesSince(ctx context.Context, since time.Time) ([]common.Hash, error)
Expand Down
57 changes: 57 additions & 0 deletions pool/apollo_xlayer.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ type apolloConfig struct {
BridgeClaimMethods []string
EnablePendingStat bool

EnableFreeGasByNonce bool
FreeGasExAddress []string
FreeGasCountPerAddr uint64
FreeGasLimit uint64

sync.RWMutex
}

Expand Down Expand Up @@ -44,6 +49,14 @@ func (c *apolloConfig) setFreeGasAddresses(freeGasAddrs []string) {
copy(c.FreeGasAddresses, freeGasAddrs)
}

func (c *apolloConfig) setFreeGasExAddresses(freeGasExAddrs []string) {
if c == nil || !c.EnableApollo {
return
}
c.FreeGasExAddress = make([]string, len(freeGasExAddrs))
copy(c.FreeGasExAddress, freeGasExAddrs)
}

func (c *apolloConfig) setBridgeClaimMethods(bridgeClaimMethods []string) {
if c == nil || !c.EnableApollo {
return
Expand All @@ -66,6 +79,12 @@ func UpdateConfig(apolloConfig Config) {
getApolloConfig().setFreeGasAddresses(apolloConfig.FreeGasAddress)
getApolloConfig().EnableWhitelist = apolloConfig.EnableWhitelist
getApolloConfig().setBridgeClaimMethods(apolloConfig.BridgeClaimMethodSigs)

getApolloConfig().EnableFreeGasByNonce = apolloConfig.EnableFreeGasByNonce
getApolloConfig().setFreeGasExAddresses(apolloConfig.FreeGasExAddress)
getApolloConfig().FreeGasCountPerAddr = apolloConfig.FreeGasCountPerAddr
getApolloConfig().FreeGasLimit = apolloConfig.FreeGasLimit

getApolloConfig().Unlock()
}

Expand Down Expand Up @@ -95,6 +114,44 @@ func isFreeGasAddress(localFreeGasAddrs []string, address common.Address) bool {
return contains(localFreeGasAddrs, address)
}

func getEnableFreeGasByNonce(enableFreeGasByNonce bool) bool {
if getApolloConfig().enable() {
getApolloConfig().RLock()
defer getApolloConfig().RUnlock()
return getApolloConfig().EnableFreeGasByNonce
}

return enableFreeGasByNonce
}

func isFreeGasExAddress(localFreeGasExAddrs []string, address common.Address) bool {
if getApolloConfig().enable() {
getApolloConfig().RLock()
defer getApolloConfig().RUnlock()
return contains(getApolloConfig().FreeGasExAddress, address)
}

return contains(localFreeGasExAddrs, address)
}

func getFreeGasCountPerAddr(localFreeGasCountPerAddr uint64) uint64 {
if getApolloConfig().enable() {
getApolloConfig().RLock()
defer getApolloConfig().RUnlock()
return getApolloConfig().FreeGasCountPerAddr
}
return localFreeGasCountPerAddr
}

func getFreeGasLimit(localFreeGasLimit uint64) uint64 {
if getApolloConfig().enable() {
getApolloConfig().RLock()
defer getApolloConfig().RUnlock()
return getApolloConfig().FreeGasLimit
}
return localFreeGasLimit
}

func getGlobalQueue(globalQueue uint64) uint64 {
if getApolloConfig().enable() {
getApolloConfig().RLock()
Expand Down
9 changes: 9 additions & 0 deletions pool/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,15 @@ type Config struct {
FreeClaimGasLimit uint64 `mapstructure:"FreeClaimGasLimit"`
// BridgeClaimMethodSignature for tracking BridgeClaimMethodSignature method
BridgeClaimMethodSigs []string `mapstructure:"BridgeClaimMethodSigs"`

// EnableFreeGasByNonce enable free gas
EnableFreeGasByNonce bool `mapstructure:"EnableFreeGasByNonce"`
// FreeGasExAddress is the ex address which can be free gas for the transfer receiver
FreeGasExAddress []string `mapstructure:"FreeGasExAddress"`
// FreeGasCountPerAddr is the count limit of free gas tx per address
FreeGasCountPerAddr uint64 `mapstructure:"FreeGasCountPerAddr"`
// FreeGasLimit is the max gas allowed use to do a free gas tx
FreeGasLimit uint64 `mapstructure:"FreeGasLimit"`
}

// EffectiveGasPriceCfg contains the configuration properties for the effective gas price
Expand Down
2 changes: 2 additions & 0 deletions pool/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ type storage interface {
GetInnerTx(ctx context.Context, txHash common.Hash) (string, error)
UpdateReadyTxCount(ctx context.Context, count uint64) error
GetReadyTxCount(ctx context.Context) (uint64, error)
AddFreeGasAddr(ctx context.Context, addr common.Address) error
IsFreeGasAddr(ctx context.Context, addr common.Address) (bool, error)
}

type stateInterface interface {
Expand Down
26 changes: 26 additions & 0 deletions pool/pgpoolstorage/pgpoolstorage_xlayer.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package pgpoolstorage

import (
"context"
"database/sql"
"errors"
"time"

Expand Down Expand Up @@ -98,3 +99,28 @@ func (p *PostgresPoolStorage) GetReadyTxCount(ctx context.Context) (uint64, erro

return count, nil
}

// IsFreeGasAddr determines if the address is free gas or
// not.
func (p *PostgresPoolStorage) IsFreeGasAddr(ctx context.Context, addr common.Address) (bool, error) {
var exists bool
req := "SELECT exists (SELECT 1 FROM pool.free_gas WHERE addr = $1)"
err := p.db.QueryRow(ctx, req, addr.String()).Scan(&exists)
if err != nil && err != sql.ErrNoRows {
return false, err
}

return exists, nil
}

// AddFreeGasAddr add free gas address
func (p *PostgresPoolStorage) AddFreeGasAddr(ctx context.Context, addr common.Address) error {
sql := `INSERT INTO pool.free_gas(addr) VALUES ($1)`

_, err := p.db.Exec(ctx, sql, addr.String())
if err != nil {
return err
}

return nil
}
17 changes: 15 additions & 2 deletions pool/pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ type Pool struct {
gasPrices GasPrices
gasPricesMux *sync.RWMutex
effectiveGasPrice *EffectiveGasPrice
dynamicGasPrice *big.Int
dgpMux *sync.RWMutex
}

type preExecutionResponse struct {
Expand Down Expand Up @@ -87,6 +89,7 @@ func NewPool(cfg Config, batchConstraintsCfg state.BatchConstraintsCfg, s storag
gasPrices: GasPrices{0, 0},
gasPricesMux: new(sync.RWMutex),
effectiveGasPrice: NewEffectiveGasPrice(cfg.EffectiveGasPrice),
dgpMux: new(sync.RWMutex),
}
p.refreshGasPrices()
go func(cfg *Config, p *Pool) {
Expand Down Expand Up @@ -535,8 +538,12 @@ func (p *Pool) validateTx(ctx context.Context, poolTx Transaction) error {
}
}

// Reject transactions with a gas price lower than the minimum gas price
if !isFreeGasAddress(p.cfg.FreeGasAddress, from) || !poolTx.IsClaims { // XLayer handle
freeGp, err := p.checkFreeGp(ctx, poolTx, from)
if err != nil {
return err
}

if !freeGp { // XLayer handle
p.minSuggestedGasPriceMux.RLock()
gasPriceCmp := poolTx.GasPrice().Cmp(p.minSuggestedGasPrice)
if gasPriceCmp == -1 {
Expand Down Expand Up @@ -604,6 +611,12 @@ func (p *Pool) validateTx(ctx context.Context, poolTx Transaction) error {
return err
}

if getEnableFreeGasByNonce(p.cfg.EnableFreeGasByNonce) {
if err := p.checkAndUpdateFreeGasAddr(ctx, poolTx, from, lastL2Block.Root()); err != nil {
return err
}
}

return nil
}

Expand Down
Loading

0 comments on commit d405aa5

Please sign in to comment.