open-ethereum-pool以太坊礦池原始碼分析(3)payouts模組
# open-ethereum-pool以太坊礦池-payouts模組
## PayoutsProcessor定義
```go
type PayoutsProcessor struct {
config *PayoutsConfig
backend *storage.RedisClient
rpc *rpc.RPCClient
halt bool
lastFail error
}
```
## payouts流程圖
![](payouts.png)
## GetPendingPayments原理
```go
func (r *RedisClient) GetPendingPayments() []*PendingPayment {
//ZREVRANGE eth:payments:pending 0 -1 WITHSCORES
raw := r.client.ZRevRangeWithScores(r.formatKey("payments", "pending"), 0, -1)
var result []*PendingPayment
for _, v := range raw.Val() {
// timestamp -> "address:amount"
payment := PendingPayment{}
payment.Timestamp = int64(v.Score)
fields := strings.Split(v.Member.(string), ":")
payment.Address = fields[0]
payment.Amount, _ = strconv.ParseInt(fields[1], 10, 64)
result = append(result, &payment)
}
return result
}
```
## GetPayees原理
```go
func (r *RedisClient) GetPayees() ([]string, error) {
payees := make(map[string]struct{})
var result []string
var c int64
for {
var keys []string
var err error
c, keys, err = r.client.Scan(c, r.formatKey("miners", "*"), 100).Result()
if err != nil {
return nil, err
}
for _, row := range keys {
login := strings.Split(row, ":")[2]
payees[login] = struct{}{}
}
if c == 0 {
break
}
}
for login, _ := range payees {
result = append(result, login)
}
return result, nil
}
```
## LockPayouts原理
```go
func (r *RedisClient) LockPayouts(login string, amount int64) error {
//eth:payments:lock
key := r.formatKey("payments", "lock")
//SETNX eth:payments:lock login:amount 0
//Setnx(SET if Not eXists) 命令在指定的 key 不存在時,為 key 設定指定的值
result := r.client.SetNX(key, join(login, amount), 0).Val()
if !result {
return fmt.Errorf("Unable to acquire lock '%s'", key)
}
return nil
}
```
## UpdateBalance原理
```go
func (r *RedisClient) UpdateBalance(login string, amount int64) error {
tx := r.client.Multi()
defer tx.Close()
ts := util.MakeTimestamp() / 1000
_, err := tx.Exec(func() error {
//Hincrby 命令用於為雜湊表中的欄位值加上指定增量值
//HINCRBY eth:miners:login balance -amount
tx.HIncrBy(r.formatKey("miners", login), "balance", (amount * -1))
//HINCRBY eth:miners:login pending amount
tx.HIncrBy(r.formatKey("miners", login), "pending", amount)
//HINCRBY eth:finances balance -amount
tx.HIncrBy(r.formatKey("finances"), "balance", (amount * -1))
//HINCRBY eth:finances pending amount
tx.HIncrBy(r.formatKey("finances"), "pending", amount)
//ZADD eth:payments:pending ts login:amount
//Zadd 命令用於將一個或多個成員元素及其分數值加入到有序集當中
tx.ZAdd(r.formatKey("payments", "pending"), redis.Z{Score: float64(ts), Member: join(login, amount)})
return nil
})
return err
}
```
## RollbackBalance原理
```go
func (r *RedisClient) RollbackBalance(login string, amount int64) error {
tx := r.client.Multi()
defer tx.Close()
_, err := tx.Exec(func() error {
tx.HIncrBy(r.formatKey("miners", login), "balance", amount)
tx.HIncrBy(r.formatKey("miners", login), "pending", (amount * -1))
tx.HIncrBy(r.formatKey("finances"), "balance", amount)
tx.HIncrBy(r.formatKey("finances"), "pending", (amount * -1))
tx.ZRem(r.formatKey("payments", "pending"), join(login, amount))
return nil
})
return err
}
```
## WritePayment原理
```go
func (r *RedisClient) WritePayment(login, txHash string, amount int64) error {
tx := r.client.Multi()
defer tx.Close()
ts := util.MakeTimestamp() / 1000
_, err := tx.Exec(func() error {
//HINCRBY eth:miners:login pending -amount
tx.HIncrBy(r.formatKey("miners", login), "pending", (amount * -1))
//HINCRBY eth:miners:login paid amount
tx.HIncrBy(r.formatKey("miners", login), "paid", amount)
//HINCRBY eth:finances pending -amount
tx.HIncrBy(r.formatKey("finances"), "pending", (amount * -1))
//HINCRBY eth:finances paid amount
tx.HIncrBy(r.formatKey("finances"), "paid", amount)
//ZADD eth:payments:all ts txHash:login:amount
tx.ZAdd(r.formatKey("payments", "all"), redis.Z{Score: float64(ts), Member: join(txHash, login, amount)})
//ZADD eth:payments:login ts txHash:amount
tx.ZAdd(r.formatKey("payments", login), redis.Z{Score: float64(ts), Member: join(txHash, amount)})
//ZREM eth:payments:pending login:amount
//Zrem 命令 Redis 有序集合(sorted set) Redis Zrem 命令用於移除有序集中的一個或多個成員
tx.ZRem(r.formatKey("payments", "pending"), join(login, amount))
//DEL 命令用於刪除已存在的鍵
//DEL eth:payments:lock
tx.Del(r.formatKey("payments", "lock"))
return nil
})
return err
}
```
網址:http://www.qukuailianxueyuan.io/
欲領取造幣技術與全套虛擬機器資料
區塊鏈技術交流QQ群:756146052 備註:CSDN
尹成學院微信:備註:CSDN
網址:http://www.qukuailianxueyuan.io/
欲領取造幣技術與全套虛擬機器資料
區塊鏈技術交流QQ群:756146052 備註:CSDN
尹成學院微信:備註:CSDN
相關文章
- open-ethereum-pool以太坊礦池原始碼分析(4)-policy模組原始碼
- open-ethereum-pool以太坊礦池原始碼分析(5)proxy模組原始碼
- open-ethereum-pool以太坊礦池原始碼分析(6)-redis模組原始碼Redis
- open-ethereum-pool以太坊礦池原始碼分析(7)unlocker模組原始碼
- open-ethereum-pool以太坊礦池原始碼分析(2)API分析原始碼API
- open-ethereum-pool以太坊礦池原始碼分析(1)-main入口分析原始碼AI
- open-ethereum-pool以太坊礦池原始碼分析(1)環境安裝原始碼
- 以太坊交易池原始碼分析原始碼
- btcpool礦池原始碼分析(3)-BlockMaker模組解析TCP原始碼BloC
- 以太坊原始碼分析(16)挖礦分析原始碼
- 以太坊原始碼分析(42)miner挖礦部分原始碼分析CPU挖礦原始碼
- 以太坊原始碼分析(26)core-txpool交易池原始碼分析原始碼
- btcpool礦池原始碼分析(4)-GbtMaker模組解析TCP原始碼
- btcpool礦池原始碼分析(5)-JobMaker模組解析TCP原始碼
- btcpool礦池原始碼分析(6)-nmcauxmaker模組解析TCP原始碼UX
- btcpool礦池原始碼分析(6)-PoolWatcher模組解析TCP原始碼
- btcpool礦池原始碼分析(7)-sharelogger模組解析TCP原始碼
- btcpool礦池原始碼分析(9)-statshttpd模組解析TCP原始碼httpd
- btcpool礦池原始碼分析(10)-StratumServer模組解析TCP原始碼Server
- 死磕以太坊原始碼分析之挖礦流程分析原始碼
- 以太坊交易池原始碼解析原始碼
- 以太坊原始碼分析(3)以太坊交易手續費明細原始碼
- 以太坊原始碼分析(37)eth以太坊協議分析原始碼協議
- 以太坊原始碼分析(18)以太坊交易執行分析原始碼
- 以太坊原始碼分析(36)ethdb原始碼分析原始碼
- 以太坊原始碼分析(38)event原始碼分析原始碼
- 以太坊原始碼分析(41)hashimoto原始碼分析原始碼
- 以太坊原始碼分析(43)node原始碼分析原始碼
- 以太坊原始碼分析(51)rpc原始碼分析原始碼RPC
- 以太坊原始碼分析(52)trie原始碼分析原始碼
- 以太坊原始碼分析(13)RPC分析原始碼RPC
- 以太坊原始碼分析(52)以太坊fast sync演算法原始碼AST演算法
- 以太坊原始碼分析(1)go-ethereum的設計思路及模組組織形式原始碼Go
- 以太坊原始碼分析(5)accounts程式碼分析原始碼
- 以太坊原始碼分析(8)區塊分析原始碼
- 以太坊原始碼分析(9)cmd包分析原始碼
- 以太坊原始碼分析(35)eth-fetcher原始碼分析原始碼
- 以太坊原始碼分析(20)core-bloombits原始碼分析原始碼OOM