package proxy import ( "context" "crypto/rand" "encoding/hex" "fmt" pb "pool/internal/server/proxy/proto" block "pool/internal/server/proxy/proto/block" transaction "pool/internal/server/proxy/proto/transaction" "sync" "google.golang.org/grpc" ) // BaseNode客户端示例 type BaseNodeClient struct { conn *grpc.ClientConn client pb.BaseNodeClient ctx context.Context } type NewBlockTemplateResponse struct { NewBlockTemplate *block.NewBlockTemplate `json:"new_block_template"` InitialSyncAchieved bool `json:"initial_sync_achieved"` MinerData *pb.MinerData `json:"miner_data"` } type NewBlockTemplate struct { Header *block.BlockHeader `json:"header"` Body *transaction.AggregateBody `json:"body"` } // 创建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) } ctx := context.Background() return &BaseNodeClient{ conn: conn, client: pb.NewBaseNodeClient(conn), ctx: ctx, }, nil } type RandomxTJob struct { JobID string `json:"job_id"` SeedHash string `json:"seed_hash"` Height uint64 `json:"height"` MiningHash string `json:"mining_hash"` Blob string `json:"blob"` // hash_blob Difficulty uint64 `json:"diffculty"` Header string `json:"header"` Body string `json:"body"` } type MoneroNotify_params_msg struct { Id string `json:"id"` JobId string `json:"job_id"` SeedHash string `json:"seed_hash"` Blob string `json:"blob"` Height uint32 `json:"height"` Target string `json:"target"` NextSeedHash string `json:"next_seed_hash"` Algo string `json:"algo"` } type Monero_msg struct { Jsonrpc string `json:"jsonrpc"` Method string `json:"method"` Params MoneroNotify_params_msg `json:"params"` } type MoneroAuthorize_reply struct { ID float64 `json:"id"` Jsonrpc string `json:"jsonrpc"` Error interface{} `json:"error"` Result MoneroJob `json:"result"` } type MoneroJob struct { Id string `json:"id"` Job MoneroNotify_params_msg `json:"job"` Status string `json:"status"` } func randomxJobId() string { // 生成4个字节 bytes := make([]byte, 4) _, err := rand.Read(bytes) if err != nil { panic(err) } // 转成 hex 字符串 hexStr := hex.EncodeToString(bytes) return hexStr } var jobs sync.Map func (c *BaseNodeClient) get_randomxt_data() { getblocktemplateReq := &pb.NewBlockTemplateRequest{ Algo: &block.PowAlgo{ PowAlgo: block.PowAlgo_POW_ALGOS_RANDOMXT, // 使用 SHA3X 算法 }, MaxWeight: 0x00ff, // 设置最大权重 } blocktemplate, err := c.client.GetNewBlockTemplate(c.ctx, getblocktemplateReq) if err != nil { fmt.Println("get block template failed:", err) return } synced := blocktemplate.InitialSyncAchieved if !synced { fmt.Println("chain doesn`t synced!") return } diff := blocktemplate.MinerData.TargetDifficulty template := blocktemplate.NewBlockTemplate newblock, err := c.client.GetNewBlock(c.ctx, template) if err != nil { fmt.Println("get new block failed:", err) return } height := newblock.Block.Header.Height newblockblob, err := c.client.GetNewBlockBlob(c.ctx, template) if err != nil { fmt.Println("get new block blob failed:", err) return } mining_hash_byte, vm_key_byte := newblock.BlockHash, newblock.VmKey header_byte, body_byte := newblockblob.Header, newblockblob.BlockBody // 构造tari-ranomdxt hashing_blob // 3字节前导0 + 32字节mining_hash + 8字节nonce + 1字节pow_algo + 32字节pow_data pilotZero := make([]byte, 3) pow_algo := []byte{0x20} pow_data := make([]byte, 32) initNonce := make([]byte, 8) hashing_blob := make([]byte, 76) copy(hashing_blob[0:3], pilotZero) // 3字节 copy(hashing_blob[3:35], mining_hash_byte) // 32字节 copy(hashing_blob[35:43], initNonce) // 8字节 copy(hashing_blob[43:44], pow_algo) // 1字节 copy(hashing_blob[44:76], pow_data) // 32字节 jobId := randomxJobId() var job RandomxTJob job.MiningHash = hex.EncodeToString(mining_hash_byte) job.Blob = hex.EncodeToString(hashing_blob) job.Header = hex.EncodeToString(header_byte) job.Body = hex.EncodeToString(body_byte) job.Height = height job.Difficulty = diff job.SeedHash = hex.EncodeToString(vm_key_byte) job.JobID = jobId jobs.LoadOrStore(jobId, job) }