Commit 1b9aee50 authored by szh's avatar szh

update syncblock

parent b9be98f0
...@@ -11,7 +11,6 @@ import ( ...@@ -11,7 +11,6 @@ import (
"chain33-pai/routers" "chain33-pai/routers"
"chain33-pai/models" "chain33-pai/models"
"chain33-pai/pkg/util" "chain33-pai/pkg/util"
"chain33-pai/pkg/chain33"
"net" "net"
"time" "time"
"chain33-pai/service/pai_service" "chain33-pai/service/pai_service"
...@@ -22,7 +21,7 @@ func init() { ...@@ -22,7 +21,7 @@ func init() {
models.Setup() models.Setup()
logging.Setup() logging.Setup()
//gredis.Setup() //gredis.Setup()
chain33.Setup() //chain33.Setup()
util.Setup() util.Setup()
} }
...@@ -34,7 +33,7 @@ func init() { ...@@ -34,7 +33,7 @@ func init() {
// @license.url https://chain33-pai/blob/master/LICENSE // @license.url https://chain33-pai/blob/master/LICENSE
func main() { func main() {
gin.SetMode(setting.ServerSetting.RunMode) gin.SetMode(setting.ServerSetting.RunMode)
go broadcast() //go broadcast()
routersInit := routers.InitRouter() routersInit := routers.InitRouter()
readTimeout := setting.ServerSetting.ReadTimeout readTimeout := setting.ServerSetting.ReadTimeout
writeTimeout := setting.ServerSetting.WriteTimeout writeTimeout := setting.ServerSetting.WriteTimeout
...@@ -54,7 +53,7 @@ func main() { ...@@ -54,7 +53,7 @@ func main() {
server.ListenAndServe() server.ListenAndServe()
select {} //select {}
// If you want Graceful Restart, you need a Unix system and download github.com/fvbock/endless // If you want Graceful Restart, you need a Unix system and download github.com/fvbock/endless
//endless.DefaultReadTimeOut = readTimeout //endless.DefaultReadTimeOut = readTimeout
//endless.DefaultWriteTimeOut = writeTimeout //endless.DefaultWriteTimeOut = writeTimeout
......
package main
import (
"github.com/gin-gonic/gin"
"chain33-pai/pkg/logging"
"chain33-pai/pkg/setting"
"chain33-pai/models"
"chain33-pai/pkg/util"
"chain33-pai/miner"
"chain33-pai/pkg/chain33"
)
func init() {
setting.Setup()
models.Setup()
logging.Setup()
//gredis.Setup()
chain33.Setup()
util.Setup()
}
// @title Golang Gin API
// @version 1.0
// @description An example of gin
// @termsOfService https://chain33-pai
// @license.name MIT
// @license.url https://chain33-pai/blob/master/LICENSE
func main() {
gin.SetMode(setting.ServerSetting.RunMode)
go miner.SyncBlock()
}
\ No newline at end of file
package miner
import (
"github.com/pkg/errors"
"github.com/33cn/chain33/types"
"fmt"
)
var execAddress map[string]string
func accountConvert(acc *types.Account) *RMinerStat {
return &RMinerStat{
Frozen: acc.Frozen,
Balance: acc.Balance,
Total: acc.Frozen + acc.Balance,
}
}
func fromAccount(l *types.ReceiptAccountTransfer) *RMinerStat {
return accountConvert(l.Current)
}
// coins/ticket-addr
func fromExecAccount(l *types.ReceiptExecAccountTransfer) *RMinerStat {
detail := accountConvert(l.Current)
return detail
}
// LogFeeConvert LogFeeConvert
func LogFeeConvert(v []byte) (*RMinerStat, error) {
var l types.ReceiptAccountTransfer
err := types.Decode(v, &l)
if err == nil {
return fromAccount(&l), nil
}
return nil, err
}
// LogTransferConvert LogTransferConvert
func LogTransferConvert(v []byte) (*RMinerStat, error) {
var l types.ReceiptAccountTransfer
err := types.Decode(v, &l)
if err == nil {
return fromAccount(&l), nil
}
return nil, err
}
// LogDepositConvert LogDepositConvert
func LogDepositConvert(v []byte) (*RMinerStat, error) {
var l types.ReceiptAccountTransfer
err := types.Decode(v, &l)
if err == nil {
return fromAccount(&l), nil
}
return nil, err
}
// LogExecTransferConvert LogExecTransferConvert
func LogExecTransferConvert(v []byte) (*RMinerStat, error) {
var l types.ReceiptExecAccountTransfer
err := types.Decode(v, &l)
if err == nil {
return fromExecAccount(&l), nil
}
return nil, err
}
// LogExecWithdrawConvert LogExecWithdrawConvert
func LogExecWithdrawConvert(v []byte) (*RMinerStat, error) {
var l types.ReceiptExecAccountTransfer
err := types.Decode(v, &l)
if err == nil {
return fromExecAccount(&l), nil
}
return nil, err
}
// LogExecDepositConvert LogExecDepositConvert
func LogExecDepositConvert(v []byte) (*RMinerStat, error) {
var l types.ReceiptExecAccountTransfer
err := types.Decode(v, &l)
if err == nil {
return fromExecAccount(&l), nil
}
return nil, err
}
// LogExecFrozenConvert LogExecFrozenConvert
func LogExecFrozenConvert(v []byte) (*RMinerStat, error) {
var l types.ReceiptExecAccountTransfer
err := types.Decode(v, &l)
if err == nil {
return fromExecAccount(&l), nil
}
return nil, err
}
// LogExecActiveConvert LogExecActiveConvert
func LogExecActiveConvert(v []byte) (*RMinerStat, error) {
var l types.ReceiptExecAccountTransfer
err := types.Decode(v, &l)
if err == nil {
return fromExecAccount(&l), nil
}
return nil, err
}
// LogGenesisTransferConvert LogGenesisTransferConvert
func LogGenesisTransferConvert(v []byte) (*RMinerStat, error) {
var l types.ReceiptAccountTransfer
err := types.Decode(v, &l)
if err == nil {
return fromAccount(&l), nil
}
return nil, err
}
// LogGenesisDepositConvert LogGenesisDepositConvert
func LogGenesisDepositConvert(v []byte) (*RMinerStat, error) {
var l types.ReceiptAccountTransfer
err := types.Decode(v, &l)
if err == nil {
return fromAccount(&l), nil
}
return nil, err
}
// LogMintConvert LogMintConvert
func LogMintConvert(v []byte) (*RMinerStat, error) {
var l types.ReceiptAccountTransfer
err := types.Decode(v, &l)
if err == nil {
return fromAccount(&l), nil
}
return nil, err
}
// LogBurnConvert LogBurnConvert
func LogBurnConvert(v []byte) (*RMinerStat, error) {
var l types.ReceiptAccountTransfer
err := types.Decode(v, &l)
if err == nil {
return fromAccount(&l), nil
}
return nil, err
}
// AssetLogConvert convert asset log
func AssetLogConvert(ty int32, v []byte) (*RMinerStat, error) {
detail, err := assetLogConvert(ty, v)
if err != nil {
return nil, errors.Wrapf(err, "convert asset log: %d", ty)
}
return detail, nil
}
func assetLogConvert(ty int32, v []byte) (*RMinerStat, error) {
if ty == types.TyLogFee {
return LogFeeConvert(v)
} else if ty == types.TyLogTransfer {
return LogTransferConvert(v)
} else if ty == types.TyLogDeposit {
return LogDepositConvert(v)
} else if ty == types.TyLogExecTransfer {
return LogExecTransferConvert(v)
} else if ty == types.TyLogExecWithdraw {
return LogExecWithdrawConvert(v)
} else if ty == types.TyLogExecDeposit {
return LogExecDepositConvert(v)
} else if ty == types.TyLogExecFrozen {
return LogExecFrozenConvert(v)
} else if ty == types.TyLogExecActive {
return LogExecActiveConvert(v)
} else if ty == types.TyLogGenesisTransfer {
return LogGenesisTransferConvert(v)
} else if ty == types.TyLogGenesisDeposit {
return LogGenesisDepositConvert(v)
} else if ty == types.TyLogMint {
return LogMintConvert(v)
} else if ty == types.TyLogBurn {
return LogBurnConvert(v)
}
return nil, notSupport(ty, v)
}
func notSupport(logType int32, json []byte) (err error) {
return errors.New("notSupport" + fmt.Sprintf("-log:%d", logType))
}
\ No newline at end of file
package miner package miner
import (
"chain33-pai/models"
"sync"
"chain33-pai/pkg/chain33"
"chain33-pai/pkg/logging"
"time"
"github.com/33cn/chain33/types"
ttype "github.com/33cn/plugin/plugin/dapp/ticket/types"
)
func init() { func init() {
height,err := models.GetHeight()
if err != nil {
panic(err)
}
prev.LocalHeight = height
prev.SetMainHeight()
}
var (
prev prevHeight
client chain33.PaiClient
)
type prevHeight struct {
Height int64
LocalHeight int64
lock sync.Mutex
} }
func SyncBlock() { func SyncBlock() {
for {
var t time.Duration
prev.lock.Lock()
if prev.Height > prev.LocalHeight {
err := DealBlock()
if err != nil {
logging.Error("DealBlock err",err)
}
prev.LocalHeight++
t = time.Millisecond * 50
} else {
prev.SetMainHeight()
t = time.Second * 5
}
prev.lock.Unlock()
logging.Info("prevHeight",prev)
time.Sleep(t)
}
}
func (prev *prevHeight) SetMainHeight() error {
header,err := client.GetLastHeader()
if err != nil {
logging.Error("GetLastHeader err ",err)
return err
}
prev.Height = header.Height
return nil
}
func DealBlock() error {
blocks ,err := client.GetBlocks(&types.ReqBlocks{Start:prev.LocalHeight+1,End:prev.LocalHeight+1,IsDetail:true})
if err != nil {
logging.Error("GetBlocks err",err)
return err
}
block := blocks.GetItems()[0]
var rs RMinerStat
var rt RMinerTxs
//处理交易数据
for k,v := range block.Block.Txs {
if block.Receipts[k].Ty == types.ExecOk {
rt1,rs1,err := dealTx(v)
if err != nil {
logging.Error("dealTx err ",err)
return err
}
if rt1 != nil {
rt = *rt1
}
if rs1 != nil {
rs.MinedTicketCount += rs1.MinedTicketCount
rs.MiningTicketCount += rs1.MiningTicketCount
rs.MinedAmount += rs1.MinedAmount
}
}
}
rs.Time = block.Block.BlockTime
rs.Height = block.Block.Height
rt.Height = block.Block.Height
rt.Time = block.Block.BlockTime
//处理交易日志
//for _,v := range block.Receipts {
// if v.Ty == types.ExecOk {
// logs := v.GetLogs()
// for _, vv := range logs {
//
// }
// }
//
//}
raspStat := NewMinerStat(&rs)
raspTxs := NewMinerTxs(&rt)
err = models.UpdateBlock(raspTxs,raspStat)
if err != nil {
logging.Error("UpdateBlock err ",err)
return err
}
return nil
}
type RMinerTxs struct {
Miner string `json:"miner"`
ReturnAddr string `json:"return_addr"`
Amount int64 `json:"amount"`
Height int64 `json:"height"`
Time int64 `json:"time"`
}
type RMinerStat struct {
Addr string `json:"addr"`
MinedAmount int64 `json:"mined_amount"`
MinedTicketCount int64 `json:"mined_ticket_count"`
MiningTicketCount int64 `json:"mining_ticket_count"`
Total int64 `json:"total"`
Balance int64 `json:"balance"`
Frozen int64 `json:"frozen"`
Height int64 `json:"height"`
Time int64 `json:"time"`
} }
func dealTx(tx *types.Transaction) (*RMinerTxs,*RMinerStat,error) {
var rt RMinerTxs
var rs RMinerStat
//只处理ticket合约
if string(tx.Execer) == "ticket" {
var miner ttype.TicketAction
err := types.Decode(tx.Payload,&miner)
if err != nil {
logging.Error("decode ticket err ",err)
return nil,nil,err
}
switch miner.Ty {
case ttype.TicketActionMiner:
rt.Amount = miner.GetMiner().Reward
rt.Miner = tx.From()
rs.MinedAmount = miner.GetMiner().Reward
rs.MinedTicketCount = 1
case ttype.TicketActionClose:
rs.MiningTicketCount -= int64(len(miner.GetTclose().TicketId))
case ttype.TicketActionOpen:
rs.MiningTicketCount += int64(miner.GetTopen().Count)
}
}
return &rt,&rs,nil
}
func NewMinerStat(rs *RMinerStat) *models.RaspMinerStat {
var r models.RaspMinerStat
r.Height = rs.Height
r.Time = rs.Time
r.MinedAmount = rs.MinedAmount
r.MiningTicketCount = rs.MiningTicketCount
r.MinedTicketCount = rs.MinedTicketCount
return &r
}
func NewMinerTxs(rt *RMinerTxs) *models.RaspMinerTxs {
var r models.RaspMinerTxs
r.Time = rt.Time
r.Height = rt.Height
r.Amount = rt.Amount
r.Miner = rt.Miner
return &r
}
func bityuanMiner(height int64) int64 {
// ForkChainParamV2
if height >= 2270000 {
return 8 * types.Coin
} else if height > 0 {
return 30 * types.Coin
}
return 0
}
\ No newline at end of file
package models
import (
"github.com/jinzhu/gorm"
)
type RaspConfig struct {
Model
Height int64 `json:"height"`
}
// GetHeight get lastheight in chain33
func GetHeight() (int64, error) {
var raspConfig RaspConfig
err := db.Select("height").First(&raspConfig).Error
if err != nil && err != gorm.ErrRecordNotFound {
return 0, err
}
return raspConfig.Height, nil
}
// EditArticle modify a single article
func UpdateHeight(height int64) error {
if err := db.Model(&RaspConfig{}).Update("Height",height).Error; err != nil {
return err
}
return nil
}
// AddArticle add a single article
func InitHeight(data map[string]interface{}) error {
config := RaspConfig{
Height: data["height"].(int64),
}
if err := db.Create(&config).Error; err != nil {
return err
}
return nil
}
package models
import (
"github.com/jinzhu/gorm"
)
type RaspMinerStat struct {
Model
Addr string `json:"addr"`
MinedAmount int64 `json:"mined_amount"`
MinedTicketCount int64 `json:"mined_ticket_count"`
MiningTicketCount int64 `json:"mining_ticket_count"`
Total int64 `json:"total"`
Balance int64 `json:"balance"`
Frozen int64 `json:"frozen"`
Height int64 `json:"height"`
Time int64 `json:"time"`
}
// ExistByAddr checks if an addr exists based on addr
func ExistByAddr(addr string) (bool, error) {
var stat RaspMinerStat
err := db.Select("addr").Where("addr = ? ", addr).First(&stat).Error
if err != nil && err != gorm.ErrRecordNotFound {
return false, err
}
if stat.Addr != "" {
return true, nil
}
return false, nil
}
// GetAddrTotal gets the total number of addr based on the constraints
func GetAddrTotal(maps interface{}) (int, error) {
var count int
if err := db.Model(&RaspMinerStat{}).Where(maps).Count(&count).Error; err != nil {
return 0, err
}
return count, nil
}
// GetAddrs gets a list of articles based on paging constraints
func GetAddrs(pageNum int, pageSize int, maps interface{}) ([]*RaspMinerStat, error) {
var stat []*RaspMinerStat
err := db.Where(maps).Offset(pageNum).Limit(pageSize).Find(&stat).Error
if err != nil && err != gorm.ErrRecordNotFound {
return nil, err
}
return stat, nil
}
// GetAddr Get a single addr based on ID
func GetAddr(addr string) (*RaspMinerStat, error) {
var stat RaspMinerStat
err := db.Where("addr = ? ", addr).First(&stat).Error
if err != nil && err != gorm.ErrRecordNotFound {
return nil, err
}
return &stat, nil
}
// EditAddr modify a single addr
func EditAddr(addr string, data interface{}) error {
if err := db.Model(&Article{}).Where("addr = ? ", addr).Updates(data).Error; err != nil {
return err
}
return nil
}
// AddAddr add a single addr
func AddAddr(data map[string]interface{}) error {
stat := RaspMinerStat{
Addr: data["addr"].(string),
MinedAmount: data["mined_amount"].(int64),
MinedTicketCount: data["mined_ticket_count"].(int64),
MiningTicketCount: data["mining_ticket_count"].(int64),
Total: data["total"].(int64),
Balance: data["balance"].(int64),
Frozen: data["frozen"].(int64),
Height: data["height"].(int64),
Time: data["time"].(int64),
}
if err := db.Create(&stat).Error; err != nil {
return err
}
return nil
}
package models
import (
"github.com/jinzhu/gorm"
)
type RaspMinerTxs struct {
Model
Miner string `json:"miner"`
ReturnAddr string `json:"return_addr"`
Amount int64 `json:"amount"`
Height int64 `json:"height"`
Time int64 `json:"time"`
}
// ExistByAddr checks if an addr exists based on addr
func ExistByAddrHeight(addr string,height int64) (bool, error) {
var txs RaspMinerTxs
err := db.Select("miner").Where("miner = ? and height = ?", addr,height).First(&txs).Error
if err != nil && err != gorm.ErrRecordNotFound {
return false, err
}
if txs.Miner != "" {
return true, nil
}
return false, nil
}
// GetAddrTotal gets the total number of addr based on the constraints
func GetMinerTxsTotal(addr string) (int, error) {
var count int
if err := db.Model(&RaspMinerTxs{}).Where("miner = ? ",addr).Count(&count).Error; err != nil {
return 0, err
}
return count, nil
}
// GetAddrs gets a list of articles based on paging constraints
func GetMinerTxs(pageNum int, pageSize int, maps interface{}) ([]*RaspMinerTxs, error) {
var txs []*RaspMinerTxs
err := db.Where(maps).Offset(pageNum).Limit(pageSize).Find(&txs).Error
if err != nil && err != gorm.ErrRecordNotFound {
return nil, err
}
return txs, nil
}
// AddAddr add a single addr
func AddMinerTxs(data map[string]interface{}) error {
tx := RaspMinerTxs{
Miner: data["addr"].(string),
ReturnAddr: data["return_addr"].(string),
Amount: data["amount"].(int64),
Height: data["height"].(int64),
Time: data["time"].(int64),
}
if err := db.Create(&tx).Error; err != nil {
return err
}
return nil
}
package models
func UpdateBlock(rt *RaspMinerTxs,rs *RaspMinerStat) error {
tx := db.Begin()
defer func() {
if r := recover(); r != nil {
tx.Rollback()
}
}()
if err := tx.Error; err != nil {
return err
}
if err := tx.Model(&RaspMinerStat{}).Updates(&rs).Error;err != nil {
tx.Rollback()
return err
}
if err := tx.Model(&RaspMinerTxs{}).Updates(&rt).Error;err != nil {
tx.Rollback()
return err
}
if err := tx.Model(&RaspConfig{}).Update("Height",rt.Height).Error;err != nil {
tx.Rollback()
return err
}
return tx.Commit().Error
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment