m2pool_core/internal/server/alph/alph.go

635 lines
21 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package alph
import (
//"database/sql"
"encoding/binary"
"encoding/hex"
"encoding/json"
"strings"
//"log"
//"math"
"math/big"
"fmt"
"pool/internal/msg"
"pool/internal/server/coin"
"pool/internal/server/dbif"
"pool/internal/stratum"
"pool/internal/utility"
"time"
_ "github.com/mattn/go-sqlite3"
"go.uber.org/zap"
)
const SERVER_ALPH_VERSION = "alph v1.0"
type ServerAlphContext struct {
ServerCtx *coin.ServerContext
logg *zap.Logger
AlphJob msg.AlphStratumJob
}
var logg *zap.Logger
var ServerAlphCtx ServerAlphContext
type Notify_msg_alph struct {
ID interface{} `json:"id"`
Method string `json:"method"`
Params []msg.AlphStratumJob `json:"params"`
}
func handle_submit(miner *coin.MinerObj, id float64, miner_user string, job_id string, nonce string) (bool, bool, bool) {
var submit_item coin.BlockMsg
/*var user_blk_item coin.UserBlockMsg*/
var pool_blk_item coin.PoolBlkMsg
var blk_detail_height int64
var blk_detail_hash string
var blk_detail_success bool
var blk_detail_miner_diff float64
var blk_detail_pool_diff float64
if miner.Authorized != true {
miner.ErrOthers = miner.ErrOthers + 1
stratum.Handle_exception(miner, id, stratum.MINER_ERR_UNAUTH_WORKER)
stratum.Send_reconnect_msg(miner)
return false, false, false
}
var new_found bool = false
var ack stratum.Submit_ack
ack.ID = id
ack.Result = true
v, ok := miner.Jobs.Load(job_id)
if ok {
job := v.(msg.AlphStratumJob)
if job.Height < miner.CurHeight-1 {
ack.Result = false
stratum.Handle_exception(miner, id, stratum.MINER_ERR_STALED_JOB)
miner.ErrStaleds = miner.ErrStaleds + 1
return false, false, false
}
if (miner.LastNonce != nonce) || (miner.LastHeader != job.HeaderBlob) {
miner.LastHeader = job.HeaderBlob
miner.LastNonce = nonce
job.Nonce = nonce
logg.Debug("[server]", zap.Uint32("height", job.Height), zap.String("target", job.TargetBlob))
// ============== 对nonce+区块头进行double blake3 hash ==============
phb, _ := hex.DecodeString(job.HeaderBlob) // 区块头 []byte
nb, _ := hex.DecodeString(nonce) // nonce []byte
// Blake3 Hash Test Code
// headerStr := "00070000000208dd35a4511b86c67d4559b94a09a64f7b35ad8d821b5bb0fb4e8c05000000008e7b7b385b727d6bedfc7b9fa8b76f39a2ef318b406a522007b56faa000000020901b382ec2b14149902d5e825d5785b41794f6dfe7a767fe5488e5f00000003178d4a043a964da8afea94bb315711a29ab70532e69f0a51c77501200000000030d339eadb0ce263f5ee49a356dd967a7f23152b6453ab57671d550100000001632ef4dab01759432e37b50d818d39f15cabab11ae0ad9949b2ca742000000000be91faa2a5b6c68762856350092244146fa5d03899ed8aecd8ef0d3446b0d40f1f22eb47dc4df7c9f2a849fa2c2f5ed5c50d626360be988b92244aa0c5dfbc04f756fc5de7f962edf62996f08ed373c51112bcb09637f9a64e6640e00000194f909ea901dff0b28"
// nonceStr := "cd1359f22f500001cd1359f22f50000151956b6400000000"
// _header, _ := hex.DecodeString(headerStr)
// _nonce, _ := hex.DecodeString(nonceStr)
// _hash := Hash(append(_nonce, _header...))
// fmt.Println("测试用hash", _hash)
// Hash Diff Test Code
// _hash, _ := hex.DecodeString("0000000044b373be04ff72d317ec7f1e63b7d8eb8babbc6f33ab29bf640feee7")
// diff := utility.AlphShareDiff(_hash)
// fmt.Println("测试用diff", diff)
// 计算hash, nonce + header
var calc_hash []byte
calc_hash = append(nb, phb...)
calc_hash = Hash(calc_hash)
logg.Debug("[server]", zap.String("hash in", submit_item.Header))
logg.Debug("[server]", zap.String("calc_hash", hex.EncodeToString(calc_hash)))
// ==================================================================
submit_target := new(big.Int)
submit_target.SetBytes(calc_hash) // bignum.fromBuffer(hash);
calc_diff := utility.AlphShareDiff(calc_hash) // 根据hash计算难度,shareDiff
// fmt.Println("提交shares难度", calc_diff)
// fmt.Println("任务难度:", job.JobDifficulty)
logg.Warn("[server]", zap.String("user", miner.User+"."+miner.Miner), zap.Float64("target diff", miner.Difficulty), zap.Float64("submit diff", calc_diff))
if calc_diff < job.JobDifficulty {
ack.Result = false
miner.ErrLowDiffs = miner.ErrLowDiffs + 1
stratum.Handle_exception(miner, id, stratum.MINER_ERR_LOW_DIF_SHARE)
return false, false, false
}
var addZero string = ""
if len(job.TargetBlob) < 64 {
addZero = strings.Repeat("0", 64-len(job.TargetBlob))
}
stb, _ := hex.DecodeString(addZero + job.TargetBlob)
// server_diff := utility.Target2Diff(utility.Reverse(stb))
server_diff := utility.AlphShareDiff(utility.Reverse(stb))
network_target := new(big.Int)
network_target.SetBytes(stb)
Net_target := hex.EncodeToString(network_target.Bytes()) // jobTarget
logg.Info("[server]", zap.Float64("calc_diff", calc_diff), zap.Float64("miner.Difficulty", miner.Difficulty), zap.Float64("server_diff", server_diff))
logg.Debug("[server]", zap.String("submit_target", hex.EncodeToString(submit_target.Bytes())), zap.String("network_target", hex.EncodeToString(network_target.Bytes())), zap.String("target", hex.EncodeToString(miner.ServerTarget.Bytes())), zap.Int("cmp", network_target.Cmp(submit_target)))
submit_item.Hash = hex.EncodeToString(calc_hash)
submit_item.Target = hex.EncodeToString(miner.Target.Bytes())
submit_item.Submit_target = hex.EncodeToString(calc_hash)
submit_item.Height = int64(job.Height)
submit_item.Pow = hex.EncodeToString(calc_hash)
submit_item.Net_target = strings.Repeat("0", 64-len(Net_target)) + Net_target
pool_blk_item.Height = int64(job.Height)
pool_blk_item.Hash = hex.EncodeToString(calc_hash)
pool_blk_item.Pow = hex.EncodeToString(calc_hash)
pool_blk_item.Net_target = strings.Repeat("0", 64-len(Net_target)) + Net_target
blk_detail_height = int64(job.Height)
blk_detail_hash = hex.EncodeToString(calc_hash)
blk_detail_success = false
// blk_detail_miner_diff = job.JobDifficulty
blk_detail_miner_diff = miner.Difficulty
blk_detail_pool_diff = miner.Server.RefDifficulty
// fmt.Println("mienr.Diff:", miner.Difficulty)
// fmt.Println("job.Diff:", job.JobDifficulty)
// fmt.Println("提交任务:", "Hash:", submit_item.Hash, "\tTarget:", submit_item.Target, "\tNet_target:", submit_item.Net_target)
// fmt.Println("submit_item", submit_item)
// fmt.Println("pool_blk_item", pool_blk_item)
// fmt.Println("blk_detail_height", blk_detail_height)
if ack.Result == true {
if (calc_diff >= server_diff) || (network_target.Cmp(submit_target) >= 0) {
miner.Server.SubIdx++
Produce_block_submit(miner, &job, submit_item.Hash, miner.Server.SubIdx)
miner.SubmitIndex++
miner.Submits = miner.Submits + 1
new_found = true
}
}
} else {
miner.LastHeader = job.HeaderBlob
miner.LastNonce = nonce
ack.Result = false
stratum.Handle_exception(miner, id, stratum.MINER_ERR_DUP_SHARE)
miner.ErrDuplicates = miner.ErrDuplicates + 1
return false, false, false
}
} else {
ack.Result = false
stratum.Handle_exception(miner, id, stratum.MINER_ERR_NOT_FOUND_JOB)
miner.ErrStaleds = miner.ErrStaleds + 1
return false, false, false
}
miner.LastJobId = job_id
ack.Error = nil
body, err := json.Marshal(ack)
if err != nil {
logg.Error("[server]", zap.String("Marshal", err.Error()))
miner.ErrOthers = miner.ErrOthers + 1
stratum.Handle_exception(miner, id, stratum.MINER_ERR_UNKNOWN)
return false, false, false
}
var body_string = string(body) + "\n"
err = stratum.Conn_tx(miner.Conn, []byte(body_string))
if err != nil {
//miner.Server.Miners.Delete(miner.MinerId)
}
if miner.ZlogInit {
miner.Zlog.Info().Msg(body_string)
}
logg.Debug("[server]", zap.String("tx", body_string))
miner.TxLock.Lock()
miner.Status = coin.MINER_STATUS_RUNNING
miner.TxLock.Unlock()
if ack.Result {
miner.Accepts += miner.Difficulty
miner.M5Accepts += miner.Difficulty
miner.VarDiffOpt.SubmitShares += miner.Difficulty
} else {
miner.Rejects += miner.Difficulty
}
now := time.Now()
if miner.Server.Config.Diff.Filter == "kalman" {
if ack.Result {
share_interval := now.Sub(miner.LastSubmitime).Seconds()
mhs := miner.Difficulty * share_interval
diff_next, kalman_p := miner.DiffHandler.Handler(miner.Difficulty, share_interval)
mhs_est := diff_next * miner.Server.Config.Diff.DiffAdjustInterval
ratio := diff_next / miner.Difficulty
if ratio > 0 {
if now.Sub(miner.StartSubmitTime).Seconds() > 180 {
if ratio >= 2 {
//miner.DifficultyNext = math.Ceil(diff_next*100) / 100
miner.DifficultyNext = diff_next * 10000000 / 10000000
} else if ratio <= 0.5 {
//miner.DifficultyNext = math.Ceil(diff_next*100) / 100
miner.DifficultyNext = diff_next * 10000000 / 10000000
} else {
}
} else {
//miner.DifficultyNext = math.Ceil(diff_next*100) / 100
miner.DifficultyNext = diff_next * 10000000 / 10000000
}
}
if miner.DifficultyNext > 0.0 {
if miner.DifficultyNext < miner.VarDiffOpt.MinDiff {
miner.DifficultyNext = miner.VarDiffOpt.MinDiff
} else if miner.DifficultyNext > miner.VarDiffOpt.MaxDiff {
miner.DifficultyNext = miner.VarDiffOpt.MaxDiff
}
}
//miner.VarDiffOpt.LastCalcTime = now
if miner.Server.Config.Diff.Dbg {
coin.New_diff_into_db(miner.User, miner.Miner, fmt.Sprint(miner.MinerIndex), miner.Difficulty, diff_next, kalman_p, share_interval, mhs, mhs_est)
}
//log.Println("diff adjust", ratio, diff_next, miner.Difficulty, miner.DifficultyNext)
}
} else {
// submit time < DiffAdjustInterval,then up adjust diff
if now.Sub(miner.LastSubmitime).Seconds() < miner.Server.Config.Diff.DiffAdjustInterval {
if ack.Result {
if miner.VarDiffOpt.Uptimes++; miner.VarDiffOpt.Uptimes >= coin.DIFFICULTY_WAIT_TIMES {
coin.VarAdjustDifficulty(miner, coin.UP_DIFF)
miner.VarDiffOpt.LastCalcTime = now
}
}
} else {
miner.VarDiffOpt.Uptimes = 0
}
// submit time > 2 * DiffAdjustInterval,then down adjust diff
if now.Sub(miner.LastSubmitime).Seconds() > miner.Server.Config.Diff.DiffAdjustInterval*2 {
if ack.Result {
if miner.VarDiffOpt.Downtimes++; miner.VarDiffOpt.Downtimes >= coin.DIFFICULTY_WAIT_TIMES {
coin.VarAdjustDifficulty(miner, coin.DOWN_DIFF)
miner.VarDiffOpt.LastCalcTime = now
}
}
} else {
miner.VarDiffOpt.Downtimes = 0
}
}
if ack.Result {
miner.LastSubmitime = now
miner.VarDiffOpt.LastSubmitTime = now
}
var duration float64 = float64(now.Sub(miner.StartSubmitTime)) / 1000000000
if duration < 1 {
duration = 1
}
diffOneShareHashesAvg := uint64(0x00000000FFFFFFFF)
miner.AverageHashrate = miner.Accepts * float64(diffOneShareHashesAvg) / duration / 1000000
var m5_duration float64 = float64(now.Sub(miner.M5SubmitTime)) / 1000000000
if m5_duration >= float64(time.Minute*5)/1000000000 {
miner.M5SubmitTime = now
miner.M5Hashrate = miner.M5Accepts * float64(diffOneShareHashesAvg) / m5_duration / 1000000
logg.Info("[server]", zap.Float64("Accepts", miner.Accepts), zap.Float64("M5Accepts", miner.M5Accepts), zap.Float64("M5Hashrate(MH/S)", miner.M5Hashrate))
miner.M5Accepts = 0
}
logg.Warn("[server]", zap.Float64("M5Accepts", miner.M5Accepts), zap.Float64("M5Hashrate(MH/S)", miner.M5Hashrate))
if miner.Server.Config.Diff.Filter == "kalman" {
} else {
if float64(now.Sub(miner.VarDiffOpt.LastCalcTime))/1000000000 >= miner.VarDiffOpt.AdjustTime {
coin.VarAdjustDifficulty(miner, coin.UPDATE_DIFF)
miner.VarDiffOpt.LastCalcTime = now
}
}
if new_found {
pool_blk_item.Submit = "y"
pool_blk_item.Success = false
pool_blk_item.Accepts = miner.Accepts
pool_blk_item.Rejects = miner.Rejects
pool_blk_item.Reward = 0
pool_blk_item.Fee = 0
pool_blk_item.Nonce = nonce
pool_blk_item.SubIdx = miner.Server.SubIdx
dbif.NotifyPoolBlkStatsDb2(miner.Server, &pool_blk_item)
}
if ack.Result {
submit_item.Success = false
if new_found {
submit_item.Submit = "y"
submit_item.SubIdx = miner.Server.SubIdx
} else {
submit_item.Submit = "n"
submit_item.SubIdx = -1
}
submit_item.Accepts = miner.Accepts
submit_item.Total_accepts = miner.Accepts
submit_item.Rejects = miner.Rejects
submit_item.Total_rejects = miner.Rejects
submit_item.Reward = 0
submit_item.Fee = 0
submit_item.Nonce = nonce
dbif.NotifyBlkDetailDb(miner, blk_detail_height, blk_detail_hash, blk_detail_success, blk_detail_miner_diff, blk_detail_pool_diff, nonce, submit_item.SubIdx)
return true, new_found, true
}
return false, false, true
}
// 该方法和alph-gbt的768行代码相对应
func Produce_block_submit(miner *coin.MinerObj, job *msg.AlphStratumJob, PowHash string, SubIdx int64) {
var nm msg.BlockAlphMsg
nm.Id = job.JobId
nm.Header = job.HeaderBlob
nm.Nonce = job.Nonce
nm.FromGroup = job.FromGroup
nm.ToGroup = job.ToGroup
nm.SubIdx = SubIdx
nm.User = miner.User
nm.Miner = miner.Miner
nm.Hash = PowHash
nm.Index = fmt.Sprint(miner.MinerIndex)
body, err := json.Marshal(nm)
if err != nil {
logg.Error("[server]", zap.String("failed to Marshal job", err.Error()))
return
}
blk := string(body)
//Add Height
heightb := utility.Uint32ToByte(job.Height)
heights := hex.EncodeToString(heightb)
blk += heights
var Height uint32 = utility.ByteToUint32(heightb)
logg.Warn("[server]", zap.Uint32("Height", Height))
//Add SubmitIndex
indexb := utility.Uint32ToByte(miner.SubmitIndex)
indexs := hex.EncodeToString(indexb)
blk += indexs
var SubmitIndex uint32 = utility.ByteToUint32(indexb)
logg.Info("[server]", zap.Uint32("SubmitIndex", SubmitIndex))
logg.Info("[server]", zap.String("blk", blk))
if miner.Server.PubCh == nil {
miner.Server.PubCh = utility.InitZmqPub(miner.Server.Config.Zmq.Pub)
}
if miner.Server.PubCh != nil {
//miner.Server.PubCh.SendChan <- [][]byte{[]byte("blknexa"), []byte(blk)}
err := miner.Server.PubCh.SendMessage([][]byte{[]byte("blkalph"), []byte(blk)})
if err != nil {
miner.Server.PubCh.Destroy()
miner.Server.PubCh = nil
logg.Info("[server]", zap.String("blk", err.Error()))
} else {
logg.Info("[server]", zap.String("blk", "sent"))
}
}
}
func alph_parse_miner_notify(miner *coin.MinerObj, msg msg.AlphStratumJob) int {
if miner.AlphJob.Height != msg.Height {
miner.Job.IsClean = true
}
miner.AlphJob = msg
miner.AlphJob.Extranonce1 = miner.Job.Extranonce1
miner.Job.Extranonce2_size = msg.Extranonce2_size
//miner.Server.Logg.Info("[server]", zap.Int32("miner.Version", miner.Version), zap.Int32("msg.Version", msg.Version))
return 1
}
func Init(server *coin.ServerContext) {
ServerAlphCtx.ServerCtx = server
logg = server.Logg
logg.Info("[server]", zap.String("server_alph_version", SERVER_ALPH_VERSION))
coin.Init_diff_db()
}
func Start() {
}
func Stop() {
coin.DiffStop()
}
func InitMiner(miner *coin.MinerObj) {
be1 := make([]byte, 8)
binary.LittleEndian.PutUint64(be1, (miner.Server.Extranonce1 /* + 0x81000000*/))
miner.Job.Extranonce1 = hex.EncodeToString(be1)
miner.AlphJob.Extranonce1 = miner.Job.Extranonce1
miner.Server.Extranonce1++
// fmt.Println("miner.Server.Extranonce1:", miner.Server.Extranonce1)
target, err := utility.DiffToTarget(miner.Difficulty)
if err != nil {
logg.Error("[server]", zap.String("DiffToTarget", err.Error()))
return
}
miner.Target = target
logg.Debug("[target]", zap.String("target", hex.EncodeToString(target.Bytes())), zap.Float64("diff", miner.Difficulty))
server_target := new(big.Int)
t_bytes, err := hex.DecodeString(miner.AlphJob.TargetBlob)
if err != nil {
logg.Error("[server]", zap.String("DecodeString", err.Error()))
return
}
//server_target.SetBytes(common.Reverse(t_bytes))
server_target.SetBytes(t_bytes)
miner.ServerTarget = server_target
miner.ServerTargetS = miner.Server.SJob.Target
miner.AlphJob = miner.Server.AlphJob
}
func HandleMinerSubscribe(miner *coin.MinerObj, id float64, extranonce1 string, msg string) {
}
func HandleMinerAuth(miner *coin.MinerObj) {
// randomNumber := rand.Intn(65536)
// hexString := fmt.Sprintf("%04x", randomNumber)
// method := "mining.set_extranonce"
// params := []string{hexString}
// setExtranonce_msg := stratum.AlphSetExtranonce{Method: method, ID: nil, Params: params}
// fmt.Println("extranonce:", setExtranonce_msg)
// ex_msg, err := json.Marshal(setExtranonce_msg)
// if err != nil {
// logg.Error("[server]", zap.String("Marshal", err.Error()))
// return
// }
// stratum.Conn_tx(miner.Conn, ex_msg)
}
func HandleMinerSubmit(miner *coin.MinerObj, id float64, miner_user string, job_id string, nonce2 string, ntime string, nonce string) (bool, bool, bool) {
accept_ok, submit_ok, handle_ok := handle_submit(miner, id, miner_user, job_id, nonce)
return accept_ok, submit_ok, handle_ok
}
func SetDifficulty(miner *coin.MinerObj) {
extra_msg := stratum.AlphSetExtranonce()
err := stratum.Conn_tx(miner.Conn, extra_msg)
if err != nil {
fmt.Println("alph.set_extranonce发送消息失败:", err)
}
stratum.Set_difficulty(miner)
}
func AlphNotify(miner *coin.MinerObj) {
miner.TxLock.Lock()
if !((miner.Status == coin.MINER_STATUS_AUTHORIZED) || (miner.Status == coin.MINER_STATUS_RUNNING)) {
miner.TxLock.Unlock()
return
}
miner.TxLock.Unlock()
if miner.DifficultyNext > -1 {
ratio := miner.DifficultyNext / miner.Difficulty
if ratio > 1.1 || ratio < 0.9 {
miner.Difficulty = miner.DifficultyNext
miner.DifficultyNext = -1
stratum.Set_difficulty(miner)
logg.Info("[gbt]", zap.Float64("update Diff", miner.Difficulty))
} else {
miner.DifficultyNext = -1
}
}
miner.TxLock.Lock()
var params msg.AlphStratumJob
target := utility.AlphDiffToTarget2(miner.Difficulty)
params.JobId = miner.AlphJob.JobId
params.HeaderBlob = miner.AlphJob.HeaderBlob
params.TargetBlob = target
params.Height = miner.AlphJob.Height
params.FromGroup = miner.AlphJob.FromGroup
params.ToGroup = miner.AlphJob.ToGroup
params.TxsBlob = miner.AlphJob.TxsBlob
miner.CurHeight = miner.AlphJob.Height
miner.AlphJob.JobDifficulty = miner.Difficulty
miner.Jobs.LoadOrStore(miner.AlphJob.JobId, miner.AlphJob)
stratum.AddAndUpdateJob(miner)
stratum.UpdateJobs(miner)
miner.JobId++
// 发送mining.notify消息
var body []byte
var err error
var msg Notify_msg_alph
msg.ID = nil
msg.Method = "mining.notify"
msg.Params = append(msg.Params, params)
body, err = json.Marshal(msg)
if err != nil {
miner.Server.Logg.Error("[server]", zap.String("Marshal", err.Error()))
miner.TxLock.Unlock()
return
}
var body_string = string(body) + "\n"
err = stratum.Conn_tx(miner.Conn, []byte(body_string))
if err != nil {
//delete(miner.Server.Miners, miner.MinerId)
//miner.Server.Miners.Delete(miner.MinerId)
}
miner.Server.Logg.Debug("[server]", zap.String("tx", body_string))
miner.TxLock.Unlock()
if miner.ZlogInit {
miner.Zlog.Info().Msg(body_string)
}
}
func Notify(miner *coin.MinerObj) {
AlphNotify(miner)
}
func HandleJobMsg(server *coin.ServerContext, Msg []byte) {
var result msg.AlphStratumJob
server.Logg.Warn("[server]", zap.String("receive", "job"))
if err := json.Unmarshal(Msg, &result); err != nil {
server.Logg.Error("[server]", zap.String("Unmarshal", err.Error()))
return
}
server.AlphJob = msg.AlphStratumJob(result)
logg.Debug("[gbt]", zap.String("Target", server.AlphJob.TargetBlob))
// server.NexaJob.Extranonce2_size = 8
// server.SJob.Extranonce2_size = 8
logg.Debug("[gbt]", zap.Uint32("Height", server.AlphJob.Height), zap.String("Target", server.AlphJob.TargetBlob), zap.String("Header", server.AlphJob.HeaderBlob) /*, zap.Uint64("Timastamp", server.NexaJob.CurTime)*/)
// targetb, _ := hex.DecodeString(server.AlphJob.TargetBlob)
// jobIdInt, err := strconv.ParseInt(server.AlphJob.JobId, 16, 64)
// if err != nil {
// logg.Error("[server]", zap.String("Atoi", err.Error()))
// return
// }
// uint64Id := uint64(jobIdInt)
// logg.Debug("[gbt]", zap.Uint64("Id", uint64Id), zap.Float64("network diff", utility.Target2Diff(utility.Reverse(targetb))))
server.NetHight = uint64(server.AlphJob.Height)
server.NetTarget = server.AlphJob.TargetBlob // 任务的target就是全网target
server.Miners.Range(func(k, v interface{}) bool {
m, ok := v.(*(coin.MinerObj))
if ok {
server.Logg.Info("[server]", zap.String("lock", "start"))
m.TxLock.Lock()
status := m.Status
cmd := alph_parse_miner_notify(m, server.AlphJob)
m.TxLock.Unlock()
server.Logg.Info("[server]", zap.String("lock", "end"))
var need_notify bool = true
if time.Now().Sub(m.ConnSetupTime) >= time.Duration(coin.CONN_EXPIRED_TIME)*time.Second {
if (status != coin.MINER_STATUS_RUNNING) && (status != coin.MINER_STATUS_AUTHORIZED) {
//m.Conn.Close()
need_notify = false
}
}
if need_notify {
switch cmd {
case 0: //extranonce 1 and extranonce2 size
//TODO
case 1: //notify
AlphNotify(m)
}
}
}
return true
})
}
func IsMhsLow(miner *coin.MinerObj) bool {
if miner.Mhs5M < 1 {
return true
}
return false
}
func GetBlockInterval() int {
return 180
}