m2pool_core/internal/gbt/enx/enx.go

248 lines
5.6 KiB
Go
Raw Normal View History

2025-04-10 07:27:24 +00:00
package enx
import (
"encoding/hex"
"fmt"
"pool/internal/db"
"pool/internal/gbt/coin"
"pool/internal/gbt/enx/templatemanager"
"pool/internal/msg"
"sync"
"sync/atomic"
"time"
"github.com/kaspanet/kaspad/domain/consensus/model/externalapi"
"github.com/kaspanet/kaspad/domain/consensus/utils/pow"
"github.com/kaspanet/kaspad/util/difficulty"
"go.uber.org/zap"
)
const GBT_ENX_VERSION string = "enx v1.15.2"
type EnxAddrConfig struct {
Addr string `json:"addr"`
}
type EnxConfig struct {
Enx EnxAddrConfig `json:"enx"`
}
type GbtEnxContext struct {
Config EnxConfig
GbtCtx *coin.GbtContext
last_time time.Time
last_gbt EnxGbtTemplate
Submits float64
addressIndex int
new_block_chan chan int
new_block_index int
last_height uint32
}
var logg *zap.Logger
var GbtEnxCtx GbtEnxContext
// Kaspa GetBlockTemplate 结构体
type EnxGbtTemplate struct {
Block struct {
Header struct {
Version int `json:"version"`
ParentsByLevel [][]string `json:"parents_by_level"`
HashMerkleRoot string `json:"hash_merkle_root"`
AcceptedIdMerkleRoot string `json:"accepted_id_merkle_root"`
UtxoCommitment string `json:"utxo_commitment"`
Timestamp uint64 `json:"timestamp"`
Bits uint32 `json:"bits"`
Nonce uint64 `json:"nonce"`
DaaScore uint64 `json:"daa_score"`
BlueWork [3]uint64 `json:"blue_work"` // 可改为 big.Int
BlueScore uint64 `json:"blue_score"`
PruningPoint string `json:"pruning_point"`
} `json:"header"`
Transactions []struct {
Version int `json:"version"`
LockTime uint64 `json:"lock_time"`
SubnetworkId string `json:"subnetwork_id"`
Gas uint64 `json:"gas"`
PayLoad string `json:"payload"`
Mass uint64 `json:"mass"`
Inputs []struct{} `json:"inputs"`
Outputs []struct{} `json:"outputs"`
VerboseData interface{} `json:"verbose_data"`
} `json:"transactions"`
} `json:"block"`
IsSync bool `json:"is_sync"`
}
type BlockCheckData struct {
Height int
Nonce string
User string
Miner string
MinerId string
Hash string
SubIdx int
}
type PushBlkNewMsg struct {
Coin string `json:"coin"`
Height int `json:"height"`
Nonce string `json:"nonce"`
}
type EnxJob struct {
JobID uint32
Job *externalapi.DomainBlock
State *pow.State
}
type EnxContext struct {
GbtCtx *coin.GbtContext
SLock sync.Mutex
JobID uint32
Jobs []EnxJob
LastHeight uint64
Submits float64
}
var enxCtx EnxContext
func update_block_confirm(gbt *GbtEnxContext) {}
var hashesTried uint64
func get_blocktemplate(gbt *GbtEnxContext, mineWhenNotSynced bool) (*externalapi.DomainBlock, *pow.State) {
tryCount := 0
const sleepTime = 500 * time.Millisecond
const sleepTimeWhenNotSynced = 5 * time.Second
for {
tryCount++
shouldLog := (tryCount-1)%10 == 0
template, state, isSynced := templatemanager.Get()
if template == nil {
if shouldLog {
logg.Info("Waiting for the initial template")
}
time.Sleep(sleepTime)
continue
}
if !isSynced && !mineWhenNotSynced {
if shouldLog {
logg.Warn("Kaspad is not synced. Skipping current block template")
}
time.Sleep(sleepTimeWhenNotSynced)
continue
}
return template, state
}
}
func get_gbt_msg(gbt *GbtEnxContext) []byte {
// 这里从节点获取区块模版(block template)
dagInfoMsg, err := gbt.GbtCtx.ClientEnx.GetBlockDAGInfo()
if err != nil {
logg.Info("[gbt]", zap.String("GetBlockDAGInfo ", err.Error()))
return nil
}
height := dagInfoMsg.VirtualDAAScore
if err != nil {
logg.Info("[gbt]", zap.String("GetBlockCount ", err.Error()))
return nil
}
height = height + 1
block, state := getBlockForMining(mineWhenNotSynced)
//state.Nonce = nonce
state.Nonce = 0
atomic.AddUint64(&hashesTried, 1)
var job msg.EnxStratumJob
enxCtx.SLock.Lock()
job.Job_id = 0
job.Gbt_id = enxCtx.JobID
enxCtx.SLock.Unlock()
job.CurTime = uint64(state.Timestamp)
job.Target = hex.EncodeToString(state.Target.Bytes())
job.Bits = difficulty.BigToCompact(&(state.Target))
job.Nonce = ""
job.Extranonce1 = ""
job.Extranonce2_size = 6
job.Extranonce2 = ""
job.Data = hex.EncodeToString(state.GetPrePowHash())
job.PrevBlockHash = fmt.Sprint("%s", block.Header.DirectParents())
job.Height = block.Header.BlueScore()
return []byte{}
}
func getBlockForMining(mineWhenNotSynced bool) (*externalapi.DomainBlock, *pow.State) {
tryCount := 0
const sleepTime = 500 * time.Millisecond
const sleepTimeWhenNotSynced = 5 * time.Second
for {
tryCount++
shouldLog := (tryCount-1)%10 == 0
template, state, isSynced := templatemanager.Get()
if template == nil {
if shouldLog {
logg.Info("Waiting for the initial template")
}
time.Sleep(sleepTime)
continue
}
if !isSynced && !mineWhenNotSynced {
if shouldLog {
logg.Warn("Kaspad is not synced. Skipping current block template")
}
time.Sleep(sleepTimeWhenNotSynced)
continue
}
return template, state
}
}
func gbt_notify_running(gbt *GbtEnxContext) {}
func gbt_running(gbt *GbtEnxContext) {}
func enxInit(config *EnxConfig) {}
func Init(GbtCtx *coin.GbtContext, DbCtx *db.DbContext) {}
func Start() {
go gbt_running(&GbtEnxCtx)
go gbt_notify_running(&GbtEnxCtx)
go submit_block_running(&GbtEnxCtx)
}
func Stop() {
defer close(GbtEnxCtx.new_block_chan)
}
func new_block_into_db(block *GbtEnxContext, user string, miner string, minerid string, height int64, nonce string, hash string, subidx int64) bool {
return true
}
func submit_block_running(block *GbtEnxContext) {}
func new_job_from_gbt(gbt *GbtEnxContext, rxmsg *msg.GbtMsg) []byte { return []byte{} }