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 }