345 lines
8.1 KiB
Go
345 lines
8.1 KiB
Go
// gbt.go
|
|
package gbt
|
|
|
|
/*
|
|
#cgo LDFLAGS: -lzmq
|
|
#include <zmq.h>
|
|
|
|
void set_max_msg_size(void *ctx, int size) {
|
|
zmq_ctx_set(ctx, ZMQ_MAXMSGSIZE, size);
|
|
}
|
|
*/
|
|
import "C"
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"log"
|
|
|
|
"io/ioutil"
|
|
"pool/internal/db"
|
|
"sync/atomic"
|
|
|
|
//"pool/internal/cache"
|
|
"pool/internal/gbt/alph"
|
|
"pool/internal/gbt/alph/http"
|
|
"pool/internal/gbt/coin"
|
|
"pool/internal/gbt/dgb"
|
|
"pool/internal/gbt/enx"
|
|
"pool/internal/gbt/grs"
|
|
"pool/internal/gbt/mona"
|
|
"pool/internal/gbt/nexa"
|
|
"pool/internal/utility"
|
|
|
|
"os"
|
|
"os/signal"
|
|
"syscall"
|
|
|
|
"time"
|
|
|
|
"github.com/btcsuite/btcd/rpcclient"
|
|
kaspad "github.com/kaspanet/kaspad/infrastructure/network/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 {
|
|
switch gbt.Coin {
|
|
case "alph":
|
|
// alph初始化逻辑
|
|
host := gbt.Config.Rpc.Host
|
|
port := gbt.Config.Rpc.Port
|
|
apiHost := gbt.Config.Rpc.ApiHost
|
|
apiPort := gbt.Config.Rpc.ApiPort
|
|
apiKey := gbt.Config.Rpc.ApiKey
|
|
client, err := alph.NewAlphPool(host, port)
|
|
apiClient := http.NewHttpClient(apiHost, apiPort, apiKey)
|
|
if err != nil {
|
|
logg.Info("[gbt]", zap.String("rpcclient new ", err.Error()))
|
|
return err
|
|
}
|
|
gbt.ClientAlph = client
|
|
gbt.ClientAlphApi = apiClient
|
|
// blockCount := apiClient.GetBlockCount()
|
|
return nil
|
|
case "enx":
|
|
host := gbt.Config.Rpc.Host
|
|
port := gbt.Config.Rpc.Port
|
|
client, err := kaspad.NewRPCClient(host + ":" + port)
|
|
if err != nil {
|
|
logg.Info("[gbt]", zap.String("rpcclient new ", err.Error()))
|
|
return err
|
|
}
|
|
gbt.ClientEnx = client
|
|
dagInfoMsg, err := client.GetBlockDAGInfo()
|
|
if err != nil {
|
|
logg.Info("[gbt]", zap.String("GetBlockDAGInfo ", err.Error()))
|
|
return err
|
|
}
|
|
blockCount := dagInfoMsg.VirtualDAAScore
|
|
logg.Info("[gbt]", zap.Int64("Block count ", int64(blockCount)))
|
|
return nil
|
|
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},
|
|
{Coin: "grs", Init: grs.Init, Start: grs.Start, Stop: grs.Stop},
|
|
{Coin: "mona", Init: mona.Init, Start: mona.Start, Stop: mona.Stop},
|
|
{Coin: "dgbo", Init: dgb.Init, Start: dgb.Start, Stop: dgb.Stop},
|
|
{Coin: "dgbq", Init: dgb.Init, Start: dgb.Start, Stop: dgb.Stop},
|
|
{Coin: "dgbs", Init: dgb.Init, Start: dgb.Start, Stop: dgb.Stop},
|
|
{Coin: "alph", Init: alph.Init, Start: alph.Start, Stop: alph.Stop},
|
|
{Coin: "enx", Init: enx.Init, Start: enx.Start, Stop: enx.Stop},
|
|
}
|
|
|
|
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) {
|
|
/*zmqctx := C.zmq_ctx_new()
|
|
defer C.zmq_ctx_term(zmqctx)
|
|
C.set_max_msg_size(zmqctx, 1024*1024*8)*/
|
|
|
|
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.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.MinerAddrs = make([]string, 4)
|
|
// GbtCtx.MinerAddrs[0] = "1EjmgB5GzbvVpu63a3GxLPjk4DNedhpjNZvVz5oCMpHg5"
|
|
// GbtCtx.MinerAddrs[1] = "1BHkVwr7VNW2ViqphAR2wy3QdmAm29jYaTVt4w62kH9V1"
|
|
// GbtCtx.MinerAddrs[2] = "15aeh8ugDpDjWRWhVHeLhyz3KTKSqKaoydTdMFxjD99BJ"
|
|
// GbtCtx.MinerAddrs[3] = "17sEVHyyfHiwFXDH3onX9MxsbP6kh2B8hrtPd7mk3Qa6r"
|
|
// 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) {
|
|
fmt.Println("gbt退出了")
|
|
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()
|
|
}
|