区块链网站|NFTS BTC教学指南 兄弟公司区块链教程btcpool矿池源代码分析StratumServer模块分析

兄弟公司区块链教程btcpool矿池源代码分析StratumServer模块分析

广告位

兄弟连区块链教程btcpool矿池源码分析StratumServer模块解析

兄弟公司区块链教程btcpool矿池源代码分析StratumServer模块分析。2018年下半年,区块链行业正逐渐褪去浮躁,回归发展之初的理性。表面上看,相关人才的需求和价值似乎在回落。但事实上,正是最初泡沫的逐渐消退,才让人们更加关注区块链的真正技术。

# btcpool矿池-StratumServer模块分析

# #核心机制概述

*接收到的延迟超过60秒的作业将被丢弃。

*如果作业中的prevHash与本地作业中的prevHash不同,则已生成新块,并且作业中的isClean状态将设置为true。

* true要求采掘机立即切换作业。

*在三种情况下,一个新的作业将被发布给矿机:

*收到新高度的作业

*过去的工作是新的高度和空的工作,最新的工作是非空的工作。

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

*最后一次发出作业的时间将被写入文件(由file_last_notify_time指定)。

*本地作业的有效期为300秒。

*每10秒拉一次新用户列表(由list_id_api_url指定),用户将其写入本地映射。

* s服务器的最大可用SessionId是16777214。

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

*处理地层协议:

* suggest_target相当于suggest _ difference,用来设置初始挖掘难度。它需要在订阅前请求。

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

*授权前15秒、授权后10分钟以及10分钟未提交将断开连接。

*初始难度为16384,或者从suggest _ difference中指定。下次调整到位10s,提交分享。

*每个会话将维护一个队列长度为10的本地作业队列。

*共享被拒绝的几种情况:

* JOB_NOT_FOUND,localJobs_ queue中的作业已被挤出。

* DUPLICATE_SHARE,共享已提交,提交的共享核算包含在submitShares中_

* JOB_NOT_FOUND,jobRepository_中的作业不存在,即作业已过期(过期时间为300秒)

* JOB_NOT_FOUND,jobRepository_中作业的状态是陈旧的,即该作业是旧的而不是新的。

* TIME_TOO_OLD,共享中提交的时间小于作业指定的时间。

* TIME_TOO_OLD,提交的共享时间比当前时间大10分钟。

* LOW _ cavity,share中提交的hash不符合难度目标。

*处理BtcAgent扩展协议:

*代理下矿机默认难度也是16384。

*使用Agent sessionID作为extraNonce2_的前半部分,保证Agent下的挖机任务不重复。

*当矿池发布新任务时,如BtcAgent for session,将为代理下的所有矿机计算难度。

*如果难度发生变化,将根据难度的不同构造多个CMD_MINING_SET_DIFF指令,并一起发出和处理。

## StratumServer命令使用

“贝壳

sserver -c sserver.cfg -l log_dir

#-c指定服务器配置文件

#-l指定日志目录

“`

## sserver.cfg配置文件

“贝壳

//是否使用testnet

testnet=true

//kafka集群

卡夫卡={

经纪人=\’1.1.1.1:9092,2.2.2:9092,3 . 3 . 3:9092 \’;

};

//服务器配置

sserver={

//IP和端口

IP=\’ 0 . 0 . 0 . 0 \’;

端口=3333;

//服务器id,全局唯一,取值范围[1,255]

id=1;

//最后一次挖掘通知时间写入文件进行监控。

file _ last _ notify _ time=\’/work/XXX/s server _ last notify time . txt \’;

//如果模拟器被启用,所有共享都被接受进行测试。

enable _ simulator=false

//如果启用,所有共享都将被分块并提交进行测试。

enable _ submit _ invalid _ block=false;

//两次股份提交之间的时间间隔

share _ avg _ seconds=10

};

用户={

//用户列表api

list _ id _ API _ URL=\’ example . com/get _ user _ id _ list \’;

};

“`

##已解决_分享消息

` ` c

if(isSubmitInvalidBlock _==true | | bnBlockHash=bnNetworkTarget){

//

//生成找到的块

//

FoundBlock foundBlock

found block . jobid _=share . jobid _;

foundblock . workerid _=share . worker hashid _;

found block . userid _=share . userid _;

foundblock . height _=sjob-height _;

memcpy(foundBlock.header80_,(const uint8_t *)header,sizeof(CBlockHeader));

snprintf(foundblock . worker full name _,sizeof(foundblock . worker full name _),

“%s”,work full name . c _ str());

//发送

sendsolvedshare 2卡夫卡(foundBlock,coin basebin);

//将作业标记为过时

作业存储库_-markAllJobsAsStale();

\”日志(信息)\”找到一个新块:“blkHash .ToString()

,jobId: \’ share.jobId_ \’,userId: \’ share.userId_

,由:\”工作全名\”;

}

“`

## 计算挖矿难度

` ` c

//构造函数

//kMinDiff_为最小难度,静态常数uint64 kMinDiff _=64

//kMaxDiff_为最大难度,静态常数uint 64 kMaxDiff _=4611686018427387904 ull;

//kDefaultDiff_为默认初始难度,静态常量uint64 kDefaultDiff _=16384

//kDiffWindow_为普通个分享的时间窗口,静态常数time _ t kDiffWindow _=900

//kRecordSeconds_为一个分享的时间,静态常数time _ t kRecordSeconds _=10

//sharesNum_和股份_初始值均为90

差分控制器(const int 32 _ t shareAvgSeconds):

startTime_(0),

minDiff_(kMinDiff_),curDiff_(kDefaultDiff_),curHashRateLevel_(0),

股份数量_(kDiffWindow _/kRecordSeconds _),/*每隔普通秒作为一条记录*/

shares _(kDiffWindow _/kRecordSeconds _)

{

if(shareAvgSeconds=1 shareAvgSeconds=60){

shareAvgSeconds _=shareAvgSeconds;

}否则{

shareAvgSeconds _=8;

}

}

//代码btcpool/src/StratumSession.h

//计算挖矿难度

//不低于最小难度64

uint 64差分控制器:calcCurDiff(){

uint 64 diff=_ calcCurDiff();

if (diff minDiff_) {

diff=minDiff _;

}

返回差异;

}

uint 64差分控制器:_ calcCurDiff(){

const time _ t now=time(nullptr);

const int 64k=now/kRecordSeconds _;

const double股数=(double)股数\\总和(k)和:

如果(startTime_==0) { //第一次,我们设置开始时间

开始时间_=时间(空指针);

}

常数double kRateHigh=1.40

常数double kRateLow=0.40

//时间窗口(900秒)内预期的分享数

double预期计数=round(kDiffWindow _/(double)shareAvgSeconds _);

//return now=start time _ kDiffWindow _;

if (isFullWindow(now)) { /*现在有一个完整的窗口*/

//大型矿商有较大预期股份数,使其看起来更平稳。

期望计数*=miner系数(现在,k);

}

if (expectedCount kDiffWindow_) {

//最多一秒提交一个,预期分享数最大为900

预期计数=kDiffWindow _;//每股一秒就够了

}

//这是用于非常低哈希速率的矿工,例如通用串行总线矿工

//应该每60秒收到至少一个共享

//非完整时间窗口、且时间已超过60年代提交的分享数小于(60秒一个)、当前难度大于或等于2倍最小难度

//此时降低难度为之前1/2

如果(!isFullWindow(now)now=开始时间_ 60

股份计数=(int 32 _ t)((现在开始时间_)/60.0)

curDiff_=minDiff_*2) {

setCurDiff(curDiff _/2);

sharesNum_ .地图乘法(2.0);

返回curDiff _;

}

//太快了

//如果提交分享数超过预期数的1.4倍时

if(股份计数预期计数* krate高){

//如果分享数大于预期分享数,且当前难度最大难度时,提升难度为原来2倍

while (sharesNum_ .总和(千)预期计数

curDiff_ kMaxDiff_) {

setCurDiff(curDiff _ * 2);

sharesNum_ .mapDivide(2.0);//共享数/2

}

返回curDiff _;

}

//太慢

//如果是完整时间窗口,且当前难度大于或等于2被最小难度

if(is full window(now)curDiff _=minDiff _ * 2){

//如果分享数低于预期数的0.4,且当前难度大于或等于2倍最小难度,降低难度为原来的1/2

while (sharesNum_ .sum(k) expectedCount * kRateLow

curDiff_=minDiff_*2) {

setCurDiff(curDiff _/2);

sharesNum_ .地图乘法(2.0);//共享数乘2

}

assert(curDiff _=minDiff _);

返回curDiff _;

}

返回curDiff _;

}

“`

##服务器校验分享的机制

“贝壳

//本地工作列表本地作业_最多保留最近10条任务,如有新任务,将挤出一条老任务。如果分享所对应的工作未在本地列表中,将StratumError:JOB_NOT_FOUND

//本地分享列表提交股份_中,如果已有本条分享,即重复,将StratumError:DUPLICATE_SHARE

//校验分享不通过

//作业列表exJobs_没有找到作业,exJobs_中工作有300秒过期时间,过期将删除,报StratumError:JOB_NOT_FOUND

//共享中nTime小于工作的最小时间,过老,报StratumError:TIME_TOO_OLD

//共享中nTime超过工作中的时间10分钟分钟,过新,报StratumError:TIME_TOO_NEW

//区块哈希工作难度目标,不合格,报StratumError:低_难度

“`

##服务器下发新工作的机制

1、如果收到新高度状态作业,将立即下发新工作

` ` c

bool isClean=false

if (latestPrevBlockHash_!=sjob-prevHash_) {

isClean=true

latestPrevBlockHash _=sjob-prev hash _;

日志(信息)\”收到新的高度状态作业,高度:\” sjob-height_

,prevhash: \’ sjob-prevHash_ .ToString();

}

shared _ ptrStratumJobEx job=STD:make _ sharedStratumJobEx(sjob,is clean);

{

范围锁sl(lock _);

if (isClean) {

//将所有作业标记为过时,应该在插入新作业之前这样做

for (auto it : exJobs_) {

它。second-mark stale();

}

}

//插入新作业

ex jobs _[sjob-jobId _]=ex job;

}

if (isClean) {

sendMiningNotify(ex job);

返回;

}

“`

2、如果过去一个工作为新高度且为空块工作,并且最新工作非空块工作,将尽快下发新工作

“`

if (isClean==false exJobs_ .size()=2) {

auto itr=exJobs_ .Rb egin();

shared _ ptrStratumJobEx job 1=itr-second;

itr

shared _ ptrStratumJobEx job 2=itr-second;

if (exJob2-isClean_==true

exJob2-sjob_-merkleBranch_ .size()==0

exJob1-sjob_-merkleBranch_ .size()!=0) {

sendMiningNotify(ex job);

}

}

“`

3、每超过一定时间间隔(30秒),将下发新工作

“`

void作业资料档案库:checkAndSendMiningNotify(){

//上一个作业已\”完成\”,发送一个新作业

if (exJobs_ .大小()

lastJobSendTime _ kminingotifyinterval _=time(空指针))

{

shared _ ptrStratumJobEx job=ex jobs _ .Rb egin()-秒;

sendMiningNotify(ex job);

}

}

job repository:job repository(const char * kafkaBrokers,

常量字符串fileLastNotifyTime,

服务器*服务器):

跑步_(真),

kafkaConsumer_(kafkaBrokers,KAFKA_TOPIC_STRATUM_JOB,0/* partition */),

服务器_(服务器),文件最后通知时间_(文件最后通知时间),

kMaxJobsLifeTime_(300),

kminingotifyinterval _(30),//TODO: make as config arg

lastJobSendTime_(0)

{

assert(kminingotifyinterval _ kMaxJobsLifeTime _);

}

“`

广告位
本文来自网络,不代表区块链网站|NFTS立场,转载请注明出处:https://www.qklwz.com/btb/btbjiaoxue/18337.html
上一篇
下一篇

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

返回顶部