123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252 |
- package blockchain
- import (
- "context"
- "encoding/hex"
- "fmt"
- "ktogame/contractgo/Collect"
- "ktogame/controller"
- "ktogame/dbUtil"
- "ktogame/models"
- "os"
- "strings"
- "time"
- "github.com/astaxie/beego"
- "github.com/astaxie/beego/logs"
- "github.com/ethereum/go-ethereum/accounts/abi"
- utilAddress "github.com/korthochain/korthochain/pkg/address"
- "github.com/korthochain/korthochain/pkg/block"
- pb "github.com/korthochain/korthochain/pkg/server/grpcserver/message"
- "github.com/korthochain/korthochain/pkg/transaction"
- "google.golang.org/grpc"
- )
- var ktoClient pb.GreeterClient
- var ktoRpc = beego.AppConfig.String("miner_node")
- var currentBlock uint64
- var TopsMap map[string]string
- func init() {
- kc, err := grpc.Dial(ktoRpc, grpc.WithInsecure(), grpc.WithBlock())
- if err != nil {
- logs.Error(err)
- os.Exit(1)
- }
- ktoClient = pb.NewGreeterClient(kc)
- utilAddress.SetNetWork("mainnet")
- tm := make(map[string]string, 0)
- tm[TOPIC_PARTICIPATE] = COLLECT_PARTICIPATE
- tm[TOPIC_CLAIM] = COLLECT_CLAIMREWARDS
- TopsMap = tm
- go scanBlock()
- go confirmClaimedTxs()
- }
- func scanBlock() {
- logs.Info("scanBlock...")
- var bi models.BlockInfo
- ok, err := dbUtil.Engine.Id(1).Get(&bi)
- if err != nil {
- fmt.Println("获取最新快高错误=", err)
- return
- }
- if !ok {
- fmt.Println("获取最新快高失败!")
- return
- }
- currentBlock = uint64(bi.BlockNumber) + 1
- //currentBlock =62203394
- for {
- time.Sleep(time.Second * 3)
- res, err := ktoClient.GetMaxBlockHeight(context.Background(), &pb.ReqMaxBlockHeight{})
- if err != nil {
- logs.Error("获取交易block number错误=", err)
- continue
- }
- logs.Info("currentBlock:", currentBlock, "chainblock:", res.MaxHeight)
- if res.MaxHeight < currentBlock {
- currentBlock = res.MaxHeight
- }
- bl, err := ktoClient.GetBlockByNum(context.Background(), &pb.ReqBlockByNumber{Height: currentBlock})
- if err != nil || bl.Code != 0 {
- logs.Error("获取交易block错误=", err)
- continue
- }
- blc, errs := block.Deserialize(bl.Data)
- if errs != nil {
- logs.Error("解析blcock错误=", errs)
- continue
- }
- var ERR error
- for _, v := range blc.Transactions {
- if len(v.Input) == 0 {
- continue
- }
- evm, err := transaction.DecodeEvmData(v.Input)
- if err != nil {
- logs.Error(err)
- ERR = err
- break
- }
- if len(evm.Logs) == 0 {
- continue
- }
- for _, l := range evm.Logs {
- th := l.Topics[0].Hex()
- method := TopsMap[th]
- contract := l.Address.String()
- if contract == COLLECTCONTRACT {
- if method == COLLECT_PARTICIPATE {
- var ev EventParticipate
- abi, err := abi.JSON(strings.NewReader(Collect.CollectMetaData.ABI))
- if err != nil {
- logs.Error(err)
- ERR = err
- break
- }
- err = abi.UnpackIntoInterface(&ev, method, l.Data)
- if err != nil {
- logs.Error(err)
- ERR = err
- break
- }
- logs.Info("participate data:", ev.Participant.String(), ev.Inviter.String(), v.HashToString(), float64(ev.Amount.Uint64()/controller.Decimals))
- //handle user participate
- err = participate(dbUtil.Engine, ev.Participant.String(), ev.Inviter.String(), v.HashToString(), float64(ev.Amount.Uint64()/controller.Decimals))
- if err != nil {
- logs.Error(err)
- ERR = err
- break
- }
- } else if method == COLLECT_CLAIMREWARDS {
- var evt EventClaim
- abi, err := abi.JSON(strings.NewReader(Collect.CollectMetaData.ABI))
- if err != nil {
- logs.Error(err)
- ERR = err
- break
- }
- err = abi.UnpackIntoInterface(&evt, method, l.Data)
- if err != nil {
- logs.Error(err)
- ERR = err
- break
- }
- fmt.Printf("claim event data=%+v\n ", evt)
- var bts []byte
- for _, b := range evt.Signature {
- bts = append(bts, b)
- }
- err = checkClaim(dbUtil.Engine, evt.User.String(), v.HashToString(), hex.EncodeToString(bts), float64(evt.Amount.Uint64()/controller.Decimals), int64(v.BlockNum))
- if err != nil {
- logs.Error(err)
- ERR = err
- break
- }
- }
- }
- }
- if ERR != nil {
- logs.Error(err)
- break
- }
- }
- if ERR != nil {
- logs.Error("处理错误=", ERR)
- continue
- }
- bi.BlockNumber = int64(currentBlock)
- _, err = dbUtil.Engine.ID(1).Update(&bi)
- if err != nil {
- logs.Error("更新最新快高错误=", err)
- return
- }
- currentBlock++
- }
- }
- func confirmClaimedTxs() {
- var mark int64 = 0
- for {
- time.Sleep(time.Second * 5)
- logs.Info("confirmClaimedTxs mark= %v\n", mark)
- var txs []models.ClaimedTxs
- err := dbUtil.Engine.Where("state = ?", 0).Where("droped = ?", 0).Where("id > ?", mark).Find(&txs)
- if err != nil {
- logs.Error(err)
- continue
- }
- if len(txs) > 0 {
- mark = txs[len(txs)-1].Id
- }
- for _, t := range txs {
- go func(tx models.ClaimedTxs) {
- interval := 0
- for {
- time.Sleep(time.Second * 5)
- if interval > (CONFIRMINTERVAL / 5) {
- var ui models.UserInfo
- _, err := dbUtil.Engine.Id(tx.Hash).Get(&ui)
- if err != nil {
- mark = tx.Id - 1
- return
- }
- ui.AvailableClaim += tx.Amount
- ui.TotalClaimed -= tx.Amount
- _, err = dbUtil.Engine.ID(tx.Addr).Cols("total_claimed,available_claim").Update(&ui)
- if err != nil {
- mark = tx.Id - 1
- return
- }
- tx.Droped = 1
- _, err = dbUtil.Engine.ID(tx.Hash).Cols("droped").Update(&tx)
- if err != nil {
- mark = tx.Id - 1
- return
- }
- return
- }
- ptx, err := ktoClient.GetTxByHash(context.Background(), &pb.ReqTxByHash{Hash: tx.Hash})
- if err != nil {
- interval++
- continue
- }
- if ptx.Code != 0 {
- interval++
- continue
- }
- ftx, err := transaction.DeserializeFinishedTransaction(ptx.Data)
- if err != nil {
- interval++
- continue
- }
- //pending tx
- if ftx.BlockNum == 0 {
- interval++
- continue
- }
- tx.State = 1
- _, err = dbUtil.Engine.ID(tx.Hash).Cols("state").Update(&tx)
- if err != nil {
- mark = tx.Id - 1
- }
- return
- }
- }(t)
- }
- }
- }
|