兄弟連區塊鏈教程btcpool礦池源碼分析核心機制總結及優化思考
阿新 • • 發佈:2018-10-16
tcp dup 最大 啟動 清除 延時 超時 too 文件名 btcpool礦池-核心機制總結及優化思考
核心機制總結
①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
- 三種情況下將向礦機下發新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協議:
???? 使用sessionID作為extraNonce1_以確保礦機任務不重復
???? authorize之前有15秒讀超時,authorize之後有10分鐘讀超時,10分鐘無提交將斷開連接
???? 初始難度為16384,或從suggest_difficulty指定,下次將一次調整到位保持10s提交share
????* 每個session會維護一個localJobs_隊列,隊列長度為10條 - share被拒絕的幾種情況:
???? JOB_NOT_FOUND,localJobs_隊列中該job已被擠出
???? DUPLICATESHARE,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對 - 監聽STRATUMJOB目的為獲取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
- 接收SHARELOG,寫入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
- 監聽並接收SHARELOG,按Worker、user、pool統計acceptCount、acceptShareSec、rejectShareMin
???? 同時統計totalWorkerCount和totalUserCount
???? 延時超過1小時的SHARE_LOG將被忽略 - 每15s寫入數據庫(可由flush_dbinterval指定),每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不同
兄弟連區塊鏈教程btcpool礦池源碼分析核心機制總結及優化思考