273 lines
7.6 KiB
Go
273 lines
7.6 KiB
Go
package enx
|
||
|
||
import (
|
||
"bytes"
|
||
"encoding/binary"
|
||
"encoding/hex"
|
||
"encoding/json"
|
||
"fmt"
|
||
"pool/internal/msg"
|
||
"pool/internal/server/coin"
|
||
"pool/internal/stratum"
|
||
"pool/internal/utility"
|
||
|
||
"github.com/btcsuite/btcd/wire"
|
||
"go.uber.org/zap"
|
||
)
|
||
|
||
const SERVER_ENX_VERSION string = "enx v1.15.2"
|
||
|
||
type ServerEnxContext struct {
|
||
ServerCtx *coin.ServerContext
|
||
logg *zap.Logger
|
||
Job msg.StratumJob
|
||
}
|
||
|
||
var logg *zap.Logger
|
||
var ServerEnxCtx ServerEnxContext
|
||
|
||
// headerHash:本身的pow计算结果,收到后根据nonce和timestamp重新计算该值,确保该值正确
|
||
// headerHash本身可以通过计算得出难度
|
||
func handle_submit(miner *coin.MinerObj, id float64, miner_user string, job_id string, headerHash string, ntime 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
|
||
//logg.Warn("[server]", zap.String("user", miner.User), zap.String("miner", miner.Miner))
|
||
//logg.Debug("[server]", zap.Float64("id", id), zap.String("job_id", job_id))
|
||
//logg.Debug("[server]", zap.String("nonce2", nonce2), zap.String("ntime", ntime), zap.String("nonce", nonce))
|
||
//stratum.UpdateJobs(miner)
|
||
v, ok := miner.Jobs.Load(job_id)
|
||
if ok {
|
||
job := v.(msg.StratumJob)
|
||
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.LastNonce = nonce
|
||
if miner.ZlogInit {
|
||
miner.Zlog.Info().Msg("height " + fmt.Sprintf("%d", job.Height) + " target " + job.Target + " extra1 " + job.Extranonce1 + " size " + fmt.Sprintf("%d", job.Extranonce2_size) + " " + miner.User + "." + miner.Miner)
|
||
}
|
||
}
|
||
vb := make([]byte, 4)
|
||
binary.LittleEndian.PutUint32(vb, uint32(job.Version))
|
||
vBuffer := bytes.NewBuffer(vb)
|
||
binary.Read(vBuffer, binary.BigEndian, &(miner.Version))
|
||
|
||
job.Nonce = nonce
|
||
job.Extranonce2 = headerHash
|
||
|
||
var calc_hash []byte
|
||
var header wire.BlockHeader
|
||
|
||
}
|
||
}
|
||
|
||
// 构造提交至节点的区块
|
||
func Produce_block_submit(miner *coin.MinerObj, header wire.BlockHeader, job *msg.StratumJob, PowHash string, SubIdx int64) {
|
||
}
|
||
|
||
// server-->miner
|
||
func enx_parse_miner_notify(miner *coin.MinerObj, msg msg.StratumJob) int {}
|
||
|
||
func Init(server *coin.ServerContext) {
|
||
ServerEnxCtx.ServerCtx = server
|
||
logg = server.Logg
|
||
logg.Info("[server]", zap.String("server_mona_version", SERVER_ENX_VERSION))
|
||
coin.Init_diff_db()
|
||
}
|
||
|
||
func Start() {
|
||
|
||
}
|
||
|
||
func Stop() {
|
||
coin.DiffStop()
|
||
}
|
||
|
||
func InitMiner(miner *coin.MinerObj) {}
|
||
|
||
func Handle_subscribe_enx(miner *coin.MinerObj, id float64, extranonce1 string) {
|
||
stratum.Handle_subscribe(miner, id, extranonce1)
|
||
}
|
||
|
||
func HandleMinerSubscribe(miner *coin.MinerObj, id float64, extranonce1 string, msg string) {
|
||
Handle_subscribe_enx(miner, id, extranonce1)
|
||
}
|
||
|
||
func HandleMinerAuth(miner *coin.MinerObj) {
|
||
|
||
}
|
||
|
||
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, nonce2, ntime, nonce)
|
||
return accept_ok, submit_ok, handle_ok
|
||
}
|
||
|
||
func set_difficulty(miner *coin.MinerObj) {}
|
||
|
||
func SetDifficulty(miner *coin.MinerObj) {
|
||
set_difficulty(miner)
|
||
}
|
||
|
||
/**
|
||
id: int, method: string, params:[string(jobid), string(headerHash, 32 byte serialized header, 8 bytes timestamp)]
|
||
*/
|
||
func EnxNotify(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
|
||
//Set_difficulty(miner)
|
||
miner.Server.CoinCtx.SetDifficulty(miner)
|
||
} else {
|
||
miner.DifficultyNext = -1
|
||
}
|
||
}
|
||
miner.TxLock.Lock()
|
||
//log.Println("[server]extra1, id", miner.Job.Extranonce1, miner.Job.Job_id, miner.MinerId)
|
||
var params [9]interface{}
|
||
var tlist []string = make([]string, 0)
|
||
idb := make([]byte, 4)
|
||
binary.BigEndian.PutUint32(idb, miner.JobId)
|
||
miner.Job.Job_id = hex.EncodeToString(idb)
|
||
params[0] = miner.Job.Job_id
|
||
if len(miner.Job.PrevblockS) > 0 {
|
||
params[1] = miner.Job.PrevblockBig
|
||
} else {
|
||
p_big := utility.Convert_big_endian(miner.Job.Prevblock.CloneBytes())
|
||
params[1] = hex.EncodeToString(p_big)
|
||
}
|
||
params[2] = miner.Job.Coinbase1
|
||
params[3] = miner.Job.Coinbase2
|
||
params[4] = tlist
|
||
|
||
miner.CurHeight = miner.Job.Height
|
||
|
||
if miner.Job.Transactions != nil {
|
||
if len(*miner.Job.Transactions) > 0 {
|
||
params[4] = miner.Job.Transactions
|
||
|
||
/*miner.Server.Logg.Error("[notify]", zap.String("coinbase1", miner.Job.Coinbase1), zap.String("coinbase2", miner.Job.Coinbase2), zap.Uint32("height", miner.Job.Height))
|
||
for i := 0; i < len(*miner.Job.Transactions); i++ {
|
||
miner.Server.Logg.Error("[notify]", zap.String("trans", (*miner.Job.Transactions)[i]))
|
||
}*/
|
||
|
||
}
|
||
}
|
||
vb := make([]byte, 4)
|
||
binary.LittleEndian.PutUint32(vb, uint32(miner.Job.Version))
|
||
params[5] = hex.EncodeToString(vb)
|
||
bb := make([]byte, 4)
|
||
binary.LittleEndian.PutUint32(bb, miner.Job.Bits)
|
||
params[6] = hex.EncodeToString(bb)
|
||
t := miner.Job.Timestamp.Unix()
|
||
if t > int64(^uint32(0)) {
|
||
tb := make([]byte, 8)
|
||
binary.LittleEndian.PutUint64(tb, uint64(t))
|
||
params[7] = hex.EncodeToString(tb)
|
||
} else {
|
||
tb := make([]byte, 4)
|
||
binary.LittleEndian.PutUint32(tb, uint32(t))
|
||
params[7] = hex.EncodeToString(tb)
|
||
}
|
||
if miner.Reconnect {
|
||
params[8] = true
|
||
miner.Reconnect = false
|
||
} else {
|
||
params[8] = miner.Job.IsClean
|
||
}
|
||
miner.Job.JobDifficulty = miner.Difficulty
|
||
|
||
//miner.Jobs[miner.Job.Job_id] = miner.Job
|
||
miner.Jobs.LoadOrStore(miner.Job.Job_id, miner.Job)
|
||
|
||
/*var entry coin.JobListEntry
|
||
entry.Job_id = miner.Job.Job_id
|
||
entry.Ts = time.Now()
|
||
|
||
miner.LockForJobs.Lock()
|
||
miner.JobList.PushFront(entry)
|
||
var removes string = ""
|
||
if miner.JobList.Len() > int(coin.LOCAL_JOBS_TOTAL_SIZE) {
|
||
e := miner.JobList.Back()
|
||
entry := e.Value.(coin.JobListEntry)
|
||
removes = entry.Job_id
|
||
miner.JobList.Remove(e)
|
||
}
|
||
miner.LockForJobs.Unlock()
|
||
if len(removes) > 0 {
|
||
miner.Jobs.Delete(removes)
|
||
}*/
|
||
stratum.AddAndUpdateJob(miner)
|
||
stratum.UpdateJobs(miner)
|
||
|
||
//miner.LastJobId = miner.Job.Job_id
|
||
miner.JobId++
|
||
|
||
var msg stratum.Notify_msg
|
||
msg.ID = nil
|
||
msg.Method = "mining.notify"
|
||
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) {
|
||
EnxNotify(miner)
|
||
}
|
||
|
||
func HandleJobMsg(server *coin.ServerContext, Msg []byte) {}
|
||
|
||
func IsMhsLow(miner *coin.MinerObj) bool {
|
||
return miner.Mhs5M < 1
|
||
}
|
||
|
||
func GetBlockInterval() int {
|
||
return 30 // 30秒没获取到任务发送退出信号
|
||
}
|