ITPub博客

首页 > 区块链 > 区块链 > 区块链教程btcpool矿池源码分析核心机制总结及优化思考

区块链教程btcpool矿池源码分析核心机制总结及优化思考

原创 区块链 作者:兄弟连区块链入门教程 时间:2018-10-16 14:48:06 0 删除 编辑

## 核心机制总结

 

### ① gbtmaker

 

* 监听 Bitcoind ZMQ 中 BITCOIND_ZMQ_HASHBLOCK 消息,一有新块产生,将立即向 kafka 发送新 Gbt

* 另默认每 5 秒间隔(可从配置文件中指定)主动 RPC 请求 Bitcoind ,获取 Gbt 发送给 kafka

* Gbt 消息大小约 2M ,含交易列表

 

### ② jobmaker

 

* 同时监听 kafka KAFKA_TOPIC_RAWGBT 和 KAFKA_TOPIC_NMC_AUXBLOCK ,以支持混合挖矿

* 接收的 Gbt 消息,如果与本地时间延迟超过 60 秒将丢弃,如果延迟超过 3 秒将打印 log

* 可用的 Gbt 消息,将以 gbtTime+isEmptyBlock+height 来构造 key 写入本地 Map ,另 gbtHash 也会写入本地队列

* 本地 gbtHash 队列仅保存最近 20 条,本地 gbtMap 中 Gbt 消息有效期:非空 Gbt 有效期 90 秒,空 Gbt 有效期 15 秒,过期将清除

    * 有效期可从配置文件中指定

* Gbt 消息如果高度低于本地 Gbt 高度,且本地 Gbt 非空,且与本地时间间隔没超过 2 倍 stratumJobInterval_ , Gbt 消息将丢弃

* 三种情况下将立即向 kafka 发送 StratumJob :

    * 高度大于本地高度(即已发现新块)

    * 高度与本地高度相同,但前个 Job 为空块 Job ,但新 Gbt 非空块

    * 达到预定的时间间隔 20 秒(可从配置文件中指定)

 

### ③ sserver

 

* 接收的 job 延迟超过 60 秒将丢弃

* 如果 job 中 prevHash 与本地 job 中 prevHash 不同,即为已产生新块, job 中 isClean 状态将置为 true

    * true 即要求矿机立即切换 job

* 三种情况下将向矿机下发新 job :

    * 收到新高度的 job

    * 过去一个 job 为新高度且为空块 job ,且最新 job 为非空块 job

    * 达到预定的时间间隔 30 秒

* 最近一次下发 job 的时间将写入文件(由 file_last_notify_time 指定)

* 本地 job 有效期为 300 秒

* 每 10 秒拉取一次新用户列表(由 list_id_api_url 指定),用户写入本地 map 中

* sserver 最大可用 SessionId 数为 16777214

* btcpool 支持 BtcAgent 扩展协议和 Stratum 协议,使用 magic_number ( 0x7F )区分

* 处理 Stratum 协议:

    * suggest_target 与 suggest_difficulty 等价,用于设置初始挖矿难度,需在 subscribe 之前请求

    * 使用 sessionID 作为 extraNonce1_ 以确保矿机任务不重复

    * authorize 之前有 15 秒读超时, authorize 之后有 10 分钟读超时, 10 分钟无提交将断开连接

    * 初始难度为 16384 ,或从 suggest_difficulty 指定,下次将一次调整到位保持 10s 提交 share

    * 每个 session 会维护一个 localJobs_ 队列,队列长度为 10 条

* share 被拒绝的几种情况:

    * JOB_NOT_FOUND , localJobs_ 队列中该 job 已被挤出

    * DUPLICATE_SHARE , share 已提交过,已提交的 share 会计入 submitShares_

    * JOB_NOT_FOUND , jobRepository_ 中 job 不存在,即 job 已过期( 300 秒过期时间)

    * JOB_NOT_FOUND , jobRepository_ 中 job 状态为 Stale ,即 job 是旧的非新 job

    * TIME_TOO_OLD , share 中提交的 nTime 小于 job 规定的 minTime

    * TIME_TOO_OLD , share 中提交的 nTime 比当前时间大 10 分钟

    * LOW_DIFFICULTY , share 中提交的 hash 不满足难度目标

* 处理 BtcAgent 扩展协议:

    * Agent 下矿机默认难度也为 16384

    * 使用 Agent sessionID 作为 extraNonce2_ 前半部分,以确保 Agent 下矿机任务不重复

    * 矿池下发新任务时,如 session 为 BtcAgent ,将为 Agent 下所有矿机计算难度

        * 如难度发生变更,将按难度不同,分别构造多条 CMD_MINING_SET_DIFF 指令一并下发处理

 

### ④ blkmaker

 

* blkmaker 可以连多个 bitcoind 节点

* blkmaker 监听和接收 4 类消息: RAWGBT 、 STRATUM_JOB 、 SOLVED_SHARE 和 NMC_SOLVED_SHARE

* 监听 RAWGBT 目的为获取 gbtHash/ 交易列表,用于构建 Block , gbtHash 和 vtxs 写入 rawGbtMap_

    * rawGbtMap_ 保存最近 100 条 gbtHash/vtxs 对

* 监听 STRATUM_JOB 目的为获取 jobId_/gbtHash , jobId_ 和 gbtHash 写入 jobId2GbtHash_

    * jobId2GbtHash_ 保存最近 120 条 jobId_/gbtHash 对

* 监听 SOLVED_SHARE 目的为获取 BlockHeader 和 coinbaseTx

    * BlockHeader+coinbaseTx+vtxs 构造 Block

* 构造好的 Block 会提交连接的所有 bitcoind 节点

* 构造好的 Block 入库,入库字段包括:

    * puid 、 worker_id 、 worker_full_name 、 job_id 、 height 、 hash

    * rewards (即 coinbaseValue )、 size (即 blksize )、 prev_hash 、 bits 、 version 、 created_at

    * created_at 为入库时间非爆块时间

    

### ⑤ sharelogger

 

* 接收 SHARE_LOG ,写入 shares_ ,每 2 秒写入文件(路径由 data_dir 指定)

    * 每天一个新文件,文件名形如: sharelog-2016-07-12.bin

    * 最多维护最近 3 天的文件句柄

 

### ⑥ slparser

 

* 支持三种功能:

    * 指定 Date 和 UID ,将打印指定日期指定用户的 share 信息到 stdout

        * UID=0 时,将打印指定日期所有用户的 share 信息

    * 指定 Date 但未指定 UID ,读取指定日期 sharelog ,统计数据并写入数据库

        * 按 Worker 、 user 、 pool 三个维度统计 :Accept1h 、 Accept1d 、 score1h 、 score1d 、 Reject1h 、 Reject1d

        * 数据库仅保留最近 3 个月统计数据

    * 如果 Date 和 UID 均未指定,将监听文件变化,读取 share 并统计数据,每 15 秒写入数据库

        * 同时启动 Httpd 服务,开放 ServerStatus 和 WorkerStatus

 

### ⑦ statshttpd

 

* 监听并接收 SHARE_LOG ,按 Worker 、 user 、 pool 统计 acceptCount_ 、 acceptShareSec_ 、 rejectShareMin_

    * 同时统计 totalWorkerCount_ 和 totalUserCount_

    * 延时超过 1 小时的 SHARE_LOG 将被忽略

* 每 15s 写入数据库(可由 flush_db_interval 指定),每 30 分钟清理过期 Worker

    * 如果 Worker 超过 1 小时未提交 share ,将被置为过期状态

    * 计算每个 Worker 的 accept1m_ 、 accept5m_ 、 accept15m_ 、 reject15m_ 、 accept1h_ 、 reject1h_

        * 以及 acceptCount_ 、 lastShareIP_ 、 lastShareTime_

    * DROP 并 CREATE 数据表 mining_workers_tmp , Worker 统计数据批量写入 mining_workers_tmp

    * mining_workers_tmp 数据写入数据表 mining_workers

* 监听并接收 COMMON_EVENTS ,获取 workerName 和 minerAgent ,更新数据表 mining_workers

* 启动 Httpd 服务,开放 ServerStatus 和 WorkerStatus

 

### ⑧ poolwatcher

 

* 监听 StratumJob ,更新 poolStratumJob_ ,用于和第三方矿池比对

* 作为 client 连接第三方矿池,如收到挖矿任务,仅当接收的 job 高度 = 本地矿池 job 高度 +1 时,将构造 EmptyGBT

* 如下几种情况将丢弃从第三方矿池接收的 job :

    * job 高度与本地矿池 job 高度相同

    * job 高度不等于本地矿池 job 高度 +1 ,高度跳跃太大

    * nBits 与本地矿池 job nBits 不同


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/31557831/viewspace-2216547/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2018-10-11

  • 博文量
    79
  • 访问量
    59481