兄弟連區塊鏈教程open-ethereum-pool礦池源碼分析unlocker模組

來源:互聯網
上載者:User

標籤:pow   defer   turn   pre   write   tin   maxheight   rds   ble   

兄弟連區塊鏈教程open-ethereum-pool以太坊礦池源碼分析unlocker模組
open-ethereum-pool以太坊礦池-unlocker模組

unlocker模組配置

json
"unlocker": {
????"enabled": false,
????"poolFee": 1.0,
????"poolFeeAddress": "",
????"donate": true,
????"depth": 120,
????"immatureDepth": 20,
????"keepTxFees": false,
????"interval": "10m",
????"daemon": "http://127.0.0.1:8545",
????"timeout": "10s"
},

BlockUnlocker定義

go
type BlockUnlocker struct {
????config UnlockerConfig
????backend
storage.RedisClient
????rpc *rpc.RPCClient
????halt bool
????lastFail error
}

unlocker流程圖GetCandidates原理

go
func (r RedisClient) GetCandidates(maxHeight int64) ([]BlockData, error) {
????//ZRANGEBYSCORE eth:blocks:candidates 0 maxHeight WITHSCORES
????option := redis.ZRangeByScore{Min: "0", Max: strconv.FormatInt(maxHeight, 10)}
????cmd := r.client.ZRangeByScoreWithScores(r.formatKey("blocks", "candidates"), option)
????if cmd.Err() != nil {
????????return nil, cmd.Err()
????}
????return convertCandidateResults(cmd), nil
}

func convertCandidateResults(raw redis.ZSliceCmd) []BlockData {
????var result []*BlockData
????for , v := range raw.Val() {
????????// "nonce:powHash:mixDigest:timestamp:diff:totalShares"
????????block := BlockData{}
????????block.Height = int64(v.Score)
????????block.RoundHeight = block.Height
????????fields := strings.Split(v.Member.(string), ":")
????????block.Nonce = fields[0]
????????block.PowHash = fields[1]
????????block.MixDigest = fields[2]
????????block.Timestamp,
= strconv.ParseInt(fields[3], 10, 64)
????????block.Difficulty, = strconv.ParseInt(fields[4], 10, 64)
????????block.TotalShares,
= strconv.ParseInt(fields[5], 10, 64)
????????block.candidateKey = v.Member.(string)
????????result = append(result, &block)
????}
????return result
}

writeImmatureBlock原理

go
//Immature即未成年
func (r RedisClient) writeImmatureBlock(tx redis.Multi, block *BlockData) {
????// Redis 2.8.x returns "ERR source and destination objects are the same"
????if block.Height != block.RoundHeight {
????????//RENAME eth:shares:candidates:round&RoundHeight:nonce eth:shares:candidates:round&blockHeight:nonce
????????tx.Rename(r.formatRound(block.RoundHeight, block.Nonce), r.formatRound(block.Height, block.Nonce))
????}
????
????//Zrem 命令用於移除有序集中的一個或多個成員,不存在的成員將被忽略
????//candidates為候選者
????//ZREM eth:blocks:candidates nonce:powHash:mixDigest:timestamp:diff:totalShares
????tx.ZRem(r.formatKey("blocks", "candidates"), block.candidateKey)
????
????//ZADD eth:blocks:immature block.Height UncleHeight:Orphan:Nonce:serializeHash:Timestamp:Difficulty:TotalShares:Reward
????tx.ZAdd(r.formatKey("blocks", "immature"), redis.Z{Score: float64(block.Height), Member: block.key()})
}

func (b *BlockData) key() string {
????return join(b.UncleHeight, b.Orphan, b.Nonce, b.serializeHash(), b.Timestamp, b.Difficulty, b.TotalShares, b.Reward)
}

WriteImmatureBlock原理

go
func (r RedisClient) WriteImmatureBlock(block BlockData, roundRewards map[string]int64) error {
????tx := r.client.Multi()
????defer tx.Close()

????_, err := tx.Exec(func() error {
????????//寫入未成年塊,目的何在?
????????//補充unlockPendingBlocks()階段,均寫入未成年塊
????????r.writeImmatureBlock(tx, block)
????????total := int64(0)
????????//遍曆roundRewards
????????for login, amount := range roundRewards {
????????????//求和
????????????total += amount
????????????//Hincrby 命令用於為雜湊表中的欄位值加上指定增量值
????????????//HINCRBY eth:miners:login immature amount
????????????tx.HIncrBy(r.formatKey("miners", login), "immature", amount)
????????????
????????????//HSETNX eth:credits:immature:Height:Hash login amount
????????????//Hsetnx 命令用於為雜湊表中不存在的的欄位賦值
????????????tx.HSetNX(r.formatKey("credits", "immature", block.Height, block.Hash), login, strconv.FormatInt(amount, 10))
????????}
????????
????????//Hincrby 命令用於為雜湊表中的欄位值加上指定增量值
????????//HINCRBY eth:finances:immature total
????????tx.HIncrBy(r.formatKey("finances"), "immature", total)
????????return nil
????})
????return err
}

GetImmatureBlocks原理
func (r *RedisClient) GetImmatureBlocks(maxHeight int64) ([]*BlockData, error) {????option := redis.ZRangeByScore{Min: "0", Max: strconv.FormatInt(maxHeight, 10)}????cmd := r.client.ZRangeByScoreWithScores(r.formatKey("blocks", "immature"), option)????if cmd.Err() != nil {????????return nil, cmd.Err()????}????return convertBlockResults(cmd), nil}func convertBlockResults(rows ...*redis.ZSliceCmd) []*BlockData {????var result []*BlockData????for _, row := range rows {????????for _, v := range row.Val() {????????????// "uncleHeight:orphan:nonce:blockHash:timestamp:diff:totalShares:rewardInWei"????????????block := BlockData{}????????????block.Height = int64(v.Score)????????????block.RoundHeight = block.Height????????????fields := strings.Split(v.Member.(string), ":")????????????block.UncleHeight, _ = strconv.ParseInt(fields[0], 10, 64)????????????block.Uncle = block.UncleHeight > 0????????????block.Orphan, _ = strconv.ParseBool(fields[1])????????????block.Nonce = fields[2]????????????block.Hash = fields[3]????????????block.Timestamp, _ = strconv.ParseInt(fields[4], 10, 64)????????????block.Difficulty, _ = strconv.ParseInt(fields[5], 10, 64)????????????block.TotalShares, _ = strconv.ParseInt(fields[6], 10, 64)????????????block.RewardString = fields[7]????????????block.ImmatureReward = fields[7]????????????block.immatureKey = v.Member.(string)????????????result = append(result, &block)????????}????}????return result}## WriteOrphan原理func (r *RedisClient) WriteOrphan(block *BlockData) error {????creditKey := r.formatKey("credits", "immature", block.RoundHeight, block.Hash)????tx, err := r.client.Watch(creditKey)????// Must decrement immatures using existing log entry????immatureCredits := tx.HGetAllMap(creditKey)????if err != nil {????????return err????}????defer tx.Close()????_, err = tx.Exec(func() error {????????r.writeMaturedBlock(tx, block)????????// Decrement immature balances????????totalImmature := int64(0)????????for login, amountString := range immatureCredits.Val() {????????????amount, _ := strconv.ParseInt(amountString, 10, 64)????????????totalImmature += amount????????????tx.HIncrBy(r.formatKey("miners", login), "immature", (amount * -1))????????}????????tx.Del(creditKey)????????tx.HIncrBy(r.formatKey("finances"), "immature", (totalImmature * -1))????????return nil????})????return err}func (r *RedisClient) writeMaturedBlock(tx *redis.Multi, block *BlockData) {tx.Del(r.formatRound(block.RoundHeight, block.Nonce))tx.ZRem(r.formatKey("blocks", "immature"), block.immatureKey)tx.ZAdd(r.formatKey("blocks", "matured"), redis.Z{Score: float64(block.Height), Member: block.key()})}

兄弟連區塊鏈教程open-ethereum-pool礦池源碼分析unlocker模組

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.