github.com/turingchain2020/turingchain@v1.1.21/blockchain/proc.go (about) 1 // Copyright Turing Corp. 2018 All Rights Reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package blockchain 6 7 //message callback 8 import ( 9 "fmt" 10 "sync/atomic" 11 12 "github.com/turingchain2020/turingchain/common" 13 "github.com/turingchain2020/turingchain/queue" 14 "github.com/turingchain2020/turingchain/types" 15 ) 16 17 //ProcRecvMsg blockchain模块的消息接收处理 18 func (chain *BlockChain) ProcRecvMsg() { 19 defer chain.recvwg.Done() 20 reqnum := make(chan struct{}, 1000) 21 for msg := range chain.client.Recv() { 22 chainlog.Debug("blockchain recv", "msg", types.GetEventName(int(msg.Ty)), "id", msg.ID, "cap", len(reqnum)) 23 msgtype := msg.Ty 24 reqnum <- struct{}{} 25 atomic.AddInt32(&chain.runcount, 1) 26 if chain.procLocalDB(msgtype, msg, reqnum) { 27 continue 28 } 29 switch msgtype { 30 case types.EventQueryTx: 31 go chain.processMsg(msg, reqnum, chain.queryTx) 32 case types.EventGetBlocks: 33 go chain.processMsg(msg, reqnum, chain.getBlocks) 34 case types.EventSyncBlock: // block 35 go chain.processMsg(msg, reqnum, chain.addBlock) 36 case types.EventGetBlockHeight: 37 go chain.processMsg(msg, reqnum, chain.getBlockHeight) 38 case types.EventTxHashList: 39 go chain.processMsg(msg, reqnum, chain.txHashList) 40 case types.EventGetHeaders: 41 go chain.processMsg(msg, reqnum, chain.getHeaders) 42 case types.EventGetLastHeader: 43 go chain.processMsg(msg, reqnum, chain.getLastHeader) 44 case types.EventAddBlockDetail: 45 go chain.processMsg(msg, reqnum, chain.addBlockDetail) 46 case types.EventBroadcastAddBlock: //block 47 go chain.processMsg(msg, reqnum, chain.broadcastAddBlock) 48 case types.EventGetTransactionByAddr: 49 go chain.processMsg(msg, reqnum, chain.getTransactionByAddr) 50 case types.EventGetTransactionByHash: 51 go chain.processMsg(msg, reqnum, chain.getTransactionByHashes) 52 case types.EventGetBlockOverview: //blockOverview 53 go chain.processMsg(msg, reqnum, chain.getBlockOverview) 54 case types.EventGetAddrOverview: //addrOverview 55 go chain.processMsg(msg, reqnum, chain.getAddrOverview) 56 case types.EventGetBlockHash: //GetBlockHash 57 go chain.processMsg(msg, reqnum, chain.getBlockHash) 58 //订阅指定类型的交易回执 59 case types.EventSubscribePush: 60 go chain.processMsg(msg, reqnum, chain.subscribePush) 61 case types.EventAddBlockHeaders: 62 go chain.processMsg(msg, reqnum, chain.addBlockHeaders) 63 case types.EventGetLastBlock: 64 go chain.processMsg(msg, reqnum, chain.getLastBlock) 65 case types.EventIsSync: 66 go chain.processMsg(msg, reqnum, chain.isSync) 67 case types.EventIsNtpClockSync: 68 go chain.processMsg(msg, reqnum, chain.isNtpClockSyncFunc) 69 case types.EventGetLastBlockSequence: 70 go chain.processMsg(msg, reqnum, chain.getLastBlockSequence) 71 case types.EventGetBlockSequences: 72 go chain.processMsg(msg, reqnum, chain.getBlockSequences) 73 case types.EventGetBlockByHashes: 74 go chain.processMsg(msg, reqnum, chain.getBlockByHashes) 75 case types.EventGetBlockBySeq: 76 go chain.processMsg(msg, reqnum, chain.getBlockBySeq) 77 case types.EventDelParaChainBlockDetail: 78 go chain.processMsg(msg, reqnum, chain.delParaChainBlockDetail) 79 case types.EventAddParaChainBlockDetail: 80 go chain.processMsg(msg, reqnum, chain.addParaChainBlockDetail) 81 case types.EventGetSeqByHash: 82 go chain.processMsg(msg, reqnum, chain.getSeqByHash) 83 case types.EventListPushes: 84 go chain.processMsg(msg, reqnum, chain.listPush) 85 case types.EventGetPushLastNum: 86 go chain.processMsg(msg, reqnum, chain.getPushLastNum) 87 case types.EventGetLastBlockMainSequence: 88 go chain.processMsg(msg, reqnum, chain.GetLastBlockMainSequence) 89 case types.EventGetMainSeqByHash: 90 go chain.processMsg(msg, reqnum, chain.GetMainSeqByHash) 91 //para共识模块操作blockchain db的事件 92 case types.EventSetValueByKey: 93 go chain.processMsg(msg, reqnum, chain.setValueByKey) 94 case types.EventGetValueByKey: 95 go chain.processMsg(msg, reqnum, chain.getValueByKey) 96 //通过平行链title获取平行链的交易 97 case types.EventGetParaTxByTitle: 98 go chain.processMsg(msg, reqnum, chain.getParaTxByTitle) 99 100 //获取拥有此title交易的区块高度 101 case types.EventGetHeightByTitle: 102 go chain.processMsg(msg, reqnum, chain.getHeightByTitle) 103 104 //通过区块高度列表+title获取平行链交易 105 case types.EventGetParaTxByTitleAndHeight: 106 go chain.processMsg(msg, reqnum, chain.getParaTxByTitleAndHeight) 107 // 获取chunk record 108 case types.EventGetChunkRecord: 109 go chain.processMsg(msg, reqnum, chain.getChunkRecord) 110 // 获取chunk record 111 case types.EventAddChunkRecord: 112 go chain.processMsg(msg, reqnum, chain.addChunkRecord) 113 // 从localdb中获取Chunk BlockBody 114 case types.EventGetChunkBlockBody: 115 go chain.processMsg(msg, reqnum, chain.getChunkBlockBody) 116 // 用于chunk同步区块 117 case types.EventAddChunkBlock: 118 go chain.processMsg(msg, reqnum, chain.addChunkBlock) 119 default: 120 go chain.processMsg(msg, reqnum, chain.unknowMsg) 121 } 122 } 123 } 124 125 func (chain *BlockChain) unknowMsg(msg *queue.Message) { 126 chainlog.Warn("ProcRecvMsg unknow msg", "msgtype", msg.Ty) 127 } 128 129 func (chain *BlockChain) listPush(msg *queue.Message) { 130 cbs, err := chain.ProcListPush() 131 if err != nil { 132 chainlog.Error("listPush", "err", err.Error()) 133 msg.Reply(chain.client.NewMessage("rpc", types.EventListPushes, err)) 134 return 135 } 136 msg.Reply(chain.client.NewMessage("rpc", types.EventListPushes, cbs)) 137 } 138 func (chain *BlockChain) getPushLastNum(msg *queue.Message) { 139 data := (msg.Data).(*types.ReqString) 140 141 num, _ := chain.ProcGetLastPushSeq(data.Data) 142 lastNum := &types.Int64{Data: num} 143 msg.Reply(chain.client.NewMessage("rpc", types.EventGetPushLastNum, lastNum)) 144 } 145 146 func (chain *BlockChain) queryTx(msg *queue.Message) { 147 txhash := (msg.Data).(*types.ReqHash) 148 txDetail, err := chain.ProcQueryTxMsg(txhash.Hash) 149 if err != nil { 150 chainlog.Debug("ProcQueryTxMsg", "err", err.Error()) 151 msg.Reply(chain.client.NewMessage("rpc", types.EventTransactionDetail, err)) 152 } else { 153 msg.Reply(chain.client.NewMessage("rpc", types.EventTransactionDetail, txDetail)) 154 } 155 } 156 157 func (chain *BlockChain) getBlocks(msg *queue.Message) { 158 requestblocks := (msg.Data).(*types.ReqBlocks) 159 blocks, err := chain.ProcGetBlockDetailsMsg(requestblocks) 160 if err != nil { 161 chainlog.Error("ProcGetBlockDetailsMsg", "err", err.Error()) 162 msg.Reply(chain.client.NewMessage("rpc", types.EventBlocks, err)) 163 } else { 164 //chainlog.Debug("ProcGetBlockDetailsMsg", "success", "ok") 165 msg.Reply(chain.client.NewMessage("rpc", types.EventBlocks, blocks)) 166 } 167 } 168 169 func (chain *BlockChain) addBlock(msg *queue.Message) { 170 var reply types.Reply 171 reply.IsOk = true 172 blockpid := msg.Data.(*types.BlockPid) 173 //chainlog.Error("addBlock", "height", blockpid.Block.Height, "pid", blockpid.Pid) 174 if chain.GetDownloadSyncStatus() == fastDownLoadMode { 175 err := chain.WriteBlockToDbTemp(blockpid.Block, true) 176 if err != nil { 177 chainlog.Error("WriteBlockToDbTemp", "height", blockpid.Block.Height, "err", err.Error()) 178 reply.IsOk = false 179 reply.Msg = []byte(err.Error()) 180 } 181 //downLoadTask 运行时设置对应的blockdone 182 if chain.downLoadTask.InProgress() { 183 chain.downLoadTask.Done(blockpid.Block.GetHeight()) 184 } 185 } else { 186 _, err := chain.ProcAddBlockMsg(false, &types.BlockDetail{Block: blockpid.Block}, blockpid.Pid) 187 if err != nil { 188 chainlog.Error("ProcAddBlockMsg", "height", blockpid.Block.Height, "err", err.Error()) 189 reply.IsOk = false 190 reply.Msg = []byte(err.Error()) 191 } 192 chainlog.Debug("EventAddBlock", "height", blockpid.Block.Height, "pid", blockpid.Pid, "success", "ok") 193 } 194 msg.Reply(chain.client.NewMessage("p2p", types.EventReply, &reply)) 195 } 196 197 func (chain *BlockChain) getBlockHeight(msg *queue.Message) { 198 var replyBlockHeight types.ReplyBlockHeight 199 replyBlockHeight.Height = chain.GetBlockHeight() 200 //chainlog.Debug("EventGetBlockHeight", "success", "ok") 201 msg.Reply(chain.client.NewMessage("consensus", types.EventReplyBlockHeight, &replyBlockHeight)) 202 } 203 204 func (chain *BlockChain) txHashList(msg *queue.Message) { 205 txhashlist := (msg.Data).(*types.TxHashList) 206 duptxhashlist, err := chain.GetDuplicateTxHashList(txhashlist) 207 if err != nil { 208 chainlog.Error("txHashList", "err", err.Error()) 209 msg.Reply(chain.client.NewMessage("consensus", types.EventTxHashListReply, err)) 210 return 211 } 212 //chainlog.Debug("EventTxHashList", "success", "ok") 213 msg.Reply(chain.client.NewMessage("consensus", types.EventTxHashListReply, duptxhashlist)) 214 } 215 216 func (chain *BlockChain) getHeaders(msg *queue.Message) { 217 requestblocks := (msg.Data).(*types.ReqBlocks) 218 headers, err := chain.ProcGetHeadersMsg(requestblocks) 219 if err != nil { 220 chainlog.Error("ProcGetHeadersMsg", "err", err.Error()) 221 msg.Reply(chain.client.NewMessage("rpc", types.EventHeaders, err)) 222 } else { 223 //chainlog.Debug("EventGetHeaders", "success", "ok") 224 msg.Reply(chain.client.NewMessage("rpc", types.EventHeaders, headers)) 225 } 226 } 227 228 func (chain *BlockChain) isSync(msg *queue.Message) { 229 ok := chain.IsCaughtUp() 230 msg.Reply(chain.client.NewMessage("", types.EventReplyIsSync, &types.IsCaughtUp{Iscaughtup: ok})) 231 } 232 233 func (chain *BlockChain) getLastHeader(msg *queue.Message) { 234 header, err := chain.ProcGetLastHeaderMsg() 235 if err != nil { 236 chainlog.Error("ProcGetLastHeaderMsg", "err", err.Error()) 237 msg.Reply(chain.client.NewMessage("account", types.EventHeader, err)) 238 } else { 239 //chainlog.Debug("EventGetLastHeader", "success", "ok") 240 msg.Reply(chain.client.NewMessage("account", types.EventHeader, header)) 241 } 242 } 243 244 //共识过来的block是没有被执行的,首先判断此block的parent block是否是当前best链的tip 245 //在blockchain执行时需要做tx的去重处理,所以在执行成功之后需要将最新区块详情返回给共识模块 246 func (chain *BlockChain) addBlockDetail(msg *queue.Message) { 247 blockDetail := msg.Data.(*types.BlockDetail) 248 Height := blockDetail.Block.Height 249 chainlog.Debug("EventAddBlockDetail", "height", blockDetail.Block.Height, "parent", common.ToHex(blockDetail.Block.ParentHash)) 250 blockDetail, err := chain.ProcAddBlockMsg(true, blockDetail, "self") 251 if err != nil { 252 chainlog.Error("addBlockDetail", "height", Height, "procAddBlockMsg err", err.Error()) 253 msg.Reply(chain.client.NewMessage("consensus", types.EventAddBlockDetail, err)) 254 return 255 } 256 if blockDetail == nil { 257 err = types.ErrExecBlockNil 258 chainlog.Error("addBlockDetail", "height", Height, "nil block err", err.Error()) 259 msg.Reply(chain.client.NewMessage("consensus", types.EventAddBlockDetail, err)) 260 return 261 } 262 chainlog.Debug("addBlockDetail success ", "Height", Height, "hash", common.HashHex(blockDetail.Block.Hash(chain.client.GetConfig()))) 263 msg.Reply(chain.client.NewMessage("consensus", types.EventAddBlockDetail, blockDetail)) 264 } 265 266 //超前太多或者落后太多的广播区块都不做处理: 267 //当本节点在同步阶段并且远远落后主网最新高度时不处理广播block,暂定落后128个区块 268 //以免广播区块占用go goroutine资源 269 //目前回滚只支持10000个区块,所以收到落后10000高度之外的广播区块也不做处理 270 func (chain *BlockChain) broadcastAddBlock(msg *queue.Message) { 271 var reply types.Reply 272 reply.IsOk = true 273 blockwithpid := msg.Data.(*types.BlockPid) 274 275 castheight := blockwithpid.Block.Height 276 curheight := chain.GetBlockHeight() 277 278 futureMaximum := castheight > curheight+BackBlockNum 279 backWardMaximum := curheight > MaxRollBlockNum && castheight < curheight-MaxRollBlockNum 280 281 if futureMaximum || backWardMaximum { 282 chainlog.Debug("EventBroadcastAddBlock", "curheight", curheight, "castheight", castheight, "hash", common.ToHex(blockwithpid.Block.Hash(chain.client.GetConfig())), "pid", blockwithpid.Pid) 283 msg.Reply(chain.client.NewMessage("", types.EventReply, &reply)) 284 return 285 } 286 _, err := chain.ProcAddBlockMsg(true, &types.BlockDetail{Block: blockwithpid.Block}, blockwithpid.Pid) 287 if err != nil { 288 chainlog.Error("EventBroadcastAddBlock", "height", castheight, "err", err.Error()) 289 reply.IsOk = false 290 reply.Msg = []byte(err.Error()) 291 } 292 chainlog.Debug("EventBroadcastAddBlock", "height", castheight, "hash", common.ToHex(blockwithpid.Block.Hash(chain.client.GetConfig())), "pid", blockwithpid.Pid) 293 294 msg.Reply(chain.client.NewMessage("", types.EventReply, &reply)) 295 } 296 297 func (chain *BlockChain) getTransactionByAddr(msg *queue.Message) { 298 addr := (msg.Data).(*types.ReqAddr) 299 //chainlog.Warn("EventGetTransactionByAddr", "req", addr) 300 replyTxInfos, err := chain.ProcGetTransactionByAddr(addr) 301 if err != nil { 302 chainlog.Error("ProcGetTransactionByAddr", "err", err.Error()) 303 msg.Reply(chain.client.NewMessage("rpc", types.EventReplyTxInfo, err)) 304 } else { 305 //chainlog.Debug("EventGetTransactionByAddr", "success", "ok") 306 msg.Reply(chain.client.NewMessage("rpc", types.EventReplyTxInfo, replyTxInfos)) 307 } 308 } 309 310 func (chain *BlockChain) getTransactionByHashes(msg *queue.Message) { 311 txhashs := (msg.Data).(*types.ReqHashes) 312 //chainlog.Info("EventGetTransactionByHash", "hash", txhashs) 313 TransactionDetails, err := chain.ProcGetTransactionByHashes(txhashs.Hashes) 314 if err != nil { 315 chainlog.Error("ProcGetTransactionByHashes", "err", err.Error()) 316 msg.Reply(chain.client.NewMessage("rpc", types.EventTransactionDetails, err)) 317 } else { 318 //chainlog.Debug("EventGetTransactionByHash", "success", "ok") 319 msg.Reply(chain.client.NewMessage("rpc", types.EventTransactionDetails, TransactionDetails)) 320 } 321 } 322 323 func (chain *BlockChain) getBlockOverview(msg *queue.Message) { 324 ReqHash := (msg.Data).(*types.ReqHash) 325 BlockOverview, err := chain.ProcGetBlockOverview(ReqHash) 326 if err != nil { 327 chainlog.Error("ProcGetBlockOverview", "err", err.Error()) 328 msg.Reply(chain.client.NewMessage("rpc", types.EventReplyBlockOverview, err)) 329 } else { 330 //chainlog.Debug("ProcGetBlockOverview", "success", "ok") 331 msg.Reply(chain.client.NewMessage("rpc", types.EventReplyBlockOverview, BlockOverview)) 332 } 333 } 334 335 func (chain *BlockChain) getAddrOverview(msg *queue.Message) { 336 addr := (msg.Data).(*types.ReqAddr) 337 AddrOverview, err := chain.ProcGetAddrOverview(addr) 338 if err != nil { 339 chainlog.Error("ProcGetAddrOverview", "err", err.Error()) 340 msg.Reply(chain.client.NewMessage("rpc", types.EventReplyAddrOverview, err)) 341 } else { 342 //chainlog.Debug("ProcGetAddrOverview", "success", "ok") 343 msg.Reply(chain.client.NewMessage("rpc", types.EventReplyAddrOverview, AddrOverview)) 344 } 345 } 346 347 func (chain *BlockChain) getBlockHash(msg *queue.Message) { 348 height := (msg.Data).(*types.ReqInt) 349 replyhash, err := chain.ProcGetBlockHash(height) 350 if err != nil { 351 chainlog.Error("ProcGetBlockHash", "err", err.Error()) 352 msg.Reply(chain.client.NewMessage("rpc", types.EventBlockHash, err)) 353 } else { 354 //chainlog.Debug("ProcGetBlockHash", "success", "ok") 355 msg.Reply(chain.client.NewMessage("rpc", types.EventBlockHash, replyhash)) 356 } 357 } 358 359 func (chain *BlockChain) addBlockHeaders(msg *queue.Message) { 360 var reply types.Reply 361 reply.IsOk = true 362 headerspid := msg.Data.(*types.HeadersPid) 363 err := chain.ProcAddBlockHeadersMsg(headerspid.Headers, headerspid.Pid) 364 if err != nil { 365 chainlog.Error("addBlockHeaders", "err", err.Error()) 366 reply.IsOk = false 367 reply.Msg = []byte(err.Error()) 368 } else { 369 } 370 chainlog.Debug("addBlockHeaders", "pid", headerspid.Pid, "success", "ok") 371 msg.Reply(chain.client.NewMessage("p2p", types.EventReply, &reply)) 372 } 373 374 func (chain *BlockChain) getLastBlock(msg *queue.Message) { 375 block, err := chain.ProcGetLastBlockMsg() 376 if err != nil { 377 chainlog.Error("ProcGetLastBlockMsg", "err", err.Error()) 378 msg.Reply(chain.client.NewMessage("consensus", types.EventBlock, err)) 379 } else { 380 //chainlog.Debug("ProcGetLastBlockMsg", "success", "ok") 381 msg.Reply(chain.client.NewMessage("consensus", types.EventBlock, block)) 382 } 383 } 384 385 func (chain *BlockChain) isNtpClockSyncFunc(msg *queue.Message) { 386 ok := chain.GetNtpClockSyncStatus() 387 msg.Reply(chain.client.NewMessage("", types.EventReplyIsNtpClockSync, &types.IsNtpClockSync{Isntpclocksync: ok})) 388 } 389 390 type funcProcess func(msg *queue.Message) 391 392 func (chain *BlockChain) processMsg(msg *queue.Message, reqnum chan struct{}, cb funcProcess) { 393 beg := types.Now() 394 //NOTE: 由于部分msg做了内存回收处理,业务逻辑处理后不能对msg进行引用访问, 相关数据提前保存 395 ty := msg.Ty 396 defer func() { 397 <-reqnum 398 atomic.AddInt32(&chain.runcount, -1) 399 chainlog.Debug("process", "cost", types.Since(beg), "msg", types.GetEventName(int(ty))) 400 if r := recover(); r != nil { 401 chainlog.Error("blockchain panic error", "err", r) 402 msg.Reply(chain.client.NewMessage("", ty, fmt.Errorf("%s:%v", types.ErrExecPanic.Error(), r))) 403 return 404 } 405 }() 406 cb(msg) 407 } 408 409 //获取最新的block执行序列号 410 func (chain *BlockChain) getLastBlockSequence(msg *queue.Message) { 411 var lastSequence types.Int64 412 var err error 413 lastSequence.Data, err = chain.blockStore.LoadBlockLastSequence() 414 if err != nil { 415 chainlog.Debug("getLastBlockSequence", "err", err) 416 } 417 msg.Reply(chain.client.NewMessage("rpc", types.EventReplyLastBlockSequence, &lastSequence)) 418 } 419 420 //获取指定区间的block执行序列信息,包含blockhash和操作类型:add/del 421 func (chain *BlockChain) getBlockSequences(msg *queue.Message) { 422 requestSequences := (msg.Data).(*types.ReqBlocks) 423 BlockSequences, err := chain.GetBlockSequences(requestSequences) 424 if err != nil { 425 chainlog.Error("GetBlockSequences", "err", err.Error()) 426 msg.Reply(chain.client.NewMessage("rpc", types.EventReplyBlockSequences, err)) 427 } else { 428 msg.Reply(chain.client.NewMessage("rpc", types.EventReplyBlockSequences, BlockSequences)) 429 } 430 } 431 432 func (chain *BlockChain) getBlockByHashes(msg *queue.Message) { 433 blockhashes := (msg.Data).(*types.ReqHashes) 434 BlockDetails, err := chain.GetBlockByHashes(blockhashes.Hashes) 435 if err != nil { 436 chainlog.Error("GetBlockByHashes", "err", err.Error()) 437 msg.Reply(chain.client.NewMessage("rpc", types.EventBlocks, err)) 438 } else { 439 msg.Reply(chain.client.NewMessage("rpc", types.EventBlocks, BlockDetails)) 440 } 441 } 442 443 func (chain *BlockChain) getBlockBySeq(msg *queue.Message) { 444 seq := (msg.Data).(*types.Int64) 445 req := &types.ReqBlocks{Start: seq.Data, End: seq.Data, IsDetail: false, Pid: []string{}} 446 sequences, err := chain.GetBlockSequences(req) 447 if err != nil { 448 chainlog.Error("getBlockBySeq", "seqUpdateChan err", err.Error()) 449 msg.Reply(chain.client.NewMessage("rpc", types.EventGetBlockBySeq, err)) 450 return 451 } 452 reqHashes := &types.ReqHashes{Hashes: [][]byte{sequences.Items[0].Hash}} 453 blocks, err := chain.GetBlockByHashes(reqHashes.Hashes) 454 if err != nil { 455 chainlog.Error("getBlockBySeq", "hash err", err.Error()) 456 msg.Reply(chain.client.NewMessage("rpc", types.EventGetBlockBySeq, err)) 457 return 458 } 459 460 blockSeq := &types.BlockSeq{ 461 Num: seq.Data, 462 Seq: sequences.Items[0], 463 Detail: blocks.Items[0], 464 } 465 msg.Reply(chain.client.NewMessage("rpc", types.EventGetBlockBySeq, blockSeq)) 466 467 } 468 469 //平行链del block的处理 470 func (chain *BlockChain) delParaChainBlockDetail(msg *queue.Message) { 471 var parablockDetail *types.ParaChainBlockDetail 472 var reply types.Reply 473 reply.IsOk = true 474 parablockDetail = msg.Data.(*types.ParaChainBlockDetail) 475 476 chainlog.Debug("delParaChainBlockDetail", "height", parablockDetail.Blockdetail.Block.Height, "hash", common.HashHex(parablockDetail.Blockdetail.Block.Hash(chain.client.GetConfig()))) 477 478 // 平行链上P2P模块关闭,不用广播区块 479 err := chain.ProcDelParaChainBlockMsg(false, parablockDetail, "self") 480 if err != nil { 481 chainlog.Error("ProcDelParaChainBlockMsg", "err", err.Error()) 482 reply.IsOk = false 483 reply.Msg = []byte(err.Error()) 484 } 485 chainlog.Debug("delParaChainBlockDetail", "success", "ok") 486 msg.Reply(chain.client.NewMessage("p2p", types.EventReply, &reply)) 487 } 488 489 //平行链add block的处理 490 func (chain *BlockChain) addParaChainBlockDetail(msg *queue.Message) { 491 parablockDetail := msg.Data.(*types.ParaChainBlockDetail) 492 493 //根据配置chain.cfgBatchSync和parablockDetail.IsSync 494 //来决定写数据库时是否需要刷盘,主要是为了同步阶段提高执行区块的效率 495 if !parablockDetail.IsSync && !chain.cfgBatchSync { 496 atomic.CompareAndSwapInt32(&chain.isbatchsync, 1, 0) 497 } else { 498 atomic.CompareAndSwapInt32(&chain.isbatchsync, 0, 1) 499 } 500 501 chainlog.Debug("EventAddParaChainBlockDetail", "height", parablockDetail.Blockdetail.Block.Height, "hash", common.HashHex(parablockDetail.Blockdetail.Block.Hash(chain.client.GetConfig()))) 502 // 平行链上P2P模块关闭,不用广播区块 503 blockDetail, err := chain.ProcAddParaChainBlockMsg(false, parablockDetail, "self") 504 if err != nil { 505 chainlog.Error("ProcAddParaChainBlockMsg", "err", err.Error()) 506 msg.Reply(chain.client.NewMessage("p2p", types.EventReply, err)) 507 } 508 chainlog.Debug("EventAddParaChainBlockDetail", "success", "ok") 509 msg.Reply(chain.client.NewMessage("p2p", types.EventReply, blockDetail)) 510 } 511 512 //parachian 通过blockhash获取对应的seq,只记录了addblock时的seq 513 func (chain *BlockChain) getSeqByHash(msg *queue.Message) { 514 blockhash := (msg.Data).(*types.ReqHash) 515 seq, err := chain.ProcGetSeqByHash(blockhash.Hash) 516 if err != nil { 517 chainlog.Error("getSeqByHash", "err", err.Error()) 518 msg.Reply(chain.client.NewMessage("rpc", types.EventReply, err)) 519 } 520 msg.Reply(chain.client.NewMessage("rpc", types.EventGetSeqByHash, &types.Int64{Data: seq})) 521 } 522 523 //获取指定地址参与的tx交易计数 524 func (chain *BlockChain) localAddrTxCount(msg *queue.Message) { 525 reqkey := (msg.Data).(*types.ReqKey) 526 527 count := types.Int64{} 528 var counts int64 529 530 TxsCount, err := chain.blockStore.db.Get(reqkey.Key) 531 if err != nil && err != types.ErrNotFound { 532 counts = 0 533 chainlog.Error("localAddrTxCount", "err", err.Error()) 534 msg.Reply(chain.client.NewMessage("rpc", types.EventLocalReplyValue, &types.Int64{Data: counts})) 535 return 536 } 537 if len(TxsCount) == 0 { 538 counts = 0 539 chainlog.Error("localAddrTxCount", "TxsCount", "0") 540 msg.Reply(chain.client.NewMessage("rpc", types.EventLocalReplyValue, &types.Int64{Data: counts})) 541 return 542 } 543 err = types.Decode(TxsCount, &count) 544 if err != nil { 545 counts = 0 546 chainlog.Error("localAddrTxCount", "types.Decode", err) 547 msg.Reply(chain.client.NewMessage("rpc", types.EventLocalReplyValue, &types.Int64{Data: counts})) 548 return 549 } 550 counts = count.Data 551 msg.Reply(chain.client.NewMessage("rpc", types.EventLocalReplyValue, &types.Int64{Data: counts})) 552 } 553 554 //GetLastBlockMainSequence 获取最新的block执行序列号 555 func (chain *BlockChain) GetLastBlockMainSequence(msg *queue.Message) { 556 var lastSequence types.Int64 557 var err error 558 lastSequence.Data, err = chain.blockStore.LoadBlockLastMainSequence() 559 if err != nil { 560 chainlog.Debug("GetLastBlockMainSequence", "err", err) 561 msg.Reply(chain.client.NewMessage("rpc", types.EventReplyLastBlockMainSequence, err)) 562 return 563 } 564 msg.Reply(chain.client.NewMessage("rpc", types.EventReplyLastBlockMainSequence, &lastSequence)) 565 } 566 567 //GetMainSeqByHash parachian 通过blockhash获取对应的seq,只记录了addblock时的seq 568 func (chain *BlockChain) GetMainSeqByHash(msg *queue.Message) { 569 blockhash := (msg.Data).(*types.ReqHash) 570 seq, err := chain.ProcGetMainSeqByHash(blockhash.Hash) 571 if err != nil { 572 chainlog.Error("GetMainSeqByHash", "err", err.Error()) 573 msg.Reply(chain.client.NewMessage("rpc", types.EventReplyMainSeqByHash, err)) 574 return 575 } 576 msg.Reply(chain.client.NewMessage("rpc", types.EventReplyMainSeqByHash, &types.Int64{Data: seq})) 577 } 578 579 //setValueByKey 设置kv对到blockchain db中 580 func (chain *BlockChain) setValueByKey(msg *queue.Message) { 581 var reply types.Reply 582 reply.IsOk = true 583 if !chain.isParaChain { 584 reply.IsOk = false 585 reply.Msg = []byte("Must Para Chain Support!") 586 msg.Reply(chain.client.NewMessage("", types.EventReply, &reply)) 587 return 588 } 589 kvs := (msg.Data).(*types.LocalDBSet) 590 err := chain.SetValueByKey(kvs) 591 if err != nil { 592 chainlog.Error("setValueByKey", "err", err.Error()) 593 reply.IsOk = false 594 reply.Msg = []byte(err.Error()) 595 } 596 msg.Reply(chain.client.NewMessage("", types.EventReply, &reply)) 597 } 598 599 //GetValueByKey 获取value通过key从blockchain db中 600 func (chain *BlockChain) getValueByKey(msg *queue.Message) { 601 if !chain.isParaChain { 602 msg.Reply(chain.client.NewMessage("", types.EventLocalReplyValue, nil)) 603 return 604 } 605 keys := (msg.Data).(*types.LocalDBGet) 606 values := chain.GetValueByKey(keys) 607 msg.Reply(chain.client.NewMessage("", types.EventLocalReplyValue, values)) 608 } 609 610 //getParaTxByTitle //通过平行链title获取平行链的交易 611 func (chain *BlockChain) getParaTxByTitle(msg *queue.Message) { 612 req := (msg.Data).(*types.ReqParaTxByTitle) 613 reply, err := chain.GetParaTxByTitle(req) 614 if err != nil { 615 chainlog.Error("getParaTxByTitle", "req", req, "err", err.Error()) 616 msg.Reply(chain.client.NewMessage("", types.EventReplyParaTxByTitle, err)) 617 return 618 } 619 msg.Reply(chain.client.NewMessage("", types.EventReplyParaTxByTitle, reply)) 620 } 621 622 //getHeightByTitle //获取拥有此title交易的区块高度 623 func (chain *BlockChain) getHeightByTitle(msg *queue.Message) { 624 req := (msg.Data).(*types.ReqHeightByTitle) 625 reply, err := chain.LoadParaTxByTitle(req) 626 if err != nil { 627 chainlog.Error("getHeightByTitle", "req", req, "err", err.Error()) 628 msg.Reply(chain.client.NewMessage("", types.EventReplyHeightByTitle, err)) 629 return 630 } 631 msg.Reply(chain.client.NewMessage("", types.EventReplyHeightByTitle, reply)) 632 } 633 634 //getParaTxByTitleAndHeight //通过区块高度列表+title获取平行链交易 635 func (chain *BlockChain) getParaTxByTitleAndHeight(msg *queue.Message) { 636 req := (msg.Data).(*types.ReqParaTxByHeight) 637 reply, err := chain.GetParaTxByHeight(req) 638 if err != nil { 639 chainlog.Error("getParaTxByTitleAndHeight", "req", req, "err", err.Error()) 640 msg.Reply(chain.client.NewMessage("", types.EventReplyParaTxByTitle, err)) 641 return 642 } 643 msg.Reply(chain.client.NewMessage("", types.EventReplyParaTxByTitle, reply)) 644 } 645 646 // getChunkRecord // 获取当前chunk record 647 func (chain *BlockChain) getChunkRecord(msg *queue.Message) { 648 req := (msg.Data).(*types.ReqChunkRecords) 649 reply, err := chain.GetChunkRecord(req) 650 if err != nil { 651 chainlog.Error("getChunkRecord", "req", req, "err", err.Error()) 652 msg.Reply(chain.client.NewMessage("", types.EventGetChunkRecord, &types.Reply{IsOk: false, Msg: []byte(err.Error())})) 653 return 654 } 655 chainlog.Debug("getChunkRecord", "start", req.Start, "end", req.End) 656 msg.Reply(chain.client.NewMessage("", types.EventGetChunkRecord, reply)) 657 } 658 659 // addChunkRecord // 添加chunk record 660 func (chain *BlockChain) addChunkRecord(msg *queue.Message) { 661 req := (msg.Data).(*types.ChunkRecords) 662 chain.AddChunkRecord(req) 663 for _, info := range req.Infos { 664 chain.chunkRecordTask.Done(info.ChunkNum) 665 chainlog.Debug("addChunkRecord", "chunkNum", info.ChunkNum, "chunkHash", common.ToHex(info.ChunkHash)) 666 } 667 } 668 669 // getChunkBlockBody // 获取chunk BlockBody 670 func (chain *BlockChain) getChunkBlockBody(msg *queue.Message) { 671 req := (msg.Data).(*types.ChunkInfoMsg) 672 if req.End < (atomic.LoadInt64(&chain.maxSerialChunkNum)-int64(DelRollbackChunkNum)+1)*chain.cfg.ChunkblockNum { 673 msg.Reply(chain.client.NewMessage("", types.EventGetChunkBlockBody, types.ErrNotFound)) 674 return 675 } 676 reply, err := chain.GetChunkBlockBody(req) 677 if err != nil { 678 msg.Reply(chain.client.NewMessage("", types.EventGetChunkBlockBody, &types.Reply{IsOk: false, Msg: []byte(err.Error())})) 679 return 680 } 681 chainlog.Debug("getChunkBlockBody", "start", req.Start, "end", req.End, "chunkHash", common.ToHex(req.ChunkHash)) 682 msg.Reply(chain.client.NewMessage("", types.EventGetChunkBlockBody, reply)) 683 } 684 685 // addChunkBlock // 添加chunk Block 686 func (chain *BlockChain) addChunkBlock(msg *queue.Message) { 687 blocks := (msg.Data).(*types.Blocks) 688 if blocks == nil || len(blocks.Items) == 0 { 689 str := "blocks is nil" 690 chainlog.Error("addChunkBlock", "err", str) 691 return 692 } 693 694 if chain.GetDownloadSyncStatus() == chunkDownLoadMode { 695 for _, blk := range blocks.Items { 696 chain.WriteBlockToDbTemp(blk, true) 697 //downLoadTask 运行时设置对应的blockdone 698 if chain.downLoadTask.InProgress() { 699 chain.downLoadTask.Done(blk.Height) 700 } 701 } 702 } else { 703 for _, blk := range blocks.Items { 704 _, err := chain.ProcAddBlockMsg(false, &types.BlockDetail{Block: blk}, "-self") //这里认为非自己节点 705 if err != nil { 706 chainlog.Error("addChunkBlock ProcAddBlockMsg", "height", blk.Height, "err", err.Error()) 707 return 708 } 709 } 710 } 711 chainlog.Debug("addChunkBlock", "start", blocks.Items[0].Height, "end", blocks.Items[len(blocks.Items)-1].Height) 712 } 713 714 func (chain *BlockChain) subscribePush(msg *queue.Message) { 715 reply := &types.ReplySubscribePush{ 716 IsOk: true, 717 Msg: "Succeed", 718 } 719 subReq := (msg.Data).(*types.PushSubscribeReq) 720 err := chain.procSubscribePush(subReq) 721 if err != nil { 722 reply.IsOk = false 723 reply.Msg = err.Error() 724 msg.Reply(chain.client.NewMessage("rpc", types.EventReplySubscribePush, reply)) 725 return 726 } 727 728 msg.Reply(chain.client.NewMessage("rpc", types.EventReplySubscribePush, reply)) 729 }