mirror of
https://github.com/GMWalletApp/epusdt.git
synced 2026-07-07 10:16:15 +00:00
refactor(rpc): streamline RPC node selection and remove hardcoded defaults
This commit is contained in:
@@ -18,8 +18,6 @@ import (
|
||||
"github.com/ethereum/go-ethereum/ethclient"
|
||||
)
|
||||
|
||||
const bscDefaultWsURL = "wss://bsc.drpc.org"
|
||||
|
||||
type bscRecipientSnapshot struct {
|
||||
addrs map[string]struct{}
|
||||
}
|
||||
@@ -68,7 +66,10 @@ func runBscListener(contracts []common.Address) {
|
||||
}
|
||||
}()
|
||||
|
||||
wsURL := resolveChainWsURL(mdb.NetworkBsc, bscDefaultWsURL)
|
||||
wsURL, ok := resolveChainWsURL(mdb.NetworkBsc, "[BSC-WS]")
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
log.Sugar.Infof("[BSC-WS] connecting to %s watching %d contract(s)", wsURL, len(contracts))
|
||||
|
||||
query := ethereum.FilterQuery{
|
||||
|
||||
@@ -90,12 +90,22 @@ func loadChainTokenContracts(network, logPrefix string) []common.Address {
|
||||
}
|
||||
|
||||
// resolveChainWsURL picks a healthy WS endpoint from rpc_nodes for the
|
||||
// given network, falling back to the provided default (usually the
|
||||
// public node URL) when no row is configured.
|
||||
func resolveChainWsURL(network, fallback string) string {
|
||||
// given network. If no enabled node is configured, the caller skips the
|
||||
// current listener run so admin-side disabled/deleted rows are respected.
|
||||
func resolveChainWsURL(network, logPrefix string) (string, bool) {
|
||||
node, err := data.SelectRpcNode(network, mdb.RpcNodeTypeWs)
|
||||
if err == nil && node != nil && node.ID > 0 {
|
||||
return node.Url
|
||||
rpcURL := strings.TrimSpace(node.Url)
|
||||
if rpcURL != "" {
|
||||
return rpcURL, true
|
||||
}
|
||||
log.Sugar.Errorf("%s rpc_nodes id=%d has empty url", logPrefix, node.ID)
|
||||
return "", false
|
||||
}
|
||||
return fallback
|
||||
if err != nil {
|
||||
log.Sugar.Errorf("%s resolve rpc_nodes err=%v", logPrefix, err)
|
||||
} else {
|
||||
log.Sugar.Warnf("%s no enabled %s WS RPC node configured in rpc_nodes", logPrefix, network)
|
||||
}
|
||||
return "", false
|
||||
}
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
package task
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/assimon/luuu/internal/testutil"
|
||||
"github.com/assimon/luuu/model/dao"
|
||||
"github.com/assimon/luuu/model/mdb"
|
||||
)
|
||||
|
||||
func TestResolveChainWsURLRequiresEnabledRpcNode(t *testing.T) {
|
||||
cleanup := testutil.SetupTestDatabases(t)
|
||||
defer cleanup()
|
||||
|
||||
if got, ok := resolveChainWsURL(mdb.NetworkEthereum, "[TEST]"); ok {
|
||||
t.Fatalf("resolveChainWsURL() = (%q, true), want false", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolveChainWsURLWithRow(t *testing.T) {
|
||||
cleanup := testutil.SetupTestDatabases(t)
|
||||
defer cleanup()
|
||||
|
||||
node := &mdb.RpcNode{
|
||||
Network: mdb.NetworkEthereum,
|
||||
Url: " wss://ethereum.example.com ",
|
||||
Type: mdb.RpcNodeTypeWs,
|
||||
Weight: 1,
|
||||
Enabled: true,
|
||||
Status: mdb.RpcNodeStatusOk,
|
||||
}
|
||||
if err := dao.Mdb.Create(node).Error; err != nil {
|
||||
t.Fatalf("seed rpc_node: %v", err)
|
||||
}
|
||||
|
||||
got, ok := resolveChainWsURL(mdb.NetworkEthereum, "[TEST]")
|
||||
if !ok {
|
||||
t.Fatalf("resolveChainWsURL() ok=false, want true")
|
||||
}
|
||||
if got != "wss://ethereum.example.com" {
|
||||
t.Fatalf("resolveChainWsURL() = %q, want wss://ethereum.example.com", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolveChainWsURLDisabledRow(t *testing.T) {
|
||||
cleanup := testutil.SetupTestDatabases(t)
|
||||
defer cleanup()
|
||||
|
||||
node := &mdb.RpcNode{
|
||||
Network: mdb.NetworkEthereum,
|
||||
Url: "wss://disabled.example.com",
|
||||
Type: mdb.RpcNodeTypeWs,
|
||||
Weight: 1,
|
||||
Enabled: true,
|
||||
Status: mdb.RpcNodeStatusOk,
|
||||
}
|
||||
if err := dao.Mdb.Create(node).Error; err != nil {
|
||||
t.Fatalf("seed rpc_node: %v", err)
|
||||
}
|
||||
if err := dao.Mdb.Model(node).Update("enabled", false).Error; err != nil {
|
||||
t.Fatalf("disable rpc_node: %v", err)
|
||||
}
|
||||
|
||||
if got, ok := resolveChainWsURL(mdb.NetworkEthereum, "[TEST]"); ok {
|
||||
t.Fatalf("resolveChainWsURL() = (%q, true), want false", got)
|
||||
}
|
||||
}
|
||||
+4
-19
@@ -7,7 +7,6 @@ import (
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/assimon/luuu/config"
|
||||
"github.com/assimon/luuu/model/data"
|
||||
"github.com/assimon/luuu/model/mdb"
|
||||
"github.com/assimon/luuu/model/service"
|
||||
@@ -22,22 +21,6 @@ import (
|
||||
// Transfer 事件签名 — ERC-20 signature, same on every EVM chain.
|
||||
var transferEventHash = common.HexToHash("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef")
|
||||
|
||||
const ethereumDefaultWsURL = "wss://ethereum.publicnode.com"
|
||||
|
||||
// resolveEthereumWsURL picks a healthy WS endpoint. Falls back to the
|
||||
// legacy .env value (if set) before the shared default — keeps existing
|
||||
// deployments working until the admin adds an rpc_nodes row.
|
||||
func resolveEthereumWsURL() string {
|
||||
node, err := data.SelectRpcNode(mdb.NetworkEthereum, mdb.RpcNodeTypeWs)
|
||||
if err == nil && node != nil && node.ID > 0 {
|
||||
return node.Url
|
||||
}
|
||||
if u := config.GetEthereumWsUrl(); u != "" {
|
||||
return u
|
||||
}
|
||||
return ethereumDefaultWsURL
|
||||
}
|
||||
|
||||
type ethRecipientSnapshot struct {
|
||||
addrs map[string]struct{}
|
||||
}
|
||||
@@ -88,7 +71,10 @@ func runEthereumListener(contracts []common.Address) {
|
||||
}
|
||||
}()
|
||||
|
||||
wsURL := resolveEthereumWsURL()
|
||||
wsURL, ok := resolveChainWsURL(mdb.NetworkEthereum, "[ETH-WS]")
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
log.Sugar.Infof("[ETH-WS] connecting to %s watching %d contract(s)", wsURL, len(contracts))
|
||||
|
||||
query := ethereum.FilterQuery{
|
||||
@@ -145,4 +131,3 @@ func isWatchedEthRecipient(to common.Address) bool {
|
||||
_, ok := snap.addrs[strings.ToLower(to.Hex())]
|
||||
return ok
|
||||
}
|
||||
|
||||
|
||||
@@ -18,8 +18,6 @@ import (
|
||||
"github.com/ethereum/go-ethereum/ethclient"
|
||||
)
|
||||
|
||||
const plasmaDefaultWsURL = "wss://rpc.plasma.to"
|
||||
|
||||
type plasmaRecipientSnapshot struct {
|
||||
addrs map[string]struct{}
|
||||
}
|
||||
@@ -67,7 +65,10 @@ func runPlasmaListener(contracts []common.Address) {
|
||||
}
|
||||
}()
|
||||
|
||||
wsURL := resolveChainWsURL(mdb.NetworkPlasma, plasmaDefaultWsURL)
|
||||
wsURL, ok := resolveChainWsURL(mdb.NetworkPlasma, "[PLASMA-WS]")
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
log.Sugar.Infof("[PLASMA-WS] connecting to %s watching %d contract(s)", wsURL, len(contracts))
|
||||
|
||||
query := ethereum.FilterQuery{
|
||||
|
||||
@@ -18,8 +18,6 @@ import (
|
||||
"github.com/ethereum/go-ethereum/ethclient"
|
||||
)
|
||||
|
||||
const polygonDefaultWsURL = "wss://polygon-bor-rpc.publicnode.com"
|
||||
|
||||
type polygonRecipientSnapshot struct {
|
||||
addrs map[string]struct{}
|
||||
}
|
||||
@@ -67,7 +65,10 @@ func runPolygonListener(contracts []common.Address) {
|
||||
}
|
||||
}()
|
||||
|
||||
wsURL := resolveChainWsURL(mdb.NetworkPolygon, polygonDefaultWsURL)
|
||||
wsURL, ok := resolveChainWsURL(mdb.NetworkPolygon, "[POLYGON-WS]")
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
log.Sugar.Infof("[POLYGON-WS] connecting to %s watching %d contract(s)", wsURL, len(contracts))
|
||||
|
||||
query := ethereum.FilterQuery{
|
||||
|
||||
Reference in New Issue
Block a user