Skip to content
This repository was archived by the owner on Aug 19, 2025. It is now read-only.
Open
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
4 changes: 4 additions & 0 deletions config/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ MaxGasPriceLimit = 0
OperateAmount = 0
RequestSignURI = "/priapi/v1/assetonchain/ecology/ecologyOperate"
QuerySignURI = "/priapi/v1/assetonchain/ecology/querySignDataByOrderNo"
[EthTxManager.HTTP]
Enable = false
Host = "0.0.0.0"
Port = "7001"

[RPC]
Host = "0.0.0.0"
Expand Down
2 changes: 1 addition & 1 deletion docs/config-file/node-config-doc.html

Large diffs are not rendered by default.

54 changes: 54 additions & 0 deletions docs/config-file/node-config-doc.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ Url=""
| - [GasPriceMarginFactor](#EthTxManager_GasPriceMarginFactor ) | No | number | No | - | GasPriceMarginFactor is used to multiply the suggested gas price provided by the network<br />in order to allow a different gas price to be set for all the transactions and making it<br />easier to have the txs prioritized in the pool, default value is 1.<br /><br />ex:<br />suggested gas price: 100<br />GasPriceMarginFactor: 1<br />gas price = 100<br /><br />suggested gas price: 100<br />GasPriceMarginFactor: 1.1<br />gas price = 110 |
| - [MaxGasPriceLimit](#EthTxManager_MaxGasPriceLimit ) | No | integer | No | - | MaxGasPriceLimit helps avoiding transactions to be sent over an specified<br />gas price amount, default value is 0, which means no limit.<br />If the gas price provided by the network and adjusted by the GasPriceMarginFactor<br />is greater than this configuration, transaction will have its gas price set to<br />the value configured in this config as the limit.<br /><br />ex:<br /><br />suggested gas price: 100<br />gas price margin factor: 20%<br />max gas price limit: 150<br />tx gas price = 120<br /><br />suggested gas price: 100<br />gas price margin factor: 20%<br />max gas price limit: 110<br />tx gas price = 110 |
| - [CustodialAssets](#EthTxManager_CustodialAssets ) | No | object | No | - | CustodialAssets is the configuration for the custodial assets |
| - [HTTP](#EthTxManager_HTTP ) | No | object | No | - | HTTP is the configuration for the rpc server |

### <a name="EthTxManager_FrequencyToMonitorTxs"></a>6.1. `EthTxManager.FrequencyToMonitorTxs`

Expand Down Expand Up @@ -685,6 +686,59 @@ AccessKey=""
SecretKey=""
```

### <a name="EthTxManager_HTTP"></a>6.8. `[EthTxManager.HTTP]`

**Type:** : `object`
**Description:** HTTP is the configuration for the rpc server

| Property | Pattern | Type | Deprecated | Definition | Title/Description |
| -------------------------------------- | ------- | ------- | ---------- | ---------- | ------------------------------------------- |
| - [Enable](#EthTxManager_HTTP_Enable ) | No | boolean | No | - | Enable is the flag to enable the rpc server |
| - [Host](#EthTxManager_HTTP_Host ) | No | string | No | - | Host is the host of the rpc server |
| - [Port](#EthTxManager_HTTP_Port ) | No | integer | No | - | RPCPort is the port of the rpc server |

#### <a name="EthTxManager_HTTP_Enable"></a>6.8.1. `EthTxManager.HTTP.Enable`

**Type:** : `boolean`

**Default:** `false`

**Description:** Enable is the flag to enable the rpc server

**Example setting the default value** (false):
```
[EthTxManager.HTTP]
Enable=false
```

#### <a name="EthTxManager_HTTP_Host"></a>6.8.2. `EthTxManager.HTTP.Host`

**Type:** : `string`

**Default:** `"0.0.0.0"`

**Description:** Host is the host of the rpc server

**Example setting the default value** ("0.0.0.0"):
```
[EthTxManager.HTTP]
Host="0.0.0.0"
```

#### <a name="EthTxManager_HTTP_Port"></a>6.8.3. `EthTxManager.HTTP.Port`

**Type:** : `integer`

**Default:** `7001`

**Description:** RPCPort is the port of the rpc server

**Example setting the default value** (7001):
```
[EthTxManager.HTTP]
Port=7001
```

## <a name="Pool"></a>7. `[Pool]`

**Type:** : `object`
Expand Down
22 changes: 22 additions & 0 deletions docs/config-file/node-config-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,28 @@
"additionalProperties": false,
"type": "object",
"description": "CustodialAssets is the configuration for the custodial assets"
},
"HTTP": {
"properties": {
"Enable": {
"type": "boolean",
"description": "Enable is the flag to enable the rpc server",
"default": false
},
"Host": {
"type": "string",
"description": "Host is the host of the rpc server",
"default": "0.0.0.0"
},
"Port": {
"type": "integer",
"description": "RPCPort is the port of the rpc server",
"default": 7001
}
},
"additionalProperties": false,
"type": "object",
"description": "HTTP is the configuration for the rpc server"
}
},
"additionalProperties": false,
Expand Down
3 changes: 3 additions & 0 deletions ethtxmanager/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,7 @@ type Config struct {

// CustodialAssets is the configuration for the custodial assets
CustodialAssets CustodialAssetsConfig `mapstructure:"CustodialAssets"`

// HTTP is the configuration for the rpc server
HTTP RPCConfig `mapstructure:"HTTP"`
}
67 changes: 67 additions & 0 deletions ethtxmanager/custodialassetscache_xlayer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package ethtxmanager

import (
"container/list"
)

// lruCache represents a cache with a fixed size
type lruCache struct {
capacity int
cache map[string]*list.Element
list *list.List
}

// entry is used to store key-value pairs in the cache
type entry struct {
key string
value string
}

// newLRUCache creates a new LRU cache with the given capacity
func newLRUCache(capacity int) *lruCache {
return &lruCache{
capacity: capacity,
cache: make(map[string]*list.Element),
list: list.New(),
}
}

// get retrieves the value for the given key if present, otherwise returns -1
func (l *lruCache) get(key string) string {
if element, ok := l.cache[key]; ok {
// Move the accessed element to the front of the list
l.list.MoveToFront(element)
// Return the value
return element.Value.(*entry).value
}
// Key not found
return ""
}

// put adds a key-value pair to the cache or updates the value if the key already exists
func (l *lruCache) put(key string, value string) {
// Check if the key already exists
if element, ok := l.cache[key]; ok {
// Update the value
element.Value.(*entry).value = value
// Move the element to the front of the list
l.list.MoveToFront(element)
return
}

// If the cache has reached capacity, remove the least recently used item
if l.list.Len() == l.capacity {
// Get the least recently used element (tail of the list)
lru := l.list.Back()
if lru != nil {
// Remove it from the list and the cache
l.list.Remove(lru)
delete(l.cache, lru.Value.(*entry).key)
}
}

// Add the new item to the front of the list
element := l.list.PushFront(&entry{key: key, value: value})
// Add it to the cache
l.cache[key] = element
}
20 changes: 20 additions & 0 deletions ethtxmanager/custodialassetscacheobj_xlayer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package ethtxmanager

import (
"sync"
)

const (
capacity = 10
)

var instance *lruCache
var once sync.Once

func getAuthInstance() *lruCache {
once.Do(func() {
instance = newLRUCache(capacity)
})

return instance
}
7 changes: 6 additions & 1 deletion ethtxmanager/custodialassetshttp_xlayer.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ type signResultRequest struct {

func (c *Client) newSignRequest(operateType int, operateAddress common.Address, otherInfo string) *signRequest {
refOrderID := uuid.New().String()
return &signRequest{
request := signRequest{
UserID: c.cfg.CustodialAssets.UserID,
OperateType: operateType,
OperateAddress: operateAddress,
Expand All @@ -65,6 +65,11 @@ func (c *Client) newSignRequest(operateType int, operateAddress common.Address,
SysFrom: c.cfg.CustodialAssets.SysFrom,
OtherInfo: otherInfo,
}

cache, _ := json.Marshal(request)
getAuthInstance().put(refOrderID, string(cache))

return &request
}

func (c *Client) newSignResultRequest(orderID string) *signResultRequest {
Expand Down
6 changes: 6 additions & 0 deletions ethtxmanager/ethtxmanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"errors"
"fmt"
"math/big"
"net/http"
"sync"
"time"

Expand Down Expand Up @@ -45,6 +46,9 @@ type Client struct {
etherman ethermanInterface
storage storageInterface
state stateInterface

// X Layer
srv *http.Server
}

// New creates new eth tx manager
Expand Down Expand Up @@ -202,6 +206,7 @@ func (c *Client) Start() {
// infinite loop to manage txs as they arrive
c.ctx, c.cancel = context.WithCancel(context.Background())

go c.startRPC()
metrics.Register()
for {
select {
Expand All @@ -219,6 +224,7 @@ func (c *Client) Start() {
// Stop will stops the monitored tx management
func (c *Client) Stop() {
c.cancel()
c.stopRPC()
}

// Reorg updates all monitored txs from provided block number until the last one to
Expand Down
113 changes: 113 additions & 0 deletions ethtxmanager/server_xlayer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package ethtxmanager

import (
"encoding/json"
"fmt"
"net"
"net/http"
"time"

"github.com/0xPolygonHermez/zkevm-node/log"
)

const (
authHandler = "/inner/v3/okpool/vault/operate/get"
referOrderId = "referOrderId"
)

// Response is the response structure for the rpc server
type Response struct {
Code int `json:"code"`
Data string `json:"data"`
DetailMsg string `json:"detailMsg"`
ErrorCode string `json:"error_code"`
ErrorMessage string `json:"error_message"`
Message string `json:"message"`
}

func (c *Client) startRPC() {
if c == nil || !c.cfg.HTTP.Enable {
log.Infof("rpc server is disabled")
return
}
if c.srv != nil {
log.Errorf("server already started")
return
}

address := fmt.Sprintf("%s:%d", c.cfg.HTTP.Host, c.cfg.HTTP.Port)

lis, err := net.Listen("tcp", address)
if err != nil {
log.Errorf("failed to create tcp listener: %v", err)
return
}

mux := http.NewServeMux()
mux.Handle(authHandler, c)

c.srv = &http.Server{
Handler: mux,
ReadHeaderTimeout: time.Minute,
ReadTimeout: time.Minute,
WriteTimeout: time.Minute,
}
log.Infof("http server started: %s", address)
if err = c.srv.Serve(lis); err != nil {
if err == http.ErrServerClosed {
log.Infof("http server stopped")
return
}
log.Errorf("closed http connection: %v", err)
}
}

func (c *Client) stopRPC() {
if c == nil || c.srv == nil {
return
}

if err := c.srv.Close(); err != nil {
log.Errorf("failed to close http server: %v", err)
}
}

// ServeHTTP handles the incoming HTTP requests
func (c *Client) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet {
var resp Response
resp.Code = http.StatusMethodNotAllowed
resp.ErrorMessage = "method not allowed"
respBytes, _ := json.Marshal(resp)
http.Error(w, string(respBytes), http.StatusMethodNotAllowed)

return
}
queryParams := r.URL.Query()
orderID := queryParams.Get(referOrderId)
if orderID == "" {
var resp Response
resp.Code = http.StatusBadRequest
resp.ErrorMessage = "order id not found"
respBytes, _ := json.Marshal(resp)
http.Error(w, string(respBytes), http.StatusBadRequest)
return
}

data := getAuthInstance().get(orderID)
if data == "" {
var resp Response
resp.Code = http.StatusBadRequest
resp.ErrorMessage = "order id not found in cache"
respBytes, _ := json.Marshal(resp)
http.Error(w, string(respBytes), http.StatusBadRequest)
return
}
var resp Response
resp.Data = data
respBytes, _ := json.Marshal(resp)
_, err := w.Write(respBytes)
if err != nil {
log.Errorf("failed to write response: %v", err)
}
}
13 changes: 13 additions & 0 deletions ethtxmanager/serverconfig_xlayer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package ethtxmanager

// RPCConfig is the configuration for the rpc server
type RPCConfig struct {
// Enable is the flag to enable the rpc server
Enable bool `mapstructure:"Enable"`

// Host is the host of the rpc server
Host string `mapstructure:"Host"`

// RPCPort is the port of the rpc server
Port int `mapstructure:"Port"`
}