Commit b7816a8e authored by szh's avatar szh

up

parent c55e58e6
......@@ -11,6 +11,8 @@ import (
ttype "github.com/33cn/plugin/plugin/dapp/ticket/types"
"github.com/jinzhu/gorm"
"github.com/33cn/chain33/common"
"sort"
"strings"
)
func Setup() {
......@@ -47,6 +49,8 @@ type prevHeight struct {
lock sync.Mutex
}
func SyncBlock() {
logging.Info("init prevheight",prev)
for {
......@@ -61,73 +65,31 @@ func SyncBlock() {
}
//速度模式
for processHeight := startHeight + 1; processHeight <= lastHeight; processHeight += maxDownload {
statMap := make(map[string]*models.RaspMinerStat,0)
txsMap := make(map[int64]*models.RaspMinerTxs,0)
//statList := make([]*models.RaspMinerStat,0)
txsList := make([]*models.RaspMinerTxs,0)
checkList := make(map[int64]int64,0)
blocks := &types.BlockDetails{}
var wg sync.WaitGroup
var mutx sync.Mutex
for height := processHeight ;height < processHeight + maxDownload;height ++ {
wg.Add(1)
go func(height int64) {
//defer wg.Done()
stat,txs,err := DealBlock(height)
block,err := DealBlock(height)
if err != nil {
logging.Error("DealBlock err",err)
panic(err)
}
mutx.Lock()
for _, vv:= range stat {
if _,ok := statMap[vv.Addr];!ok {
statMap[vv.Addr] = vv
} else {
statMap[vv.Addr].MinedTicketCount += vv.MinedTicketCount
statMap[vv.Addr].MiningTicketCount += vv.MiningTicketCount
statMap[vv.Addr].MinedAmount += vv.MinedAmount
}
}
txsList = append(txsList,txs)
blocks.Items = append(blocks.Items,block.Items...)
mutx.Unlock()
logging.Info("DealBlock",height)
checkList[height] = height
wg.Done()
}(height)
}
//db.SetMainNetHeight(int(processHeight + types.MaxProcessBlocks + 1))
wg.Wait()
logging.Info("total block",len(blocks.Items))
for _,v := range txsList {
if v != nil && v.Height >0 {
if _, ok := txsMap[v.Height];!ok {
txsMap[v.Height] = v
}
}
}
if len(txsList) != int(maxDownload) {
logging.Error("txsList",len(txsList),"txsMap",len(txsMap),"statMap",len(statMap),"checkList",len(checkList))
for _,v:= range checkList {
var t bool
for _, vv:= range txsList {
if v == vv.Height {
t = true
break
}
}
statMap,txsMap,err := GetData(blocks.Items)
if !t {
logging.Error("++++++++",v)
}
}
for _, vv:= range txsList {
logging.Info("txslist:",*vv)
}
for _, vv:= range statMap {
logging.Info("statMap:",*vv)
}
panic("exception txs not eq expect")
}
err := models.UpdateBlocks(txsMap,statMap,processHeight+maxDownload-1)
if err != nil {
panic(err)
......@@ -160,75 +122,149 @@ func (prev *prevHeight) SetMainHeight() error {
return nil
}
func DealBlock(height int64) ( []*models.RaspMinerStat, *models.RaspMinerTxs,error) {
blocks ,err := client.GetBlocks(&types.ReqBlocks{Start:height,End:height,IsDetail:true})
func DealBlock(height int64) ( *types.BlockDetails,error) {
blocks, err := client.GetBlocks(&types.ReqBlocks{Start: height, End: height, IsDetail: true})
if err != nil {
logging.Error("GetBlocks err",err)
return nil,nil,err
logging.Error("GetBlocks err", err)
return blocks, err
}
block := blocks.GetItems()[0]
rsMap := make(map[string]*RMinerStat,0)
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 nil,nil,err
}
if rt1 != nil && rt1.Miner != ""{
rt.Miner = rt1.Miner
rt.Amount = rt1.Amount
rt.Hash = rt1.Hash
}
if rs1 != nil && rs1.Addr != "" {
rs := &RMinerStat{}
if _,ok := rsMap[rs1.Addr];!ok {
rs.Addr = rs1.Addr
rs.MinedTicketCount = rs1.MinedTicketCount
rs.MiningTicketCount = rs1.MiningTicketCount
rs.MinedAmount = rs1.MinedAmount
rs.Time = block.Block.BlockTime
rs.Height = block.Block.Height
rsMap[rs1.Addr] = rs
} else {
rsMap[rs1.Addr].MiningTicketCount += rs1.MiningTicketCount
return blocks,nil
}
func GetData(list []*types.BlockDetail) (map[string]*models.RaspMinerStat,map[int64]*models.RaspMinerTxs,error) {
statMap := make(map[string]*models.RaspMinerStat,0)
txsMap := make(map[int64]*models.RaspMinerTxs,0)
//txhash确认票的mineraddress 和 returnaddress
ticketopenlist := make(map[string]*ttype.TicketOpen,0)
sort.Sort(BlockWrapper{list,func(p, q * types.BlockDetail) bool{
return p.Block.Height > q.Block.Height
}})
for _,v := range list {
logging.Info("height:",v.Block.Height)
for _,vv:= range v.Block.Txs {
txs := models.RaspMinerTxs{}
if string(vv.Execer) == "ticket" {
var payload ttype.TicketAction
err := types.Decode(vv.Payload,&payload)
if err != nil {
return nil,nil,err
}
switch payload.Ty {
case ttype.TicketActionClose:
for _,vvv := range payload.GetTclose().TicketId {
stat := models.RaspMinerStat{}
realAddress := ""
ticketinfo := &ttype.TicketOpen{}
slist := strings.Split(vvv,":")
if slist[1] == "" {
return nil,nil,err
}
if _,ok := ticketopenlist[slist[1]];ok {
ticketinfo = ticketopenlist[slist[1]]
} else {
ticketi,err:= models.GetTicketInfo(vvv)
if err != nil {
return nil,nil,err
}
ticketinfo.MinerAddress = ticketi.Miner
ticketinfo.MinerAddress = ticketi.ReturnAddress
}
realAddress = ticketinfo.ReturnAddress
if _,ok := statMap[realAddress];!ok {
stat.Addr = realAddress
stat.Height = v.Block.Height
stat.MiningTicketCount= int64(-1)
statMap[realAddress] = &stat
} else {
statMap[realAddress].MiningTicketCount -= 1
}
}
case ttype.TicketActionGenesis:
stat := models.RaspMinerStat{}
realAddress := payload.GetGenesis().ReturnAddress
if _,ok := statMap[realAddress];!ok {
stat.Addr = realAddress
stat.Height = v.Block.Height
stat.MiningTicketCount = int64(payload.GetGenesis().Count)
statMap[realAddress] = &stat
} else {
statMap[realAddress].MiningTicketCount += int64(payload.GetGenesis().Count)
}
case ttype.TicketActionMiner:
stat := models.RaspMinerStat{}
realAddress := ""
ticketinfo := &ttype.TicketOpen{}
slist := strings.Split(payload.GetMiner().TicketId,":")
if slist[1] == "" {
return nil,nil,err
}
if _,ok := ticketopenlist[slist[1]];ok {
ticketinfo = ticketopenlist[slist[1]]
} else {
ticketi,err:= models.GetTicketInfo(payload.GetMiner().TicketId)
if err != nil {
return nil,nil,err
}
ticketinfo.MinerAddress = ticketi.Miner
ticketinfo.MinerAddress = ticketi.ReturnAddress
}
realAddress = ticketinfo.ReturnAddress
if _,ok := statMap[realAddress];!ok {
stat.Addr = realAddress
stat.Height = v.Block.Height
stat.MinedAmount += payload.GetMiner().Reward
statMap[realAddress] = &stat
} else {
statMap[realAddress].MinedAmount += payload.GetMiner().Reward
}
txs.Height = v.Block.Height
txs.Time = v.Block.BlockTime
txs.Hash = common.ToHex(vv.Hash())
txs.Amount = payload.GetMiner().Reward
txs.Miner = vv.From()
txs.ReturnAddr = realAddress
case ttype.TicketActionOpen:
if _,ok := ticketopenlist[common.ToHex(vv.Hash())];!ok {
ticketopenlist[common.ToHex(vv.Hash())] = payload.GetTopen()
}
stat := models.RaspMinerStat{}
realAddress := payload.GetGenesis().ReturnAddress
if _,ok := statMap[realAddress];!ok {
stat.Addr = realAddress
stat.Height = v.Block.Height
stat.MiningTicketCount = int64(payload.GetTopen().Count)
statMap[realAddress] = &stat
} else {
statMap[realAddress].MiningTicketCount += int64(payload.GetTopen().Count)
}
}
}
//dealTx(vv)
if txs.Height > 0 {
txsMap[txs.Height] = &txs
}
}
}
return statMap,txsMap,nil
}
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 {
//
// }
// }
//
//}
raspStatList := make([]*models.RaspMinerStat,0)
for _,v := range rsMap {
raspStat := NewMinerStat(v)
raspStatList = append(raspStatList,raspStat)
logging.Info("stat",*raspStat)
}
raspTxs := NewMinerTxs(rt)
logging.Info("txs",*raspTxs)
//err = models.UpdateBlock(raspTxs,raspStat)
//if err != nil {
// logging.Error("UpdateBlock err ",err)
// return err
//}
return raspStatList,raspTxs,nil
//将[]types.BlockDetail和比较的准则cmp封装在了一起,形成了BlockWrapper 函数
type BlockWrapper struct {
block []*types.BlockDetail
by func(p, q *types.BlockDetail) bool
}
type SortBy func(p, q *types.BlockDetail) bool
func (pw BlockWrapper) Len() int { // 重写 Len() 方法
return len(pw.block)
}
func (pw BlockWrapper) Swap(i, j int){ // 重写 Swap() 方法
pw.block[i], pw.block[j] = pw.block[j], pw.block[i]
}
func (pw BlockWrapper) Less(i, j int) bool { // 重写 Less() 方法
return pw.by(pw.block[i], pw.block[j])
}
type RMinerTxs struct {
Miner string `json:"miner"`
......
package models
type RaspTickets struct {
Id string
Miner string
ReturnAddress string
Height int64
Pubhash string
Status int64
}
func GetTicketInfo(id string) (*RaspTickets,error) {
var ticket RaspTickets
if err := db.Model(&RaspTickets{}).Where(&RaspTickets{Id:id}).First(&ticket).Error; err != nil {
return nil,err
} else {
return &ticket,nil
}
}
\ No newline at end of file
package util
import "github.com/33cn/chain33/types"
type TxDetail struct{
Height int64
Time int64
Transaction *types.Transaction
}
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