121 lines
3.1 KiB
Go
121 lines
3.1 KiB
Go
|
package tari
|
|||
|
|
|||
|
import (
|
|||
|
"context"
|
|||
|
"encoding/base64"
|
|||
|
"encoding/hex"
|
|||
|
"fmt"
|
|||
|
base_node "pool/internal/gbt/tari/proto"
|
|||
|
block "pool/internal/gbt/tari/proto/block"
|
|||
|
|
|||
|
"google.golang.org/grpc"
|
|||
|
)
|
|||
|
|
|||
|
// var PowAlgoMap = []string{"randomxM", "sha3x", "randomxT"}
|
|||
|
|
|||
|
type BaseNodeClient struct {
|
|||
|
Conn *grpc.ClientConn
|
|||
|
Client base_node.BaseNodeClient
|
|||
|
}
|
|||
|
|
|||
|
// 创建BaseNode客户端
|
|||
|
func NewBaseNodeClient(address string) (*BaseNodeClient, error) {
|
|||
|
conn, err := grpc.Dial(address, grpc.WithInsecure())
|
|||
|
if err != nil {
|
|||
|
return nil, fmt.Errorf("failed to connect to base node: %v", err)
|
|||
|
}
|
|||
|
// 移除 defer conn.Close(),让连接保持打开状态
|
|||
|
|
|||
|
client := base_node.NewBaseNodeClient(conn)
|
|||
|
|
|||
|
return &BaseNodeClient{
|
|||
|
Conn: conn,
|
|||
|
Client: client,
|
|||
|
}, nil
|
|||
|
}
|
|||
|
|
|||
|
// Close 关闭GRPC连接
|
|||
|
func (c *BaseNodeClient) Close() error {
|
|||
|
if c.Conn != nil {
|
|||
|
return c.Conn.Close()
|
|||
|
}
|
|||
|
return nil
|
|||
|
}
|
|||
|
|
|||
|
type TariBlockTemplate struct {
|
|||
|
MiningHash string
|
|||
|
Header string
|
|||
|
Body string
|
|||
|
Height uint64
|
|||
|
TargetDifficulty uint64
|
|||
|
}
|
|||
|
|
|||
|
func base64ToHex(data string) (string, error) {
|
|||
|
result, err := base64.StdEncoding.DecodeString(data)
|
|||
|
if err != nil {
|
|||
|
return "", err
|
|||
|
}
|
|||
|
return hex.EncodeToString(result), nil
|
|||
|
}
|
|||
|
|
|||
|
func (nc *BaseNodeClient) GetBlockTemplate(ctx context.Context, powIndex uint32) (TariBlockTemplate, error) {
|
|||
|
var pow_algo block.PowAlgo_PowAlgos
|
|||
|
switch powIndex {
|
|||
|
case 0:
|
|||
|
pow_algo = block.PowAlgo_POW_ALGOS_RANDOMXM
|
|||
|
case 1:
|
|||
|
pow_algo = block.PowAlgo_POW_ALGOS_SHA3X
|
|||
|
case 2:
|
|||
|
pow_algo = block.PowAlgo_POW_ALGOS_RANDOMXT
|
|||
|
default:
|
|||
|
fmt.Println("不支持", powIndex, "算法")
|
|||
|
}
|
|||
|
templateReq := &base_node.NewBlockTemplateRequest{
|
|||
|
Algo: &block.PowAlgo{
|
|||
|
PowAlgo: pow_algo,
|
|||
|
},
|
|||
|
MaxWeight: 0x00,
|
|||
|
}
|
|||
|
templateResp, err := nc.Client.GetNewBlockTemplate(ctx, templateReq)
|
|||
|
if err != nil {
|
|||
|
fmt.Println(pow_algo, "获取区块模板失败:", err)
|
|||
|
return TariBlockTemplate{}, err
|
|||
|
}
|
|||
|
// 节点未同步完成
|
|||
|
if !templateResp.InitialSyncAchieved {
|
|||
|
fmt.Println("节点还未完成同步")
|
|||
|
return TariBlockTemplate{}, err
|
|||
|
}
|
|||
|
blk_template, miner_data := templateResp.NewBlockTemplate, templateResp.MinerData
|
|||
|
targetDifficulty := miner_data.TargetDifficulty
|
|||
|
height := blk_template.Header.Height
|
|||
|
blockBlob, err := nc.Client.GetNewBlockBlob(ctx, blk_template)
|
|||
|
if err != nil {
|
|||
|
fmt.Println("获得block blob失败:", err)
|
|||
|
return TariBlockTemplate{}, err
|
|||
|
}
|
|||
|
mining_hash, header, body := blockBlob.BlockHash, blockBlob.Header, blockBlob.BlockBody
|
|||
|
var t_bt = TariBlockTemplate{
|
|||
|
MiningHash: hex.EncodeToString(mining_hash),
|
|||
|
Header: hex.EncodeToString(header),
|
|||
|
Body: hex.EncodeToString(body),
|
|||
|
TargetDifficulty: targetDifficulty,
|
|||
|
Height: height,
|
|||
|
}
|
|||
|
return t_bt, nil
|
|||
|
}
|
|||
|
|
|||
|
func (nc *BaseNodeClient) SubmitBlock(ctx context.Context, header, body []byte) ([]byte, error) {
|
|||
|
submitReq := &base_node.BlockBlobRequest{
|
|||
|
HeaderBlob: header,
|
|||
|
BodyBlob: body,
|
|||
|
}
|
|||
|
submitResp, err := nc.Client.SubmitBlockBlob(ctx, submitReq)
|
|||
|
if err != nil {
|
|||
|
fmt.Println("提交区块失败:", err)
|
|||
|
return nil, err
|
|||
|
}
|
|||
|
blockHash := submitResp.BlockHash
|
|||
|
return blockHash, nil
|
|||
|
}
|