github.com/turingchain2020/turingchain@v1.1.21/system/mempool/eventprocess.go (about)

     1  package mempool
     2  
     3  import (
     4  	"github.com/turingchain2020/turingchain/queue"
     5  	"github.com/turingchain2020/turingchain/types"
     6  )
     7  
     8  func (mem *Mempool) reply() {
     9  	defer mlog.Info("piple line quit")
    10  	defer mem.wg.Done()
    11  	for m := range mem.out {
    12  		if m.Err() != nil {
    13  			m.Reply(mem.client.NewMessage("rpc", types.EventReply,
    14  				&types.Reply{IsOk: false, Msg: []byte(m.Err().Error())}))
    15  		} else { //TODO, rpc和p2p交易发送需要区分, rpc需要消息答复,p2p不需要
    16  			mem.sendTxToP2P(m.GetData().(types.TxGroup).Tx())
    17  			m.Reply(mem.client.NewMessage("rpc", types.EventReply, &types.Reply{IsOk: true, Msg: nil}))
    18  		}
    19  	}
    20  }
    21  
    22  func (mem *Mempool) pipeLine() <-chan *queue.Message {
    23  	//check sign
    24  	step1 := func(data *queue.Message) *queue.Message {
    25  		if data.Err() != nil {
    26  			return data
    27  		}
    28  		return mem.checkSign(data)
    29  	}
    30  	chs := make([]<-chan *queue.Message, processNum)
    31  	for i := 0; i < processNum; i++ {
    32  		chs[i] = step(mem.done, mem.in, step1)
    33  	}
    34  	out1 := merge(mem.done, chs)
    35  
    36  	//checktx remote
    37  	step2 := func(data *queue.Message) *queue.Message {
    38  		if data.Err() != nil {
    39  			return data
    40  		}
    41  		return mem.checkTxRemote(data)
    42  	}
    43  	chs2 := make([]<-chan *queue.Message, processNum)
    44  	for i := 0; i < processNum; i++ {
    45  		chs2[i] = step(mem.done, out1, step2)
    46  	}
    47  	return merge(mem.done, chs2)
    48  }
    49  
    50  // 处理其他模块的消息
    51  func (mem *Mempool) eventProcess() {
    52  	defer mem.wg.Done()
    53  	defer close(mem.in)
    54  	//event process
    55  	mem.out = mem.pipeLine()
    56  	mlog.Info("mempool piple line start")
    57  	mem.wg.Add(1)
    58  	go mem.reply()
    59  
    60  	for msg := range mem.client.Recv() {
    61  		//NOTE: 由于部分msg做了内存回收处理,业务逻辑处理后不能对msg进行引用访问, 相关数据提前保存
    62  		msgName := types.GetEventName(int(msg.Ty))
    63  		mlog.Debug("mempool recv", "msgid", msg.ID, "msg", msgName)
    64  		beg := types.Now()
    65  		switch msg.Ty {
    66  		case types.EventTx:
    67  			mem.eventTx(msg)
    68  		case types.EventGetMempool:
    69  			// 消息类型EventGetMempool:获取mempool内所有交易
    70  			mem.eventGetMempool(msg)
    71  		case types.EventTxList:
    72  			// 消息类型EventTxList:获取mempool中一定数量交易
    73  			mem.eventTxList(msg)
    74  		case types.EventDelTxList:
    75  			// 消息类型EventDelTxList:获取mempool中一定数量交易,并把这些交易从mempool中删除
    76  			mem.eventDelTxList(msg)
    77  		case types.EventAddBlock:
    78  			// 消息类型EventAddBlock:将添加到区块内的交易从mempool中删除
    79  			mem.eventAddBlock(msg)
    80  		case types.EventGetMempoolSize:
    81  			// 消息类型EventGetMempoolSize:获取mempool大小
    82  			mem.eventGetMempoolSize(msg)
    83  		case types.EventGetLastMempool:
    84  			// 消息类型EventGetLastMempool:获取最新十条加入到mempool的交易
    85  			mem.eventGetLastMempool(msg)
    86  		case types.EventDelBlock:
    87  			// 回滚区块,把该区块内交易重新加回mempool
    88  			mem.eventDelBlock(msg)
    89  		case types.EventGetAddrTxs:
    90  			// 获取mempool中对应账户(组)所有交易
    91  			mem.eventGetAddrTxs(msg)
    92  		case types.EventGetProperFee:
    93  			// 获取对应排队策略中合适的手续费
    94  			mem.eventGetProperFee(msg)
    95  			// 消息类型EventTxListByHash:通过hash获取对应的tx列表
    96  		case types.EventTxListByHash:
    97  			mem.eventTxListByHash(msg)
    98  		case types.EventCheckTxsExist:
    99  			mem.eventCheckTxsExist(msg)
   100  		default:
   101  		}
   102  		mlog.Debug("mempool", "cost", types.Since(beg), "msg", msgName)
   103  	}
   104  }
   105  
   106  //EventTx 初步筛选后存入mempool
   107  func (mem *Mempool) eventTx(msg *queue.Message) {
   108  	if !mem.getSync() {
   109  		msg.Reply(mem.client.NewMessage("", types.EventReply, &types.Reply{Msg: []byte(types.ErrNotSync.Error())}))
   110  		mlog.Debug("wrong tx", "err", types.ErrNotSync.Error())
   111  	} else {
   112  		checkedMsg := mem.checkTxs(msg)
   113  		select {
   114  		case mem.in <- checkedMsg:
   115  		case <-mem.done:
   116  		}
   117  	}
   118  }
   119  
   120  // EventGetMempool 获取Mempool内所有交易
   121  func (mem *Mempool) eventGetMempool(msg *queue.Message) {
   122  	var isAll bool
   123  	if msg.GetData() == nil {
   124  		isAll = false
   125  	} else {
   126  		isAll = msg.GetData().(*types.ReqGetMempool).GetIsAll()
   127  	}
   128  	msg.Reply(mem.client.NewMessage("rpc", types.EventReplyTxList,
   129  		&types.ReplyTxList{Txs: mem.filterTxList(0, nil, isAll)}))
   130  }
   131  
   132  // EventDelTxList 获取Mempool中一定数量交易,并把这些交易从Mempool中删除
   133  func (mem *Mempool) eventDelTxList(msg *queue.Message) {
   134  	hashList := msg.GetData().(*types.TxHashList)
   135  	if len(hashList.GetHashes()) == 0 {
   136  		msg.ReplyErr("EventDelTxList", types.ErrSize)
   137  	} else {
   138  		err := mem.RemoveTxs(hashList)
   139  		msg.ReplyErr("EventDelTxList", err)
   140  	}
   141  }
   142  
   143  // EventTxList 获取mempool中一定数量交易
   144  func (mem *Mempool) eventTxList(msg *queue.Message) {
   145  	hashList := msg.GetData().(*types.TxHashList)
   146  	if hashList.Count <= 0 {
   147  		msg.Reply(mem.client.NewMessage("", types.EventReplyTxList, types.ErrSize))
   148  		mlog.Error("not an valid size", "msg", msg)
   149  	} else {
   150  		txList := mem.getTxList(hashList)
   151  		msg.Reply(mem.client.NewMessage("", types.EventReplyTxList, &types.ReplyTxList{Txs: txList}))
   152  	}
   153  }
   154  
   155  // EventAddBlock 将添加到区块内的交易从mempool中删除
   156  func (mem *Mempool) eventAddBlock(msg *queue.Message) {
   157  	block := msg.GetData().(*types.BlockDetail).Block
   158  	height := mem.Height()
   159  	if block.Height > height || (block.Height == 0 && height == 0) {
   160  		header := &types.Header{}
   161  		header.BlockTime = block.BlockTime
   162  		header.Height = block.Height
   163  		header.StateHash = block.StateHash
   164  		mem.setHeader(header)
   165  	}
   166  	//同步状态等mempool中不存在交易时,不需要执行操作
   167  	if mem.Size() > 0 {
   168  		mem.RemoveTxsOfBlock(block)
   169  		mem.removeExpired()
   170  	}
   171  }
   172  
   173  // EventGetMempoolSize 获取mempool大小
   174  func (mem *Mempool) eventGetMempoolSize(msg *queue.Message) {
   175  	memSize := int64(mem.Size())
   176  	msg.Reply(mem.client.NewMessage("rpc", types.EventMempoolSize,
   177  		&types.MempoolSize{Size: memSize}))
   178  }
   179  
   180  // EventGetLastMempool 获取最新十条加入到mempool的交易
   181  func (mem *Mempool) eventGetLastMempool(msg *queue.Message) {
   182  	txList := mem.GetLatestTx()
   183  	msg.Reply(mem.client.NewMessage("rpc", types.EventReplyTxList,
   184  		&types.ReplyTxList{Txs: txList}))
   185  }
   186  
   187  // EventDelBlock 回滚区块,把该区块内交易重新加回mempool
   188  func (mem *Mempool) eventDelBlock(msg *queue.Message) {
   189  	block := msg.GetData().(*types.BlockDetail).Block
   190  	if block.Height != mem.GetHeader().GetHeight() {
   191  		return
   192  	}
   193  	lastHeader, err := mem.GetLastHeader()
   194  	if err != nil {
   195  		mlog.Error(err.Error())
   196  		return
   197  	}
   198  	h := lastHeader.(*queue.Message).Data.(*types.Header)
   199  	mem.setHeader(h)
   200  	mem.delBlock(block)
   201  }
   202  
   203  // eventGetAddrTxs 获取mempool中对应账户(组)所有交易
   204  func (mem *Mempool) eventGetAddrTxs(msg *queue.Message) {
   205  	addrs := msg.GetData().(*types.ReqAddrs)
   206  	txlist := mem.GetAccTxs(addrs)
   207  	msg.Reply(mem.client.NewMessage("", types.EventReplyAddrTxs, txlist))
   208  }
   209  
   210  // eventGetProperFee 获取排队策略中合适的手续费率
   211  func (mem *Mempool) eventGetProperFee(msg *queue.Message) {
   212  	req, _ := msg.GetData().(*types.ReqProperFee)
   213  	properFee := mem.GetProperFeeRate(req)
   214  	msg.Reply(mem.client.NewMessage("rpc", types.EventReplyProperFee,
   215  		&types.ReplyProperFee{ProperFee: properFee}))
   216  }
   217  
   218  func (mem *Mempool) checkSign(data *queue.Message) *queue.Message {
   219  	tx, ok := data.GetData().(types.TxGroup)
   220  	if ok && tx.CheckSign() {
   221  		return data
   222  	}
   223  	mlog.Error("wrong tx", "err", types.ErrSign)
   224  	data.Data = types.ErrSign
   225  	return data
   226  }
   227  
   228  // eventTxListByHash 通过hash获取tx列表
   229  func (mem *Mempool) eventTxListByHash(msg *queue.Message) {
   230  	shashList := msg.GetData().(*types.ReqTxHashList)
   231  	replytxList := mem.getTxListByHash(shashList)
   232  	msg.Reply(mem.client.NewMessage("", types.EventReplyTxList, replytxList))
   233  }
   234  
   235  // eventCheckTxsExist 查找交易是否存在
   236  func (mem *Mempool) eventCheckTxsExist(msg *queue.Message) {
   237  	mem.proxyMtx.Lock()
   238  	defer mem.proxyMtx.Unlock()
   239  	reply := &types.ReplyCheckTxsExist{}
   240  	//非同步状态时mempool通常不存在交易,直接返回不做比对
   241  	if mem.sync {
   242  		hashes := msg.GetData().(*types.ReqCheckTxsExist).TxHashes
   243  		reply.ExistFlags = make([]bool, len(hashes))
   244  		for i, hash := range hashes {
   245  			reply.ExistFlags[i] = mem.cache.Exist(types.Bytes2Str(hash))
   246  			if reply.ExistFlags[i] {
   247  				reply.ExistCount++
   248  			}
   249  		}
   250  	}
   251  	msg.Reply(mem.client.NewMessage("", types.EventReply, reply))
   252  }