m2pool-core/internal/gbt/gbt.go

291 lines
6.3 KiB
Go
Raw Permalink Normal View History

2025-09-03 08:00:42 +00:00
// gbt.go
package gbt
import (
"encoding/json"
"fmt"
"log"
"io/ioutil"
"pool/internal/db"
"sync/atomic"
//"pool/internal/cache"
"pool/internal/gbt/coin"
2025-09-04 08:09:36 +00:00
"pool/internal/gbt/monero"
2025-09-03 08:00:42 +00:00
monero_rpc "pool/internal/gbt/monero/rpc"
"pool/internal/utility"
"os"
"os/signal"
"syscall"
"time"
"github.com/btcsuite/btcd/rpcclient"
"github.com/redis/go-redis/v9"
"go.uber.org/zap"
)
var logg *zap.Logger
var GbtCtx coin.GbtContext
func InitConfig(config *coin.GbtConfig) {
data, err := ioutil.ReadFile("gbt.conf")
if err != nil {
panic(err.Error())
}
if err = json.Unmarshal(data, &config); err != nil {
panic(err.Error())
}
}
func InitClient(gbt *coin.GbtContext) error {
fmt.Println(gbt.Coin)
switch gbt.Coin {
case "monero":
url := "http://" + gbt.Config.Rpc.Host
rpcClient := monero_rpc.NewHttpClient(url, 10*time.Second)
gbt.MoneroClinet = rpcClient
gbt.MoneroAddr = gbt.Config.Rpc.User
default:
var config rpcclient.ConnConfig
if gbt.Config.Rpc.Type == "testnet" {
config.Host = gbt.Config.Rpc.Testnet
} else {
config.Host = gbt.Config.Rpc.Host
}
config.User = gbt.Config.Rpc.User
config.Pass = gbt.Config.Rpc.Pass
config.HTTPPostMode = true
config.DisableTLS = true
client, err := rpcclient.New(&config, nil)
if err != nil {
logg.Info("[gbt]", zap.String("rpcclient new ", err.Error()))
return err
}
gbt.Client = client
blockCount, err := client.GetBlockCount()
if err != nil {
logg.Info("[gbt]", zap.String("GetBlockCount ", err.Error()))
return err
}
logg.Info("[gbt]", zap.Int64("Block count ", blockCount))
}
return nil
}
/*func GbtLivingHandler(gbt *coin.GbtContext) {
timer := time.NewTimer(time.Duration(600) * time.Second)
for {
select {
case aliving := <-gbt.AlivingChan:
if !aliving {
timer.Stop()
//log.Println("gbt aliving", aliving)
return
} else {
timer.Reset(time.Duration(600) * time.Second)
}
case <-time.After(time.Duration(600) * time.Second):
gbt.ExitGbtChan <- true
return
}
}
}*/
func GbtLivingHandler(gbt *coin.GbtContext) {
var to_cnt int = 0
for {
flagAliving := atomic.LoadInt32(&(gbt.FlagAliving))
flagExit := atomic.LoadInt32(&(gbt.FlagAlivingExit))
if flagExit == 1 {
logg.Error("[server]", zap.String("GbtLivingHandler exited", "exit"))
break
}
if flagAliving == 0 {
//if to_cnt > 240 {
if to_cnt > gbt.Config.Rpc.Timeout*3/1000 {
logg.Error("[server]", zap.String("GbtLivingHandler exited", "timer expired"))
cmd := "killall gbt_" + gbt.Coin + " &"
utility.ExecShellCmd(cmd)
gbt.ExitGbtChan <- true
break
}
to_cnt++
} else {
to_cnt = 0
atomic.StoreInt32(&(gbt.FlagAliving), 0)
}
time.Sleep(time.Second)
}
}
type coinobj struct {
Coin string
Init func(GbtCtx *coin.GbtContext, DbCtx *db.DbContext)
Start func()
Stop func()
}
var coinobjs = []coinobj{
// {Coin: "nexa", Init: nexa.Init, Start: nexa.Start, Stop: nexa.Stop},
2025-09-04 08:09:36 +00:00
{Coin: "monero", Init: monero.Init, Start: monero.Start, Stop: monero.Stop},
// {Coin: "sha3x", Init: sha3x.Init, Start: sha3x.Start, Stop: sha3x.Stop},
2025-09-03 08:00:42 +00:00
}
func register_signal(dbctx *db.DbContext) {
signal_ch := make(chan os.Signal, 1)
signal.Notify(signal_ch, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
go signal_handle(signal_ch, dbctx)
}
func signal_handle(signal_ch chan os.Signal, dbctx *db.DbContext) {
for s := range signal_ch {
switch s {
case syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT:
log.Println("stop!")
dbctx.AppExit <- true
default:
//fmt.Println("other signal", s)
}
}
}
/*func LoadCache(gbt *coin.GbtContext) {
val := cache.LoadPoolCache(gbt.RedisClient, gbt.Coin, "blocks")
if val != nil {
if intVal, ok := val.(int64); ok {
gbt.Blocks = intVal
}
}
val_f := cache.LoadPoolCache(gbt.RedisClient, gbt.Coin, "rewards")
if val_f != nil {
if fVal, ok := val_f.(float64); ok {
gbt.Reward = fVal
}
}
val_f = cache.LoadPoolCache(gbt.RedisClient, gbt.Coin, "fee")
if val_f != nil {
if fVal, ok := val_f.(float64); ok {
gbt.Fee = fVal
}
}
}*/
func Start(Coin string, DbCtx *db.DbContext) {
GbtCtx.DbCtx = DbCtx
GbtCtx.Coin = Coin
atomic.StoreInt32(&(GbtCtx.FlagAliving), 0)
atomic.StoreInt32(&(GbtCtx.FlagAlivingExit), 0)
InitConfig(&GbtCtx.Config)
l, lr, err := utility.InitLogg(&(GbtCtx.Config.Zaplog), &(GbtCtx.Config.Logrotae), Coin, "gbt")
logg = l
//defer logg.Sync()
GbtCtx.Log = l
GbtCtx.LogR = lr
GbtCtx.RedisClient = redis.NewClient(&redis.Options{
Addr: GbtCtx.Config.Redis.Addr,
Password: GbtCtx.Config.Redis.Password,
DB: GbtCtx.Config.Redis.DB,
})
register_signal(DbCtx)
GbtCtx.PubCh = utility.InitZmqPub(GbtCtx.Config.Zmq.Pub)
GbtCtx.SubCh = utility.InitZmqSub(GbtCtx.Config.Zmq.Sub, "blk"+Coin)
GbtCtx.MoneroNewBlockPubCh = utility.InitZmqPub(GbtCtx.Config.Rpc.ZmqSub)
GbtCtx.MoneroNewBlockSubCh = utility.InitZmqSub(GbtCtx.Config.Rpc.ZmqSub, "hashblock")
//GbtCtx.PushCh = utility.InitZmqPush(GbtCtx.Config.Profit.Push)
for {
err = InitClient(&GbtCtx)
if err != nil {
logg.Error("[gbt]", zap.String("InitClient", err.Error()))
time.Sleep(time.Duration(5) * time.Second)
continue
}
break
}
if len(GbtCtx.Config.Rpc.ZmqSub) > 0 {
GbtCtx.NodeSubCh = utility.InitZmqSub(GbtCtx.Config.Rpc.ZmqSub, utility.BITCOIND_ZMQ_HASHBLOCK)
}
GbtCtx.Started = true
GbtCtx.ExitGbtChan = make(chan bool, 256)
//GbtCtx.AlivingChan = make(chan bool, 256)
GbtCtx.MinerAddrs = db.GetAddressFromTable(DbCtx)
GbtCtx.MinerAddrIndex = 0
//LoadCache(&GbtCtx)
for _, coinobj := range coinobjs {
if coinobj.Coin == Coin {
coinobj.Init(&GbtCtx, DbCtx)
go coinobj.Start()
break
}
}
go GbtLivingHandler(&GbtCtx)
<-DbCtx.AppExit
}
func Stop(Coin string) {
GbtCtx.Started = false
GbtCtx.ExitGbtChan <- true
//GbtCtx.AlivingChan <- false
atomic.StoreInt32(&(GbtCtx.FlagAlivingExit), 1)
for _, coinobj := range coinobjs {
if coinobj.Coin == Coin {
coinobj.Stop()
break
}
}
//time.Sleep(1 * time.Second)
defer close(GbtCtx.ExitGbtChan)
//defer close(GbtCtx.AlivingChan)
if GbtCtx.NodeSubCh != nil {
defer GbtCtx.NodeSubCh.Destroy()
}
if GbtCtx.PubCh != nil {
defer GbtCtx.PubCh.Destroy()
}
if GbtCtx.SubCh != nil {
defer GbtCtx.SubCh.Destroy()
}
/*if GbtCtx.PushCh != nil {
defer GbtCtx.PushCh.Destroy()
}*/
defer GbtCtx.RedisClient.Close()
defer logg.Sync()
}