兄弟连Go语言培训openethereumpool以太坊矿池源码分析6proxy模块.docx
- 文档编号:16779349
- 上传时间:2023-07-17
- 格式:DOCX
- 页数:18
- 大小:174.76KB
兄弟连Go语言培训openethereumpool以太坊矿池源码分析6proxy模块.docx
《兄弟连Go语言培训openethereumpool以太坊矿池源码分析6proxy模块.docx》由会员分享,可在线阅读,更多相关《兄弟连Go语言培训openethereumpool以太坊矿池源码分析6proxy模块.docx(18页珍藏版)》请在冰点文库上搜索。
兄弟连Go语言培训openethereumpool以太坊矿池源码分析6proxy模块
兄弟连Go语言培训open-ethereum-pool以太坊矿池源码分析(6)proxy模块
#open-ethereum-pool以太坊矿池-proxy模块
##ProxyServer定义
```go
type ProxyServer struct {
config*Config
blockTemplateatomic.Value
upstream int32
upstreams[]*rpc.RPCClient
backend*storage.RedisClient
diff string
policy*policy.PolicyServer
hashrateExpirationtime.Duration
failsCount int64
//Stratum
sessionsMusync.RWMutex
sessions map[*Session]struct{}
timeouttime.Duration
}
```
##BlockTemplate定义
```go
type BlockTemplate struct {
sync.RWMutex
Header string
Seed string
Target string
Difficulty*big.Int
Height uint64
GetPendingBlockCache*rpc.GetBlockReplyPart
nonces map[string]bool
headers map[string]heightDiffPair
}
type heightDiffPair struct {
diff*big.Int
height uint64
}
```
##以太坊Pow算法原理
```
//以太坊Pow算法可以表示为如下公式:
//RAND(h,n)<=M/d
//其中RAND()表示一个概念函数,代表一系列的复杂运算。
其中h和n为输入,即区块Header的哈希、以及Header中的Nonce。
//M表示一个极大的数,此处使用2^256-1。
d,为区块难度,即Header中的Difficulty。
//因此在h和n确定的情况下,d越大,挖矿难度越大,即为Difficulty本义。
即不断变更Nonce,使RAND(h,n)满足RAND(h,n)<=M/d,即完成Pow。
```
##NewProxy流程图
##ProxyServerStart流程图
##eth_submitWork处理流程图
即:
processShare()
##WriteNodeState原理
```go
//cfg.Proxy.StateUpdateInterval为WriteNodeState定时器,时间为3s
//调取:
err:
=backend.WriteNodeState(cfg.Name,t.Height,t.Difficulty)
func (r*RedisClient)WriteNodeState(id string,height uint64,diff*big.Int) error {
tx:
=r.client.Multi()
defer tx.Close()
now:
=util.MakeTimestamp()/ 1000
_,err:
=tx.Exec(func() error {
//HSETeth:
nodes:
main:
namemain
tx.HSet(r.formatKey("nodes"),join(id, "name"),id)
//HSETeth:
nodes:
main:
heightheight
tx.HSet(r.formatKey("nodes"),join(id, "height"),strconv.FormatUint(height, 10))
//HSETeth:
nodes:
main:
difficultydifficulty
tx.HSet(r.formatKey("nodes"),join(id, "difficulty"),diff.String())
//HSETeth:
nodes:
main:
lastBeatnow
tx.HSet(r.formatKey("nodes"),join(id, "lastBeat"),strconv.FormatInt(now, 10))
return nil
})
return err
}
```
##WriteBlock原理
```go
//调取:
exist,err:
=s.backend.WriteBlock(login,id,params,shareDiff,h.diff.Int64(),h.height,s.hashrateExpiration)
//s.hashrateExpiration即cfg.Proxy.HashrateExpiration,为3h,即TTL(生命周期)forworkersstats,通常等于hashrateLargeWindow
func (r*RedisClient)WriteBlock(login,id string,params[]string,diff,roundDiff int64,height uint64,windowtime.Duration)(bool, error){
//写入eth:
pow中,并检查是否已存在
exist,err:
=r.checkPoWExist(height,params)
if err!
= nil {
return false,err
}
//Duplicateshare,(nonce,powHash,mixDigest)pairexist
//已存在
if exist{
return true, nil
}
tx:
=r.client.Multi()
defer tx.Close()
ms:
=util.MakeTimestamp()
ts:
=ms/ 1000 //转换成秒
cmds,err:
=tx.Exec(func() error {
//调取writeShare
r.writeShare(tx,ms,ts,login,id,diff,window)
//HSETeth:
statslastBlockFoundts
//Hset命令用于为哈希表中的字段赋值
tx.HSet(r.formatKey("stats"), "lastBlockFound",strconv.FormatInt(ts, 10))
//HDELeth:
statsroundShares
//Hdel命令用于删除哈希表key中的一个或多个指定字段,不存在的字段将被忽略
tx.HDel(r.formatKey("stats"), "roundShares")
//ZINCRBYeth:
finders1login
//Zincrby命令对有序集合中指定成员的分数加上增量increment
tx.ZIncrBy(r.formatKey("finders"), 1,login)
//HINCRBYeth:
miners:
loginblocksFound1
//Hincrby命令用于为哈希表中的字段值加上指定增量值
tx.HIncrBy(r.formatKey("miners",login), "blocksFound", 1)
//RENAMEeth:
shares:
roundCurrenteth:
shares:
round&height:
nonce
//Rename命令用于修改key的名称
tx.Rename(r.formatKey("shares", "roundCurrent"),r.formatRound(int64(height),params[0]))
//HGETALLeth:
shares:
round&height:
nonce
//Hgetall命令用于返回哈希表中,所有的字段和值
tx.HGetAllMap(r.formatRound(int64(height),params[0]))
return nil
})
if err!
= nil {
return false,err
} else {
//HGETALLeth:
shares:
round&height:
nonce
//Hgetall命令用于返回哈希表中,所有的字段和值
sharesMap,_:
=cmds[10].(*redis.StringStringMapCmd).Result()
totalShares:
=int64(0)
for _,v:
= range sharesMap{
n,_:
=strconv.ParseInt(v, 10, 64)
totalShares+=n
}
//nonce、powHash、mixDigest
hashHex:
=strings.Join(params, ":
")
//MakeTimestamp、h.diff、totalShares
s:
=join(hashHex,ts,roundDiff,totalShares)
//ZADDeth:
blocks:
candidatesheightnonce:
powHash:
mixDigest:
MakeTimestamp:
h.diff:
totalShares
//Zadd命令用于将一个或多个成员元素及其分数值加入到有序集当中
//candidates为候选者
cmd:
=r.client.ZAdd(r.formatKey("blocks", "candidates"),redis.Z{Score:
float64(height),Member:
s})
return false,cmd.Err()
}
}
func (r*RedisClient)checkPoWExist(height uint64,params[]string)(bool, error){
//SweepPoWbacklogforpreviousblocks,wehave3templatesbackinRAM
//扫描积压的前块
//ZREMRANGEBYSCOREeth:
pow-inf(height-8
//Zremrangebyscore命令用于移除有序集中,指定分数(score)区间内的所有成员
r.client.ZRemRangeByScore(r.formatKey("pow"), "-inf",fmt.Sprint("(",height-8))
//ZADDeth:
powheightparams
//Zadd命令用于将一个或多个成员元素及其分数值加入到有序集当中
val,err:
=r.client.ZAdd(r.formatKey("pow"),redis.Z{Score:
float64(height),Member:
strings.Join(params, ":
")}).Result()
return val== 0,err
}
```
##WriteShare原理
```go
func (r*RedisClient)WriteShare(login,id string,params[]string,diff int64,height uint64,windowtime.Duration)(bool, error){
//ZADDeth:
powheightparams
//写入eth:
pow中,并检查是否已存在
exist,err:
=r.checkPoWExist(height,params)
if err!
= nil {
return false,err
}
//Duplicateshare,(nonce,powHash,mixDigest)pairexist
//已存在
if exist{
return true, nil
}
tx:
=r.client.Multi()
defer tx.Close()
ms:
=util.MakeTimestamp()
ts:
=ms/ 1000
_,err=tx.Exec(func() error {
r.writeShare(tx,ms,ts,login,id,diff,window)
//HINCRBYeth:
statsroundSharesdiff
//Hincrby命令用于为哈希表中的字段值加上指定增量值
tx.HIncrBy(r.formatKey("stats"), "roundShares",diff)
return nil
})
return false,err
}
func (r*RedisClient)writeShare(tx*redis.Multi,ms,ts int64,login,id string,diff int64,expiretime.Duration){
//HINCRBYeth:
shares:
roundCurrentlogindiff
//Hincrby命令用于为哈希表中的字段值加上指定增量值
tx.HIncrBy(r.formatKey("shares", "roundCurrent"),login,diff)
//ZADDeth:
hashratetsdiff:
login:
id:
ms
//Zadd命令用于将一个或多个成员元素及其分数值加入到有序集当中
tx.ZAdd(r.formatKey("hashrate"),redis.Z{Score:
float64(ts),Member:
join(diff,login,id,ms)})
//ZADDeth:
hashrate:
logintsdiff:
login:
id:
ms
tx.ZAdd(r.formatKey("hashrate",login),redis.Z{Score:
float64(ts),Member:
join(diff,id,ms)})
//EXPIREeth:
hashrate:
loginexpire
//expire即cfg.Proxy.HashrateExpiration,即3小时
tx.Expire(r.formatKey("hashrate",login),expire) //Willdeletehashratesforminersthatgone
//HSETeth:
miners:
loginlastSharets
//Hset命令用于为哈希表中的字段赋值
tx.HSet(r.formatKey("miners",login), "lastShare",strconv.FormatInt(ts, 10))
}
```
##StratumMiningProtocol
###eth_submitLogin
```json
//Request
{
"id":
1,
"jsonrpc":
"2.0",
"method":
"eth_submitLogin",
"params":
["0xb85150eb365e7df0941f0cf08235f987ba91506a"]
}
//或
{
"id":
1,
"jsonrpc":
"2.0",
"method":
"eth_submitLogin",
"params":
["0xb85150eb365e7df0941f0cf08235f987ba91506a", "admin@"]
}
//Successfulresponse
{ "id":
1, "jsonrpc":
"2.0", "result":
true }
//{"id":
1,"jsonrpc":
"2.0","result":
null,"error":
{code:
-1,message:
"Invalidlogin"}}
```
###eth_getWork
```json
//Request
{ "id":
1, "jsonrpc":
"2.0", "method":
"eth_getWork" }
//Successfulresponse
{
"id":
1,
"jsonrpc":
"2.0",
"result":
[
"0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
"0x5eed00000000000000000000000000005eed0000000000000000000000000000",
"0xd1ff1c01710000000000000000000000d1ff1c01710000000000000000000000"
]
}
//Exceptions
{ "id":
10, "result":
null, "error":
{ code:
0, message:
"Worknotready" }}
```
###NewJobNotification
```json
//NewJobNotification
{
"jsonrpc":
"2.0",
"result":
[
"0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
"0x5eed00000000000000000000000000005eed0000000000000000000000000000",
"0xd1ff1c01710000000000000000000000d1ff1c01710000000000000000000000"
]
}
```
###eth_submitWork
```json
//Request
{
"id":
1,
"jsonrpc":
"2.0",
"method":
"eth_submitWork",
"params":
[
"0xe05d1fd4002d962f",
"0x6c872e2304cd1e64b553a65387d7383470f22331aff288cbce5748dc430f016a",
"0x2b20a6c641ed155b893ee750ef90ec3be5d24736d16838b84759385b6724220d"
]
}
//Response
{ "id":
1, "jsonrpc":
"2.0", "result":
true }
{ "id":
1, "jsonrpc":
"2.0", "result":
false }
//Exceptions
{ "id":
1, "jsonrpc":
"2.0", "result":
null, "error":
{ code:
23, message:
"Invalidshare" }}
{ "id":
1, "jsonrpc":
"2.0", "result":
null, "error":
{ code:
22, message:
"Duplicateshare" }}
{ "id":
1, "jsonrpc":
"2.0", "result":
null, "error":
{ code:
-1, message:
"Highrateofinvalidshares" }}
{ "id":
1, "jsonrpc":
"2.0", "result":
null, "error":
{ code:
25, message:
"Notsubscribed" }}
{ "id":
1, "jsonrpc":
"2.0", "result":
null, "error":
{ code:
-1, message:
"MalformedPoWresult" }}
```
###SubmitHashrate
```json
{ "id":
1, "jsonrpc":
"2.0", "result":
true }
```
##GethJavaScriptconsole
```shell
//getBlock
>eth.getBlock('pending')
{
author:
"0xdda50d9783dfda1c7ac51c4920f3561e17438be7",
difficulty:
550853386,
extraData:
"0xd5830109048650617269747986312e32342e30826c69",
gasLimit:
4700036,
gasUsed:
3933311,
hash:
"0x6615dc650abc2
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 兄弟连 Go 语言 培训 openethereumpool 以太 坊矿池 源码 分析 proxy 模块