资深Golang工程师 - 比特币挖矿领域(全职远程岗位)

资深Golang工程师 - 比特币挖矿领域(全职远程岗位) Luxor 专注于算力(计算能力)的实物交付。在过去三年中,我们一直作为算力的购买方,采购并挖掘了价值超过 4500 万美元的算力。目前,我们每天有 21,000 台机器向我们出售其算力。

公司背景

我们从根本上相信计算能力本身就是一种商品,我们希望为其构建传统的市场及衍生品。

我们正在构建一个算力现货市场,类似于计算能力版的亨利枢纽。在此完成后,我们将开始基于算力价值构建极其强大且有趣的衍生品。

您将为云解决方案或本地解决方案制定技术设计。同时,利用原创研究和高级分析来影响整个研发部门的设计。您将运用在性能测试方面丰富的领域专业知识,为业务关键且高度复杂的工程项目设计解决方案。您将监督代码和设计审查,并确保交付的功能满足业务和质量要求。

我们的团队拥有这个快速增长、全球分布式平台(例如:算力市场和 15 个独特的矿池)的关键任务方面,无论是在云端还是本地。因此,您将对产品的当前状态和未来方向产生巨大的影响,在整个组织内具有可见性,并有大量机会承担所有权。

该职位将直接向首席技术官汇报。

这是一个远程职位,但您需要位于 UTC-8 到 UTC-3 时区之间。

软件工程师

我们正在寻找一名软件工程师加入我们小而协作的团队,致力于加密货币挖矿行业中最有价值的项目之一。

基本要求

  • 扎实掌握数据库技术,如 SQL、PL/pgSQL 和关系型数据库模式设计。
  • 理解架构原则;具备专家级的软件工程能力。
  • 具备开发和调优高可用性服务器端应用程序的经验。
  • 计算机科学、工程或相关技术学科的学士学位(或其外国同等学历)或同等经验。
  • 在当前和过去职位中表现优异的记录。
  • 深入理解编程,并至少精通一种编程语言。优先考虑 Golang 和 Typescript。
  • 理解 REST API 和通用的 API 设计。
  • 出色的人际交往和沟通能力。
  • 英语语言能力。

优先要求

  • 8 年以上软件工程经验。
  • 了解区块链技术 / 矿池行业。
  • 具备敏捷开发方法论的经验。
  • 具备构建高度可扩展的分布式系统的经验。
  • 具备在生产环境中交付并拥有网络级数据系统的经验。
  • 具备使用证书的经验。
  • 了解 GCP、Kubernetes、Istio、Helm、Docker 和 Postgres。
  • 具备与远程团队合作的经验。

理想候选人:

  • 对加密货币和公共区块链技术充满热情。
  • 有兴趣以算力(计算能力)作为商品创建一个全新的市场。
  • 有兴趣思考并改进我们软件的架构,使其健壮且易于维护。
  • 享受编写代码并突破现有界限。
  • 能为团队带来乐趣,同时也能深入钻研,按时交付高质量的代码。
  • 理解架构原则;具备专家级的软件工程能力。

职责:

  • 在产品设计阶段积极参与,分析需求,并提出创新和替代解决方案。
  • 协作定义架构,始终考虑可扩展且安全的解决方案。
  • 开发高质量的代码,重点在于实现的正确性。
  • 协作进行产品的演进维护。
  • 设计、记录、自动化并执行测试计划。
  • 参与功能生成和分析的过程。

在 Luxor,我们相信任何人都可以做出有意义的贡献。我们每个人都有责任推动我们社区和工作场所的平等。我们致力于通过同工同酬、员工资源小组、包容性福利等计划和举措,打造一个反映社会的员工队伍。Luxor 是一个平等就业机会和肯定性行动的雇主。合格的申请人将获得就业考虑,不受种族、肤色、宗教、■■■、性取向、性别认知或身份、国籍、年龄、婚姻状况、受保护的退伍军人身份或残疾状况的影响。


更多关于资深Golang工程师 - 比特币挖矿领域(全职远程岗位)的实战教程也可以访问 https://www.itying.com/category-94-b0.html

4 回复

好的,收到。

更多关于资深Golang工程师 - 比特币挖矿领域(全职远程岗位)的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你好 @ethanvera 我可以帮助你解决你的需求。 请通过Skype添加我 - live:.cid.baff7c7dd9471b54 此致, Trish

您好,

我很乐意为您提供帮助。 请通过我的电子邮件:lauren@cisinlabs.com 或 Skype 与我联系,以便我们详细讨论。

此致, Lauren Wilson Skype ID: live:lauren_8606

这是一个极具吸引力的资深Golang岗位,专注于高性能、分布式系统,非常适合在区块链基础设施领域有深厚背景的工程师。以下是针对该职位要求的技术分析和示例代码,展示如何用Golang构建高可用矿池相关服务。

1. 高可用矿工连接管理 (WebSocket + 连接池)

矿池需要处理数千个矿机的稳定连接,以下示例展示如何用Golang实现带健康检查的连接管理器:

package main

import (
    "context"
    "sync"
    "time"
    "github.com/gorilla/websocket"
)

type MinerConnection struct {
    ID        string
    Conn      *websocket.Conn
    LastSeen  time.Time
    Hashrate  float64
    mu        sync.RWMutex
}

type ConnectionPool struct {
    miners     map[string]*MinerConnection
    mu         sync.RWMutex
    healthTick *time.Ticker
}

func NewConnectionPool() *ConnectionPool {
    pool := &ConnectionPool{
        miners:     make(map[string]*MinerConnection),
        healthTick: time.NewTicker(30 * time.Second),
    }
    go pool.healthCheck()
    return pool
}

func (p *ConnectionPool) AddMiner(minerID string, conn *websocket.Conn) {
    p.mu.Lock()
    defer p.mu.Unlock()
    
    p.miners[minerID] = &MinerConnection{
        ID:       minerID,
        Conn:     conn,
        LastSeen: time.Now(),
    }
}

func (p *ConnectionPool) healthCheck() {
    for range p.healthTick.C {
        p.mu.RLock()
        for id, miner := range p.miners {
            if time.Since(miner.LastSeen) > 60*time.Second {
                go p.handleStaleConnection(id)
            }
        }
        p.mu.RUnlock()
    }
}

func (p *ConnectionPool) BroadcastWork(work *WorkPackage) error {
    p.mu.RLock()
    defer p.mu.RUnlock()
    
    var wg sync.WaitGroup
    errCh := make(chan error, len(p.miners))
    
    for _, miner := range p.miners {
        wg.Add(1)
        go func(m *MinerConnection) {
            defer wg.Done()
            m.mu.Lock()
            defer m.mu.Unlock()
            
            if err := m.Conn.WriteJSON(work); err != nil {
                errCh <- err
            }
        }(miner)
    }
    
    wg.Wait()
    close(errCh)
    
    // 返回第一个错误(实际生产环境需要更完善的错误处理)
    for err := range errCh {
        return err
    }
    return nil
}

2. 算力统计与实时聚合 (使用PostgreSQL + 物化视图)

矿池需要实时统计算力数据,以下展示如何设计高效的数据聚合层:

package main

import (
    "context"
    "database/sql"
    "fmt"
    "time"
    _ "github.com/lib/pq"
)

type HashrateStats struct {
    db *sql.DB
}

func (h *HashrateStats) RecordShare(minerID string, difficulty float64) error {
    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    defer cancel()
    
    // 使用CTE快速插入并更新汇总
    query := `
    WITH new_share AS (
        INSERT INTO shares (miner_id, difficulty, timestamp)
        VALUES ($1, $2, NOW())
        RETURNING miner_id, difficulty
    ),
    update_stats AS (
        INSERT INTO hashrate_stats (miner_id, shares_count, total_difficulty, last_update)
        SELECT miner_id, 1, difficulty, NOW()
        FROM new_share
        ON CONFLICT (miner_id) 
        DO UPDATE SET 
            shares_count = hashrate_stats.shares_count + 1,
            total_difficulty = hashrate_stats.total_difficulty + EXCLUDED.total_difficulty,
            last_update = NOW()
    )
    SELECT 1
    `
    
    _, err := h.db.ExecContext(ctx, query, minerID, difficulty)
    return err
}

func (h *HashrateStats) GetRealTimeHashrate(minerID string) (float64, error) {
    // 使用物化视图快速查询
    query := `
    SELECT 
        total_difficulty / EXTRACT(EPOCH FROM (NOW() - MIN(timestamp))) as hashrate_th_s
    FROM shares
    WHERE miner_id = $1 
    AND timestamp > NOW() - INTERVAL '10 minutes'
    GROUP BY miner_id
    `
    
    var hashrate float64
    err := h.db.QueryRow(query, minerID).Scan(&hashrate)
    return hashrate, err
}

// 创建物化视图的DDL示例
const createMaterializedView = `
CREATE MATERIALIZED VIEW IF NOT EXISTS hourly_hashrate AS
SELECT 
    miner_id,
    DATE_TRUNC('hour', timestamp) as hour,
    SUM(difficulty) / 3600 as avg_hashrate_th_s,
    COUNT(*) as shares_count
FROM shares
WHERE timestamp > NOW() - INTERVAL '24 hours'
GROUP BY miner_id, DATE_TRUNC('hour', timestamp)
WITH DATA;

CREATE UNIQUE INDEX ON hourly_hashrate (miner_id, hour);
`

3. 工作证明验证引擎 (高性能验证)

矿池核心需要快速验证工作量证明,以下展示优化后的验证逻辑:

package main

import (
    "crypto/sha256"
    "encoding/binary"
    "math/big"
)

type WorkValidator struct {
    target *big.Int
}

func NewWorkValidator(networkDifficulty float64) *WorkValidator {
    // 根据网络难度计算目标值
    target := new(big.Int).Exp(big.NewInt(2), big.NewInt(256), nil)
    target.Div(target, big.NewInt(int64(networkDifficulty)))
    
    return &WorkValidator{
        target: target,
    }
}

func (w *WorkValidator) ValidateProof(header []byte, nonce uint32) bool {
    // 快速验证,避免不必要的内存分配
    var data [80]byte
    copy(data[:76], header)
    binary.LittleEndian.PutUint32(data[76:], nonce)
    
    // 双SHA256
    firstHash := sha256.Sum256(data[:])
    hash := sha256.Sum256(firstHash[:])
    
    // 反转字节序(比特币使用大端序比较)
    var reversed [32]byte
    for i := 0; i < 32; i++ {
        reversed[i] = hash[31-i]
    }
    
    // 比较哈希值是否小于目标
    hashInt := new(big.Int).SetBytes(reversed[:])
    return hashInt.Cmp(w.target) < 0
}

// 批量验证优化
func (w *WorkValidator) ValidateBatch(header []byte, nonces []uint32) []bool {
    results := make([]bool, len(nonces))
    var wg sync.WaitGroup
    
    batchSize := 1000
    for i := 0; i < len(nonces); i += batchSize {
        wg.Add(1)
        go func(start int) {
            defer wg.Done()
            end := start + batchSize
            if end > len(nonces) {
                end = len(nonces)
            }
            
            for j := start; j < end; j++ {
                results[j] = w.ValidateProof(header, nonces[j])
            }
        }(i)
    }
    
    wg.Wait()
    return results
}

4. Kubernetes健康检查端点 (生产就绪)

对于云原生部署,需要实现完善的健康检查:

package main

import (
    "database/sql"
    "net/http"
    "sync/atomic"
)

type HealthChecker struct {
    db          *sql.DB
    isReady     atomic.Value
    liveChecks  []func() error
    readyChecks []func() error
}

func (h *HealthChecker) LivenessProbe(w http.ResponseWriter, r *http.Request) {
    for _, check := range h.liveChecks {
        if err := check(); err != nil {
            w.WriteHeader(http.StatusServiceUnavailable)
            w.Write([]byte("Service unavailable"))
            return
        }
    }
    w.WriteHeader(http.StatusOK)
    w.Write([]byte("OK"))
}

func (h *HealthChecker) ReadinessProbe(w http.ResponseWriter, r *http.Request) {
    if !h.isReady.Load().(bool) {
        w.WriteHeader(http.StatusServiceUnavailable)
        return
    }
    
    for _, check := range h.readyChecks {
        if err := check(); err != nil {
            w.WriteHeader(http.StatusServiceUnavailable)
            w.Write([]byte("Not ready"))
            return
        }
    }
    w.WriteHeader(http.StatusOK)
    w.Write([]byte("Ready"))
}

func (h *HealthChecker) databaseCheck() error {
    return h.db.Ping()
}

// 在Kubernetes部署中配置
const deploymentYAML = `
apiVersion: apps/v1
kind: Deployment
spec:
  template:
    spec:
      containers:
      - name: mining-pool
        livenessProbe:
          httpGet:
            path: /health/live
            port: 8080
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /health/ready
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 5
`

5. 实时数据流处理 (使用Channel模式)

处理矿机实时提交的份额数据:

package main

import (
    "context"
    "time"
)

type Share struct {
    MinerID    string
    Difficulty float64
    Timestamp  time.Time
    Valid      bool
}

type ShareProcessor struct {
    sharesCh   chan Share
    statsCh    chan Share
    validCh    chan Share
    workers    int
}

func NewShareProcessor(workers int) *ShareProcessor {
    sp := &ShareProcessor{
        sharesCh: make(chan Share, 10000),
        statsCh:  make(chan Share, 10000),
        validCh:  make(chan Share, 10000),
        workers:  workers,
    }
    
    for i := 0; i < workers; i++ {
        go sp.processWorker()
        go sp.statsWorker()
    }
    
    return sp
}

func (sp *ShareProcessor) SubmitShare(share Share) {
    select {
    case sp.sharesCh <- share:
        // 成功提交
    default:
        // 队列满,记录丢弃
    }
}

func (sp *ShareProcessor) processWorker() {
    validator := NewWorkValidator(25.0) // 示例难度
    
    for share := range sp.sharesCh {
        // 验证工作量证明
        share.Valid = validator.ValidateProof([]byte(share.MinerID), uint32(share.Difficulty))
        
        // 分发到不同管道
        if share.Valid {
            select {
            case sp.validCh <- share:
            case <-time.After(100 * time.Millisecond):
                // 处理超时
            }
        }
        
        // 统计通道(所有份额都需要统计)
        select {
        case sp.statsCh <- share:
        default:
            // 统计队列满
        }
    }
}

func (sp *ShareProcessor) statsWorker() {
    ticker := time.NewTicker(10 * time.Second)
    var batch []Share
    
    for {
        select {
        case share := <-sp.statsCh:
            batch = append(batch, share)
            if len(batch) >= 1000 {
                sp.flushBatch(batch)
                batch = nil
            }
        case <-ticker.C:
            if len(batch) > 0 {
                sp.flushBatch(batch)
                batch = nil
            }
        }
    }
}

这些示例代码展示了构建高可用矿池系统所需的核心组件:连接管理、数据聚合、工作量证明验证、云原生健康检查和实时流处理。实际生产环境还需要考虑分布式锁、事务处理、监控指标收集和容错机制。

回到顶部