248 lines
5.6 KiB
Go
248 lines
5.6 KiB
Go
|
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{} }
|